mirror of https://gitee.com/cf-fz/WebCAD.git
!1201 功能:布局打印
parent
eeef48aec9
commit
96aeabcb78
@ -0,0 +1,67 @@
|
||||
import { Command } from "../Editor/CommandMachine";
|
||||
import { app } from "../ApplicationServices/Application";
|
||||
import { PromptStatus } from "../Editor/PromptResult";
|
||||
import { ViewportEntity } from "../DatabaseServices/ViewportEntity";
|
||||
import { Log } from "../Common/Log";
|
||||
import { Vector3 } from "three";
|
||||
|
||||
export class DrawViewport implements Command
|
||||
{
|
||||
async exec()
|
||||
{
|
||||
if (!app.Viewer.isLayout)
|
||||
{
|
||||
Log("仅能在布局模式下使用");
|
||||
return;
|
||||
}
|
||||
let rectRes = await app.Editor.GetRectPoint();
|
||||
|
||||
if (rectRes.Status === PromptStatus.OK)
|
||||
{
|
||||
let p1 = rectRes.Point1UCS;
|
||||
let p2 = rectRes.Point2UCS;
|
||||
let vp = new ViewportEntity();
|
||||
vp.UpdateByPts(p1, p2);
|
||||
app.Database.LayoutSpace.Append(vp);
|
||||
}
|
||||
}
|
||||
}
|
||||
export class Draw4Viewport implements Command
|
||||
{
|
||||
async exec()
|
||||
{
|
||||
if (!app.Viewer.isLayout)
|
||||
{
|
||||
Log("仅能在布局模式下使用");
|
||||
return;
|
||||
}
|
||||
let rectRes = await app.Editor.GetRectPoint();
|
||||
|
||||
if (rectRes.Status === PromptStatus.OK)
|
||||
{
|
||||
let p1 = rectRes.Point1UCS;
|
||||
let p2 = rectRes.Point2UCS;
|
||||
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);
|
||||
|
||||
[vp1, vp2, vp3, vp4].forEach(p => app.Database.LayoutSpace.Append(p));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,34 +1,48 @@
|
||||
import { Command } from "../Editor/CommandMachine";
|
||||
import { userConfig } from "../Editor/UserConfig";
|
||||
import { RenderType } from "../GraphicsSystem/RenderType";
|
||||
import { app } from "../ApplicationServices/Application";
|
||||
import { ViewportEntity } from "../DatabaseServices/ViewportEntity";
|
||||
import { PromptStatus } from "../Editor/PromptResult";
|
||||
|
||||
export class CMD_Wireframe implements Command
|
||||
export class ChangeRenderType implements Command
|
||||
{
|
||||
exec()
|
||||
constructor(private _type: RenderType)
|
||||
{
|
||||
userConfig.RenderType = RenderType.Wireframe;
|
||||
}
|
||||
}
|
||||
|
||||
export class CMD_Conceptual implements Command
|
||||
{
|
||||
exec()
|
||||
}
|
||||
async exec()
|
||||
{
|
||||
userConfig.RenderType = RenderType.Conceptual;
|
||||
if (app.Viewer.isLayout)
|
||||
{
|
||||
if (app.Viewer.CurrentViewport)
|
||||
{
|
||||
this.ChangeViewport([app.Viewer.CurrentViewport]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
let vres = await app.Editor.GetSelection({
|
||||
Msg: "选择要改变渲染类型的视口",
|
||||
UseSelect: true,
|
||||
Filter: {
|
||||
filterTypes: [ViewportEntity]
|
||||
}
|
||||
});
|
||||
|
||||
export class CMD_Physical implements Command
|
||||
{
|
||||
exec()
|
||||
|
||||
if (vres.Status === PromptStatus.OK)
|
||||
{
|
||||
userConfig.RenderType = RenderType.Physical;
|
||||
let vs = vres.SelectSet.SelectEntityList as ViewportEntity[];
|
||||
this.ChangeViewport(vs);
|
||||
}
|
||||
}
|
||||
export class CMD_Physical2 implements Command
|
||||
{
|
||||
exec()
|
||||
return;
|
||||
}
|
||||
userConfig.RenderType = this._type;
|
||||
}
|
||||
ChangeViewport(vs: ViewportEntity[])
|
||||
{
|
||||
userConfig.RenderType = RenderType.Physical2;
|
||||
for (let v of vs)
|
||||
{
|
||||
v.RenderType = this._type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
import { Command } from "../../Editor/CommandMachine";
|
||||
import { app } from "../../ApplicationServices/Application";
|
||||
import { FrameManage } from "../../UI/Components/Modal/FrameManager";
|
||||
|
||||
export class ShowFrmae implements Command
|
||||
{
|
||||
async exec()
|
||||
{
|
||||
app.Editor.ModalManage.RenderModeless(FrameManage);
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
import { CADFiler } from "../DatabaseServices/CADFiler";
|
||||
|
||||
export const TempCADFiler = new CADFiler();
|
@ -0,0 +1,295 @@
|
||||
import { Scene, Vector3, Line, Object3D, BufferGeometry, Color, Box3, AmbientLight, Mesh, Group, Matrix3, Curve } from "three";
|
||||
import { CameraUpdate } from "../GraphicsSystem/CameraUpdate";
|
||||
import { Entity } from "./Entity/Entity";
|
||||
import { RenderType } from "../GraphicsSystem/RenderType";
|
||||
import { BufferGeometryUtils } from "../Geometry/BufferGeometryUtils";
|
||||
import { ColorMaterial } from "../Common/ColorPalette";
|
||||
import { Factory } from "./CADFactory";
|
||||
import { updateGeometry, GetBox } from "../Geometry/GeUtils";
|
||||
import { UpdateDraw } from "../Common/Status";
|
||||
import { ObjectId } from "./ObjectId";
|
||||
import { CADFiler } from "./CADFiler";
|
||||
import { FixIndex } from "../Nest/Common/Util";
|
||||
import { AutoRecord } from "./AutoRecord";
|
||||
import { ObjectSnapMode } from "../Editor/ObjectSnapMode";
|
||||
import { Hole } from "./3DSolid/Hole";
|
||||
import { GetEntity } from "../Common/Utils";
|
||||
import { CompositeEntity } from "./Entity/CompositeEntity";
|
||||
import { DisposeThreeObj } from "../Common/Dispose";
|
||||
import { VisualSpaceBox } from "../Editor/VisualSpaceBox";
|
||||
import { Board } from "./Entity/Board";
|
||||
|
||||
@Factory
|
||||
export class ViewportEntity extends Entity
|
||||
{
|
||||
scene: Scene = new Scene();
|
||||
readonly camera: CameraUpdate = new CameraUpdate();
|
||||
private _renderType: RenderType = RenderType.Print;
|
||||
@AutoRecord hideObjectIds = new Set<ObjectId>();
|
||||
ViewData = {
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
};
|
||||
_Color = 256;
|
||||
constructor(
|
||||
private _width: number = 1,
|
||||
private _height: number = 1,
|
||||
)
|
||||
{
|
||||
super();
|
||||
this.scene.background = new Color(0xffffff);
|
||||
}
|
||||
get Left()
|
||||
{
|
||||
return this.Position.x;
|
||||
}
|
||||
get Bottom()
|
||||
{
|
||||
return this.Position.y;
|
||||
}
|
||||
get Width()
|
||||
{
|
||||
return this._width;
|
||||
}
|
||||
set Width(v: number)
|
||||
{
|
||||
if (v === this._height || v < 0)
|
||||
return;
|
||||
this.WriteAllObjectRecord();
|
||||
this._width = v;
|
||||
this.Update(UpdateDraw.Geometry);
|
||||
}
|
||||
get ViewWidth()
|
||||
{
|
||||
return this.camera.Width;
|
||||
}
|
||||
get ViewHeight()
|
||||
{
|
||||
return this.camera.Height;
|
||||
}
|
||||
get Height()
|
||||
{
|
||||
return this._height;
|
||||
}
|
||||
set Height(v: number)
|
||||
{
|
||||
if (v === this._height || v < 0)
|
||||
return;
|
||||
this.WriteAllObjectRecord();
|
||||
this._height = v;
|
||||
this.Update(UpdateDraw.Geometry);
|
||||
}
|
||||
GetObjectSnapPoints(
|
||||
snapMode: ObjectSnapMode,
|
||||
pickPoint: Vector3,
|
||||
lastPoint: Vector3,
|
||||
viewXform: Matrix3
|
||||
): Vector3[]
|
||||
{
|
||||
switch (snapMode)
|
||||
{
|
||||
case ObjectSnapMode.End:
|
||||
return this.GetGripPoints();
|
||||
case ObjectSnapMode.Mid:
|
||||
case ObjectSnapMode.Nea:
|
||||
case ObjectSnapMode.Ext:
|
||||
case ObjectSnapMode.Per:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
protected OnlyRenderType = true;
|
||||
get Entitys()
|
||||
{
|
||||
let ens: Entity[] = [];
|
||||
for (let obj of this.scene.children)
|
||||
{
|
||||
let e = GetEntity(obj);
|
||||
if (e?.TempData?.Entity)
|
||||
ens.push(e);
|
||||
}
|
||||
return ens;
|
||||
}
|
||||
get Points()
|
||||
{
|
||||
return [
|
||||
new Vector3(),
|
||||
new Vector3(this._width),
|
||||
new Vector3(this._width, this._height),
|
||||
new Vector3(0, this._height),
|
||||
];
|
||||
}
|
||||
InitDrawObject(type: RenderType)
|
||||
{
|
||||
let pts = this.Points;
|
||||
let geo = BufferGeometryUtils.CreateFromPts([...pts, pts[0]]);
|
||||
this.camera.SetSize(this._width, this._height);
|
||||
let o = new Group();
|
||||
let l = new Line(geo, ColorMaterial.GetLineMaterial(this._Color));
|
||||
o.add(l);
|
||||
let geo2 = BufferGeometryUtils.CreateFromPts([0, 1, 2, 2, 3, 0].map(i => pts[i]));
|
||||
let mesh = new Mesh(geo2, ColorMaterial.TransparentMeshMaterial);
|
||||
o.add(mesh);
|
||||
return o;
|
||||
}
|
||||
|
||||
UpdateDrawObject(type: RenderType, obj: Object3D)
|
||||
{
|
||||
let pts = this.Points;
|
||||
let line = (obj.children[0] as Line);
|
||||
let geo = line.geometry as BufferGeometry;
|
||||
if (!BufferGeometryUtils.UpdatePts(geo, [...pts, pts[0]]))
|
||||
{
|
||||
updateGeometry(line, BufferGeometryUtils.CreateFromPts([...pts, pts[0]]));
|
||||
}
|
||||
let mesh = obj.children[1] as Mesh;
|
||||
let geo2 = mesh.geometry as BufferGeometry;
|
||||
if (!BufferGeometryUtils.UpdatePts(geo2, [0, 1, 2, 2, 3, 0].map(i => pts[i])))
|
||||
{
|
||||
updateGeometry(line, BufferGeometryUtils.CreateFromPts([0, 1, 2, 2, 3, 0].map(i => pts[i])));
|
||||
}
|
||||
this.scene.updateMatrixWorld();
|
||||
}
|
||||
UpdateByPts(p1: Vector3, p2: Vector3)
|
||||
{
|
||||
let left = Math.min(p1.x, p2.x);
|
||||
let bottom = Math.min(p1.y, p2.y);
|
||||
this._width = Math.abs(p1.x - p2.x);
|
||||
this._height = Math.abs(p1.y - p2.y);
|
||||
this.Position = new Vector3(left, bottom);
|
||||
}
|
||||
GetGripPoints()
|
||||
{
|
||||
return this.Points.map(p => p.applyMatrix4(this.OCS));
|
||||
}
|
||||
MoveGripPoints(indexList: number[], moveVec: Vector3)
|
||||
{
|
||||
this.WriteAllObjectRecord();
|
||||
|
||||
let pts = this.GetGripPoints();
|
||||
|
||||
for (let index of indexList)
|
||||
{
|
||||
pts[index].add(moveVec);
|
||||
this.UpdateByPts(pts[index], pts[FixIndex(index + 2, 4)]);
|
||||
}
|
||||
this.Update(UpdateDraw.Geometry);
|
||||
}
|
||||
ZoomAll()
|
||||
{
|
||||
let box = GetBox(this.scene, true);
|
||||
if (box.isEmpty())
|
||||
box.set(new Vector3(), new Vector3(1000 * (this.Width / this.Height), 1000, 1000));
|
||||
this.camera.ZoomExtensBox3(box);
|
||||
this.camera.Zoom(1.5);
|
||||
}
|
||||
get RenderType()
|
||||
{
|
||||
return this._renderType;
|
||||
}
|
||||
set RenderType(v: RenderType)
|
||||
{
|
||||
if (v === this._renderType) return;
|
||||
this.WriteAllObjectRecord();
|
||||
this._renderType = v;
|
||||
this.Entitys.forEach(e =>
|
||||
{
|
||||
e.__CacheRenderType__ = v;
|
||||
e.UpdateRenderType(v);
|
||||
});
|
||||
}
|
||||
get BoundingBox()
|
||||
{
|
||||
return new Box3().setFromPoints(this.GetGripPoints());
|
||||
}
|
||||
AppendEntity(en: Entity)
|
||||
{
|
||||
if (en.Id
|
||||
&& en.Visible
|
||||
&& !this.hideObjectIds.has(en.Id)
|
||||
&& !en.IsErase && !(en instanceof Hole)
|
||||
&& !(en instanceof ViewportEntity)
|
||||
&& !(en instanceof VisualSpaceBox))
|
||||
{
|
||||
let ens: Entity[];
|
||||
if (en instanceof Board)
|
||||
{
|
||||
ens = en.SplitBoards;
|
||||
}
|
||||
else
|
||||
ens = [en];
|
||||
|
||||
for (let e of ens)
|
||||
{
|
||||
let originEn = e;
|
||||
if (originEn instanceof Board && originEn.__OriginalEnt__)
|
||||
originEn = originEn.__OriginalEnt__;
|
||||
|
||||
let o = this.scene.getObjectByName(e.Id.Index.toString());
|
||||
if (o)
|
||||
{
|
||||
o.visible = true;
|
||||
return;
|
||||
}
|
||||
|
||||
let cloneEN = e["__OriginalEnt__"] ? e : e.Clone();
|
||||
|
||||
cloneEN.TempData = { Entity: originEn };
|
||||
if (cloneEN instanceof CompositeEntity)
|
||||
{
|
||||
cloneEN.Traverse((e) =>
|
||||
{
|
||||
if (e.ColorIndex === 7)
|
||||
e.ColorIndex = 256;
|
||||
});
|
||||
}
|
||||
else
|
||||
if (e.ColorIndex === 7)
|
||||
cloneEN.ColorIndex = 256;
|
||||
cloneEN.UpdateRenderType(this._renderType);
|
||||
let cloneObject = cloneEN.DrawObject;
|
||||
cloneObject.name = originEn.Id.Index.toString();
|
||||
this.scene.add(cloneObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
RemoveEntity(en: Entity)
|
||||
{
|
||||
for (let o of this.scene.children)
|
||||
{
|
||||
if (o.name === en.Id.Index.toString())
|
||||
o.visible = false;
|
||||
}
|
||||
}
|
||||
GoodBye()
|
||||
{
|
||||
super.GoodBye();
|
||||
DisposeThreeObj(this.scene);
|
||||
this.scene.dispose();
|
||||
}
|
||||
protected _ReadFile(file: CADFiler)
|
||||
{
|
||||
super._ReadFile(file);
|
||||
let ver = file.Read();
|
||||
this.camera.ReadFile(file);
|
||||
this.Width = file.Read();
|
||||
this.Height = file.Read();
|
||||
this._renderType = file.Read();
|
||||
let count = file.Read();
|
||||
this.hideObjectIds.clear();
|
||||
for (let i = 0; i < count; i++)
|
||||
this.hideObjectIds.add(file.ReadSoftObjectId());
|
||||
}
|
||||
WriteFile(file: CADFiler)
|
||||
{
|
||||
super.WriteFile(file);
|
||||
file.Write(1);
|
||||
this.camera.WriteFile(file);
|
||||
file.Write(this.Width);
|
||||
file.Write(this.Height);
|
||||
file.Write(this._renderType);
|
||||
file.Write(this.hideObjectIds.size);
|
||||
this.hideObjectIds.forEach(id => file.WriteSoftObjectId(id));
|
||||
}
|
||||
}
|
@ -0,0 +1,292 @@
|
||||
import { TempCADFiler } from "../Common/TempVar";
|
||||
import { Vector3 } from "three";
|
||||
import { AppToaster } from "../UI/Components/Toaster";
|
||||
import { app } from "../ApplicationServices/Application";
|
||||
import { Entity } from "../DatabaseServices/Entity/Entity";
|
||||
import { end } from "xaop";
|
||||
import { CommandHistoryRecord } from "../DatabaseServices/CommandHistoryRecord";
|
||||
import { CommandNames } from "../Common/CommandNames";
|
||||
import { ViewportEntity } from "../DatabaseServices/ViewportEntity";
|
||||
import { arrayRemoveIf } from "../Common/ArrayExt";
|
||||
import { Hole } from "../DatabaseServices/3DSolid/Hole";
|
||||
import { CreateObjectData } from "../DatabaseServices/CreateObjectData";
|
||||
import { RemoveObjectData } from "../DatabaseServices/RemoveObjectData";
|
||||
|
||||
|
||||
const Hide_Cmds = new Set([
|
||||
CommandNames.Erase, CommandNames.HideSelect, CommandNames.HideUnSelect, CommandNames.HideDoor
|
||||
]);
|
||||
|
||||
const Show_cmds = new Set([
|
||||
CommandNames.Show, CommandNames.ShowDoor
|
||||
]);
|
||||
|
||||
|
||||
export class LayoutTool
|
||||
{
|
||||
private colorBak: number;
|
||||
constructor()
|
||||
{
|
||||
//监听模块树的变更,当变更时,刷新视图
|
||||
end(app.Database.hm, app.Database.hm.RedoEvent, (cmdName: CommandNames, historyRec: CommandHistoryRecord) =>
|
||||
{
|
||||
let createEntitys: Entity[] = [];
|
||||
let changeEntitys: Entity[] = [];
|
||||
let deleteEntitys: Entity[] = [];
|
||||
|
||||
for (let [h, hs] of historyRec.HistoryList)
|
||||
{
|
||||
if (h.Object === app.Database.ModelSpace.EntityCol)
|
||||
{
|
||||
for (let h of hs)
|
||||
{
|
||||
if (h.redoData instanceof RemoveObjectData)
|
||||
deleteEntitys.push(h.redoData.RemoveObject as Entity);
|
||||
else if (h.redoData instanceof CreateObjectData)
|
||||
createEntitys.push(h.redoData.CreateObject as Entity);
|
||||
}
|
||||
}
|
||||
if (!(h.Object instanceof Entity))
|
||||
continue;
|
||||
|
||||
let e = h.Object;
|
||||
|
||||
for (let h of hs)
|
||||
{
|
||||
if (h.redoData instanceof CreateObjectData)
|
||||
{
|
||||
createEntitys.push(e);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (e.IsErase)
|
||||
deleteEntitys.push(e);
|
||||
else
|
||||
changeEntitys.push(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Hide_Cmds.has(cmdName))
|
||||
{
|
||||
this.HideViewportEntitys(changeEntitys);
|
||||
}
|
||||
else if (Show_cmds.has(cmdName))
|
||||
{
|
||||
this.ShowViewportEntitys(changeEntitys);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.ShowViewportEntitys(createEntitys);
|
||||
this.HideViewportEntitys(deleteEntitys);
|
||||
this.ChangeViewportEntitys(changeEntitys);
|
||||
}
|
||||
|
||||
});
|
||||
end(app.Database.hm, app.Database.hm.UndoEvent, (cmdName: CommandNames, historyRec: CommandHistoryRecord) =>
|
||||
{
|
||||
|
||||
let createEntitys: Entity[] = [];
|
||||
let changeEntitys: Entity[] = [];
|
||||
let deleteEntitys: Entity[] = [];
|
||||
|
||||
for (let [h, hs] of historyRec.HistoryList)
|
||||
{
|
||||
if (h.Object === app.Database.ModelSpace.EntityCol)
|
||||
{
|
||||
for (let h of hs)
|
||||
{
|
||||
if (h.undoData instanceof RemoveObjectData)
|
||||
deleteEntitys.push(h.undoData.RemoveObject as Entity);
|
||||
else if (h.undoData instanceof CreateObjectData)
|
||||
createEntitys.push(h.undoData.CreateObject as Entity);
|
||||
}
|
||||
}
|
||||
if (!(h.Object instanceof Entity))
|
||||
continue;
|
||||
|
||||
let e = h.Object;
|
||||
|
||||
for (let h of hs)
|
||||
{
|
||||
if (h.undoData instanceof CreateObjectData)
|
||||
{
|
||||
createEntitys.push(e);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (e.IsErase)
|
||||
deleteEntitys.push(e);
|
||||
else
|
||||
changeEntitys.push(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Hide_Cmds.has(cmdName))
|
||||
{
|
||||
this.ShowViewportEntitys(changeEntitys);
|
||||
}
|
||||
else if (Show_cmds.has(cmdName))
|
||||
{
|
||||
this.HideViewportEntitys(changeEntitys);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.ShowViewportEntitys(createEntitys);
|
||||
this.HideViewportEntitys(deleteEntitys);
|
||||
this.ChangeViewportEntitys(changeEntitys);
|
||||
}
|
||||
});
|
||||
app.CommandReactor.OnCommandEnd((cmdName: CommandNames, changeObjects, createObjects) =>
|
||||
{
|
||||
if (app.Viewer.isLayout) return;
|
||||
|
||||
this.ShowViewportEntitys(createObjects.filter(e => e instanceof Entity) as Entity[]);
|
||||
|
||||
let ens = changeObjects.filter(e => e instanceof Entity) as Entity[];
|
||||
|
||||
if (Hide_Cmds.has(cmdName))
|
||||
{
|
||||
this.HideViewportEntitys(ens);
|
||||
}
|
||||
else if (Show_cmds.has(cmdName))
|
||||
{
|
||||
this.ShowViewportEntitys(ens);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.ChangeViewportEntitys(ens);
|
||||
}
|
||||
});
|
||||
}
|
||||
CacheCamera()
|
||||
{
|
||||
TempCADFiler.Data = [];
|
||||
app.Viewer.CameraCtrl.WriteFile(TempCADFiler);
|
||||
}
|
||||
Switch()
|
||||
{
|
||||
AppToaster.dismiss("vp");
|
||||
app.Viewer.OutlinePass.selectedObjects = [];
|
||||
app.Editor.SelectCtrl.Cancel();
|
||||
const isLayout = app.Viewer.isLayout;
|
||||
app.Viewer.SwitchLayout();
|
||||
|
||||
if (isLayout)
|
||||
{
|
||||
if (this.colorBak === undefined)
|
||||
this.colorBak = app.Viewer.Renderer.getClearColor().getHex();
|
||||
app.Viewer.Renderer.setClearColor(0xcccccc, 1);
|
||||
this.CacheCamera();
|
||||
app.Editor.SetUCSLookAt(new Vector3(0, 0, -1));
|
||||
app.Viewer.ViewToTop();
|
||||
app.Viewer.ZoomAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.Viewer.Renderer.setClearColor(this.colorBak);
|
||||
app.Viewer.CameraCtrl.ReadFile(TempCADFiler);
|
||||
app.Viewer.UpdateRender();
|
||||
AppToaster.clear();
|
||||
}
|
||||
}
|
||||
get CurrentSpace()
|
||||
{
|
||||
if (app.Viewer.isLayout)
|
||||
{
|
||||
return app.Database.LayoutSpace;
|
||||
}
|
||||
else
|
||||
{
|
||||
return app.Database.ModelSpace;
|
||||
}
|
||||
}
|
||||
AppendDatabaseSpace(en: Entity, changeColor = true)
|
||||
{
|
||||
if (app.Viewer.isLayout)
|
||||
{
|
||||
app.Database.LayoutSpace.Append(en);
|
||||
if (changeColor && en.ColorIndex === 7)
|
||||
en.ColorIndex = 256;
|
||||
}
|
||||
else
|
||||
{
|
||||
app.Database.ModelSpace.Append(en);
|
||||
}
|
||||
}
|
||||
RemoveDatabaseSpace(en: Entity)
|
||||
{
|
||||
if (app.Viewer.isLayout)
|
||||
{
|
||||
app.Database.LayoutSpace.Remove(en);
|
||||
}
|
||||
else
|
||||
{
|
||||
app.Database.ModelSpace.Remove(en);
|
||||
}
|
||||
}
|
||||
ShowViewportEntitys(ens?: Entity[])
|
||||
{
|
||||
let v = app.Viewer.CurrentViewport;
|
||||
|
||||
let vps = v ? [v] : app.Viewer.ViewPorts;
|
||||
|
||||
for (let vp of vps)
|
||||
{
|
||||
if (ens)
|
||||
{
|
||||
for (let en of ens)
|
||||
{
|
||||
if (en instanceof Hole) continue;
|
||||
vp.hideObjectIds.delete(en.Id);
|
||||
vp.AppendEntity(en);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (let id of vp.hideObjectIds)
|
||||
{
|
||||
let en = id.Object as Entity;
|
||||
vp.hideObjectIds.delete(id);
|
||||
vp.AppendEntity(en);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
HideViewportEntitys(selects: Entity[])
|
||||
{
|
||||
let vp = app.Viewer.CurrentViewport;
|
||||
|
||||
let vps = vp ? [vp] : app.Viewer.ViewPorts;
|
||||
|
||||
for (let en of selects)
|
||||
{
|
||||
if (en instanceof ViewportEntity) continue;
|
||||
|
||||
for (let vp of vps)
|
||||
{
|
||||
let e = en.Id ? en : en.TempData?.Entity;
|
||||
if (!vp.hideObjectIds.has(e.Id))
|
||||
{
|
||||
vp.hideObjectIds.add(e.Id);
|
||||
vp.RemoveEntity(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ChangeViewportEntitys(ens: Entity[])
|
||||
{
|
||||
for (let vp of app.Viewer.ViewPorts)
|
||||
{
|
||||
for (let en of ens)
|
||||
{
|
||||
if (en instanceof Hole) continue;
|
||||
arrayRemoveIf(vp.scene.children, o => o.name === en.Id.Index.toString());
|
||||
vp.AppendEntity(en);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
|
||||
uniform vec3 SurfaceColor;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_FragColor = vec4 (SurfaceColor, 1.0);
|
||||
}
|
@ -1,26 +1,26 @@
|
||||
import { RenderType } from "../../../GraphicsSystem/RenderType";
|
||||
import { CommandNames } from "../../../Common/CommandNames";
|
||||
|
||||
interface IVisualStyle
|
||||
{
|
||||
title: string;
|
||||
type: RenderType;
|
||||
cmd: CommandNames;
|
||||
}
|
||||
|
||||
export const VisualStyleData: IVisualStyle[] = [
|
||||
{
|
||||
title: "二维线框",
|
||||
type: RenderType.Wireframe
|
||||
cmd: CommandNames.Wireframe
|
||||
},
|
||||
{
|
||||
title: "概念",
|
||||
type: RenderType.Conceptual
|
||||
cmd: CommandNames.Conceptual
|
||||
},
|
||||
{
|
||||
title: "真实",
|
||||
type: RenderType.Physical
|
||||
cmd: CommandNames.Physical
|
||||
},
|
||||
{
|
||||
title: "真实带线框",
|
||||
type: RenderType.Physical2
|
||||
cmd: CommandNames.Physical2
|
||||
},
|
||||
];
|
||||
|
@ -0,0 +1,285 @@
|
||||
import * as React from 'react';
|
||||
import { CommonModal } from './ModalContainer';
|
||||
import { app } from '../../../ApplicationServices/Application';
|
||||
import { CommonPanel, IDirectoryProps } from '../SourceManage/CommonPanel';
|
||||
import { DirectoryId, PostJson, RequestStatus } from '../../../Common/Request';
|
||||
import { ToplineUrls } from '../../../Common/HostUrl';
|
||||
import { observable } from 'mobx';
|
||||
import { HandleDirComponent } from '../SourceManage/HandleDirComponent';
|
||||
import { AppToaster } from '../Toaster';
|
||||
import { Intent, Button, MenuItem } from '@blueprintjs/core';
|
||||
import { FrameList } from './OptionModal/FrameList';
|
||||
import { Entity } from '../../../DatabaseServices/Entity/Entity';
|
||||
import { Curve } from '../../../DatabaseServices/Entity/Curve';
|
||||
import { Text } from '../../../DatabaseServices/Text/Text';
|
||||
import { PromptStatus } from '../../../Editor/PromptResult';
|
||||
import { GroupRecord } from '../../../DatabaseServices/GroupTableRecord';
|
||||
import { GetEntitysLogo, deflate, inflate, GroupFileIn, GroupOut } from '../../../Common/SerializeMaterial';
|
||||
import { observer } from 'mobx-react';
|
||||
import { Vector3, Box3, Matrix4 } from 'three';
|
||||
import { CommandWrap } from '../../../Editor/CommandMachine';
|
||||
import { JigUtils } from '../../../Editor/JigUtils';
|
||||
|
||||
export interface IFrameManageProps
|
||||
{
|
||||
}
|
||||
|
||||
@observer
|
||||
export class FrameManage extends React.Component<IFrameManageProps> {
|
||||
private canCreateFrame = observable.box(false);
|
||||
@observable private currentInfo = { id: "", name: "" };
|
||||
constructor(props)
|
||||
{
|
||||
super(props);
|
||||
this.state = {
|
||||
defaultDirName: ""
|
||||
};
|
||||
}
|
||||
renderNav = () =>
|
||||
{
|
||||
return (
|
||||
<Button
|
||||
icon="cloud-upload"
|
||||
style={{
|
||||
marginRight: 10
|
||||
}}
|
||||
text="上传图框"
|
||||
intent={Intent.SUCCESS}
|
||||
onClick={this.startCreateFrame}
|
||||
/>
|
||||
);
|
||||
};
|
||||
renderMenuItems = () =>
|
||||
{
|
||||
return (
|
||||
<MenuItem icon="cloud-upload" text="上传图框"
|
||||
onClick={this.startCreateFrame}
|
||||
/>
|
||||
);
|
||||
};
|
||||
public render()
|
||||
{
|
||||
return (
|
||||
<CommonModal
|
||||
title="图框管理"
|
||||
close={() => app.Editor.ModalManage.Destory()}
|
||||
hasConfig={false}
|
||||
className="frame-manage"
|
||||
footerStyle={{ width: "100%" }}
|
||||
bodyStyle={{ height: 675 }}
|
||||
footerChildren={
|
||||
<>
|
||||
<Button
|
||||
text="插入"
|
||||
onClick={e => this.draw()}
|
||||
intent={Intent.SUCCESS}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<CommonPanel
|
||||
defaultDirId={DirectoryId.Frame}
|
||||
getUrl={ToplineUrls.get}
|
||||
deleteUrl={ToplineUrls.delete}
|
||||
renderNav={this.renderNav}
|
||||
renderMenuItems={this.renderMenuItems}
|
||||
clickTree={() =>
|
||||
{
|
||||
this.currentInfo.id = "";
|
||||
}}
|
||||
>
|
||||
<FrameList
|
||||
draw={this.draw}
|
||||
isRename={this.canCreateFrame}
|
||||
updata={this.handleCreateFrame}
|
||||
info={this.currentInfo}
|
||||
/>
|
||||
{
|
||||
this.canCreateFrame.get() && <HandleDirComponent
|
||||
defualtValue={this.currentInfo.name}
|
||||
isReset={false}
|
||||
isOpen={this.canCreateFrame}
|
||||
handleFunc={this.handleFrame}
|
||||
title="输入图框名称"
|
||||
/>
|
||||
}
|
||||
</CommonPanel>
|
||||
</CommonModal>
|
||||
);
|
||||
}
|
||||
private startCreateFrame = () =>
|
||||
{
|
||||
this.currentInfo.id = "";
|
||||
this.currentInfo.name = "";
|
||||
this.canCreateFrame.set(true);
|
||||
};
|
||||
handleFrame = async (name: string, currentDir, callback: Function) =>
|
||||
{
|
||||
if (!name.trim())
|
||||
{
|
||||
AppToaster.show({
|
||||
message: "名称不能为空",
|
||||
intent: Intent.DANGER,
|
||||
timeout: 1000
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (this.currentInfo.id)
|
||||
{
|
||||
await this.handleRenameTopline(name);
|
||||
await callback();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!currentDir)
|
||||
{
|
||||
AppToaster.show({
|
||||
message: "未知错误,请重试",
|
||||
timeout: 1000
|
||||
});
|
||||
return;
|
||||
}
|
||||
await this.handleCreateFrame(name, currentDir, callback);
|
||||
}
|
||||
};
|
||||
private handleCreateFrame = async (name: string, currentDir: IDirectoryProps, callback: Function) =>
|
||||
{
|
||||
app.Editor.ModalManage.ToggleShow();
|
||||
app.Editor.MaskManage.Clear();
|
||||
|
||||
const reset = () =>
|
||||
{
|
||||
app.Editor.ModalManage.ToggleShow();
|
||||
app.Editor.MaskManage.ShowMask();
|
||||
this.canCreateFrame.set(false);
|
||||
};
|
||||
|
||||
let plRes = await app.Editor.GetSelection({
|
||||
Once: true,
|
||||
AllowNone: false,
|
||||
Msg: "选择图框",
|
||||
Filter: {
|
||||
filterFunction(o, e: Entity)
|
||||
{
|
||||
return (e instanceof Curve || e instanceof Text) && !!e.GroupId;
|
||||
}
|
||||
},
|
||||
});
|
||||
if (plRes.Status !== PromptStatus.OK)
|
||||
{
|
||||
reset();
|
||||
return;
|
||||
};
|
||||
|
||||
let g = plRes.SelectSet.SelectEntityList[0].GroupId.Object as GroupRecord;
|
||||
|
||||
let ens: Entity[] = [];
|
||||
for (let id of g.Entitys)
|
||||
{
|
||||
if (id?.Object && !id.IsErase)
|
||||
{
|
||||
ens.push(id.Object.Clone() as Entity);
|
||||
}
|
||||
}
|
||||
let fileJson = GroupOut(ens);
|
||||
|
||||
let logo = await GetEntitysLogo(ens, false, new Vector3(0, 0, -1));
|
||||
|
||||
let data: { err_code: RequestStatus; };
|
||||
|
||||
if (this.currentInfo.id)
|
||||
{
|
||||
data = await PostJson(ToplineUrls.update, {
|
||||
topline_id: this.currentInfo.id,
|
||||
logo,
|
||||
file: deflate(fileJson),
|
||||
zip_type: "gzip",
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
data = await PostJson(ToplineUrls.create, {
|
||||
dir_id: currentDir.id,
|
||||
name,
|
||||
logo,
|
||||
file: deflate(fileJson),
|
||||
zip_type: "gzip",
|
||||
});
|
||||
}
|
||||
|
||||
if (data.err_code === RequestStatus.Ok)
|
||||
{
|
||||
await callback();
|
||||
}
|
||||
|
||||
reset();
|
||||
};
|
||||
|
||||
handleRenameTopline = async (name: string) =>
|
||||
{
|
||||
let data = await PostJson(ToplineUrls.update, {
|
||||
topline_id: this.currentInfo.id,
|
||||
name
|
||||
});
|
||||
if (data.code === RequestStatus.Ok)
|
||||
{
|
||||
AppToaster.show({
|
||||
message: "重命名成功",
|
||||
timeout: 1000
|
||||
});
|
||||
}
|
||||
this.canCreateFrame.set(false);
|
||||
};
|
||||
private draw = async (topline_id?: string) =>
|
||||
{
|
||||
app.Editor.ModalManage.Destory();
|
||||
if (!topline_id)
|
||||
topline_id = this.currentInfo.id;
|
||||
|
||||
if (!topline_id) return;
|
||||
|
||||
let data = await PostJson(ToplineUrls.detail, { topline_id });
|
||||
|
||||
if (data.err_code === RequestStatus.Ok)
|
||||
{
|
||||
let file = inflate(data.toplines.file);
|
||||
|
||||
await CommandWrap(async () =>
|
||||
{
|
||||
let ens = GroupFileIn(JSON.parse(file));
|
||||
let box = new Box3();
|
||||
let nens = ens.map(e => JigUtils.Draw(e));
|
||||
ens.reduce((b, e) =>
|
||||
{
|
||||
return b.union(e.BoundingBox);
|
||||
}, box);
|
||||
|
||||
let pos = box.min.clone();
|
||||
let mtx = new Matrix4();
|
||||
let ptRes = await app.Editor.GetPoint({
|
||||
Msg: "选择图框的位置",
|
||||
Callback: (p: Vector3) =>
|
||||
{
|
||||
mtx.setPosition(p.clone().sub(pos));
|
||||
for (let e of nens)
|
||||
e.ApplyMatrix(mtx);
|
||||
pos.copy(p);
|
||||
}
|
||||
});
|
||||
|
||||
if (ptRes.Status === PromptStatus.OK)
|
||||
{
|
||||
mtx.setPosition(ptRes.Point.sub(pos));
|
||||
let g = new GroupRecord();
|
||||
app.Database.GroupTable.Append(g);
|
||||
for (let e of ens)
|
||||
{
|
||||
app.LayoutTool.AppendDatabaseSpace(e);
|
||||
g.Entitys.push(e.Id);
|
||||
e.ApplyMatrix(mtx);
|
||||
}
|
||||
}
|
||||
}, "插入图框");
|
||||
}
|
||||
};
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
#commonModal .frame-manage {
|
||||
max-width: 900px;
|
||||
width: 60vw;
|
||||
height: 80vh;
|
||||
min-height: 750px;
|
||||
}
|
@ -0,0 +1,207 @@
|
||||
import { Button, ContextMenu, Intent, Menu, MenuItem } from '@blueprintjs/core';
|
||||
import { IObservableValue } from 'mobx';
|
||||
import { observer } from 'mobx-react';
|
||||
import * as React from 'react';
|
||||
import { app } from '../../../../ApplicationServices/Application';
|
||||
import { ToplineUrls } from '../../../../Common/HostUrl';
|
||||
import { PostJson, RequestStatus } from '../../../../Common/Request';
|
||||
import { deflate, GetEntitysLogo, GroupFileIn, GroupOut, inflate } from '../../../../Common/SerializeMaterial';
|
||||
import { CADFiler } from '../../../../DatabaseServices/CADFiler';
|
||||
import { Curve } from '../../../../DatabaseServices/Entity/Curve';
|
||||
import { Entity } from '../../../../DatabaseServices/Entity/Entity';
|
||||
import { Text } from '../../../../DatabaseServices/Text/Text';
|
||||
import { CommandWrap } from '../../../../Editor/CommandMachine';
|
||||
import { TempEditor } from '../../../../Editor/TempEditor';
|
||||
import { DataList } from '../../Common/Datalist';
|
||||
import { ModalPosition } from '../../Modal/ModalInterface';
|
||||
import { IDirectoryProps } from '../../SourceManage/CommonPanel';
|
||||
import { AppToaster } from '../../Toaster';
|
||||
import { FrameManage } from '../FrameManager';
|
||||
import { Vector3 } from 'three';
|
||||
|
||||
export interface IToplineListProps
|
||||
{
|
||||
deleteFun?: (topline?: { topline_id; }) => void;
|
||||
dataList?: any[];
|
||||
select?: (e: React.FormEvent<HTMLInputElement>, data: any) => void;
|
||||
draw: (id: string) => void;
|
||||
isRename: IObservableValue<boolean>;
|
||||
updata: (name: string, dir: IDirectoryProps, call: Function) => void;
|
||||
getData?: () => void;
|
||||
info: { id: string, name: string; };
|
||||
selectIds?: Set<string>;
|
||||
showInfos?: boolean;
|
||||
}
|
||||
|
||||
@observer
|
||||
export class FrameList extends React.Component<IToplineListProps, { isContextMenuOpen: boolean; }> {
|
||||
private _cameraFiler: CADFiler;
|
||||
constructor(props)
|
||||
{
|
||||
super(props);
|
||||
this.state = {
|
||||
isContextMenuOpen: false
|
||||
};
|
||||
}
|
||||
private handleDbClick = async (tpdata: { topline_id: string; }) =>
|
||||
{
|
||||
this.props.draw(tpdata.topline_id);
|
||||
};
|
||||
private handleMounseDown = (e: React.MouseEvent<HTMLElement>, tpline: any) =>
|
||||
{
|
||||
this.props.info.id = tpline.topline_id;
|
||||
this.props.info.name = tpline.name;
|
||||
};
|
||||
private exitEditor = async () =>
|
||||
{
|
||||
app.Editor.ModalManage.DestoryAll();
|
||||
await app.Editor.ModalManage.EndExecingCmd();
|
||||
if (!this._cameraFiler) return;
|
||||
app.Viewer.CameraCtrl.ReadFile(this._cameraFiler);
|
||||
TempEditor.End();
|
||||
this._cameraFiler = undefined;
|
||||
app.Editor.SelectCtrl.Cancel();
|
||||
app.Editor.ModalManage.RenderModal(FrameManage, {}, { position: ModalPosition.Old });
|
||||
};
|
||||
private renderToasterMessage = () =>
|
||||
{
|
||||
return (
|
||||
<div className="flex-between toaster-message">
|
||||
<span>正在编辑图框...</span>
|
||||
<div>
|
||||
<Button text="保存" minimal onClick={this.handleUpdateFrame} />
|
||||
<Button text="取消" minimal onClick={() =>
|
||||
{
|
||||
AppToaster.clear();
|
||||
}} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
private startEditorFrame = async (tpline) =>
|
||||
{
|
||||
TempEditor.Start();
|
||||
app.Editor.ModalManage.DestoryAll();
|
||||
|
||||
let data = await PostJson(ToplineUrls.detail, { topline_id: tpline.topline_id });
|
||||
|
||||
if (data.err_code === RequestStatus.Ok)
|
||||
{
|
||||
let file = inflate(data.toplines.file);
|
||||
let ens = GroupFileIn(JSON.parse(file));
|
||||
await CommandWrap(() =>
|
||||
{
|
||||
ens.forEach(e => app.LayoutTool.AppendDatabaseSpace(e));
|
||||
app.Database.hm.lockIndex++;//禁止初始化动作被撤销
|
||||
this._cameraFiler = new CADFiler;
|
||||
app.Viewer.CameraCtrl.WriteFile(this._cameraFiler);
|
||||
app.Viewer.CameraCtrl.LookAt(new Vector3(0, 0, -1));
|
||||
app.Viewer.ZoomAll();
|
||||
AppToaster.show({
|
||||
message: this.renderToasterMessage(),
|
||||
intent: Intent.PRIMARY,
|
||||
timeout: 0,
|
||||
onDismiss: this.exitEditor
|
||||
});
|
||||
}, "编辑图框");
|
||||
}
|
||||
};
|
||||
private handleUpdateFrame = async () =>
|
||||
{
|
||||
await app.Editor.ModalManage.EndExecingCmd();
|
||||
|
||||
let ens = app.Viewer.VisibleEntitys.filter(en => en instanceof Curve || en instanceof Text) as Entity[];
|
||||
if (ens.length > 0)
|
||||
{
|
||||
let topline_id = this.props.info.id;
|
||||
let logo = await GetEntitysLogo(ens, false, new Vector3(0, 0, -1));
|
||||
let fileJson = GroupOut(ens);
|
||||
|
||||
let data = await PostJson(ToplineUrls.update, {
|
||||
topline_id,
|
||||
logo,
|
||||
file: deflate(fileJson),
|
||||
zip_type: "gzip",
|
||||
});
|
||||
AppToaster.clear();
|
||||
if (data.err_code === RequestStatus.Ok)
|
||||
{
|
||||
this.props.getData();
|
||||
AppToaster.show({
|
||||
message: "图框保存成功",
|
||||
timeout: 1000,
|
||||
intent: Intent.SUCCESS,
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AppToaster.clear();
|
||||
AppToaster.show({
|
||||
message: "图框错误,保存失败",
|
||||
timeout: 1000,
|
||||
intent: Intent.DANGER,
|
||||
});
|
||||
}
|
||||
};
|
||||
//展示右键菜单
|
||||
private showContextMenu = (e: React.MouseEvent<HTMLElement>, tpline) =>
|
||||
{
|
||||
ContextMenu.show(
|
||||
<Menu>
|
||||
<MenuItem
|
||||
icon="folder-new"
|
||||
text="重命名"
|
||||
onClick={() => this.props.isRename.set(true)}
|
||||
/>
|
||||
<MenuItem
|
||||
icon="folder-new"
|
||||
text="编辑"
|
||||
onClick={() => this.startEditorFrame(tpline)}
|
||||
/>
|
||||
<MenuItem
|
||||
icon="trash"
|
||||
text="删除"
|
||||
intent={Intent.DANGER}
|
||||
onClick={() =>
|
||||
{
|
||||
this.props.deleteFun();
|
||||
}}
|
||||
/>
|
||||
</Menu>,
|
||||
{ left: e.clientX, top: e.clientY },
|
||||
() => this.setState({ isContextMenuOpen: false }),
|
||||
);
|
||||
this.setState({ isContextMenuOpen: true });
|
||||
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
};
|
||||
public render()
|
||||
{
|
||||
return (
|
||||
<DataList
|
||||
dataList={this.props.dataList}
|
||||
idKey="topline_id"
|
||||
select={this.props.select}
|
||||
showContextMenu={this.showContextMenu}
|
||||
showInfos={this.props.showInfos}
|
||||
dbclickImg={this.handleDbClick}
|
||||
selectData={this.props.selectIds}
|
||||
handleMounseDown={this.handleMounseDown}
|
||||
renderButtons={(data) => <>
|
||||
{
|
||||
this.props.showInfos &&
|
||||
<>
|
||||
<Button
|
||||
intent={Intent.PRIMARY}
|
||||
text="编辑"
|
||||
onClick={() => this.startEditorFrame(data)}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
</>}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in new issue