mirror of https://gitee.com/cf-fz/WebCAD.git
!929 功能:矩形变板件,命令:c2r,r2b
parent
1dcea0e6df
commit
85934cf911
@ -0,0 +1,17 @@
|
|||||||
|
import { app } from "../ApplicationServices/Application";
|
||||||
|
import { Arc } from "../DatabaseServices/Entity/Arc";
|
||||||
|
import { Line } from "../DatabaseServices/Entity/Line";
|
||||||
|
import { Command } from "../Editor/CommandMachine";
|
||||||
|
import { PromptStatus } from "../Editor/PromptResult";
|
||||||
|
|
||||||
|
export class Command_EraseLineAndArc implements Command
|
||||||
|
{
|
||||||
|
async exec()
|
||||||
|
{
|
||||||
|
let ssRes = await app.Editor.GetSelection({ UseSelect: true, Msg: "选择要被删除的直线和圆弧:", Filter: { filterTypes: [Line, Arc] } });
|
||||||
|
if (ssRes.Status !== PromptStatus.OK) return;
|
||||||
|
let ents = ssRes.SelectSet.SelectEntityList;
|
||||||
|
for (let e of ents)
|
||||||
|
e.Erase();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
import { Command } from "../../Editor/CommandMachine";
|
||||||
|
import { Line } from "../../DatabaseServices/Entity/Line";
|
||||||
|
import { app } from "../../ApplicationServices/Application";
|
||||||
|
import { PromptStatus } from "../../Editor/PromptResult";
|
||||||
|
import { RegionParse } from "../../Geometry/RegionParse";
|
||||||
|
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
|
||||||
|
import { TestDraw } from "../test/TestUtil";
|
||||||
|
|
||||||
|
export class Command_TestRegionParse implements Command
|
||||||
|
{
|
||||||
|
async exec()
|
||||||
|
{
|
||||||
|
let ssRes = await app.Editor.GetSelection({ Filter: { filterTypes: [Line] } });
|
||||||
|
if (ssRes.Status !== PromptStatus.OK) return;
|
||||||
|
let ents = ssRes.SelectSet.SelectEntityList as Line[];
|
||||||
|
|
||||||
|
let region = new RegionParse(ents);
|
||||||
|
for (let rs of [...region.RegionsOutline, ...region.RegionsInternal])
|
||||||
|
{
|
||||||
|
let pl = Polyline.Combine(rs.map(r => r.curve));
|
||||||
|
TestDraw(pl);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let e of ents)
|
||||||
|
e.Erase();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,240 @@
|
|||||||
|
import { Matrix4, Vector3 } from "three";
|
||||||
|
import { app } from "../../ApplicationServices/Application";
|
||||||
|
import { ComputerCurvesNormalOCS } from "../../Common/CurveUtils";
|
||||||
|
import { matrixIsCoplane } from "../../Common/Matrix4Utils";
|
||||||
|
import { Arc } from "../../DatabaseServices/Entity/Arc";
|
||||||
|
import { Curve } from "../../DatabaseServices/Entity/Curve";
|
||||||
|
import { Line } from "../../DatabaseServices/Entity/Line";
|
||||||
|
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
|
||||||
|
import { Command } from "../../Editor/CommandMachine";
|
||||||
|
import { PromptStatus } from "../../Editor/PromptResult";
|
||||||
|
import { CurveIntersection } from "../../Geometry/CurveIntersection";
|
||||||
|
import { Route } from "../../Geometry/CurveMap";
|
||||||
|
import { equaln, IdentityMtx4 } from "../../Geometry/GeUtils";
|
||||||
|
import { RegionParse } from "../../Geometry/RegionParse";
|
||||||
|
import { IntersectOption } from "../../GraphicsSystem/IntersectWith";
|
||||||
|
import { Curve2RecModal, Curve2RecModalStore } from "./Modals/Curve2RecModal";
|
||||||
|
|
||||||
|
//这里认为最大的板厚可能有50,当多段线的宽度小于50时,我们认为它是一个板
|
||||||
|
//这个参数以后可能开放
|
||||||
|
const MaxBoardThickness = 50;
|
||||||
|
|
||||||
|
export class CreatePolyLineFromCurve implements Command
|
||||||
|
{
|
||||||
|
IsSaveMax: boolean;//保留最大
|
||||||
|
|
||||||
|
IsOnlySaveSmall: boolean;//只保留小于指定宽度的矩形
|
||||||
|
SmallWidth: number;//矩形的最小宽度
|
||||||
|
|
||||||
|
BreakCurve: boolean;//打断曲线(分析相交区域)
|
||||||
|
ExtendsMinDist: number;//最小延伸范围
|
||||||
|
|
||||||
|
async exec()
|
||||||
|
{
|
||||||
|
let store = Curve2RecModalStore.GetInstance() as Curve2RecModalStore;
|
||||||
|
app.Editor.ModalManage.RenderModal(Curve2RecModal, { store: store });
|
||||||
|
|
||||||
|
app.Editor.ModalManage.SetCallback(async () =>
|
||||||
|
{
|
||||||
|
this.IsSaveMax = store.option.isSaveMax;
|
||||||
|
this.IsOnlySaveSmall = store.option.isSaveSmall;
|
||||||
|
this.BreakCurve = store.option.isAnaly;
|
||||||
|
this.SmallWidth = store.option.width;
|
||||||
|
this.ExtendsMinDist = store.option.gap;
|
||||||
|
let ss = await app.Editor.GetSelection({
|
||||||
|
Msg: "请选择曲线:",
|
||||||
|
UseSelect: true,
|
||||||
|
Filter: { filterTypes: [Curve] }
|
||||||
|
});
|
||||||
|
if (ss.Status === PromptStatus.OK)
|
||||||
|
{
|
||||||
|
let ens = ss.SelectSet.SelectEntityList as Curve[];
|
||||||
|
this.Doit(ens);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Doit(selectedCurs: Curve[])
|
||||||
|
{
|
||||||
|
let extendsMinDistSq = this.ExtendsMinDist ^ 2;
|
||||||
|
|
||||||
|
let groups = this.GroupCurves(selectedCurs);
|
||||||
|
let ocsInv = new Matrix4;
|
||||||
|
for (let group of groups)
|
||||||
|
{
|
||||||
|
ocsInv.getInverse(group.ocs);
|
||||||
|
|
||||||
|
//->wcs z0
|
||||||
|
for (let c of group.cus)
|
||||||
|
c.ApplyMatrix(ocsInv).Z0();
|
||||||
|
|
||||||
|
let intersect = new CurveIntersection(group.cus, false, IntersectOption.ExtendBoth);
|
||||||
|
|
||||||
|
let curves2: Curve[] = [];
|
||||||
|
|
||||||
|
//延伸+打断
|
||||||
|
for (let [cu, pmap] of intersect.intersect)
|
||||||
|
{
|
||||||
|
let sp = cu.StartPoint;
|
||||||
|
let ep = cu.EndPoint;
|
||||||
|
|
||||||
|
let epExtend: Vector3;
|
||||||
|
let epDist = Infinity;
|
||||||
|
let spExtend: Vector3;
|
||||||
|
let spDist = Infinity;
|
||||||
|
|
||||||
|
let ipts: Vector3[] = [];
|
||||||
|
for (let [, pts] of pmap)
|
||||||
|
{
|
||||||
|
ipts.push(...pts);
|
||||||
|
for (let p of pts)
|
||||||
|
{
|
||||||
|
let d = p.distanceToSquared(ep);
|
||||||
|
if (d < epDist)
|
||||||
|
{
|
||||||
|
epDist = d;
|
||||||
|
epExtend = p;
|
||||||
|
}
|
||||||
|
d = p.distanceToSquared(sp);
|
||||||
|
if (d < spDist)
|
||||||
|
{
|
||||||
|
spDist = d;
|
||||||
|
spExtend = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//延伸
|
||||||
|
if (epDist < extendsMinDistSq)
|
||||||
|
{
|
||||||
|
let param = cu.GetParamAtPoint(epExtend);
|
||||||
|
cu.Extend(param);
|
||||||
|
}
|
||||||
|
if (spDist < extendsMinDistSq)
|
||||||
|
{
|
||||||
|
let param = cu.GetParamAtPoint(spExtend);
|
||||||
|
cu.Extend(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
//打断
|
||||||
|
let curves: Curve[];
|
||||||
|
if (this.BreakCurve)
|
||||||
|
curves = cu.GetSplitCurvesByPts(ipts);
|
||||||
|
else
|
||||||
|
curves = [cu];
|
||||||
|
|
||||||
|
for (let c of curves)
|
||||||
|
{
|
||||||
|
if (c instanceof Polyline)
|
||||||
|
curves2.push(...c.Explode());
|
||||||
|
else
|
||||||
|
curves2.push(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let parse = new RegionParse(curves2);
|
||||||
|
|
||||||
|
for (let rs of parse.RegionsInternal)
|
||||||
|
this.Draw(rs, group.ocs, true);
|
||||||
|
|
||||||
|
if (this.IsSaveMax)
|
||||||
|
for (let rs of parse.RegionsOutline)
|
||||||
|
this.Draw(rs, group.ocs, false, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let e of selectedCurs)
|
||||||
|
e.Erase();
|
||||||
|
}
|
||||||
|
//曲线按所在平面分组
|
||||||
|
GroupCurves(curs: Curve[]): { ocs: Matrix4, cus: Curve[]; }[]
|
||||||
|
{
|
||||||
|
let curveGroup: { ocs: Matrix4, cus: Curve[]; }[] = [];
|
||||||
|
|
||||||
|
while (curs.length)
|
||||||
|
{
|
||||||
|
let ocs = ComputerCurvesNormalOCS(curs);
|
||||||
|
let ocsInv = new Matrix4().getInverse(ocs);
|
||||||
|
|
||||||
|
let cus: Curve[] = [];
|
||||||
|
curs = curs.filter(cu =>
|
||||||
|
{
|
||||||
|
if (CurveInOCS(cu, ocs, ocsInv))
|
||||||
|
{
|
||||||
|
cus.push(cu);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
curveGroup.push({ ocs, cus });
|
||||||
|
}
|
||||||
|
return curveGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
Draw(routes: Route[], ocs: Matrix4, isOnlySaveSmall: boolean, color?: number)
|
||||||
|
{
|
||||||
|
let curves = routes.map(r => r.curve);
|
||||||
|
let polyline = Polyline.Combine(curves);
|
||||||
|
if (polyline && polyline.IsClose)
|
||||||
|
{
|
||||||
|
if (polyline.Area < 10) return;
|
||||||
|
if (isOnlySaveSmall)
|
||||||
|
{
|
||||||
|
let size = polyline.BoundingBox.getSize(new Vector3);
|
||||||
|
if (size.x > this.SmallWidth && size.y > this.SmallWidth)
|
||||||
|
{
|
||||||
|
//都大于最小宽度,不绘制
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (color === undefined)
|
||||||
|
{
|
||||||
|
//解析类型
|
||||||
|
let size = polyline.BoundingBox.getSize(new Vector3);
|
||||||
|
if (size.x > MaxBoardThickness && size.y > MaxBoardThickness)
|
||||||
|
color = 3;
|
||||||
|
else if (size.x <= MaxBoardThickness)
|
||||||
|
color = 1;
|
||||||
|
else if (size.y <= MaxBoardThickness)
|
||||||
|
color = 2;
|
||||||
|
else color = 7;
|
||||||
|
}
|
||||||
|
polyline.UpdateMatrixTo(IdentityMtx4);
|
||||||
|
polyline.ApplyMatrix(ocs);
|
||||||
|
polyline.ColorIndex = color;
|
||||||
|
app.Database.ModelSpace.Append(polyline);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
console.warn("未预料到的错误,连接后的多段线不是闭合的");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CurveInOCS(curve: Curve, Ocs: Matrix4, OcsInv: Matrix4): boolean
|
||||||
|
{
|
||||||
|
if (curve instanceof Line)
|
||||||
|
{
|
||||||
|
let p = curve.StartPoint.applyMatrix4(OcsInv);
|
||||||
|
if (!equaln(p.z, 0)) return false;
|
||||||
|
p = curve.EndPoint.applyMatrix4(OcsInv);
|
||||||
|
if (!equaln(p.z, 0)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (curve instanceof Arc)
|
||||||
|
{
|
||||||
|
return matrixIsCoplane(curve.OCS, Ocs);
|
||||||
|
}
|
||||||
|
else if (curve instanceof Polyline)
|
||||||
|
{
|
||||||
|
if (matrixIsCoplane(curve.OCS, Ocs))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
let cus = curve.Explode();
|
||||||
|
return cus.every(c =>
|
||||||
|
{
|
||||||
|
return this.CurveInOCS(c, Ocs, OcsInv);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
.curve2rec {
|
||||||
|
.bp3-input {
|
||||||
|
width: 100px;
|
||||||
|
height: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-input-group {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-analy {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-dialog-footer {
|
||||||
|
padding: 10px 0 0 0 !important;
|
||||||
|
|
||||||
|
.bp3-dialog-footer-actions {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.bp3-label.bp3-inline {
|
||||||
|
margin: 0 auto !important;
|
||||||
|
|
||||||
|
.cf-select {
|
||||||
|
padding-bottom: 5px;
|
||||||
|
|
||||||
|
.bp3-input-group.input-select {
|
||||||
|
width: 100px !important;
|
||||||
|
|
||||||
|
>input {
|
||||||
|
width: inherit !important;
|
||||||
|
height: inherit !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,180 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { app } from "../../../ApplicationServices/Application";
|
||||||
|
import { KeyBoard } from "../../../Common/KeyEnum";
|
||||||
|
import { Classes, Card, Intent, Button, Checkbox, Divider } from "@blueprintjs/core";
|
||||||
|
import { ModalHeader, ModalFooter } from "../../../UI/Components/Modal/ModalContainer";
|
||||||
|
import { UserConfig, IConfigOption } from "../../../UI/Components/Board/UserConfig";
|
||||||
|
import { IConfigStore } from "../../../UI/Store/BoardStore";
|
||||||
|
import { BoardModalType } from "../../../UI/Components/Board/BoardModal";
|
||||||
|
import { observable, toJS } from "mobx";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
|
import { safeEval } from "../../../Common/eval";
|
||||||
|
import '../Modals/Curve2Rec.less';
|
||||||
|
import { begin } from "xaop";
|
||||||
|
import { ToasterInput, AppToaster } from "../../../UI/Components/Toaster";
|
||||||
|
import { CheckObjectType } from "../../../Common/CheckoutVaildValue";
|
||||||
|
import { IBaseOption } from "../../../UI/Store/BoardInterface";
|
||||||
|
import { DataAdapter } from "../../../Common/DataAdapter";
|
||||||
|
import { DefaultCurve2RecOption } from "../../../Editor/DefaultConfig";
|
||||||
|
import { Singleton } from "../../../Common/Singleton";
|
||||||
|
|
||||||
|
export interface Curve2RecOption extends IBaseOption
|
||||||
|
{
|
||||||
|
isSaveMax: boolean; //保留最大轮廓
|
||||||
|
isSaveSmall: boolean; //保留小于width的轮廓
|
||||||
|
width: number; //保留轮廓的宽度
|
||||||
|
isAnaly: boolean; //分析相交区域
|
||||||
|
gap: number; //最小间隙
|
||||||
|
}
|
||||||
|
export class Curve2RecModalStore extends Singleton implements IConfigStore
|
||||||
|
{
|
||||||
|
@observable configName = "默认";
|
||||||
|
@observable configsNames: string[] = [];
|
||||||
|
@observable option: Curve2RecOption = { ...DefaultCurve2RecOption };
|
||||||
|
protected uiOption;
|
||||||
|
get UIOption()
|
||||||
|
{
|
||||||
|
if (!this.uiOption)
|
||||||
|
this.uiOption = DataAdapter.ConvertUIData(this.option);
|
||||||
|
return this.uiOption;
|
||||||
|
}
|
||||||
|
InitOption = () =>
|
||||||
|
{
|
||||||
|
this.option = {
|
||||||
|
isSaveMax: false,
|
||||||
|
isSaveSmall: true,
|
||||||
|
width: 90,
|
||||||
|
isAnaly: true,
|
||||||
|
gap: 3
|
||||||
|
};
|
||||||
|
if (this.uiOption)
|
||||||
|
Object.assign(this.uiOption, DataAdapter.ConvertUIData(this.option));
|
||||||
|
};
|
||||||
|
SaveConfig = () =>
|
||||||
|
{
|
||||||
|
let newConfig: IConfigOption = {};
|
||||||
|
newConfig.option = toJS(this.option);
|
||||||
|
return newConfig;
|
||||||
|
};
|
||||||
|
UpdateOption = (cof: IConfigOption) =>
|
||||||
|
{
|
||||||
|
Object.assign(this.option, cof.option);
|
||||||
|
if (this.uiOption)
|
||||||
|
Object.assign(this.uiOption, DataAdapter.ConvertUIData(cof.option));
|
||||||
|
};
|
||||||
|
HasInvailValue = () =>
|
||||||
|
{
|
||||||
|
//如果为空或NaN: 有非法值
|
||||||
|
return (this.uiOption.gap === "" || isNaN(this.uiOption.gap)) || (this.uiOption.width === "" || isNaN(this.uiOption.width));
|
||||||
|
};
|
||||||
|
Cancel()
|
||||||
|
{
|
||||||
|
app.Editor.ModalManage.Destory();
|
||||||
|
}
|
||||||
|
OnOk()
|
||||||
|
{
|
||||||
|
let invail = this.HasInvailValue();
|
||||||
|
if (invail)
|
||||||
|
AppToaster.show({ message: "存在无效数值,请修正!", timeout: 1000, intent: "danger" });
|
||||||
|
else
|
||||||
|
app.Editor.ModalManage.DestoryAndExec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@observer
|
||||||
|
export class Curve2RecModal extends React.Component<{ store: Curve2RecModalStore; }, {}>{
|
||||||
|
private removeFuncs: Function[] = []; //移除注入
|
||||||
|
componentDidMount()
|
||||||
|
{
|
||||||
|
this.removeFuncs.push(
|
||||||
|
begin(app.Editor.ModalManage, app.Editor.ModalManage.OnKeyDown, (e: KeyboardEvent) =>
|
||||||
|
{
|
||||||
|
if (e.keyCode === KeyBoard.Enter || e.keyCode === KeyBoard.Space)
|
||||||
|
this.props.store.OnOk();
|
||||||
|
e.stopPropagation();
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
render()
|
||||||
|
{
|
||||||
|
const store = this.props.store;
|
||||||
|
const option = store.option;
|
||||||
|
return (
|
||||||
|
<div className={Classes.DIALOG_CONTAINER}>
|
||||||
|
<div className={Classes.DIALOG + " curve2rec"}>
|
||||||
|
<ModalHeader title="线条变矩形" close={() => { this.props.store.Cancel(); }} />
|
||||||
|
<Card style={{ padding: "5px 10px" }}>
|
||||||
|
<div style={{ padding: 5, fontSize: 15 }}>
|
||||||
|
<Checkbox
|
||||||
|
checked={option.isSaveMax}
|
||||||
|
label="保留最大轮廓"
|
||||||
|
onChange={() => { this.props.store.option.isSaveMax = !this.props.store.option.isSaveMax; }}
|
||||||
|
>
|
||||||
|
</Checkbox>
|
||||||
|
<div className="checkbox-input-group">
|
||||||
|
<Checkbox checked={option.isSaveSmall} onChange={() => { this.props.store.option.isSaveSmall = !this.props.store.option.isSaveSmall; }}>
|
||||||
|
</Checkbox>
|
||||||
|
<div>
|
||||||
|
只保留宽度小于
|
||||||
|
<ToasterInput
|
||||||
|
inputClassName={Classes.INPUT}
|
||||||
|
type={CheckObjectType.OnlyNumber}
|
||||||
|
option={option}
|
||||||
|
uiOption={store.UIOption}
|
||||||
|
optKey={"width"}
|
||||||
|
onChange={(e) =>
|
||||||
|
{
|
||||||
|
console.log(e.target.value.trim());
|
||||||
|
if (e.target.value === "")
|
||||||
|
{
|
||||||
|
this.props.store.option.width = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let num = safeEval(e.target.value.trim());
|
||||||
|
this.props.store.option.width = (!isNaN(num)) ? num : undefined;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
的轮廓
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="checkbox-analy">
|
||||||
|
<Checkbox
|
||||||
|
checked={option.isAnaly}
|
||||||
|
onChange={() => { this.props.store.option.isAnaly = !this.props.store.option.isAnaly; }}
|
||||||
|
>
|
||||||
|
</Checkbox>
|
||||||
|
<div>
|
||||||
|
<div>分析相交区域</div>
|
||||||
|
<div>
|
||||||
|
删除重复线和延伸最小间隙
|
||||||
|
<ToasterInput
|
||||||
|
inputClassName={Classes.INPUT}
|
||||||
|
type={CheckObjectType.OnlyNumber}
|
||||||
|
option={option}
|
||||||
|
uiOption={store.UIOption}
|
||||||
|
optKey={"gap"}
|
||||||
|
onChange={(e) =>
|
||||||
|
{
|
||||||
|
let num = safeEval(e.target.value.trim());
|
||||||
|
this.props.store.option.gap = (!isNaN(num)) ? num : undefined;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ModalFooter hasConfig={false} style={{ display: "flex", flexDirection: "column" }}>
|
||||||
|
{/* 配置 */}
|
||||||
|
<div style={{ display: "flex", width: "100%", justifyContent: "space-around" }}>
|
||||||
|
<Button style={{ width: "50%" }} intent={Intent.SUCCESS} text="确定" onClick={() => { this.props.store.OnOk(); }} />
|
||||||
|
<Button style={{ width: "50%" }} intent={Intent.DANGER} text="取消" onClick={() => { this.props.store.Cancel(); }} />
|
||||||
|
</div>
|
||||||
|
<Divider />
|
||||||
|
<UserConfig store={this.props.store} type={BoardModalType.Curves2Rec} />
|
||||||
|
</ModalFooter>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
@noteInputHeight: 2.5rem;
|
||||||
|
|
||||||
|
#rec2Br {
|
||||||
|
.boardSize {
|
||||||
|
.bp3-input {
|
||||||
|
width: 4rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.undefined.br-set{
|
||||||
|
>span:first-child{
|
||||||
|
width: 4.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.select-drillType
|
||||||
|
{
|
||||||
|
width: 9rem;
|
||||||
|
}
|
||||||
|
.note-card {
|
||||||
|
padding: 10px !important;
|
||||||
|
|
||||||
|
/* 备注信息 */
|
||||||
|
.notes {
|
||||||
|
width: 20vmin;
|
||||||
|
|
||||||
|
.bp3-input {
|
||||||
|
height: @noteInputHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-label {
|
||||||
|
line-height: @noteInputHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
>div {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
input:hover {
|
||||||
|
background: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
>label {
|
||||||
|
height: @noteInputHeight;
|
||||||
|
line-height: @noteInputHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.boardModel {
|
||||||
|
display: inline-block;
|
||||||
|
width: 35px;
|
||||||
|
height: 50px;
|
||||||
|
border: 1px solid #000;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 备注信息 */
|
||||||
|
#rec2Br .notes>div>label:first-child,
|
||||||
|
#rec2Br .notes>div>input:first-child {
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#rec2Br .notes>div>label:last-child,
|
||||||
|
#rec2Br .notes>div>input:last-child {
|
||||||
|
width: 70%;
|
||||||
|
}
|
@ -0,0 +1,519 @@
|
|||||||
|
import { Button, Card, Checkbox, Classes, H5, HTMLSelect, Radio, RadioGroup } from '@blueprintjs/core';
|
||||||
|
import { observable } from 'mobx';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import React from 'react';
|
||||||
|
import { Vector3 } from 'three';
|
||||||
|
import { begin } from 'xaop';
|
||||||
|
import { app } from '../../../ApplicationServices/Application';
|
||||||
|
import { EBoardKeyList } from '../../../Common/BoardKeyList';
|
||||||
|
import { CheckObjectType } from '../../../Common/CheckoutVaildValue';
|
||||||
|
import { KeyBoard } from '../../../Common/KeyEnum';
|
||||||
|
import { ToFixed } from '../../../Common/Utils';
|
||||||
|
import { Board } from '../../../DatabaseServices/Entity/Board';
|
||||||
|
import { TemplateRecord } from '../../../DatabaseServices/Template/TemplateRecord';
|
||||||
|
import { PromptStatus } from '../../../Editor/PromptResult';
|
||||||
|
import { userConfig } from '../../../Editor/UserConfig';
|
||||||
|
import { Input5Or4Component, Notes, SetBoardDataBlock, SetBoardDataItem } from '../../../UI/Components/Board/BoardCommon';
|
||||||
|
import { BoardModalType } from '../../../UI/Components/Board/BoardModal';
|
||||||
|
import { ModalFooter, ModalHeader } from '../../../UI/Components/Modal/ModalContainer';
|
||||||
|
import { ModalState } from '../../../UI/Components/Modal/ModalInterface';
|
||||||
|
import { ToasterInput } from '../../../UI/Components/Toaster';
|
||||||
|
import { GoodsList, IGoodInfo } from '../../../UI/MaterialEditor/GoodsList';
|
||||||
|
import '../Modals/Rec2Br.less';
|
||||||
|
import { Rec2BrStore } from '../Rec2BrStore';
|
||||||
|
enum GetOptionState
|
||||||
|
{
|
||||||
|
GetDistance = 0,
|
||||||
|
GetBoard = 1,
|
||||||
|
GetTemplate = 2,
|
||||||
|
}
|
||||||
|
@observer
|
||||||
|
export class Rec2BrModal extends React.Component<{ store: Rec2BrStore; }, {}>
|
||||||
|
{
|
||||||
|
private showShops = observable.box(false);
|
||||||
|
private startSelect = observable.box(false);
|
||||||
|
private m_ScaleParameter = [
|
||||||
|
["knifeRadius", "刀半径"],
|
||||||
|
["grooveAddLength", "槽加长"], ["grooveAddWidth", "槽加宽"], ["grooveAddDepth", "槽加深"]
|
||||||
|
];
|
||||||
|
private matPars = [
|
||||||
|
["boardMatName", "板材名"], ["material", "材料"], ["color", "颜色"]
|
||||||
|
];
|
||||||
|
private removeFuncs: Function[] = []; //移除注入
|
||||||
|
componentDidMount()
|
||||||
|
{
|
||||||
|
this.removeFuncs.push(
|
||||||
|
begin(app.Editor.ModalManage, app.Editor.ModalManage.OnKeyDown, (e: KeyboardEvent) =>
|
||||||
|
{
|
||||||
|
if (e.keyCode === KeyBoard.Enter || e.keyCode === KeyBoard.Space)
|
||||||
|
this.props.store.OnOk(ModalState.Ok);
|
||||||
|
e.stopPropagation();
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
componentWillUnmount()
|
||||||
|
{
|
||||||
|
for (let f of this.removeFuncs)
|
||||||
|
f();
|
||||||
|
this.removeFuncs.length = 0;
|
||||||
|
}
|
||||||
|
//拾取 距离 板件 模板
|
||||||
|
private getOption = async (state: GetOptionState) =>
|
||||||
|
{
|
||||||
|
app.Editor.ModalManage.ToggleShow();
|
||||||
|
app.Editor.MaskManage.Clear();
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case GetOptionState.GetBoard:
|
||||||
|
let enRes1 = await app.Editor.GetEntity({
|
||||||
|
Msg: "选择板件",
|
||||||
|
Filter: { filterTypes: [Board] }
|
||||||
|
});
|
||||||
|
if (enRes1.Status === PromptStatus.OK)
|
||||||
|
{
|
||||||
|
const data = (enRes1.Entity as Board).BoardProcessOption;
|
||||||
|
this.props.store.m_Option.roomName = data[EBoardKeyList.RoomName];
|
||||||
|
this.props.store.UIOption.roomName = data[EBoardKeyList.RoomName];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GetOptionState.GetDistance:
|
||||||
|
let basept: Vector3;
|
||||||
|
let ptRes = await app.Editor.GetPoint({ Msg: "点取距离或者输入" });
|
||||||
|
if (ptRes.Status === PromptStatus.OK)
|
||||||
|
basept = ptRes.Point;
|
||||||
|
|
||||||
|
let enRes2 = await app.Editor.GetDistance({
|
||||||
|
Msg: "点取距离或者输入",
|
||||||
|
BasePoint: basept,
|
||||||
|
Default: 1
|
||||||
|
});
|
||||||
|
if (enRes2.Status === PromptStatus.OK)
|
||||||
|
{
|
||||||
|
let dis = ToFixed(enRes2.Distance, 2);
|
||||||
|
this.props.store.m_Option.cabinetDeep = parseFloat(dis);
|
||||||
|
this.props.store.UIOption.cabinetDeep = dis;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GetOptionState.GetTemplate:
|
||||||
|
let enRes3 = await app.Editor.GetSelection({
|
||||||
|
Msg: "选择模板",
|
||||||
|
Once: true,
|
||||||
|
Filter: { filterFunction: (obj, ent) => { return ent.Template !== undefined; } }
|
||||||
|
});
|
||||||
|
if (enRes3.Status === PromptStatus.OK)
|
||||||
|
{
|
||||||
|
let ens = enRes3.SelectSet.SelectEntityList;
|
||||||
|
|
||||||
|
let template = ens[0].Template.Object as TemplateRecord;
|
||||||
|
this.props.store.m_Option.backBrTemplate = template.Root;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
app.Editor.MaskManage.ShowMask();
|
||||||
|
app.Editor.ModalManage.ToggleShow();
|
||||||
|
};
|
||||||
|
private startSelectTemplate = () =>
|
||||||
|
{
|
||||||
|
this.startSelect.set(true);
|
||||||
|
};
|
||||||
|
private selectGoods = (good: IGoodInfo) =>
|
||||||
|
{
|
||||||
|
this.props.store.m_Option.boardMatName = good.name;//是否需要更新UIOption
|
||||||
|
this.props.store.m_Option.material = good.material;
|
||||||
|
this.props.store.m_Option.color = good.color;
|
||||||
|
this.showShops.set(false);
|
||||||
|
};
|
||||||
|
render()
|
||||||
|
{
|
||||||
|
const store = this.props.store;
|
||||||
|
const selectOptions = userConfig.DrillConfigs.size > 0 ? [...userConfig.DrillConfigs.keys(), "不排"] : [];
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={Classes.DIALOG_CONTAINER}
|
||||||
|
id="rec2Br"
|
||||||
|
>
|
||||||
|
<div className={Classes.DIALOG}>
|
||||||
|
<ModalHeader
|
||||||
|
title={"矩形变板件"}
|
||||||
|
icon="blank"
|
||||||
|
close={() => { store.OnOk(ModalState.Cancel); }}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className={Classes.DIALOG_BODY + " rec2br"}
|
||||||
|
>
|
||||||
|
<div style={{ display: "flex" }}>
|
||||||
|
<Card>
|
||||||
|
<H5>柜体参数</H5>
|
||||||
|
<div>
|
||||||
|
<div className="flex br-mat">
|
||||||
|
<div>
|
||||||
|
<SetBoardDataItem
|
||||||
|
type={CheckObjectType.R2B}
|
||||||
|
optKey="cabinetDeep"
|
||||||
|
option={store.m_Option}
|
||||||
|
uiOption={store.UIOption}//style={{ display: "inline-flex", width: "65%" }}
|
||||||
|
title="柜深"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
minHeight: 18,
|
||||||
|
height: 18,
|
||||||
|
padding: 0,
|
||||||
|
fontSize: 8
|
||||||
|
}}
|
||||||
|
className="bp3-button bp3-intent-success"
|
||||||
|
onClick={() => this.getOption(GetOptionState.GetDistance)}
|
||||||
|
>拾取</button>
|
||||||
|
</div>
|
||||||
|
<SetBoardDataItem
|
||||||
|
type={CheckObjectType.R2B}
|
||||||
|
optKey="cabinetCurtail"
|
||||||
|
option={store.m_Option}
|
||||||
|
uiOption={store.UIOption}
|
||||||
|
title="柜体内缩"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<H5>背板规则</H5>
|
||||||
|
<div className="flex" style={{ flexDirection: "column" }}>
|
||||||
|
<SetBoardDataBlock
|
||||||
|
type={CheckObjectType.R2B}
|
||||||
|
className="flexWrap"
|
||||||
|
pars={[["backBrThick", "板厚"]]}
|
||||||
|
option={store.m_Option}
|
||||||
|
uiOption={store.UIOption}
|
||||||
|
/>
|
||||||
|
<SetBoardDataBlock
|
||||||
|
type={CheckObjectType.R2B}
|
||||||
|
className="flexWrap"
|
||||||
|
pars={[["backBrBiggerThanHeight", "大于高"], ["backBrBiggerThanWidth", "大于宽"]]}
|
||||||
|
option={store.m_Option}
|
||||||
|
uiOption={store.UIOption}
|
||||||
|
/>
|
||||||
|
<SetBoardDataItem
|
||||||
|
type={CheckObjectType.R2B}
|
||||||
|
optKey="backBrFrontMove"
|
||||||
|
option={store.m_Option}
|
||||||
|
uiOption={store.UIOption}
|
||||||
|
title="背板前移"
|
||||||
|
/>
|
||||||
|
<SetBoardDataBlock
|
||||||
|
type={CheckObjectType.R2B}
|
||||||
|
className="flexWrap"
|
||||||
|
pars={[["backBrLeftExtend", "左延伸"], ["backBrRightExtend", "右延伸"], ["backBrUpExtend", "上延伸"], ["backBrDownExtend", "下延伸"]]}
|
||||||
|
option={store.m_Option}
|
||||||
|
uiOption={store.UIOption}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<H5>前缩</H5>
|
||||||
|
<div className="flex" style={{}}>
|
||||||
|
<SetBoardDataBlock
|
||||||
|
type={CheckObjectType.R2B}
|
||||||
|
className="flexWrap"
|
||||||
|
pars={[["verticalBrShrink", "立板"], ["layerBrShrink", "层板"], ["topBrShrink", "顶板"], ["bottomBrShrink", "底板"], ["groundLineBrShrink", "地脚"]]}
|
||||||
|
option={store.m_Option}
|
||||||
|
uiOption={store.UIOption}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<H5>解析板件名称与板件内缩</H5>
|
||||||
|
<div className="flex" style={{ flexDirection: "column" }}>
|
||||||
|
<div style={{ display: "flex", flexDirection: "row", justifyContent: "space-between" }}>
|
||||||
|
<Checkbox
|
||||||
|
checked={store.m_Option.isfarLeftVerticalBrName}
|
||||||
|
label={"最左侧立板"}
|
||||||
|
onChange={() =>
|
||||||
|
{
|
||||||
|
store.m_Option.isfarLeftVerticalBrName = !store.m_Option.isfarLeftVerticalBrName;
|
||||||
|
store.UIOption.isfarLeftVerticalBrName = store.m_Option.isfarLeftVerticalBrName;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ToasterInput
|
||||||
|
type={CheckObjectType.R2B}
|
||||||
|
optKey="farLeftVerticalBrName"
|
||||||
|
option={store.m_Option}
|
||||||
|
uiOption={store.UIOption}
|
||||||
|
inline={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style={{ display: "flex", flexDirection: "row", justifyContent: "space-between" }}>
|
||||||
|
<Checkbox
|
||||||
|
checked={store.m_Option.isfarRightVerticalBrName}
|
||||||
|
label={"最右侧立板"}
|
||||||
|
onChange={() =>
|
||||||
|
{
|
||||||
|
store.m_Option.isfarRightVerticalBrName = !store.m_Option.isfarRightVerticalBrName;
|
||||||
|
store.UIOption.isfarRightVerticalBrName = store.m_Option.isfarRightVerticalBrName;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ToasterInput
|
||||||
|
type={CheckObjectType.R2B}
|
||||||
|
optKey="farRightVerticalBrName"
|
||||||
|
option={store.m_Option}
|
||||||
|
uiOption={store.UIOption}
|
||||||
|
inline={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style={{ display: "flex", flexDirection: "row", justifyContent: "space-between" }}>
|
||||||
|
<Checkbox
|
||||||
|
checked={store.m_Option.istopMostLayerBrName}
|
||||||
|
label={"最顶层板"}
|
||||||
|
onChange={() =>
|
||||||
|
{
|
||||||
|
store.m_Option.istopMostLayerBrName = !store.m_Option.istopMostLayerBrName;
|
||||||
|
store.UIOption.istopMostLayerBrName = store.m_Option.istopMostLayerBrName;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ToasterInput
|
||||||
|
type={CheckObjectType.R2B}
|
||||||
|
optKey="topMostLayerBrName"
|
||||||
|
option={store.m_Option}
|
||||||
|
uiOption={store.UIOption}
|
||||||
|
inline={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style={{ display: "flex", flexDirection: "row", justifyContent: "space-between" }}>
|
||||||
|
<Checkbox
|
||||||
|
checked={store.m_Option.isbottomMostLayerBrName}
|
||||||
|
label={"最底层板"}
|
||||||
|
onChange={() =>
|
||||||
|
{
|
||||||
|
store.m_Option.isbottomMostLayerBrName = !store.m_Option.isbottomMostLayerBrName;
|
||||||
|
store.UIOption.isbottomMostLayerBrName = store.m_Option.isbottomMostLayerBrName;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ToasterInput
|
||||||
|
type={CheckObjectType.R2B}
|
||||||
|
optKey="bottomMostLayerBrName"
|
||||||
|
option={store.m_Option}
|
||||||
|
uiOption={store.UIOption}
|
||||||
|
inline={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style={{ display: "flex", flexDirection: "row", justifyContent: "space-between" }}>
|
||||||
|
<Checkbox
|
||||||
|
checked={store.m_Option.isbottomMostBackBrName}
|
||||||
|
label={"最底背板"}
|
||||||
|
onChange={() =>
|
||||||
|
{
|
||||||
|
store.m_Option.isbottomMostBackBrName = !store.m_Option.isbottomMostBackBrName;
|
||||||
|
store.UIOption.isbottomMostBackBrName = store.m_Option.isbottomMostBackBrName;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ToasterInput
|
||||||
|
type={CheckObjectType.R2B}
|
||||||
|
optKey="bottomMostBackBrName"
|
||||||
|
option={store.m_Option}
|
||||||
|
uiOption={store.UIOption}
|
||||||
|
inline={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style={{ display: "flex", flexDirection: "row", justifyContent: "space-between" }}>
|
||||||
|
<Checkbox
|
||||||
|
checked={store.m_Option.isstripeBrName}
|
||||||
|
label={"收口条"}
|
||||||
|
onChange={() =>
|
||||||
|
{
|
||||||
|
store.m_Option.isstripeBrName = !store.m_Option.isstripeBrName;
|
||||||
|
store.UIOption.isstripeBrName = store.m_Option.isstripeBrName;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ToasterInput
|
||||||
|
type={CheckObjectType.R2B}
|
||||||
|
optKey="stripeBrName"
|
||||||
|
option={store.m_Option}
|
||||||
|
uiOption={store.UIOption}
|
||||||
|
inline={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
根据背板区分柜体
|
||||||
|
</div>
|
||||||
|
<RadioGroup
|
||||||
|
inline
|
||||||
|
selectedValue={store.m_Option.isMultiBackBr ? "1" : "0"}
|
||||||
|
onChange={(e) =>
|
||||||
|
{
|
||||||
|
store.m_Option.isMultiBackBr = e.currentTarget.value === "1";
|
||||||
|
store.UIOption.isMultiBackBr = store.m_Option.isMultiBackBr;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
|
||||||
|
<Radio label="多背板" value={"1"} />
|
||||||
|
<Radio label="单背板" value={"0"} />
|
||||||
|
</RadioGroup>
|
||||||
|
</div>
|
||||||
|
<div style={{ display: "flex", flexDirection: "row", justifyContent: "space-between" }}>
|
||||||
|
<Checkbox
|
||||||
|
checked={store.m_Option.iscabinetName}
|
||||||
|
label={"修改柜名"}
|
||||||
|
onChange={() =>
|
||||||
|
{
|
||||||
|
store.m_Option.iscabinetName = !store.m_Option.iscabinetName;
|
||||||
|
store.UIOption.iscabinetName = store.m_Option.iscabinetName;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ToasterInput
|
||||||
|
type={CheckObjectType.R2B}
|
||||||
|
optKey="cabinetName"
|
||||||
|
option={store.m_Option}
|
||||||
|
uiOption={store.UIOption}
|
||||||
|
inline={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
<Card>
|
||||||
|
<H5>材料信息</H5>
|
||||||
|
<div>
|
||||||
|
<SetBoardDataBlock
|
||||||
|
type={CheckObjectType.R2B}
|
||||||
|
pars={this.m_ScaleParameter}
|
||||||
|
option={store.m_Option.grooveOption}
|
||||||
|
uiOption={store.UIOption.grooveOption}
|
||||||
|
className="flexWrap"
|
||||||
|
/>
|
||||||
|
<div className="flex br-mat">
|
||||||
|
<div>
|
||||||
|
<SetBoardDataItem
|
||||||
|
type={CheckObjectType.R2B}
|
||||||
|
optKey="roomName"
|
||||||
|
option={store.m_Option}
|
||||||
|
uiOption={store.UIOption}
|
||||||
|
title="房间名"
|
||||||
|
placeHolder="输入房间名"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
minHeight: 18,
|
||||||
|
height: 18,
|
||||||
|
padding: 0,
|
||||||
|
fontSize: 8
|
||||||
|
}}
|
||||||
|
className="bp3-button bp3-intent-success"
|
||||||
|
onClick={() => this.getOption(GetOptionState.GetBoard)}
|
||||||
|
>拾取</button>
|
||||||
|
</div>
|
||||||
|
<div className="flex br-mat">
|
||||||
|
<SetBoardDataBlock
|
||||||
|
type={CheckObjectType.R2B}
|
||||||
|
pars={this.matPars}
|
||||||
|
option={store.m_Option}
|
||||||
|
uiOption={store.UIOption}
|
||||||
|
isInline={true}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
style={{ width: "2rem" }}
|
||||||
|
className="bp3-button bp3-intent-success"
|
||||||
|
onClick={() => this.showShops.set(true)}
|
||||||
|
>选择</button>
|
||||||
|
{
|
||||||
|
this.showShops.get() && <GoodsList
|
||||||
|
open={this.showShops}
|
||||||
|
select={this.selectGoods}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<label className="bp3-label bp3-inline .modifier">
|
||||||
|
<span>排钻</span>
|
||||||
|
<HTMLSelect
|
||||||
|
className="select-drillType"
|
||||||
|
value={store.m_Option.drillType}
|
||||||
|
style={{
|
||||||
|
padding: "0 5px",
|
||||||
|
width: "100%",
|
||||||
|
// outline: this.state.isDanger && "1px red solid"
|
||||||
|
}}
|
||||||
|
options={selectOptions}
|
||||||
|
onChange={(e) =>
|
||||||
|
{
|
||||||
|
store.m_Option.drillType = e.target.value;
|
||||||
|
store.UIOption.drillType = store.m_Option.drillType;
|
||||||
|
}}
|
||||||
|
// onFocus={() => { if (this.props.onFocus) this.props.onFocus(); }}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<H5>封边</H5>
|
||||||
|
<div>
|
||||||
|
{
|
||||||
|
<Input5Or4Component
|
||||||
|
type={CheckObjectType.R2B}
|
||||||
|
showDirectionIcon={true}
|
||||||
|
hasCenter={false}
|
||||||
|
optKey=""
|
||||||
|
upKey="sealedUp"
|
||||||
|
downKey="sealedDown"
|
||||||
|
leftKey="sealedLeft"
|
||||||
|
rightKey="sealedRight"
|
||||||
|
option={store.m_Option}
|
||||||
|
uiOption={store.UIOption}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<H5>备注</H5>
|
||||||
|
<div className={Classes.CARD + " note-card"} style={{ height: 250, overflow: "auto" }}>
|
||||||
|
<Notes remarks={store.m_Option.remarks} />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div style={{ display: "flex", flexDirection: "row", justifyContent: "space-between", paddingTop: 10 }}>
|
||||||
|
<Checkbox
|
||||||
|
checked={store.m_Option.backBrUseTemplate}
|
||||||
|
label={"背板使用模板"}
|
||||||
|
onChange={() =>
|
||||||
|
{
|
||||||
|
store.m_Option.backBrUseTemplate = !store.m_Option.backBrUseTemplate;
|
||||||
|
store.UIOption.backBrUseTemplate = store.m_Option.backBrUseTemplate;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
minHeight: 18,
|
||||||
|
height: 18,
|
||||||
|
padding: 0,
|
||||||
|
fontSize: 8,
|
||||||
|
width: "8rem"
|
||||||
|
}}
|
||||||
|
className="bp3-button bp3-intent-success"
|
||||||
|
onClick={() => this.getOption(GetOptionState.GetTemplate)}
|
||||||
|
>选择模板</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</Card>
|
||||||
|
{/* <Card>
|
||||||
|
|
||||||
|
</Card> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ModalFooter store={store} type={BoardModalType.Rec2Br}>
|
||||||
|
<Button
|
||||||
|
className="LeftRightBtn bp3-intent-success"
|
||||||
|
text="确定"
|
||||||
|
onClick={() =>
|
||||||
|
{
|
||||||
|
if (this.props.store.m_Option.drillType === "")
|
||||||
|
this.props.store.m_Option.drillType = selectOptions[0];
|
||||||
|
store.OnOk(ModalState.Ok);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
className="LeftRightBtn bp3-intent-danger" text="取消"
|
||||||
|
onClick={() => store.OnOk(ModalState.Cancel)}
|
||||||
|
/>
|
||||||
|
</ModalFooter>
|
||||||
|
</div>
|
||||||
|
{/* {
|
||||||
|
this.startSelect.get() &&
|
||||||
|
<TemplateSelect
|
||||||
|
open={this.startSelect}
|
||||||
|
// store={this.props.store}
|
||||||
|
/>
|
||||||
|
} */}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
|
||||||
|
import { Board, BoardType } from "../../DatabaseServices/Entity/Board";
|
||||||
|
import { Matrix4, Vector3, Box3 } from "three";
|
||||||
|
import { BoardGetFace } from "../../Geometry/DrillParse/BoardGetFace";
|
||||||
|
|
||||||
|
export class ParseBoardData
|
||||||
|
{
|
||||||
|
pl: Polyline;
|
||||||
|
faceList: BoardGetFace;//
|
||||||
|
board: Board;
|
||||||
|
constructor(br: Board, fontMatInv?: Matrix4)
|
||||||
|
{
|
||||||
|
if (!fontMatInv)
|
||||||
|
//求前视图的正矩阵和逆矩阵//?
|
||||||
|
fontMatInv = br.SpaceOCSInv;
|
||||||
|
this.Parse(br, fontMatInv);
|
||||||
|
}
|
||||||
|
IsCollisionTo(br: ParseBoardData)
|
||||||
|
{
|
||||||
|
let faceList = this.faceList.IntersectFace(br.faceList);
|
||||||
|
return !(faceList.length === 0);
|
||||||
|
}
|
||||||
|
isIntersectOrContain(br: ParseBoardData)
|
||||||
|
{
|
||||||
|
let box1 = this.pl.BoundingBox;
|
||||||
|
let box2 = br.pl.BoundingBox;
|
||||||
|
if (box1.intersectsBox(box2))
|
||||||
|
{
|
||||||
|
let unionBoxs = new Box3();//?
|
||||||
|
unionBoxs.union(box1);
|
||||||
|
unionBoxs.union(box2);
|
||||||
|
let vec = unionBoxs.max.clone().sub(unionBoxs.min);
|
||||||
|
return vec.x > 1 && vec.y > 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private Parse(br: Board, fontMatInv: Matrix4)
|
||||||
|
{
|
||||||
|
this.board = br;
|
||||||
|
this.faceList = new BoardGetFace(br);//?
|
||||||
|
let brminpt = br.MinPoint;
|
||||||
|
brminpt.applyMatrix4(fontMatInv);
|
||||||
|
brminpt.setZ(0);
|
||||||
|
let addVec: Vector3;
|
||||||
|
switch (br.BoardType)
|
||||||
|
{
|
||||||
|
case BoardType.Layer:
|
||||||
|
addVec = new Vector3(br.Height, br.Thickness);//?
|
||||||
|
break;
|
||||||
|
case BoardType.Vertical:
|
||||||
|
addVec = new Vector3(br.Thickness, br.Height);//?
|
||||||
|
break;
|
||||||
|
case BoardType.Behind:
|
||||||
|
addVec = new Vector3(br.Width, br.Height);//?
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.pl = new Polyline().RectangleFrom2Pt(brminpt, brminpt.clone().add(addVec));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,482 @@
|
|||||||
|
import { Board, BoardType } from "../../DatabaseServices/Entity/Board";
|
||||||
|
import { Vector3, Matrix4, Box3 } from "three";
|
||||||
|
import { equaln, isParallelTo } from "../../Geometry/GeUtils";
|
||||||
|
import { ParseBoardData } from "./ParseBoardData";
|
||||||
|
import { EBoardKeyList } from "../../Common/BoardKeyList";
|
||||||
|
import { DrillType, LinesType, FaceDirection } from "../../UI/Store/BoardInterface";
|
||||||
|
import { app } from "../../ApplicationServices/Application";
|
||||||
|
import { Rec2BrStore } from "./Rec2BrStore";
|
||||||
|
|
||||||
|
/*解析板件名称 根据板件的位置.
|
||||||
|
可能出现 顶底板.
|
||||||
|
地脚线.
|
||||||
|
左侧版
|
||||||
|
右侧板.
|
||||||
|
*/
|
||||||
|
interface BrLocDataValue
|
||||||
|
{
|
||||||
|
vec: Vector3;
|
||||||
|
br: Board;
|
||||||
|
}
|
||||||
|
enum SortType
|
||||||
|
{
|
||||||
|
x = "x",
|
||||||
|
xdesc = "X",
|
||||||
|
y = "y",
|
||||||
|
ydesc = "Y",
|
||||||
|
z = "z",
|
||||||
|
zdesc = "Z",
|
||||||
|
}
|
||||||
|
enum ParseType //解析类型. 整体解析 根据背板
|
||||||
|
{
|
||||||
|
ParseAll = 0,
|
||||||
|
ParseFormBackBoard = 1
|
||||||
|
}
|
||||||
|
export class ParseBoardNameUtil
|
||||||
|
{
|
||||||
|
isParseLeftBr: boolean;//左侧版.
|
||||||
|
isParseRightBr: boolean;//右侧版.
|
||||||
|
isParseTopBr: boolean;//顶板
|
||||||
|
isParseDownBr: boolean;//底板.
|
||||||
|
isParseGroundLineBr: boolean;//地脚.
|
||||||
|
isParseStripeBr: boolean;//收口条
|
||||||
|
isChangeCabinetName: boolean;//修改柜体名称
|
||||||
|
leftBrName: string;
|
||||||
|
rightBrName: string;
|
||||||
|
topBrName: string;
|
||||||
|
downBrName: string;
|
||||||
|
groundLineBrName: string;
|
||||||
|
stripeBrName: string;
|
||||||
|
cabinetName: string;//柜体名称
|
||||||
|
roomName: string;//房间名称
|
||||||
|
topBrShrink: number;//顶底板 立板层板前缩
|
||||||
|
downBrShrink: number;
|
||||||
|
verticalBrShrink: number;
|
||||||
|
layerBrShrink: number;
|
||||||
|
groundLineBrMoveBack: number;//地脚线往后面移动
|
||||||
|
//背板大小
|
||||||
|
backBrLength: number;
|
||||||
|
backBrWidth: number;
|
||||||
|
parseType: ParseType;
|
||||||
|
constructor(store: Rec2BrStore)
|
||||||
|
{
|
||||||
|
this.InitData(store);
|
||||||
|
}
|
||||||
|
InitData(store: Rec2BrStore)
|
||||||
|
{
|
||||||
|
let option = store.m_Option;
|
||||||
|
this.isParseLeftBr = option.isfarLeftVerticalBrName;
|
||||||
|
this.leftBrName = option.farLeftVerticalBrName;
|
||||||
|
this.isParseRightBr = option.isfarRightVerticalBrName;
|
||||||
|
this.rightBrName = option.farRightVerticalBrName;
|
||||||
|
this.isParseTopBr = option.istopMostLayerBrName;
|
||||||
|
this.topBrName = option.topMostLayerBrName;
|
||||||
|
this.isParseDownBr = option.isbottomMostLayerBrName;
|
||||||
|
this.downBrName = option.bottomMostLayerBrName;
|
||||||
|
this.isParseStripeBr = option.isstripeBrName;
|
||||||
|
this.stripeBrName = option.stripeBrName;
|
||||||
|
this.isParseGroundLineBr = option.isbottomMostBackBrName;
|
||||||
|
this.groundLineBrName = option.bottomMostBackBrName;
|
||||||
|
this.roomName = option.roomName;
|
||||||
|
this.backBrLength = option.backBrBiggerThanHeight;//
|
||||||
|
this.backBrWidth = option.backBrBiggerThanWidth;//
|
||||||
|
this.parseType = option.isMultiBackBr ? ParseType.ParseFormBackBoard : ParseType.ParseAll;
|
||||||
|
this.verticalBrShrink = option.verticalBrShrink;
|
||||||
|
this.layerBrShrink = option.layerBrShrink;
|
||||||
|
this.isChangeCabinetName = option.iscabinetName;
|
||||||
|
this.cabinetName = option.cabinetName;
|
||||||
|
this.topBrShrink = option.topBrShrink;
|
||||||
|
this.downBrShrink = option.bottomBrShrink;
|
||||||
|
this.groundLineBrMoveBack = option.groundLineBrShrink;
|
||||||
|
}
|
||||||
|
ParseBoardNameFormLocation(brarr: Board[])
|
||||||
|
{
|
||||||
|
if (brarr.length < 1)
|
||||||
|
return;
|
||||||
|
//板件位置数据.
|
||||||
|
let boardLocData: Map<number, BrLocDataValue[]> = new Map();
|
||||||
|
let brSpcMatInv = brarr[0].SpaceOCSInv;
|
||||||
|
//构建数据
|
||||||
|
for (let br of brarr)
|
||||||
|
{
|
||||||
|
if (br.BoardType === BoardType.Behind)
|
||||||
|
{
|
||||||
|
if (br.Height > this.backBrLength && br.Width > this.backBrWidth)
|
||||||
|
{
|
||||||
|
this.ChangeBeiBan(br);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let basePt = br.Position;
|
||||||
|
basePt.applyMatrix4(brSpcMatInv);
|
||||||
|
let arr = boardLocData.get(br.BoardType);
|
||||||
|
if (!arr)
|
||||||
|
boardLocData.set(br.BoardType, [{ vec: basePt, br: br }]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arr.push({ vec: basePt, br: br });
|
||||||
|
boardLocData.set(br.BoardType, arr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//解析与设置柜体名称.
|
||||||
|
let FuncParseBrName = (bool: boolean, name: string, sortType: SortType, boardType: BoardType) =>
|
||||||
|
{
|
||||||
|
if (bool)
|
||||||
|
{
|
||||||
|
let br = this.FindBr(boardLocData, sortType, boardType);
|
||||||
|
if (br)
|
||||||
|
br.Name = name;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
FuncParseBrName(this.isParseLeftBr, this.leftBrName, SortType.x, BoardType.Vertical);
|
||||||
|
//左侧版修改孔面
|
||||||
|
if (this.isParseLeftBr && (boardLocData.get(BoardType.Vertical)?.length > 0))
|
||||||
|
this.ChangeZuoCeBan(boardLocData.get(BoardType.Vertical)[0].br);
|
||||||
|
FuncParseBrName(this.isParseRightBr, this.rightBrName, SortType.xdesc, BoardType.Vertical);
|
||||||
|
//右侧版修改孔面
|
||||||
|
if (this.isParseRightBr && (boardLocData.get(BoardType.Vertical)?.length > 0))
|
||||||
|
this.ChangeYouCeBan(boardLocData.get(BoardType.Vertical)[0].br);
|
||||||
|
FuncParseBrName(this.isParseTopBr, this.topBrName, SortType.zdesc, BoardType.Layer);
|
||||||
|
//顶版修改孔面
|
||||||
|
if (this.isParseTopBr && (boardLocData.get(BoardType.Layer)?.length > 0))
|
||||||
|
{
|
||||||
|
let arr = boardLocData.get(BoardType.Layer);
|
||||||
|
let z = arr[0].vec.z;
|
||||||
|
for (let data of arr)
|
||||||
|
{
|
||||||
|
if (equaln(z, data.vec.z, 1e-2))
|
||||||
|
this.ChangeDingBan(data.br);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FuncParseBrName(this.isParseDownBr, this.downBrName, SortType.z, BoardType.Layer);
|
||||||
|
//底板
|
||||||
|
if (this.isParseDownBr && (boardLocData.get(BoardType.Layer)?.length > 0))
|
||||||
|
{
|
||||||
|
let arr = boardLocData.get(BoardType.Layer);
|
||||||
|
let z = arr[0].vec.z;
|
||||||
|
for (let data of arr)
|
||||||
|
{
|
||||||
|
if (equaln(z, data.vec.z, 1e-2))
|
||||||
|
this.ChangeDiBan(data.br);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//地脚
|
||||||
|
FuncParseBrName(this.isParseGroundLineBr, this.groundLineBrName, SortType.z, BoardType.Behind);
|
||||||
|
//地脚线处理
|
||||||
|
if (this.isParseGroundLineBr && (boardLocData.get(BoardType.Behind)?.length > 0))
|
||||||
|
{
|
||||||
|
let arr = boardLocData.get(BoardType.Behind);
|
||||||
|
let z = arr[0].vec.z;
|
||||||
|
for (let data of arr)
|
||||||
|
{
|
||||||
|
if (equaln(z, data.vec.z, 1e-2))
|
||||||
|
{
|
||||||
|
let br = data.br;
|
||||||
|
if (br.Height < br.Width)
|
||||||
|
this.ChangeDiJiao(br);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.CurtailBoard(boardLocData, brarr);
|
||||||
|
}
|
||||||
|
//分堆 来自背板
|
||||||
|
//解析板件数组.
|
||||||
|
ParseBoardArrFormBackBoard(arr: Board[][], brarr: Board[])
|
||||||
|
{
|
||||||
|
if (brarr.length === 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let parseBrData: ParseBoardData[] = [];
|
||||||
|
let backBrData: ParseBoardData[] = [];
|
||||||
|
for (let br of brarr)
|
||||||
|
{
|
||||||
|
let data = new ParseBoardData(br, brarr[0].SpaceOCSInv);
|
||||||
|
if (br.BoardType === BoardType.Behind && br.Width > this.backBrWidth && br.Height > this.backBrLength)
|
||||||
|
{
|
||||||
|
backBrData.push(data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
parseBrData.push(data);
|
||||||
|
}
|
||||||
|
for (let bdata of backBrData)
|
||||||
|
{
|
||||||
|
let ar: Board[] = [];
|
||||||
|
ar.push(bdata.board);//加入背板???
|
||||||
|
for (let pdata of parseBrData)
|
||||||
|
{
|
||||||
|
if (bdata.isIntersectOrContain(pdata) || bdata.IsCollisionTo(pdata))
|
||||||
|
{
|
||||||
|
ar.push(pdata.board);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arr.push(ar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Doit(brarr: Board[])
|
||||||
|
{
|
||||||
|
this.InitBoardName(brarr);
|
||||||
|
let boardarrHeap: Board[][] = [];
|
||||||
|
this.ParseBoardArrFormBackBoard(boardarrHeap, brarr);
|
||||||
|
// console.log(boardarrHeap, brarr);
|
||||||
|
if (boardarrHeap.length === 0)
|
||||||
|
boardarrHeap.push(brarr);
|
||||||
|
this.ParseShouKouTiao(brarr, boardarrHeap);
|
||||||
|
switch (this.parseType)
|
||||||
|
{
|
||||||
|
case ParseType.ParseAll://?单背板柜子
|
||||||
|
let calbrarr: Board[] = [];
|
||||||
|
for (let brarr of boardarrHeap)
|
||||||
|
{
|
||||||
|
calbrarr.push(...brarr);
|
||||||
|
}
|
||||||
|
this.ParseBoardNameFormLocation(calbrarr);
|
||||||
|
for (let br of calbrarr)
|
||||||
|
{
|
||||||
|
br.BoardProcessOption[EBoardKeyList.CabinetName] = this.cabinetName;
|
||||||
|
br.BoardProcessOption[EBoardKeyList.RoomName] = this.roomName;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ParseType.ParseFormBackBoard://?多背板柜子
|
||||||
|
let index = 1;
|
||||||
|
for (let brarr of boardarrHeap)
|
||||||
|
{
|
||||||
|
this.ParseBoardNameFormLocation(brarr);
|
||||||
|
for (let br of brarr)
|
||||||
|
{
|
||||||
|
br.BoardProcessOption[EBoardKeyList.CabinetName] = this.cabinetName + index;//?
|
||||||
|
br.BoardProcessOption[EBoardKeyList.RoomName] = this.roomName;//
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
private FindBr(map: Map<Number, BrLocDataValue[]>, sortType: SortType, boardType: BoardType)//
|
||||||
|
{
|
||||||
|
let arr = map.get(boardType);
|
||||||
|
if (arr && arr.length > 0)
|
||||||
|
{
|
||||||
|
switch (sortType.toUpperCase())
|
||||||
|
{
|
||||||
|
case "X":
|
||||||
|
arr.sort((a, b) => sortType === SortType.x ? a.vec.x - b.vec.x : b.vec.x - a.vec.x);
|
||||||
|
break;
|
||||||
|
case "Y":
|
||||||
|
arr.sort((a, b) => sortType === SortType.y ? a.vec.y - b.vec.y : b.vec.y - a.vec.y);
|
||||||
|
break;
|
||||||
|
case "Z":
|
||||||
|
arr.sort((a, b) => sortType === SortType.z ? a.vec.z - b.vec.z : b.vec.z - a.vec.z);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return arr[0].br;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//修改地脚线 前缩和改变纹路
|
||||||
|
private ChangeDiJiao(br: Board)
|
||||||
|
{
|
||||||
|
br.Name = this.groundLineBrName;
|
||||||
|
br.BoardProcessOption[EBoardKeyList.BigHole] = FaceDirection.Back;
|
||||||
|
br.BoardProcessOption[EBoardKeyList.Lines] = LinesType.Reverse;
|
||||||
|
let n = br.Normal.clone().multiplyScalar(this.groundLineBrMoveBack);
|
||||||
|
let moveMatrix = new Matrix4().setPosition(br.Normal.clone().sub(n));
|
||||||
|
br.ApplyMatrix(moveMatrix);
|
||||||
|
}
|
||||||
|
//左侧板
|
||||||
|
private ChangeZuoCeBan(br: Board)
|
||||||
|
{
|
||||||
|
br.BoardProcessOption[EBoardKeyList.BigHole] = FaceDirection.Front;
|
||||||
|
br.BoardProcessOption[EBoardKeyList.Lines] = LinesType.Positive;
|
||||||
|
}
|
||||||
|
//右侧板
|
||||||
|
private ChangeYouCeBan(br: Board)
|
||||||
|
{
|
||||||
|
br.BoardProcessOption[EBoardKeyList.BigHole] = FaceDirection.Back;
|
||||||
|
br.BoardProcessOption[EBoardKeyList.Lines] = LinesType.Positive;
|
||||||
|
}
|
||||||
|
//顶板
|
||||||
|
private ChangeDingBan(br: Board)
|
||||||
|
{
|
||||||
|
br.Name = this.topBrName;
|
||||||
|
br.BoardProcessOption[EBoardKeyList.BigHole] = FaceDirection.Front;
|
||||||
|
br.BoardProcessOption[EBoardKeyList.Lines] = LinesType.Positive;
|
||||||
|
}
|
||||||
|
//底板
|
||||||
|
private ChangeDiBan(br: Board)
|
||||||
|
{
|
||||||
|
br.Name = this.downBrName;
|
||||||
|
br.BoardProcessOption[EBoardKeyList.BigHole] = FaceDirection.Back;
|
||||||
|
br.BoardProcessOption[EBoardKeyList.Lines] = LinesType.Positive;
|
||||||
|
}
|
||||||
|
//背板
|
||||||
|
private ChangeBeiBan(br: Board)
|
||||||
|
{
|
||||||
|
br.BoardProcessOption[EBoardKeyList.BigHole] = FaceDirection.Back;
|
||||||
|
br.BoardProcessOption[EBoardKeyList.Lines] = LinesType.Positive;
|
||||||
|
}
|
||||||
|
private CurtailBoard(map: Map<Number, BrLocDataValue[]>, brarr: Board[])//
|
||||||
|
{
|
||||||
|
//todo地脚
|
||||||
|
let cbarr: Board[] = [];
|
||||||
|
let lbarr: Board[] = [];
|
||||||
|
let map1 = map.get(BoardType.Vertical);
|
||||||
|
let map0 = map.get(BoardType.Layer);
|
||||||
|
if (map1)
|
||||||
|
for (let lb of map1)
|
||||||
|
{
|
||||||
|
if (lb.br.Name === "立板")
|
||||||
|
{
|
||||||
|
lb.br.BoardProcessOption[EBoardKeyList.Lines] = LinesType.Positive;
|
||||||
|
lb.br.BoardProcessOption[EBoardKeyList.BigHole] = FaceDirection.Back;
|
||||||
|
// lb.br//纹路 正
|
||||||
|
//孔面 反
|
||||||
|
lbarr.push(lb.br);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let topbrarr: Board[] = [];
|
||||||
|
let downbrarr: Board[] = [];
|
||||||
|
if (map0)
|
||||||
|
for (let cb of map0)
|
||||||
|
{
|
||||||
|
let name = cb.br.Name;
|
||||||
|
switch (name)
|
||||||
|
{
|
||||||
|
case "层板":
|
||||||
|
cb.br.BoardProcessOption[EBoardKeyList.Lines] = LinesType.Positive;
|
||||||
|
cb.br.BoardProcessOption[EBoardKeyList.BigHole] = FaceDirection.Back;
|
||||||
|
//正纹
|
||||||
|
//孔面 反
|
||||||
|
cbarr.push(cb.br);
|
||||||
|
break;
|
||||||
|
case "顶板":
|
||||||
|
topbrarr.push(cb.br);
|
||||||
|
break;
|
||||||
|
case "底板":
|
||||||
|
downbrarr.push(cb.br);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.FrontCurtailBrs(topbrarr, this.topBrShrink, "顶板");
|
||||||
|
this.FrontCurtailBrs(downbrarr, this.downBrShrink, "底板");
|
||||||
|
this.FrontCurtailBrs(lbarr, this.verticalBrShrink, "立板");
|
||||||
|
this.FrontCurtailBrs(cbarr, this.layerBrShrink, "层板");
|
||||||
|
}
|
||||||
|
//计算收口条
|
||||||
|
private ParseShouKouTiao(brarr: Board[], calbrarr: Board[][])
|
||||||
|
{
|
||||||
|
if (!this.isParseStripeBr)
|
||||||
|
return;
|
||||||
|
for (let calbrs of calbrarr)//boardHeap
|
||||||
|
{
|
||||||
|
for (let calbr of calbrs)
|
||||||
|
{
|
||||||
|
let index = brarr.findIndex((br) => br.Id.Index === calbr.Id.Index);
|
||||||
|
brarr.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let br of brarr)
|
||||||
|
{
|
||||||
|
br.Name = this.stripeBrName;
|
||||||
|
br.BoardProcessOption[EBoardKeyList.DrillType] = DrillType.None;
|
||||||
|
if (br.Height > br.Width)
|
||||||
|
br.BoardProcessOption[EBoardKeyList.Lines] = LinesType.Positive;
|
||||||
|
else
|
||||||
|
br.BoardProcessOption[EBoardKeyList.Lines] = LinesType.Reverse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private InitBoardName(brarr: Board[])
|
||||||
|
{
|
||||||
|
for (let br of brarr)
|
||||||
|
{
|
||||||
|
switch (br.BoardType)
|
||||||
|
{
|
||||||
|
case BoardType.Layer:
|
||||||
|
br.Name = "层板";
|
||||||
|
break;
|
||||||
|
case BoardType.Vertical:
|
||||||
|
br.Name = "立板";
|
||||||
|
break;
|
||||||
|
case BoardType.Behind:
|
||||||
|
br.Name = "背板";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//前缩
|
||||||
|
private FrontCurtailBrs(brs: Board[], curtailNum: number, promptMsg: string)
|
||||||
|
{
|
||||||
|
if (brs.length < 1)
|
||||||
|
return;
|
||||||
|
let sizeBox = new Box3();
|
||||||
|
let spaceOcsInv = brs[0].SpaceOCSInv;
|
||||||
|
let boardBoxCache = new Map<Board, { box: Box3, size: Vector3; }>();
|
||||||
|
for (let br of brs)
|
||||||
|
{
|
||||||
|
let box = br.BoundingBoxInOCS;
|
||||||
|
box.applyMatrix4(spaceOcsInv.clone().multiply(br.OCS));
|
||||||
|
boardBoxCache.set(br, { box, size: box.getSize(new Vector3) });
|
||||||
|
sizeBox.union(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
//构造前缩盒子
|
||||||
|
const GenCurtailBox = (sizeBox: Box3): Box3 =>
|
||||||
|
{
|
||||||
|
let size = sizeBox.getSize(new Vector3);
|
||||||
|
let v = new Vector3(1, 1, 1);
|
||||||
|
let frontBox = new Box3(sizeBox.min.clone().sub(v), sizeBox.max.clone().sub(new Vector3(-1, size.y / 2, -1)));
|
||||||
|
return frontBox;
|
||||||
|
};
|
||||||
|
|
||||||
|
let curBox = GenCurtailBox(sizeBox);
|
||||||
|
|
||||||
|
let index = 1;
|
||||||
|
let allowDist = 0;
|
||||||
|
let minDist = Infinity;
|
||||||
|
for (let br of brs)
|
||||||
|
{
|
||||||
|
let boxData = boardBoxCache.get(br);
|
||||||
|
if (boxData.box.intersectsBox(curBox)
|
||||||
|
&& !curBox.containsBox(boxData.box)
|
||||||
|
&& !isParallelTo(br.Normal, new Vector3().setComponent(index, 1))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
minDist = Math.min(minDist, boxData.box.max.getComponent(index) - boxData.box.min.getComponent(index));
|
||||||
|
}
|
||||||
|
allowDist = minDist - 1;
|
||||||
|
}
|
||||||
|
if (curtailNum > allowDist)
|
||||||
|
{
|
||||||
|
app.Editor.Prompt(`${promptMsg}的前缩值不得超过${allowDist}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let br of brs)
|
||||||
|
{
|
||||||
|
//逐板计算拉伸盒子
|
||||||
|
let curBox2 = GenCurtailBox(br.BoundingBox);
|
||||||
|
let pts = br.GetStretchPoints();
|
||||||
|
let curtailVec = new Vector3(0, curtailNum);
|
||||||
|
let curtailIndexs = [];
|
||||||
|
//获取索引
|
||||||
|
for (let i = 0, length = pts.length; i < length; i++)
|
||||||
|
{
|
||||||
|
if (curBox2.containsPoint(pts[i]))
|
||||||
|
curtailIndexs.push(i);
|
||||||
|
}
|
||||||
|
if (!isParallelTo(curtailVec, br.Normal))
|
||||||
|
br.MoveStretchPoints(curtailIndexs, curtailVec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,148 @@
|
|||||||
|
import { BoardStore } from "../../UI/Store/BoardStore";
|
||||||
|
import { IBaseOption, IGrooveOption } from "../../UI/Store/BoardInterface";
|
||||||
|
import { CheckoutValid, CheckObjectType } from "../../Common/CheckoutVaildValue";
|
||||||
|
import { DataAdapter } from "../../Common/DataAdapter";
|
||||||
|
import { TemplateRecord } from "../../DatabaseServices/Template/TemplateRecord";
|
||||||
|
import { observable } from "mobx";
|
||||||
|
|
||||||
|
export class Rec2BrStore extends BoardStore
|
||||||
|
{
|
||||||
|
@observable m_Option: IRec2BrOption;
|
||||||
|
protected m_UiOption;
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
this.InitOption();
|
||||||
|
}
|
||||||
|
private GetDefaultOption()
|
||||||
|
{
|
||||||
|
let originOption: IRec2BrOption = {
|
||||||
|
cabinetDeep: 400,
|
||||||
|
cabinetBrThick: 18,
|
||||||
|
cabinetCurtail: 0,
|
||||||
|
backBrThick: 18,
|
||||||
|
backBrBiggerThanHeight: 200,
|
||||||
|
backBrBiggerThanWidth: 200,
|
||||||
|
backBrFrontMove: 0,
|
||||||
|
backBrLeftExtend: 0,
|
||||||
|
backBrRightExtend: 0,
|
||||||
|
backBrUpExtend: 0,
|
||||||
|
backBrDownExtend: 0,
|
||||||
|
verticalBrShrink: 0,
|
||||||
|
layerBrShrink: 0,
|
||||||
|
topBrShrink: 0,
|
||||||
|
bottomBrShrink: 0,
|
||||||
|
groundLineBrShrink: 0,
|
||||||
|
farLeftVerticalBrName: "左侧板",
|
||||||
|
farRightVerticalBrName: "右侧板",
|
||||||
|
topMostLayerBrName: "顶板",
|
||||||
|
bottomMostLayerBrName: "底板",
|
||||||
|
bottomMostBackBrName: "地脚线",
|
||||||
|
stripeBrName: "收口条",
|
||||||
|
cabinetName: "",
|
||||||
|
isfarLeftVerticalBrName: true,//最左侧立板名称
|
||||||
|
isfarRightVerticalBrName: true,
|
||||||
|
istopMostLayerBrName: true,
|
||||||
|
isbottomMostLayerBrName: true,
|
||||||
|
isbottomMostBackBrName: true,
|
||||||
|
isstripeBrName: true,
|
||||||
|
iscabinetName: false,//修改柜名
|
||||||
|
isMultiBackBr: false,
|
||||||
|
grooveOption: {
|
||||||
|
grooveAddLength: "0",
|
||||||
|
grooveAddWidth: "0",
|
||||||
|
grooveAddDepth: "0",
|
||||||
|
knifeRadius: "3",
|
||||||
|
},
|
||||||
|
roomName: "",
|
||||||
|
boardMatName: "",
|
||||||
|
material: "",
|
||||||
|
color: "",
|
||||||
|
drillType: "",
|
||||||
|
sealedDown: "1",
|
||||||
|
sealedLeft: "1",
|
||||||
|
sealedRight: "1",
|
||||||
|
sealedUp: "1",
|
||||||
|
backBrUseTemplate: false,
|
||||||
|
backBrTemplate: null,
|
||||||
|
remarks: Array.from({ length: 12 }, () => ["", ""]),
|
||||||
|
};
|
||||||
|
return originOption;
|
||||||
|
}
|
||||||
|
InitOption()
|
||||||
|
{
|
||||||
|
this.m_Option = this.GetDefaultOption();
|
||||||
|
if (this.m_UiOption)
|
||||||
|
Object.assign(this.m_UiOption, DataAdapter.ConvertUIData(this.m_Option));
|
||||||
|
}
|
||||||
|
HasInvailValue()
|
||||||
|
{
|
||||||
|
return CheckoutValid.HasInvailValue(this.m_Option, CheckObjectType.R2B);//
|
||||||
|
}
|
||||||
|
// OnOk = () =>
|
||||||
|
// {
|
||||||
|
|
||||||
|
// //检查option 封边排钻等是否有效
|
||||||
|
// };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface IRec2BrOption extends IBaseOption
|
||||||
|
{
|
||||||
|
//柜体参数
|
||||||
|
cabinetDeep: number;//柜深
|
||||||
|
cabinetBrThick: number;//板厚
|
||||||
|
cabinetCurtail: number;//柜体内缩
|
||||||
|
//背板规则
|
||||||
|
backBrThick: number;//背板厚
|
||||||
|
backBrBiggerThanHeight: number;//背板大于高
|
||||||
|
backBrBiggerThanWidth: number;//背板大于宽
|
||||||
|
backBrFrontMove: number;//背板前移
|
||||||
|
backBrLeftExtend: number;//背板上下左右延伸
|
||||||
|
backBrRightExtend: number;
|
||||||
|
backBrUpExtend: number;
|
||||||
|
backBrDownExtend: number;
|
||||||
|
//前缩
|
||||||
|
verticalBrShrink: number;//立板 层板 底板 顶板 地脚线前缩
|
||||||
|
layerBrShrink: number;
|
||||||
|
bottomBrShrink: number;
|
||||||
|
topBrShrink: number;
|
||||||
|
groundLineBrShrink: number;
|
||||||
|
//解析板件名
|
||||||
|
farLeftVerticalBrName: string;//最左侧立板名称
|
||||||
|
farRightVerticalBrName: string;
|
||||||
|
topMostLayerBrName: string;
|
||||||
|
bottomMostLayerBrName: string;
|
||||||
|
bottomMostBackBrName: string;
|
||||||
|
stripeBrName: string;
|
||||||
|
cabinetName: string;//修改柜名
|
||||||
|
//以上的checkbox是否选择
|
||||||
|
isfarLeftVerticalBrName: boolean;//最左侧立板名称
|
||||||
|
isfarRightVerticalBrName: boolean;
|
||||||
|
istopMostLayerBrName: boolean;
|
||||||
|
isbottomMostLayerBrName: boolean;
|
||||||
|
isbottomMostBackBrName: boolean;
|
||||||
|
isstripeBrName: boolean;
|
||||||
|
iscabinetName: boolean;//修改柜名
|
||||||
|
isMultiBackBr: boolean;//是否多背板柜子
|
||||||
|
backBrUseTemplate: boolean;
|
||||||
|
backBrTemplate: TemplateRecord;//背板模板
|
||||||
|
//材料信息
|
||||||
|
//刀半径
|
||||||
|
//槽加长
|
||||||
|
//槽加深
|
||||||
|
//槽加宽
|
||||||
|
grooveOption: IGrooveOption;
|
||||||
|
roomName: string;//房间名
|
||||||
|
boardMatName: string;//板材名
|
||||||
|
material: string;//材料
|
||||||
|
color: string;//颜色
|
||||||
|
drillType: string;//排钻
|
||||||
|
//封边
|
||||||
|
sealedDown: string,
|
||||||
|
sealedLeft: string,
|
||||||
|
sealedRight: string,
|
||||||
|
sealedUp: string,
|
||||||
|
//备注
|
||||||
|
remarks: [string, string][];
|
||||||
|
}
|
@ -0,0 +1,517 @@
|
|||||||
|
import { Box3, Matrix4, Vector3 } from "three";
|
||||||
|
import { app } from "../../ApplicationServices/Application";
|
||||||
|
import { arrayRemoveIf } from "../../Common/ArrayExt";
|
||||||
|
import { IsDev } from "../../Common/Deving";
|
||||||
|
import { safeEval } from "../../Common/eval";
|
||||||
|
import { matrixSetVector } from "../../Common/Matrix4Utils";
|
||||||
|
import { Board, BoardType } from "../../DatabaseServices/Entity/Board";
|
||||||
|
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
|
||||||
|
import { TemplateRecord } from "../../DatabaseServices/Template/TemplateRecord";
|
||||||
|
import { Command } from "../../Editor/CommandMachine";
|
||||||
|
import { PromptStatus } from "../../Editor/PromptResult";
|
||||||
|
import { equaln } from "../../Geometry/GeUtils";
|
||||||
|
import { IntersectOption } from "../../GraphicsSystem/IntersectWith";
|
||||||
|
import { HotCMD } from "../../Hot/HotCommand";
|
||||||
|
import { CurveInOCS } from "./CreatePolyLineFromCurve";
|
||||||
|
import { Rec2BrModal } from "./Modals/Rec2Br";
|
||||||
|
import { Rec2BrStore } from "./Rec2BrStore";
|
||||||
|
|
||||||
|
//已经实现:矩形转板件 位置正确 切割正常
|
||||||
|
//已处理名称解析,前缩部分,根据背板区分柜体部分 材料信息 备注部分. 未测试
|
||||||
|
|
||||||
|
/*
|
||||||
|
前期
|
||||||
|
pl.TempData = size;
|
||||||
|
pl.TempData2 = box;
|
||||||
|
|
||||||
|
后期
|
||||||
|
pl.TempData = br;
|
||||||
|
*/
|
||||||
|
|
||||||
|
@HotCMD
|
||||||
|
export class RectConvertToBoard implements Command
|
||||||
|
{
|
||||||
|
store = Rec2BrStore.GetInstance() as Rec2BrStore;
|
||||||
|
SpaceOCS: Matrix4;
|
||||||
|
SpaceOCSInv: Matrix4;
|
||||||
|
async exec()
|
||||||
|
{
|
||||||
|
if (!IsDev())
|
||||||
|
alert("收费功能免费试用中!截至至2020年6月1日!");
|
||||||
|
app.Editor.ModalManage.RenderModal(Rec2BrModal, { store: this.store });
|
||||||
|
|
||||||
|
app.Editor.ModalManage.SetCallback(async () =>
|
||||||
|
{
|
||||||
|
this.InitData(this.store);
|
||||||
|
|
||||||
|
let ss = await app.Editor.GetSelection({
|
||||||
|
Msg: "请选择曲线:",
|
||||||
|
UseSelect: true,
|
||||||
|
Filter: { filterTypes: [Polyline] }
|
||||||
|
});
|
||||||
|
if (ss.Status === PromptStatus.Cancel) return;
|
||||||
|
|
||||||
|
let ens = ss.SelectSet.SelectEntityList as Polyline[];
|
||||||
|
this.Doit(ens);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
boardThick: number; //板件厚度.
|
||||||
|
boardDepth: number; //板件的深度
|
||||||
|
fontDis: number; //前距
|
||||||
|
// 刀半径
|
||||||
|
knifeRadius: number;
|
||||||
|
// 槽加长
|
||||||
|
grooveLength: number;
|
||||||
|
// 槽加深
|
||||||
|
grooveDepth: number;
|
||||||
|
// 槽加宽
|
||||||
|
grooveWidth: number;
|
||||||
|
// 背板数据
|
||||||
|
// 上下左右延伸
|
||||||
|
backLeftExtend: number; backRightExtend: number; backTopExtend: number; backDownExtend: number;
|
||||||
|
//背板厚度
|
||||||
|
backBoardThick: number;
|
||||||
|
//需要移动的背板的大小
|
||||||
|
moveBackLen: number; moveBackWidth: number;
|
||||||
|
//背板移动的距离
|
||||||
|
backBoardMoveDis: number;
|
||||||
|
//背板是模板
|
||||||
|
backIsTemplate: boolean;
|
||||||
|
//背板模板
|
||||||
|
backTemplate: TemplateRecord;
|
||||||
|
//使用板名设置属性
|
||||||
|
isUseBoardNameToAttr: boolean;
|
||||||
|
//多背板柜子
|
||||||
|
isMultiBackCab: boolean = false;
|
||||||
|
//板名设置属性配置
|
||||||
|
strBoardNameConfig: string;//?
|
||||||
|
boardData;//?
|
||||||
|
InitData(store: Rec2BrStore)
|
||||||
|
{
|
||||||
|
let option = store.m_Option;
|
||||||
|
this.boardThick = option.cabinetBrThick;//18;
|
||||||
|
this.boardDepth = option.cabinetDeep;//300;
|
||||||
|
this.fontDis = option.cabinetCurtail;//0;
|
||||||
|
this.backBoardThick = option.backBrThick;//18;
|
||||||
|
this.backIsTemplate = option.backBrUseTemplate;//false;
|
||||||
|
// this.backTemplate = option.backBrTemplate;
|
||||||
|
this.backBoardMoveDis = option.backBrFrontMove;//0;
|
||||||
|
this.isUseBoardNameToAttr = false;
|
||||||
|
this.moveBackLen = option.backBrBiggerThanHeight;
|
||||||
|
this.moveBackWidth = option.backBrBiggerThanWidth;//
|
||||||
|
this.backLeftExtend = option.backBrLeftExtend;//0;
|
||||||
|
this.backRightExtend = option.backBrRightExtend;
|
||||||
|
this.backTopExtend = option.backBrUpExtend;
|
||||||
|
this.backDownExtend = option.backBrDownExtend;//0;
|
||||||
|
this.isMultiBackCab = option.isMultiBackBr;
|
||||||
|
//材料信息
|
||||||
|
this.knifeRadius = safeEval(option.grooveOption.knifeRadius);
|
||||||
|
this.grooveDepth = safeEval(option.grooveOption.grooveAddDepth);
|
||||||
|
this.grooveLength = safeEval(option.grooveOption.grooveAddLength);
|
||||||
|
this.grooveWidth = safeEval(option.grooveOption.grooveAddWidth);
|
||||||
|
}
|
||||||
|
//绘制 传入曲线id表
|
||||||
|
Doit(pls: Polyline[])
|
||||||
|
{
|
||||||
|
//默认认为用户传进来的pls都平行,都在一个平面内
|
||||||
|
if (!pls || pls.length === 0) return;
|
||||||
|
|
||||||
|
let pl0 = pls[0];
|
||||||
|
//希望根据当前的ucs进行绘制,避免坐标系没有对齐的问题
|
||||||
|
let ucs = app.Editor.UCSMatrix;
|
||||||
|
//对齐到pl0点
|
||||||
|
matrixSetVector(ucs, 3, pl0.Position);
|
||||||
|
let ucsinv = new Matrix4().getInverse(ucs);
|
||||||
|
pls = pls.filter(pl => CurveInOCS(pl, ucs, ucsinv));
|
||||||
|
for (let pl of pls)
|
||||||
|
pl.Erase();
|
||||||
|
|
||||||
|
let backPls: Polyline[] = [];//背板 //下面会处理成带孩子们
|
||||||
|
let facePls: Polyline[] = [];//条子或者地脚
|
||||||
|
let otherPls: Polyline[] = [];//层板立板//下面会过滤掉被背板包含的
|
||||||
|
for (let pl of pls)
|
||||||
|
{
|
||||||
|
pl.ApplyMatrix(ucsinv);
|
||||||
|
let box = pl.BoundingBox;
|
||||||
|
let size = box.getSize(new Vector3);
|
||||||
|
pl.TempData = size;
|
||||||
|
pl.TempData2 = box;
|
||||||
|
if (this.IsBackBoard(size))
|
||||||
|
backPls.push(pl);
|
||||||
|
else if (this.IsFaceBoard(size))
|
||||||
|
facePls.push(pl);
|
||||||
|
else
|
||||||
|
otherPls.push(pl);
|
||||||
|
}
|
||||||
|
|
||||||
|
let backAndChildrens: Polyline[][] = [];//背板带着孩子们 [back,x,x,x,x][]
|
||||||
|
for (let pl of backPls)
|
||||||
|
{
|
||||||
|
let g = [pl];
|
||||||
|
otherPls = otherPls.filter(pln =>
|
||||||
|
{
|
||||||
|
if (this.IsPolyLineContain(pl, pln))
|
||||||
|
{
|
||||||
|
g.push(pln);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
backAndChildrens.push(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
//此时被剩下的otherpls 黄金圣斗士 孤立无援
|
||||||
|
|
||||||
|
//绘制空间坐标系
|
||||||
|
this.SpaceOCS = ucs.clone();
|
||||||
|
let y = new Vector3().setFromMatrixColumn(this.SpaceOCS, 1);
|
||||||
|
let z = new Vector3().setFromMatrixColumn(this.SpaceOCS, 2);
|
||||||
|
matrixSetVector(this.SpaceOCS, 1, z.negate());
|
||||||
|
matrixSetVector(this.SpaceOCS, 2, y);
|
||||||
|
|
||||||
|
let allBoards: Board[] = [];
|
||||||
|
|
||||||
|
let layerVerBoards: Board[] = this.DrawBoard(otherPls);
|
||||||
|
let tzdj = this.DrawBoard(facePls, false, 4);//条子或地脚板
|
||||||
|
allBoards.push(...tzdj);
|
||||||
|
|
||||||
|
let backBoards: Board[] = [];
|
||||||
|
for (let g of backAndChildrens)
|
||||||
|
{
|
||||||
|
let brs = this.DrawBoard(g, true);
|
||||||
|
let br = brs.shift();
|
||||||
|
backBoards.push(br);
|
||||||
|
layerVerBoards.push(...brs);
|
||||||
|
}
|
||||||
|
|
||||||
|
allBoards.push(...backBoards, ...layerVerBoards);
|
||||||
|
|
||||||
|
let m = new Matrix4;
|
||||||
|
const CurtailFunc = (br: Board, curtail: number, changeWidth: boolean = true) =>
|
||||||
|
{
|
||||||
|
if (changeWidth)
|
||||||
|
br.Width -= curtail;
|
||||||
|
m.setPosition(0, curtail, 0);
|
||||||
|
br.ApplyMatrix(m);
|
||||||
|
};
|
||||||
|
|
||||||
|
//切割
|
||||||
|
for (let br of layerVerBoards)
|
||||||
|
{
|
||||||
|
br.Subtract(backBoards);
|
||||||
|
//柜体内缩
|
||||||
|
CurtailFunc(br, this.fontDis);
|
||||||
|
}
|
||||||
|
for (let br of tzdj)
|
||||||
|
{
|
||||||
|
CurtailFunc(br, this.fontDis, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//修改材料数据,封边数据,备注数据
|
||||||
|
let storeOption = this.store.m_Option;
|
||||||
|
allBoards.forEach((b) =>
|
||||||
|
{
|
||||||
|
b.KnifeRadius = this.knifeRadius;
|
||||||
|
b.GroovesAddDepth = this.grooveDepth;
|
||||||
|
b.GroovesAddWidth = this.grooveWidth;
|
||||||
|
b.GroovesAddLength = this.grooveLength;
|
||||||
|
b.BoardProcessOption.material = storeOption.material;
|
||||||
|
b.BoardProcessOption.color = storeOption.color;
|
||||||
|
b.BoardProcessOption.boardName = storeOption.boardMatName;
|
||||||
|
b.BoardProcessOption.roomName = storeOption.roomName;
|
||||||
|
b.BoardProcessOption.drillType = storeOption.drillType;
|
||||||
|
b.BoardProcessOption.sealedUp = storeOption.sealedUp;
|
||||||
|
b.BoardProcessOption.sealedDown = storeOption.sealedDown;
|
||||||
|
b.BoardProcessOption.sealedLeft = storeOption.sealedLeft;
|
||||||
|
b.BoardProcessOption.sealedRight = storeOption.sealedRight;
|
||||||
|
let remarks: [string, string][] = [];
|
||||||
|
for (let d of storeOption.remarks)
|
||||||
|
{
|
||||||
|
if (d[0] && d[1])
|
||||||
|
remarks.push([d[0], d[1]]);
|
||||||
|
}
|
||||||
|
b.BoardProcessOption.remarks = remarks;
|
||||||
|
});
|
||||||
|
|
||||||
|
let cabGroup: Board[][] = [];
|
||||||
|
|
||||||
|
if (!this.isMultiBackCab)
|
||||||
|
{
|
||||||
|
//这里我们开始分柜子,共有几个柜子?
|
||||||
|
//1.将背板的范围拉大
|
||||||
|
for (let pl of backPls)
|
||||||
|
{
|
||||||
|
let box = pl.TempData2 as Box3;
|
||||||
|
let [x1, y1, x2, y2] = [box.min.x, box.min.y, box.max.x, box.max.y];
|
||||||
|
let pts = [
|
||||||
|
new Vector3(x1 - 50, y1),
|
||||||
|
new Vector3(x1, y1 - 50),
|
||||||
|
|
||||||
|
new Vector3(x2 + 50, y2),
|
||||||
|
new Vector3(x2, y2 + 50),
|
||||||
|
];
|
||||||
|
for (let p of pts)
|
||||||
|
{
|
||||||
|
let boxTemp = box.clone();
|
||||||
|
boxTemp.expandByPoint(p);
|
||||||
|
|
||||||
|
//如果不相交则延伸成功
|
||||||
|
if (!backPls.some(pl2 => { return pl2 !== pl && boxTemp.intersectsBox(pl2.TempData2); }))
|
||||||
|
box = boxTemp;
|
||||||
|
}
|
||||||
|
pl.TempData2 = box;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let pl of backPls)
|
||||||
|
{
|
||||||
|
let group: Polyline[] = [pl];
|
||||||
|
let box1 = pl.TempData2 as Box3;
|
||||||
|
pls = pls.filter(pln =>
|
||||||
|
{
|
||||||
|
if (pln === pl) return false;
|
||||||
|
let box2 = pln.TempData2 as Box3;
|
||||||
|
if (box1.intersectsBox(box2))
|
||||||
|
{
|
||||||
|
group.push(pln);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
cabGroup.push(group.map(pl => pl.TempData));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cabGroup = [allBoards];
|
||||||
|
|
||||||
|
let spaceInv = new Matrix4().getInverse(this.SpaceOCS);
|
||||||
|
for (let i = 0; i < cabGroup.length; i++)
|
||||||
|
{
|
||||||
|
let group = cabGroup[i];
|
||||||
|
|
||||||
|
//改柜名
|
||||||
|
if (storeOption.iscabinetName)
|
||||||
|
{
|
||||||
|
group.forEach((br) => { br.BoardProcessOption.cabinetName = storeOption.cabinetName + (this.isMultiBackCab ? "" : (i + 1)); });
|
||||||
|
}
|
||||||
|
//#region 这里我们开始解析板件类型
|
||||||
|
//此时我们分析收口条和地脚线
|
||||||
|
let skts: Board[] = [];//收口条
|
||||||
|
let djxs: Board[] = [];//地脚
|
||||||
|
|
||||||
|
let topBoards: Board[] = [];//顶部的板
|
||||||
|
let downBoards: Board[] = [];//底部的板
|
||||||
|
|
||||||
|
let leftBoards: Board[] = [];//左侧的立板
|
||||||
|
let rightBoards: Board[] = [];//右侧的立板
|
||||||
|
|
||||||
|
let ordinarylays: Board[] = [];//普通的层板
|
||||||
|
let ordinaryvers: Board[] = [];//普通的立板
|
||||||
|
|
||||||
|
let layers = group.filter(br => br.BoardType === BoardType.Layer);
|
||||||
|
let vers = group.filter(br => br.BoardType === BoardType.Vertical);
|
||||||
|
let backs = group.filter(br => br.BoardType === BoardType.Behind);
|
||||||
|
|
||||||
|
//左右侧板
|
||||||
|
let left = Infinity;
|
||||||
|
let right = - Infinity;
|
||||||
|
for (let br of vers)
|
||||||
|
{
|
||||||
|
let p = br.MinPoint.applyMatrix4(spaceInv);
|
||||||
|
if (p.x < left)
|
||||||
|
left = p.x;
|
||||||
|
if (p.x > right)
|
||||||
|
right = p.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let br of vers)
|
||||||
|
{
|
||||||
|
let p = br.MinPoint.applyMatrix4(spaceInv);
|
||||||
|
if (equaln(p.x, left))
|
||||||
|
leftBoards.push(br);
|
||||||
|
else if (equaln(p.x, right))
|
||||||
|
rightBoards.push(br);
|
||||||
|
else
|
||||||
|
ordinaryvers.push(br);
|
||||||
|
}
|
||||||
|
|
||||||
|
//顶底板
|
||||||
|
let top = -Infinity;
|
||||||
|
let down = Infinity;
|
||||||
|
for (let br of layers)
|
||||||
|
{
|
||||||
|
let p = br.MinPoint.applyMatrix4(spaceInv);
|
||||||
|
if (p.z > top) top = p.z;
|
||||||
|
if (p.z < down) down = p.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let br of layers)
|
||||||
|
{
|
||||||
|
let p = br.MinPoint.applyMatrix4(spaceInv);
|
||||||
|
if (equaln(p.z, top))
|
||||||
|
topBoards.push(br);
|
||||||
|
else if (equaln(p.z, down))
|
||||||
|
downBoards.push(br);
|
||||||
|
else
|
||||||
|
ordinarylays.push(br);
|
||||||
|
}
|
||||||
|
|
||||||
|
//收口条
|
||||||
|
skts = backs.filter(br => br.ColorIndex === 4);
|
||||||
|
|
||||||
|
down = Infinity;
|
||||||
|
for (let br of skts)
|
||||||
|
{
|
||||||
|
let p = br.MinPoint.applyMatrix4(spaceInv);
|
||||||
|
if (p.z < down) down = p.z;
|
||||||
|
}
|
||||||
|
//地脚线
|
||||||
|
arrayRemoveIf(skts, br =>
|
||||||
|
{
|
||||||
|
let isdjx = br.Width > br.Height && equaln(br.MinPoint.applyMatrix4(spaceInv).z, down);
|
||||||
|
if (isdjx)
|
||||||
|
djxs.push(br);
|
||||||
|
return isdjx;
|
||||||
|
});
|
||||||
|
|
||||||
|
//修改板名和前缩
|
||||||
|
let curtail = 0;
|
||||||
|
let leftrightbrs = [...leftBoards, ...rightBoards];//左右侧
|
||||||
|
for (let i = 0; i < leftrightbrs.length; i++)
|
||||||
|
{
|
||||||
|
let br = leftrightbrs[i];
|
||||||
|
if (i < leftrightbrs.length - 1)
|
||||||
|
{
|
||||||
|
if (storeOption.isfarLeftVerticalBrName)
|
||||||
|
br.Name = storeOption.farLeftVerticalBrName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (storeOption.isfarRightVerticalBrName)
|
||||||
|
br.Name = storeOption.farRightVerticalBrName;
|
||||||
|
br.ColorIndex = 1;
|
||||||
|
}
|
||||||
|
for (let br of ordinaryvers)//普通立板
|
||||||
|
{
|
||||||
|
CurtailFunc(br, storeOption.verticalBrShrink);
|
||||||
|
}
|
||||||
|
|
||||||
|
let topbottombrs = [...topBoards, ...downBoards];//顶底板
|
||||||
|
for (let i = 0; i < topbottombrs.length; i++)
|
||||||
|
{
|
||||||
|
let br = topbottombrs[i];
|
||||||
|
if (i < topBoards.length)
|
||||||
|
{
|
||||||
|
if (storeOption.topMostLayerBrName)
|
||||||
|
br.Name = storeOption.topMostLayerBrName;
|
||||||
|
curtail = storeOption.topBrShrink;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (storeOption.bottomMostLayerBrName)
|
||||||
|
br.Name = storeOption.bottomMostLayerBrName;
|
||||||
|
curtail = storeOption.bottomBrShrink;
|
||||||
|
}
|
||||||
|
CurtailFunc(br, curtail);
|
||||||
|
br.ColorIndex = 7;
|
||||||
|
}
|
||||||
|
for (let br of ordinarylays)//普通层板
|
||||||
|
{
|
||||||
|
CurtailFunc(br, storeOption.layerBrShrink);
|
||||||
|
}
|
||||||
|
|
||||||
|
//地脚和收口条
|
||||||
|
for (let br of djxs)
|
||||||
|
{
|
||||||
|
if (storeOption.bottomMostBackBrName)
|
||||||
|
br.Name = storeOption.bottomMostBackBrName;
|
||||||
|
CurtailFunc(br, storeOption.groundLineBrShrink, false);
|
||||||
|
br.ColorIndex = 5;
|
||||||
|
}
|
||||||
|
for (let br of skts)
|
||||||
|
{
|
||||||
|
if (storeOption.isstripeBrName)
|
||||||
|
br.Name = storeOption.stripeBrName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawBoard(pls: Polyline[], isBack = false, color?: number): Board[]
|
||||||
|
{
|
||||||
|
let depth = this.boardDepth;
|
||||||
|
if (isBack)
|
||||||
|
depth -= this.backBoardMoveDis + this.backBoardThick;
|
||||||
|
|
||||||
|
let brs: Board[] = [];
|
||||||
|
|
||||||
|
for (let pl of pls)
|
||||||
|
{
|
||||||
|
let size = pl.TempData as Vector3;
|
||||||
|
if (size.x < 1 || size.y < 1)
|
||||||
|
{
|
||||||
|
console.log("奇怪的矩形");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let box = pl.TempData2 as Box3;
|
||||||
|
let minp = box.min.clone();
|
||||||
|
let br: Board;
|
||||||
|
if (size.x > size.y && size.y < 50) //层板
|
||||||
|
{
|
||||||
|
br = Board.CreateBoard(size.x, depth, size.y, BoardType.Layer);
|
||||||
|
[minp.x, minp.y, minp.z] = [minp.x + size.x, minp.z, minp.y];
|
||||||
|
}
|
||||||
|
else if (size.x < size.y && size.x < 50)//立板
|
||||||
|
{
|
||||||
|
br = Board.CreateBoard(size.y, depth, size.x, BoardType.Vertical);
|
||||||
|
[minp.x, minp.y, minp.z] = [minp.x, minp.z, minp.y];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[minp.x, minp.y, minp.z] = [minp.x, minp.z + this.backBoardThick, minp.y];
|
||||||
|
if (isBack)
|
||||||
|
{
|
||||||
|
minp.y += this.boardDepth - this.backBoardThick - this.backBoardMoveDis;//移动到后面
|
||||||
|
|
||||||
|
minp.x -= this.backLeftExtend;
|
||||||
|
minp.z -= this.backDownExtend;
|
||||||
|
|
||||||
|
size.x += this.backLeftExtend + this.backRightExtend;
|
||||||
|
size.y += this.backTopExtend + this.backDownExtend;
|
||||||
|
}
|
||||||
|
br = Board.CreateBoard(size.y, size.x, this.backBoardThick, BoardType.Behind);
|
||||||
|
}
|
||||||
|
let m = new Matrix4().setPosition(minp);
|
||||||
|
br.ApplyMatrix(m);
|
||||||
|
br.ApplyMatrix(this.SpaceOCS);
|
||||||
|
if (color !== undefined) br.ColorIndex = color;
|
||||||
|
app.Database.ModelSpace.Append(br);
|
||||||
|
|
||||||
|
brs.push(br);
|
||||||
|
pl.TempData = br;
|
||||||
|
}
|
||||||
|
|
||||||
|
return brs;
|
||||||
|
}
|
||||||
|
|
||||||
|
//pl1是否包含pl2
|
||||||
|
IsPolyLineContain(pl1: Polyline, pl2: Polyline)
|
||||||
|
{
|
||||||
|
let box1 = pl1.TempData2 as Box3;
|
||||||
|
let box2 = pl2.TempData2 as Box3;
|
||||||
|
let box = box1.clone().intersect(box2);
|
||||||
|
let s = box.getSize(new Vector3);
|
||||||
|
if (s.x < 1 || s.y < 1) return false;
|
||||||
|
let int = pl1.IntersectWith(pl2, IntersectOption.OnBothOperands);
|
||||||
|
return int.length > 0 || pl1.PtInCurve(pl2.StartPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
//是否为一个背板的尺寸大小
|
||||||
|
private IsBackBoard(size: Vector3): boolean
|
||||||
|
{
|
||||||
|
return size.x >= this.moveBackWidth && size.y >= this.moveBackLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IsFaceBoard(size: Vector3): boolean
|
||||||
|
{
|
||||||
|
return size.x >= 50 && size.y >= 50;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue