!1431 功能:自定义一键布局

pull/1431/MERGE
ZoeLeeFZ 4 years ago committed by ChenX
parent 3ecb8538b8
commit 2282b07e5e

@ -14,6 +14,7 @@ import { Board } from "../DatabaseServices/Entity/Board";
import { BoardOpenDir } from "../UI/Store/BoardInterface";
import { HardwareCompositeEntity } from "../DatabaseServices/Hardware/HardwareCompositeEntity";
import { Hole } from "../DatabaseServices/3DSolid/Hole";
import { RenderType } from "../GraphicsSystem/RenderType";
async function GetViewportInfo()
@ -149,28 +150,8 @@ export class Draw4Viewport implements Command
}
}
export function Get4Viewport(p1: Vector3, p2: Vector3, ens: Entity[], isHideDoor = false)
function GetEntityIds(ens: Entity[])
{
let left = Math.min(p1.x, p2.x);
let bottom = Math.min(p1.y, p2.y);
let width = Math.abs(p1.x - p2.x);
let height = Math.abs(p1.y - p2.y);
let vp1 = new ViewportEntity(width / 2, height / 2);
vp1.Position = new Vector3(left, bottom);
let vp2 = new ViewportEntity(width / 2, height / 2);
vp2.Position = new Vector3(left + width / 2, bottom);
vp2.camera.LookAt(new Vector3(1, 1, -1));
let vp3 = new ViewportEntity(width / 2, height / 2);
vp3.camera.LookAt(new Vector3(-1));
vp3.Position = new Vector3(left + width / 2, bottom + height / 2);
let vp4 = new ViewportEntity(width / 2, height / 2);
vp4.camera.LookAt(new Vector3(0, 1));
vp4.Position = new Vector3(left, bottom + height / 2);
let ids: ObjectId[] = [];
let noDoorIds: ObjectId[] = [];
let doorIds: ObjectId[] = [];
@ -202,6 +183,32 @@ export function Get4Viewport(p1: Vector3, p2: Vector3, ens: Entity[], isHideDoor
noDoorIds.push(en.Id);
}
}
return { ids, doorIds, noDoorIds };
}
export function Get4Viewport(p1: Vector3, p2: Vector3, ens: Entity[], isHideDoor = false)
{
let left = Math.min(p1.x, p2.x);
let bottom = Math.min(p1.y, p2.y);
let width = Math.abs(p1.x - p2.x);
let height = Math.abs(p1.y - p2.y);
let vp1 = new ViewportEntity(width / 2, height / 2);
vp1.Position = new Vector3(left, bottom);
let vp2 = new ViewportEntity(width / 2, height / 2);
vp2.Position = new Vector3(left + width / 2, bottom);
vp2.camera.LookAt(new Vector3(1, 1, -1));
let vp3 = new ViewportEntity(width / 2, height / 2);
vp3.camera.LookAt(new Vector3(-1));
vp3.Position = new Vector3(left + width / 2, bottom + height / 2);
let vp4 = new ViewportEntity(width / 2, height / 2);
vp4.camera.LookAt(new Vector3(0, 1));
vp4.Position = new Vector3(left, bottom + height / 2);
let { ids, doorIds, noDoorIds } = GetEntityIds(ens);
vp1.AppendShowObjects(ids);
vp2.AppendShowObjects(ids);
@ -384,3 +391,30 @@ export class Draw3Viewport implements Command
AppToaster.dismiss('layout');
}
}
export interface ICustomViewportInfo
{
renderType: RenderType,
dir: Vector3;
width: number;
height: number;
position: Vector3;
}
export function DrawCustomViewports(infos: ICustomViewportInfo[], ens: Entity[])
{
let { ids } = GetEntityIds(ens);
let vps: ViewportEntity[] = [];
for (let info of infos)
{
let vp = new ViewportEntity(info.width, info.height);
vp.camera.LookAt(info.dir);
vp.Position = info.position;
vp.RenderType = info.renderType;
vp.AppendShowObjects(ids);
vps.push(vp);
}
return vps;
}

@ -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;
}
}
}
}

Loading…
Cancel
Save