|
|
|
@ -12,8 +12,8 @@ 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 { Box3, Object3D, Vector3 } from "three";
|
|
|
|
|
import { DrawCustomViewports, Get4Viewport, ICustomViewportInfo } from "../DrawViewport";
|
|
|
|
|
import { ViewportEntity } from "../../DatabaseServices/ViewportEntity";
|
|
|
|
|
import { GroupRecord } from "../../DatabaseServices/GroupTableRecord";
|
|
|
|
|
import { Log } from "../../Common/Log";
|
|
|
|
@ -21,9 +21,17 @@ import { Sleep } from "../../Common/Sleep";
|
|
|
|
|
import { AlignedDimension } from "../../DatabaseServices/Dimension/AlignedDimension";
|
|
|
|
|
import { PromptStatus } from "../../Editor/PromptResult";
|
|
|
|
|
import { DownPanelStore } from "../../UI/Store/DownPanelStore";
|
|
|
|
|
import { SelectBox, SelectType } from "../../Editor/SelectBox";
|
|
|
|
|
import { AsVector2 } from "../../Geometry/GeUtils";
|
|
|
|
|
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
|
|
|
|
|
import { IRectInfo, IsRect } from "../../Common/CurveUtils";
|
|
|
|
|
import { Text } from "../../DatabaseServices/Text/Text";
|
|
|
|
|
import { RenderType } from "../../GraphicsSystem/RenderType";
|
|
|
|
|
import { EBoardKeyList } from "../../Common/BoardKeyList";
|
|
|
|
|
|
|
|
|
|
export class OneKeyLayout implements Command
|
|
|
|
|
{
|
|
|
|
|
private _cacheRect = new WeakSet<Entity>();
|
|
|
|
|
async exec()
|
|
|
|
|
{
|
|
|
|
|
if (!app.Viewer.isLayout)
|
|
|
|
@ -32,23 +40,39 @@ export class OneKeyLayout implements Command
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let curves: Entity[];
|
|
|
|
|
let curves: Entity[] = [];
|
|
|
|
|
let frameWidth: number;
|
|
|
|
|
let p1: Vector3;
|
|
|
|
|
let p2: Vector3;
|
|
|
|
|
let basePt = new Vector3();
|
|
|
|
|
let originObjects: Object3D[] = [];
|
|
|
|
|
let specialTexts = new Set<Entity>();
|
|
|
|
|
let texts: Text[] = [];
|
|
|
|
|
|
|
|
|
|
const handleEntitys = (ens: Entity[]) =>
|
|
|
|
|
{
|
|
|
|
|
let box = new Box3();
|
|
|
|
|
ens.reduce((b, e) =>
|
|
|
|
|
for (let en of ens)
|
|
|
|
|
{
|
|
|
|
|
return b.union(e.BoundingBox);
|
|
|
|
|
}, box);
|
|
|
|
|
if (en instanceof Polyline)
|
|
|
|
|
originObjects.push(en.DrawObject);
|
|
|
|
|
let cloneC = en.Clone();
|
|
|
|
|
cloneC.TempData = en;
|
|
|
|
|
if (cloneC instanceof Text)
|
|
|
|
|
{
|
|
|
|
|
if (cloneC.TextString.startsWith("@"))
|
|
|
|
|
texts.push(en as Text);
|
|
|
|
|
if (cloneC.TextString.startsWith("$"))
|
|
|
|
|
specialTexts.add(cloneC);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
box.union(en.BoundingBox);
|
|
|
|
|
curves.push(cloneC);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
curves = ens;
|
|
|
|
|
let basePt = box.min;
|
|
|
|
|
basePt.copy(box.min);
|
|
|
|
|
frameWidth = box.getSize(new Vector3).x;
|
|
|
|
|
ens.forEach(e => e.Position = e.Position.sub(basePt));
|
|
|
|
|
curves.forEach(e => e.Position = e.Position.sub(basePt));
|
|
|
|
|
if (p1)
|
|
|
|
|
{
|
|
|
|
|
p1.sub(basePt);
|
|
|
|
@ -68,8 +92,9 @@ export class OneKeyLayout implements Command
|
|
|
|
|
});
|
|
|
|
|
if (gRes.Status === PromptStatus.OK)
|
|
|
|
|
{
|
|
|
|
|
let ens = (gRes.Entity.GroupId.Object as GroupRecord).Entitys.map(i => i.Object.Clone()) as Entity[];
|
|
|
|
|
handleEntitys(ens);
|
|
|
|
|
let originEns = (gRes.Entity.GroupId.Object as GroupRecord).Entitys.map(i => i.Object) as Entity[];
|
|
|
|
|
|
|
|
|
|
handleEntitys(originEns);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if (gRes.Status > PromptStatus.None)
|
|
|
|
@ -198,6 +223,16 @@ export class OneKeyLayout implements Command
|
|
|
|
|
vpsHeight = Math.abs(p1.y - p2.y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let selectP1 = new Vector3(left + vpsWidth + 1, bottom - 1).add(basePt);
|
|
|
|
|
let selectP2 = new Vector3(left - 1, bottom + vpsHeight + 1).add(basePt);
|
|
|
|
|
app.Viewer.WorldToScreen(selectP1);
|
|
|
|
|
app.Viewer.WorldToScreen(selectP2);
|
|
|
|
|
|
|
|
|
|
let selectBox = new SelectBox(app.Viewer, AsVector2(selectP2), AsVector2(selectP1), SelectType.W);
|
|
|
|
|
selectBox.Select(originObjects, { filterErase: false });
|
|
|
|
|
let selectEns = selectBox.SelectEntityList;
|
|
|
|
|
let vpInfos: ICustomViewportInfo[] = this.GetVpInfos([...selectEns, ...texts], basePt);
|
|
|
|
|
|
|
|
|
|
const Total_Length = frameWidth + DIST;
|
|
|
|
|
|
|
|
|
|
let vps: ViewportEntity[] = [];
|
|
|
|
@ -213,14 +248,39 @@ export class OneKeyLayout implements Command
|
|
|
|
|
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));
|
|
|
|
|
if (vpInfos.length > 0)
|
|
|
|
|
{
|
|
|
|
|
const newInfos: ICustomViewportInfo[] = [];
|
|
|
|
|
for (let info of vpInfos)
|
|
|
|
|
{
|
|
|
|
|
let newInfo = { ...info };
|
|
|
|
|
newInfo.position = info.position.clone();
|
|
|
|
|
newInfo.position.x += i * Total_Length;
|
|
|
|
|
newInfos.push(newInfo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vps.push(...DrawCustomViewports(newInfos, bs));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
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();
|
|
|
|
|
g.Name = "图框";
|
|
|
|
|
app.Database.GroupTable.Add(g);
|
|
|
|
|
|
|
|
|
|
let board = bs.find(b => b instanceof Board) as Board;
|
|
|
|
|
for (let c of curves)
|
|
|
|
|
{
|
|
|
|
|
if (this._cacheRect.has(c.TempData)) continue;
|
|
|
|
|
let cloneC = c.Clone();
|
|
|
|
|
if (specialTexts.has(c))
|
|
|
|
|
{
|
|
|
|
|
this.HandleTextMetaData(cloneC as Text, board);
|
|
|
|
|
if (!(<Text>cloneC).TextString)
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
app.LayoutTool.AppendDatabaseSpace(cloneC);
|
|
|
|
|
g.Entitys.push(cloneC.Id);
|
|
|
|
|
cloneC.Position = cloneC.Position.add(new Vector3(i * Total_Length));
|
|
|
|
@ -242,4 +302,158 @@ export class OneKeyLayout implements Command
|
|
|
|
|
AppToaster.dismiss('onekey');
|
|
|
|
|
Entity.__ReadFileIng__ = false;
|
|
|
|
|
}
|
|
|
|
|
private GetVpInfos = (selectEns: Entity[], basePt: Vector3) =>
|
|
|
|
|
{
|
|
|
|
|
let vpInfos: ICustomViewportInfo[] = [];
|
|
|
|
|
let vpRects: IRectInfo[] = [];
|
|
|
|
|
let renderTypeTexts: Text[] = [];
|
|
|
|
|
let dirTexts: Text[] = [];
|
|
|
|
|
|
|
|
|
|
const GetRenderType = (txt: string) =>
|
|
|
|
|
{
|
|
|
|
|
switch (txt)
|
|
|
|
|
{
|
|
|
|
|
case "线框":
|
|
|
|
|
case "二维线框":
|
|
|
|
|
case "二维":
|
|
|
|
|
return RenderType.Wireframe;
|
|
|
|
|
case "概念":
|
|
|
|
|
return RenderType.Conceptual;
|
|
|
|
|
case "真实":
|
|
|
|
|
return RenderType.Physical;
|
|
|
|
|
case "真实带线框":
|
|
|
|
|
return RenderType.Physical2;
|
|
|
|
|
default:
|
|
|
|
|
return RenderType.Print;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const GetDir = (txt: string) =>
|
|
|
|
|
{
|
|
|
|
|
switch (txt)
|
|
|
|
|
{
|
|
|
|
|
case "左":
|
|
|
|
|
case "左视":
|
|
|
|
|
return new Vector3(1);
|
|
|
|
|
case "右":
|
|
|
|
|
case "右视":
|
|
|
|
|
return new Vector3(-1);
|
|
|
|
|
case "俯":
|
|
|
|
|
case "俯视":
|
|
|
|
|
return new Vector3(0, 0, -1);
|
|
|
|
|
case "仰":
|
|
|
|
|
case "仰视":
|
|
|
|
|
return new Vector3(0, 0, 1);
|
|
|
|
|
case "前":
|
|
|
|
|
case "前视":
|
|
|
|
|
return new Vector3(0, 1);
|
|
|
|
|
case "后":
|
|
|
|
|
case "后视":
|
|
|
|
|
return new Vector3(0, -1);
|
|
|
|
|
case "西南":
|
|
|
|
|
case "西南等轴侧":
|
|
|
|
|
case "西南等轴测":
|
|
|
|
|
return new Vector3(1, 1, -1);
|
|
|
|
|
default:
|
|
|
|
|
return new Vector3(0, 0, -1);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (let en of selectEns)
|
|
|
|
|
{
|
|
|
|
|
if (en instanceof Polyline)
|
|
|
|
|
{
|
|
|
|
|
let res = IsRect(en);
|
|
|
|
|
if (res.isRect && res.size.x > 50 && res.size.y > 50)
|
|
|
|
|
{
|
|
|
|
|
this._cacheRect.add(en);
|
|
|
|
|
vpRects.push(res);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (en instanceof Text)
|
|
|
|
|
{
|
|
|
|
|
if (en.TextString.startsWith("@@"))
|
|
|
|
|
{
|
|
|
|
|
renderTypeTexts.push(en);
|
|
|
|
|
}
|
|
|
|
|
else if (en.TextString.startsWith("@"))
|
|
|
|
|
{
|
|
|
|
|
dirTexts.push(en);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const useCache = new WeakSet<Entity>();
|
|
|
|
|
|
|
|
|
|
for (let info of vpRects)
|
|
|
|
|
{
|
|
|
|
|
let vpInfo: ICustomViewportInfo = {
|
|
|
|
|
width: info.size.x,
|
|
|
|
|
height: info.size.y,
|
|
|
|
|
dir: new Vector3(),
|
|
|
|
|
position: info.box.min.clone().sub(basePt),
|
|
|
|
|
renderType: RenderType.Print,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let box = info.box.clone();
|
|
|
|
|
box.max.setZ(0);
|
|
|
|
|
box.min.setZ(0);
|
|
|
|
|
|
|
|
|
|
for (let text of dirTexts)
|
|
|
|
|
{
|
|
|
|
|
let pos = text.Position.setZ(0);
|
|
|
|
|
if (!useCache.has(text) && box.containsPoint(pos))
|
|
|
|
|
{
|
|
|
|
|
vpInfo.dir.copy(GetDir(text.TextString.slice(1)));
|
|
|
|
|
useCache.add(text);
|
|
|
|
|
this._cacheRect.add(text);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (let text of renderTypeTexts)
|
|
|
|
|
{
|
|
|
|
|
let pos = text.Position.setZ(0);
|
|
|
|
|
if (!useCache.has(text) && box.containsPoint(pos))
|
|
|
|
|
{
|
|
|
|
|
vpInfo.renderType = GetRenderType(text.TextString.slice(2));
|
|
|
|
|
useCache.add(text);
|
|
|
|
|
this._cacheRect.add(text);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
vpInfos.push(vpInfo);
|
|
|
|
|
}
|
|
|
|
|
return vpInfos;
|
|
|
|
|
};
|
|
|
|
|
private HandleTextMetaData(text: Text, en?: Board)
|
|
|
|
|
{
|
|
|
|
|
let metaData = text.TextString.slice(1);
|
|
|
|
|
if (en)
|
|
|
|
|
{
|
|
|
|
|
const option = en.BoardProcessOption;
|
|
|
|
|
|
|
|
|
|
switch (metaData)
|
|
|
|
|
{
|
|
|
|
|
case "房名":
|
|
|
|
|
case "房间名":
|
|
|
|
|
text.TextString = option[EBoardKeyList.RoomName];
|
|
|
|
|
break;
|
|
|
|
|
case "柜名":
|
|
|
|
|
text.TextString = option[EBoardKeyList.CabinetName];
|
|
|
|
|
break;
|
|
|
|
|
case "板材名":
|
|
|
|
|
text.TextString = option[EBoardKeyList.BrMat];
|
|
|
|
|
break;
|
|
|
|
|
case "材料":
|
|
|
|
|
text.TextString = option[EBoardKeyList.Mat];
|
|
|
|
|
break;
|
|
|
|
|
case "颜色":
|
|
|
|
|
text.TextString = option[EBoardKeyList.Color];
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|