!939 功能:设置见光面封边 命令:SetSmoothEdge

pull/939/MERGE
ZoeLeeFZ 5 years ago committed by ChenX
parent 4fde14ab05
commit 8423f5f25b

@ -0,0 +1,138 @@
import { Button, Classes, H5, UL } from "@blueprintjs/core";
import { observer } from "mobx-react";
import * as React from 'react';
import { app } from "../../ApplicationServices/Application";
import { CheckObjectType } from "../../Common/CheckoutVaildValue";
import { Board } from "../../DatabaseServices/Entity/Board";
import { Command } from "../../Editor/CommandMachine";
import { PromptStatus } from "../../Editor/PromptResult";
import { SetBoardDataItem } from "../../UI/Components/Board/BoardCommon";
import { BoardModalType } from "../../UI/Components/Board/BoardModal";
import { CommonModal } from "../../UI/Components/Modal/ModalContainer";
import { userConfigStore } from "../../UI/Store/UserConfigStore";
import { smoothEdgeStore, SmoothEdgeStore } from "./SmoothEdgeStore";
import { SetSmoothEdges } from "./SetSmoothEdgeFace";
export class SetSmoothEdge implements Command
{
async exec()
{
let brRes = await app.Editor.GetSelection({
Msg: "选择板件",
Filter: { filterTypes: [Board] }
});
if (brRes.Status === PromptStatus.Cancel) return;
app.Editor.ModalManage.RenderModal(SetSmoothEdgeModal, { brs: brRes.SelectSet.SelectEntityList, store: smoothEdgeStore });
await app.Editor.ModalManage.Wait();
}
}
@observer
class SetSmoothEdgeModal extends React.Component<{ brs: Board[]; store: SmoothEdgeStore; }>
{
renderItem = () =>
{
const store = this.props.store;
const els: JSX.Element[] = [];
const kv = {
smoothEdge: "见光面封边",
edge: "不见光封边",
scale: "见光面比例",
};
for (let key in store.option)
{
if (key !== "filterArr")
els.push(
<SetBoardDataItem
title={kv[key]}
type={CheckObjectType.SmoothEdge}
optKey={key}
option={store.option}
uiOption={store.UiOption}
>
{
key === "scale" && "%"
}
</SetBoardDataItem>
);
}
return els;
};
async UNSAFE_componentWillMount()
{
const smoothEdgeStore = this.props.store;
if (!userConfigStore.readConfigs.has(BoardModalType.SmoothEdge))
{
await userConfigStore.UpdateBoardOption(smoothEdgeStore.configName, BoardModalType.SmoothEdge, smoothEdgeStore);
}
}
render()
{
const { store } = this.props;
return (
<CommonModal
title="设置见光面封边"
icon="bold"
close={this.cancel}
hasConfig={false}
footerChildren={
<>
<Button
className={Classes.INTENT_SUCCESS}
text="确定"
onClick={this.confirm} />
<Button
className={Classes.INTENT_DANGER}
text="取消"
onClick={this.cancel} />
</>
}
footerStyle={{ width: "100%" }}
>
<div className="smooth-edge">
{
this.renderItem()
}
<H5>
</H5>
<UL className={Classes.LIST_UNSTYLED}>
{
store.option.filterArr.map((s, i) => <li>
<input type="text" value={store.option.filterArr[i]} onChange={e => store.option.filterArr[i] = e.target.value} />
</li>)
}
</UL>
</div>
</CommonModal>
);
}
confirm = () =>
{
const store = this.props.store;
app.Editor.ModalManage.Destory();
const brs = this.props.brs;
if (this.props.brs.length === 1)
{
let edge = store.option.smoothEdge.toString();
this.props.brs[0].BoardProcessOption.sealedLeft = edge;
this.props.brs[0].BoardProcessOption.sealedRight = edge;
this.props.brs[0].BoardProcessOption.sealedUp = edge;
this.props.brs[0].BoardProcessOption.sealedDown = edge;
this.props.brs[0].BoardProcessOption.highSealed.forEach(d => d.size = store.option.smoothEdge);
}
else
{
SetSmoothEdges(brs, store.option);
}
userConfigStore.SaveConfig(BoardModalType.SmoothEdge, store, { toaster: false });
};
cancel = () =>
{
app.Editor.ModalManage.Destory();
};
}

@ -0,0 +1,160 @@
import { BoardGetFace, GetSideFaceMtx, BoardFaceType, MatrixIsCoplane2 } from "../../Geometry/DrillParse/BoardGetFace";
import { Curve } from "../../DatabaseServices/Entity/Curve";
import { equaln } from "../../Geometry/GeUtils";
import { Arc } from "../../DatabaseServices/Entity/Arc";
import { GetBoardSealingCurves, GetBoardHighSeal, HandleRectBoardSealingData } from "../../GraphicsSystem/CalcEdgeSealing";
import { Face } from "../../Geometry/DrillParse/Face";
import { Matrix4 } from "three";
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
import { Board } from "../../DatabaseServices/Entity/Board";
import { Box3Ext } from "../../Geometry/Box";
import { ISmoothEdgeOption, IHighSealedItem } from "../../UI/Store/BoardInterface";
class SetSmoothEdgeFaces extends BoardGetFace
{
FaceSealingDataMap: Map<Face, number>;
SmoothFace = new Set<Face>();
highSealingData: IHighSealedItem[];
private sealCus: Curve[];
constructor(public Board: Board)
{
super(Board);
}
GetTopAndBottomFace()
{
super.GetTopAndBottomFace(true);
}
GetSideFaces()
{
this.FaceSealingDataMap = new Map();
let con = this.Board.ContourCurve.Clone();
let inverseZ = con.Area2 < 0;
let sealCus = GetBoardSealingCurves(this.Board);
this.highSealingData = GetBoardHighSeal(this.Board, sealCus);
this.sealCus = sealCus;
for (let i = 0; i < sealCus.length; i++)
{
let sealCu = sealCus[i];
let cus: Curve[];
if (sealCu instanceof Polyline)
{
cus = sealCu.Explode();
}
else
cus = [sealCu];
for (let cu of cus)
{
let length = cu.Length;
if (equaln(length, 0) || cu instanceof Arc)
continue;
let mtx = GetSideFaceMtx(cu, inverseZ);
let f = new Face({
type: BoardFaceType.Side,
localBoard: this.Board,
isPositiveFace: true,
matrix4: new Matrix4().multiplyMatrices(this.Board.OCS.clone(), mtx),
length,
width: this.Board.Thickness,
});
this.FaceSealingDataMap.set(f, i);
this.Faces.push(f);
}
}
}
GetSmoothFaces(bg: this)
{
for (let f1 of this.Faces)
{
if (this.SmoothFace.has(f1)) continue;
for (let f2 of bg.Faces)
{
if (bg.SmoothFace.has(f2)) continue;
//都是正面,或者不允许侧面同侧面并且2板件类型不一样就跳过
if (f1.type === f2.type
&& (f1.type === BoardFaceType.NoSide || bg.Board.BoardType !== this.Board.BoardType)
)
continue;
//不共面
if (!MatrixIsCoplane2(f1.OCS, f2.OCS, 1e-2))
continue;
if (f1.IsIntersect(f2))
{
if (f1.type === BoardFaceType.Side)
{
this.SmoothFace.add(f1);
}
if (f2.type === BoardFaceType.Side)
{
bg.SmoothFace.add(f2);
}
}
}
}
}
WriteSealingData(option: ISmoothEdgeOption)
{
let useIndex = new Set<number>();
for (let f of this.Faces)
{
if (f.type === BoardFaceType.Side && !this.SmoothFace.has(f))
{
let index = this.FaceSealingDataMap.get(f);
if (index !== undefined)
{
this.highSealingData[index].size = option.smoothEdge;
useIndex.add(index);
}
}
}
for (let i = 0; i < this.highSealingData.length; i++)
{
if (!useIndex.has(i))
this.highSealingData[i].size = option.edge;
}
this.Board.BoardProcessOption.highSealed = this.highSealingData;
HandleRectBoardSealingData(this.Board, this.highSealingData, this.sealCus);
}
}
export function SetSmoothEdges(brs: Board[], option: ISmoothEdgeOption)
{
if (brs.length === 0) return;
let BoardGeList: SetSmoothEdgeFaces[] = [];
let boxCache: Map<Board, Box3Ext> = new Map();
let ocsInv = brs[0].OCSInv;
let filterArr = option.filterArr.filter(s => s);
for (let b of brs)
{
BoardGeList.push(new SetSmoothEdgeFaces(b));
boxCache.set(b, b.GetBoundingBoxInMtx(ocsInv));
}
for (let i = 0; i < BoardGeList.length; i++)
{
let f = BoardGeList[i];
let localBox = boxCache.get(f.Board);
if (filterArr.some(s => f.Board.Name.includes(s))) continue;
for (let j = i + 1; j < BoardGeList.length; j++)
{
let f1 = BoardGeList[j];
let interBox = boxCache.get(f1.Board);
//板件包围盒相交
if (localBox.intersectsBox(interBox, 1e-2))
f.GetSmoothFaces(f1);
}
}
for (let brGe of BoardGeList)
{
brGe.WriteSealingData(option);
}
}

@ -0,0 +1,49 @@
import { IConfigStore } from "../../UI/Store/BoardStore";
import { observable, toJS } from "mobx";
import { ISmoothEdgeOption, IUiOption } from "../../UI/Store/BoardInterface";
import { IConfigOption } from "../../UI/Components/Board/UserConfig";
import { DataAdapter } from "../../Common/DataAdapter";
export class SmoothEdgeStore implements IConfigStore
{
@observable option: ISmoothEdgeOption = {
smoothEdge: 0,
edge: 0,
scale: 5,
filterArr: new Array(10).fill(""),
};
@observable uiOption: IUiOption<ISmoothEdgeOption>;
configName = "default";
configsNames = ['default'];
InitOption()
{
Object.assign(this.option, {
smoothEdge: 0,
edge: 0,
scale: 5,
filterArr: new Array(10).fill(""),
});
}
get UiOption()
{
if (!this.uiOption)
this.uiOption = DataAdapter.ConvertUIData(this.option);
return this.uiOption;
}
SaveConfig()
{
//新的配置
let newConfig: IConfigOption<ISmoothEdgeOption> = {};
newConfig.option = toJS(this.option);
return newConfig;
}
UpdateOption(cof: IConfigOption<ISmoothEdgeOption>)
{
Object.assign(this.option, cof.option);
if (this.uiOption)
Object.assign(this.uiOption, DataAdapter.ConvertUIData(cof.option));
}
}
export const smoothEdgeStore = new SmoothEdgeStore();

@ -13,7 +13,7 @@ export class Command_ShowProcessingGroupModal2 implements Command
if (!config)
{
store.processGroupCategory = ["抽屉", "格子抽", "裤抽", "酒格", "弧形", "拼框门", "异形加工"];
userConfigStore.SaveConfig(BoardModalType.ProcessGroupCategory, ProcessingGroupModalStore.GetInstance(), true);
userConfigStore.SaveConfig(BoardModalType.ProcessGroupCategory, ProcessingGroupModalStore.GetInstance(), { isInit: true, toaster: false });
}
else
store.processGroupCategory = config.processGroupCategory;

@ -17,6 +17,7 @@ export enum CheckObjectType
R2B = "rec2br",
OnlyNumber = "onlyNum",
None = "none",
SmoothEdge = "smoothEdge"
}
export namespace CheckoutValid
@ -102,6 +103,12 @@ export namespace CheckoutValid
case CheckObjectType.OnlyNumber:
if (!isNum(v))
return "数值不能为空且必须为数字";
case CheckObjectType.SmoothEdge:
if (!isNum(v))
return "数值不能为空且必须为数字";
let val = safeEval(v);
if (val < 0)
return "数值不能小于0";
default:
return "";
}

@ -170,6 +170,7 @@ import { CreatePolyLineFromCurve } from "../Add-on/twoD2threeD/CreatePolyLineFro
import { RectConvertToBoard } from "../Add-on/twoD2threeD/RectConvertToBr";
import { Command_EraseLineAndArc } from "../Add-on/EraseLineAndArc";
import { Command_TestRegionParse } from "../Add-on/testEntity/TestRegionParse";
import { SetSmoothEdge } from "../Add-on/SetSmoothEdge/SetSmoothEdge";
export function registerCommand()
{
@ -470,6 +471,8 @@ export function registerCommand()
commandMachine.RegisterCommand("curve2rec", new CreatePolyLineFromCurve());
commandMachine.RegisterCommand("r2b", new RectConvertToBoard());
commandMachine.RegisterCommand("SetSmoothEdge", new SetSmoothEdge());
RegistCustomCommand();
}

@ -28,7 +28,7 @@ export class BoardGetFace
//侧面
this.GetSideFaces();
}
GetTopAndBottomFace()
GetTopAndBottomFace(isEdgeFace = false)
{
let curve = this.Board.ContourCurve;
let reg: Region;
@ -39,7 +39,7 @@ export class BoardGetFace
let ocs = this.Board.OCS;
const opt = this.Board.BoardProcessOption;
//正反面
if (opt.frontDrill)
if (opt.frontDrill || isEdgeFace)
this.Faces.push(new Face({
type: BoardFaceType.NoSide,
region: reg,
@ -52,7 +52,7 @@ export class BoardGetFace
width: this.Board.Height
}));
if (opt.backDrill)
if (opt.backDrill || isEdgeFace)
{
let mat = GetMirrorMat(ZAxis).setPosition(new Vector3());
this.Faces.push(new Face({
@ -143,7 +143,7 @@ export class BoardGetFace
}
//坐标系共面且法线相反
function MatrixIsCoplane2(matrixFrom: Matrix4, matrixTo: Matrix4, fuzz = 1e-5): boolean
export function MatrixIsCoplane2(matrixFrom: Matrix4, matrixTo: Matrix4, fuzz = 1e-5): boolean
{
let nor1 = new Vector3().setFromMatrixColumn(matrixFrom, 2);
let nor2 = new Vector3().setFromMatrixColumn(matrixTo, 2);

@ -146,4 +146,50 @@ export class Face
}
return newFaces;
}
IsIntersect(f: Face): boolean
{
//获得侧面和非侧面
let [sideFace, noSideFace] = this.type === BoardFaceType.Side ? [this, f] : [f, this];
//布尔面和被布尔面得差异矩阵
let diffMtx = sideFace.OCSInv.multiply(noSideFace.OCS);
MatrixPlanarizere(diffMtx);
let x = new Vector3().setFromMatrixColumn(diffMtx, 0);
let ang = x.angleTo(XAxis);
//盒子旋转0,90,180度不会被破坏
let canUseBoxCalc = equaln(ang, 0) || equaln(ang, Math.PI / 2) || equaln(ang, Math.PI);
//如果不是矩形,用布尔运算,如果
if (!noSideFace.IsRect || !canUseBoxCalc)
{
let c1 = new Polyline().Rectangle(this.Length, this.Width);
let c2 = noSideFace.LocalBoard.ContourCurve.Clone().ApplyMatrix(diffMtx);
let box = c1.BoundingBox.intersect(c2.BoundingBox);
let size = box.getSize(new Vector3);
if (equaln(size.x * size.y, 0))
return false;
return c1.IntersectWith(c2, 0).length > 1;
}
else
{
let retBox = new Box3Ext(new Vector3(), new Vector3(sideFace.Length, sideFace.Width));
let p1 = new Vector3().setFromMatrixPosition(diffMtx);
let p2 = new Vector3(noSideFace.Length, noSideFace.Width).applyMatrix4(diffMtx);
let box3 = new Box3Ext().setFromPoints([p1, p2]);
if (retBox.intersectsBox(box3))
{
retBox.intersect(box3);
let size = retBox.getSize(new Vector3());
return !equaln(size.x * size.y, 0);
}
}
return false;
}
}

@ -184,8 +184,9 @@ export function GetBoardHighSeal(br: Board, sealcus: Curve[])
/**
* 线
* 线,
* isOffset-
* */
export function GetBoardSealingCurves(br: Board, isLook = false): Curve[]
export function GetBoardSealingCurves(br: Board, isOffset = false): Curve[]
{
let cu: ExtureContourCurve = Production.GetSpliteOutlineBySpliteSize(br);
if (cu)
@ -193,7 +194,7 @@ export function GetBoardSealingCurves(br: Board, isLook = false): Curve[]
let cus: Curve[] = [];
cu = Production.GetSpliteOutline(br, false);
if (isLook)
if (isOffset)
{
let dir = Math.sign(cu.Area2);
let newCu = cu.GetOffsetCurves(-1 * dir)[0] as ExtureContourCurve;

@ -41,7 +41,8 @@ export enum BoardModalType
ToplineMetals = "toplinemetals", //顶线五金
UserConfig = "userConfig", //用户配置
Curves2Rec = "curves2rec",//线条转矩形
Rec2Br = "rec2br"
Rec2Br = "rec2br",
SmoothEdge = "smoothEdge",
}
export interface BoardModalProps
{

@ -61,7 +61,7 @@ export class DrillModal extends React.Component<{ store?: DrillStore; }, {}> {
});
return;
}
userConfigStore.SaveConfig(BoardModalType.Dr, this.props.store, false);
userConfigStore.SaveConfig(BoardModalType.Dr, this.props.store);
app.Editor.ModalManage.Destory();
commandMachine.ExecCommand('PZ');
};

@ -64,7 +64,7 @@ export class UserConfig extends React.Component<IConfigProps, UserConfigState>{
};
private handleSaveConfig = async (isInit: boolean = false) =>
{
await this._userConfigStore.SaveConfig(this.props.type, this.props.store, isInit, true);
await this._userConfigStore.SaveConfig(this.props.type, this.props.store, { isInit, isCheckName: true });
};
//删除配置
private handleDeleteConfig = async () =>

@ -290,7 +290,6 @@ export class CADModal
let maxBottom = window.innerHeight - modal.offsetHeight;
modalX = e.clientX - modal.offsetLeft;
modalY = e.clientY - modal.offsetTop;
modal.style.cursor = "move";
document.onmousemove = (e) =>
{
let moveX = e.clientX - modalX;
@ -321,7 +320,6 @@ export class CADModal
};
document.onmouseup = (e) =>
{
modal.style.cursor = "default";
document.onmousemove = null;
};
}

@ -239,3 +239,4 @@
@import (less) "./LookOverBoardInfos.less";
@import (less) "../../Template/Template.less";
@import (less) "./SaveAs.less";
@import (less) "./SmoothEdge.less";

@ -0,0 +1,20 @@
#commonModal {
.smooth-edge {
padding-left: 30px;
.br-set {
span {
width: 70px;
}
}
&>ul {
height: 100px;
overflow: auto;
li {
margin: 0;
}
}
}
}

@ -42,7 +42,7 @@ export class ConfigStore extends Singleton
this.oldBgcolor = this.bgColor;
localStorage.setItem(StoreageKeys.kjlConfig, JSON.stringify(toJS(userConfig.kjlConfig)));
app.Editor.ModalManage.Destory();
await userConfigStore.SaveConfig(BoardModalType.UserConfig, userConfig, false, false);
await userConfigStore.SaveConfig(BoardModalType.UserConfig, userConfig);
};
}

@ -160,7 +160,7 @@ export class ProcessingGroupModal extends React.Component<{ store: ProcessingGro
for (let f of this.removeFuncs)
f();
this.removeFuncs.length = 0;
userConfigStore.SaveConfig(BoardModalType.ProcessGroupCategory, ProcessingGroupModalStore.GetInstance(), false);
userConfigStore.SaveConfig(BoardModalType.ProcessGroupCategory, ProcessingGroupModalStore.GetInstance(), { toaster: false });
}
//检查加工类别中有无重复实体
CheckSelect = () =>

@ -312,3 +312,12 @@ export enum BoardOpenDir
}
export type AnyObject = { [key: string]: any; };
//见光面封边设置
export interface ISmoothEdgeOption extends IBaseOption
{
smoothEdge: number;//见光面
edge: number;//非见光面
scale: number;//见光比例
filterArr: string[];//
}

@ -27,6 +27,13 @@ function GetIndexDBID(id)
return localStorage.getItem(StoreageKeys.Uid) + ":" + id;
}
interface ISaveOption
{
isInit?: boolean;
isCheckName?: boolean;
toaster?: boolean;
}
export class UserConfigStore extends Singleton
{
readConfigs: Set<string> = new Set(); //已经读取过的配置
@ -107,7 +114,7 @@ export class UserConfigStore extends Singleton
userConfig.DrillConfigs = config.ruleMap;
}
else
await this.SaveConfig(BoardModalType.Dr, drillStore, true);
await this.SaveConfig(BoardModalType.Dr, drillStore, { isInit: true });
}
async InitWinerackConfig()
{
@ -115,7 +122,7 @@ export class UserConfigStore extends Singleton
if (config)
userConfig.winerackConfig = config.option as IWineRackOption;
else
await this.SaveConfig(BoardModalType.JG, WineRackStore.GetInstance(), true);
await this.SaveConfig(BoardModalType.JG, WineRackStore.GetInstance(), { isInit: true });
}
async InitUserConfig()
{
@ -126,7 +133,7 @@ export class UserConfigStore extends Singleton
}
else
{
await this.SaveConfig(BoardModalType.UserConfig, userConfig, true);
await this.SaveConfig(BoardModalType.UserConfig, userConfig, { isInit: true });
}
}
/**处理用户登陆后的信息 */
@ -204,8 +211,9 @@ export class UserConfigStore extends Singleton
this.ChangeDrillRuleMap(configs);
return configs;
}
async SaveConfig(type: BoardModalType, store: IConfigStore, isInit: boolean = false, isCheckName = false)
async SaveConfig(type: BoardModalType, store: IConfigStore, option: ISaveOption = {})
{
const { isInit = false, isCheckName = false, toaster = true } = option;
let name = store.configName;
if (name === "")
{
@ -260,7 +268,7 @@ export class UserConfigStore extends Singleton
await dbStore.Put(StoreName.ConfigData, GetIndexDBID(type), configs);
await dbStore.Put(StoreName.ConfigVersion, GetIndexDBID(type), data.version);
appCache.set(type, configs);
if (type !== BoardModalType.ProcessGroupCategory)
if (toaster)
AppToaster.show({
message: isInit ? "初始化配置成功" : "配置保存成功",
timeout: 1000

Loading…
Cancel
Save