mirror of https://gitee.com/cf-fz/WebCAD.git
!1168 功能:矩形变酒格,命令Rect2Winerack
parent
50ff76a9d9
commit
e16bd26a07
@ -0,0 +1,168 @@
|
||||
import { Command } from "../../Editor/CommandMachine";
|
||||
import { app } from "../../ApplicationServices/Application";
|
||||
import { PromptStatus } from "../../Editor/PromptResult";
|
||||
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
|
||||
import { ISpaceParse } from "../../Geometry/SpaceParse/ISpaceParse";
|
||||
import { Box3Ext } from "../../Geometry/Box";
|
||||
import { Vector3, Matrix4, Box3 } from "three";
|
||||
import { Rect2Winerack } from "../../UI/Components/Board/Rect2Winerack";
|
||||
import { rect2WinerackStore } from "../../UI/Store/Rect2WinerackStore";
|
||||
import { ModalState } from "../../UI/Components/Modal/ModalInterface";
|
||||
import { toJS } from "mobx";
|
||||
import { Rect2WinerackTool } from "./Rect2WinerackTool";
|
||||
import { matrixSetVector } from "../../Common/Matrix4Utils";
|
||||
import { MergeCurvelist } from "../../Common/CurveUtils";
|
||||
import { ProcessingGroupRecord } from "../../DatabaseServices/ProcessingGroup/ProcessingGroupRecord";
|
||||
|
||||
export class Polyline2Winerack implements Command
|
||||
{
|
||||
async exec()
|
||||
{
|
||||
let plRes = await app.Editor.GetSelection({
|
||||
Msg: "选择酒格封闭矩形",
|
||||
Filter: { filterTypes: [Polyline] }
|
||||
});
|
||||
|
||||
if (plRes.Status === PromptStatus.OK)
|
||||
{
|
||||
|
||||
app.Editor.ModalManage.RenderModal(Rect2Winerack, { store: rect2WinerackStore });
|
||||
|
||||
let res = await app.Editor.ModalManage.Wait();
|
||||
|
||||
if (res.Status === ModalState.Cancel) return;
|
||||
|
||||
let pllist = plRes.SelectSet.SelectEntityList as Polyline[];
|
||||
|
||||
let plss = this.Classify(pllist.filter(c => c.IsClose));
|
||||
|
||||
let tool = Rect2WinerackTool.GetInstance() as Rect2WinerackTool;
|
||||
|
||||
let ucsInv = new Matrix4().getInverse(app.Editor.UCSMatrix);
|
||||
|
||||
for (let pls of plss)
|
||||
{
|
||||
const box = new Box3Ext();
|
||||
let wcsBox = new Box3Ext();
|
||||
|
||||
for (let pl of pls)
|
||||
{
|
||||
box.union(pl.BoundingBox);
|
||||
pl.ApplyMatrix(ucsInv);
|
||||
wcsBox.union(pl.BoundingBox);
|
||||
}
|
||||
|
||||
let min = box.min;
|
||||
let max = box.max;
|
||||
let minWcs = wcsBox.min;
|
||||
|
||||
const option = toJS(rect2WinerackStore.option);
|
||||
|
||||
let mtx = app.Editor.UCSMatrix;
|
||||
mtx.setPosition(min);
|
||||
let mtxInv = new Matrix4().getInverse(mtx);
|
||||
let p1 = min.clone().applyMatrix4(mtxInv);
|
||||
let p2 = max.clone().applyMatrix4(mtxInv).setZ(0);
|
||||
|
||||
let spaceBox = new Box3Ext().setFromPoints([p1, p2]);
|
||||
spaceBox.max.setZ(option.depth);
|
||||
|
||||
//设置坐标系原点
|
||||
p1.copy(spaceBox.min).applyMatrix4(mtx);
|
||||
mtx.setPosition(p1);
|
||||
spaceBox.max.sub(spaceBox.min);
|
||||
spaceBox.min.set(0, 0, 0);
|
||||
|
||||
let y = new Vector3().setFromMatrixColumn(mtx, 1);
|
||||
let z = new Vector3().setFromMatrixColumn(mtx, 2);
|
||||
matrixSetVector(mtx, 1, z.negate());
|
||||
matrixSetVector(mtx, 2, y);
|
||||
|
||||
[spaceBox.min.y, spaceBox.min.z] = [spaceBox.min.z, spaceBox.min.y];
|
||||
[spaceBox.max.y, spaceBox.max.z] = [spaceBox.max.z, spaceBox.max.y];
|
||||
|
||||
mtxInv.getInverse(mtx);
|
||||
|
||||
let space = new ISpaceParse([], mtx);
|
||||
space.SpaceBox = spaceBox;
|
||||
|
||||
|
||||
for (let pl of pls)
|
||||
{
|
||||
pl.Position = pl.Position.sub(minWcs);
|
||||
pl.Erase();
|
||||
}
|
||||
|
||||
tool.ParseFromRects(pls, space, toJS(rect2WinerackStore.option));
|
||||
tool.boardlist.forEach(b => app.Database.ModelSpace.Append(b));
|
||||
|
||||
//添加加工组
|
||||
let ng = new ProcessingGroupRecord();
|
||||
ng.Name = "酒格";
|
||||
app.Database.ProcessingGroupTable.Add(ng);
|
||||
for (let en of tool.boardlist)
|
||||
{
|
||||
ng.Objects.push(en.Id);
|
||||
en.ProcessingGroupList.push(ng.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
private Classify(pllist: Polyline[])
|
||||
{
|
||||
let plss: Polyline[][] = [];
|
||||
|
||||
let boxCache = new WeakMap<Polyline, Box3>();
|
||||
|
||||
//合并共线线段
|
||||
for (let i = 0; i < pllist.length; i++)
|
||||
{
|
||||
let pl = pllist[i];
|
||||
if (pl.EndParam !== 4)
|
||||
{
|
||||
let cus = pl.Explode();
|
||||
MergeCurvelist(cus);
|
||||
pllist[i] = Polyline.Combine(cus);
|
||||
}
|
||||
}
|
||||
|
||||
while (pllist.length > 0)
|
||||
{
|
||||
let firstPl = pllist.shift();
|
||||
|
||||
let arr = [firstPl];
|
||||
let box = firstPl.BoundingBox;
|
||||
|
||||
while (true)
|
||||
{
|
||||
let remPls = pllist.filter(l =>
|
||||
{
|
||||
let bo = boxCache.get(l);
|
||||
if (!bo)
|
||||
{
|
||||
bo = l.BoundingBox;
|
||||
boxCache.set(l, bo);
|
||||
}
|
||||
|
||||
if (bo.intersectsBox(box))
|
||||
{
|
||||
box.union(bo);
|
||||
arr.push(l);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (remPls.length === pllist.length)
|
||||
{
|
||||
plss.push(arr);
|
||||
break;
|
||||
}
|
||||
else
|
||||
pllist = remPls;
|
||||
}
|
||||
}
|
||||
return plss;
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
|
||||
import { ISpaceParse } from "../../Geometry/SpaceParse/ISpaceParse";
|
||||
import { IR2WROption } from "../../UI/Store/WineRackInterface";
|
||||
import { DrawObliqueWineRackTool } from "./DrawObliqueWineRackTool";
|
||||
|
||||
export class Rect2WinerackTool extends DrawObliqueWineRackTool
|
||||
{
|
||||
ParseFromRects(pls: Polyline[], space: ISpaceParse, config: IR2WROption)
|
||||
{
|
||||
this.space = space;
|
||||
this.boardlist.length = 0;
|
||||
this.DrawBoardFormPolyLine(pls, undefined, config);
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
import { IConfigStore } from "./BoardStore";
|
||||
import { IR2WROption } from "./WineRackInterface";
|
||||
import { observable, toJS } from "mobx";
|
||||
import { EBoardKeyList } from "../../Common/BoardKeyList";
|
||||
import { IUiOption } from "./BoardInterface";
|
||||
import { DataAdapter } from "../../Common/DataAdapter";
|
||||
import { IConfigOption } from "../Components/Board/UserConfig";
|
||||
|
||||
export class Rect2WinerackStore implements IConfigStore
|
||||
{
|
||||
@observable configName = "默认";
|
||||
@observable configsNames = [];
|
||||
@observable option: IR2WROption = {
|
||||
depth: 350,
|
||||
addLen: 0,
|
||||
knifeRadius: 3,
|
||||
[EBoardKeyList.UpSealed]: 1,
|
||||
[EBoardKeyList.DownSealed]: 1,
|
||||
[EBoardKeyList.LeftSealed]: 1,
|
||||
[EBoardKeyList.RightSealed]: 1,
|
||||
};
|
||||
uiOption: IUiOption<IR2WROption>;
|
||||
get UIOption()
|
||||
{
|
||||
if (!this.uiOption)
|
||||
this.uiOption = DataAdapter.ConvertUIData(this.option);
|
||||
return this.uiOption;
|
||||
}
|
||||
InitOption()
|
||||
{
|
||||
Object.assign(this.option, {
|
||||
depth: 350,
|
||||
addLen: 0,
|
||||
knifeRadius: 3,
|
||||
[EBoardKeyList.UpSealed]: 1,
|
||||
[EBoardKeyList.DownSealed]: 1,
|
||||
[EBoardKeyList.LeftSealed]: 1,
|
||||
[EBoardKeyList.RightSealed]: 1,
|
||||
});
|
||||
if (!this.uiOption)
|
||||
this.uiOption = DataAdapter.ConvertUIData(this.option);
|
||||
else
|
||||
{
|
||||
Object.assign(this.uiOption, DataAdapter.ConvertUIData(this.option));
|
||||
}
|
||||
}
|
||||
SaveConfig()
|
||||
{
|
||||
return {
|
||||
option: toJS(this.option)
|
||||
};
|
||||
}
|
||||
UpdateOption(cof: IConfigOption<IR2WROption>)
|
||||
{
|
||||
Object.assign(this.option, cof.option);
|
||||
if (this.uiOption)
|
||||
Object.assign(this.uiOption, DataAdapter.ConvertUIData(cof.option));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const rect2WinerackStore = new Rect2WinerackStore();
|
Loading…
Reference in new issue