mirror of https://gitee.com/cf-fz/WebCAD.git
!1212 功能:一键布局,命令onekeylayout
parent
8448f856c2
commit
05b404cd17
@ -0,0 +1,228 @@
|
||||
import { Command } from "../../Editor/CommandMachine";
|
||||
import { app } from "../../ApplicationServices/Application";
|
||||
import { Board } from "../../DatabaseServices/Entity/Board";
|
||||
import { Entity } from "../../DatabaseServices/Entity/Entity";
|
||||
import { CompositeEntity } from "../../DatabaseServices/Entity/CompositeEntity";
|
||||
import { SweepSolid } from "../../DatabaseServices/3DSolid/SweepSolid";
|
||||
import { Hole } from "../../DatabaseServices/3DSolid/Hole";
|
||||
import { ParseBoardList } from "../../Common/BoardUtil";
|
||||
import { Box3Ext } from "../../Geometry/Box";
|
||||
import { PostJson, RequestStatus } from "../../Common/Request";
|
||||
import { ToplineUrls } from "../../Common/HostUrl";
|
||||
import { AppToaster } from "../../UI/Components/Toaster";
|
||||
import { Intent } from "@blueprintjs/core";
|
||||
import { inflate, GroupFileIn } from "../../Common/SerializeMaterial";
|
||||
import { Box3, Vector3 } from "three";
|
||||
import { Get4Viewport } from "../DrawViewport";
|
||||
import { ViewportEntity } from "../../DatabaseServices/ViewportEntity";
|
||||
import { GroupRecord } from "../../DatabaseServices/GroupTableRecord";
|
||||
import { Log } from "../../Common/Log";
|
||||
import { Sleep } from "../../Common/Sleep";
|
||||
import { AlignedDimension } from "../../DatabaseServices/Dimension/AlignedDimension";
|
||||
import { PromptStatus } from "../../Editor/PromptResult";
|
||||
|
||||
export class OneKeyLayout implements Command
|
||||
{
|
||||
async exec()
|
||||
{
|
||||
if (!app.Viewer.isLayout)
|
||||
{
|
||||
Log("仅能在布局模式下使用");
|
||||
return;
|
||||
}
|
||||
|
||||
let curves: Entity[];
|
||||
let frameWidth: number;
|
||||
let p1: Vector3;
|
||||
let p2: Vector3;
|
||||
|
||||
const handleEntitys = (ens: Entity[]) =>
|
||||
{
|
||||
let box = new Box3();
|
||||
ens.reduce((b, e) =>
|
||||
{
|
||||
return b.union(e.BoundingBox);
|
||||
}, box);
|
||||
|
||||
curves = ens;
|
||||
let basePt = box.min;
|
||||
frameWidth = box.getSize(new Vector3).x;
|
||||
ens.forEach(e => e.Position = e.Position.sub(basePt));
|
||||
if (p1)
|
||||
{
|
||||
p1.sub(basePt);
|
||||
p2.sub(basePt);
|
||||
}
|
||||
};
|
||||
|
||||
while (true)
|
||||
{
|
||||
let gRes = await app.Editor.GetEntity({
|
||||
Msg: "选择一键布局的图框",
|
||||
KeyWordList: [{ msg: "使用默认", key: "D" }, { msg: "视口范围", key: "R" }],
|
||||
NotNone: true,
|
||||
Filter: {
|
||||
filterFunction: (o, e) => !!e.GroupId
|
||||
}
|
||||
});
|
||||
if (gRes.Status === PromptStatus.OK)
|
||||
{
|
||||
let ens = (gRes.Entity.GroupId.Object as GroupRecord).Entitys.map(i => i.Object.Clone()) as Entity[];
|
||||
handleEntitys(ens);
|
||||
break;
|
||||
}
|
||||
else if (gRes.Status === PromptStatus.Keyword)
|
||||
{
|
||||
if (gRes.StringResult === "D")
|
||||
{
|
||||
let data = await PostJson(ToplineUrls.get, {
|
||||
dir_id: "",
|
||||
name: "默认图框",
|
||||
});
|
||||
if (data.err_code === RequestStatus.Ok && Number(data.count))
|
||||
{
|
||||
data = await PostJson(ToplineUrls.detail, { topline_id: data.toplines[0].topline_id });
|
||||
if (data.err_code === RequestStatus.Ok)
|
||||
{
|
||||
let file = inflate(data.toplines.file);
|
||||
let ens = GroupFileIn(JSON.parse(file));
|
||||
handleEntitys(ens);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (gRes.StringResult === "R")
|
||||
{
|
||||
const rRes = await app.Editor.GetRectPoint();
|
||||
if (rRes.Status === PromptStatus.OK)
|
||||
{
|
||||
p1 = rRes.Point1UCS;
|
||||
p2 = rRes.Point2UCS;
|
||||
}
|
||||
else return;
|
||||
}
|
||||
}
|
||||
else return;
|
||||
}
|
||||
|
||||
if (!curves)
|
||||
{
|
||||
AppToaster.show({
|
||||
message: "不存在默认图框",
|
||||
timeout: 2000,
|
||||
intent: Intent.DANGER
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
let boardList: Board[] = [];
|
||||
let hardwares: (CompositeEntity | SweepSolid)[] = [];
|
||||
let others: Entity[] = [];
|
||||
|
||||
for (let en of app.Database.ModelSpace.Entitys)
|
||||
{
|
||||
if (en?.Id && !en.IsErase && en.Visible)
|
||||
{
|
||||
if (en instanceof Board)
|
||||
boardList.push(en);
|
||||
else if (en instanceof CompositeEntity || en instanceof SweepSolid)
|
||||
hardwares.push(en);
|
||||
else if (!(en instanceof Hole))
|
||||
others.push(en);
|
||||
}
|
||||
}
|
||||
|
||||
if (boardList.length === 0)
|
||||
{
|
||||
Log("没找到柜体");
|
||||
return;
|
||||
}
|
||||
const ocsInv = boardList[0].SpaceOCSInv;
|
||||
|
||||
let boxBoardMap = ParseBoardList([...boardList, ...hardwares], ocsInv);
|
||||
|
||||
const useEntity = new WeakSet<Entity>();
|
||||
|
||||
let boxMap = new WeakMap<Entity, Box3Ext>();
|
||||
|
||||
for (let [box, bs] of boxBoardMap)
|
||||
{
|
||||
for (let en of others)
|
||||
{
|
||||
if (useEntity.has(en)) continue;
|
||||
let b = boxMap.get(en);
|
||||
if (!b)
|
||||
{
|
||||
b = en.BoundingBox as Box3Ext;
|
||||
boxMap.set(en, b);
|
||||
}
|
||||
if (b.isEmpty)
|
||||
{
|
||||
if (en instanceof AlignedDimension)
|
||||
{
|
||||
let dist = box.distanceToPoint(en.FootP1.applyMatrix4(ocsInv));
|
||||
if (dist <= 50)
|
||||
{
|
||||
useEntity.add(en);
|
||||
(bs as Entity[]).push(en);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (b.intersectsBox(box))
|
||||
{
|
||||
(bs as Entity[]).push(en);
|
||||
useEntity.add(en);
|
||||
box.union(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let left = 600;
|
||||
let bottom = 230;
|
||||
|
||||
let vpsWidth = 2320;
|
||||
let vpsHeight = 1820;
|
||||
|
||||
const DIST = 1 / 8 * frameWidth;
|
||||
|
||||
if (p1 && p2)
|
||||
{
|
||||
left = Math.min(p1.x, p2.x);
|
||||
bottom = Math.min(p1.y, p2.y);
|
||||
vpsWidth = Math.abs(p1.x - p2.x);
|
||||
vpsHeight = Math.abs(p1.y - p2.y);
|
||||
}
|
||||
|
||||
const Total_Length = frameWidth + DIST;
|
||||
|
||||
let vps: ViewportEntity[] = [];
|
||||
|
||||
AppToaster.show({
|
||||
message: "正在生成布局,请稍后",
|
||||
timeout: 0,
|
||||
intent: Intent.PRIMARY
|
||||
}, "onekey");
|
||||
|
||||
await Sleep(16);
|
||||
|
||||
let i = 0;
|
||||
for (let [, bs] of boxBoardMap)
|
||||
{
|
||||
let x = left + i * Total_Length;
|
||||
vps.push(...Get4Viewport(new Vector3(x, bottom), new Vector3(x + vpsWidth, bottom + vpsHeight), bs, true));
|
||||
let g = new GroupRecord();
|
||||
app.Database.GroupTable.Add(g);
|
||||
for (let c of curves)
|
||||
{
|
||||
let cloneC = c.Clone();
|
||||
app.LayoutTool.AppendDatabaseSpace(cloneC);
|
||||
g.Entitys.push(cloneC.Id);
|
||||
cloneC.Position = cloneC.Position.add(new Vector3(i * Total_Length));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
vps.forEach(v => app.Database.LayoutSpace.Append(v));
|
||||
AppToaster.dismiss('onekey');
|
||||
}
|
||||
}
|
Loading…
Reference in new issue