mirror of https://gitee.com/cf-fz/WebCAD.git
!728 实现可视化空间布局
parent
613c40d091
commit
efa7d71f94
@ -0,0 +1,139 @@
|
||||
import { Matrix4 } from "three";
|
||||
import { app } from "../../ApplicationServices/Application";
|
||||
import { Log } from "../../Common/Log";
|
||||
import { TemplateVisualSpace } from "../../DatabaseServices/Template/ProgramTempate/TemplateVisualSpace";
|
||||
import { TemplateRecord } from "../../DatabaseServices/Template/TemplateRecord";
|
||||
import { SelectTempate } from "../../DatabaseServices/Template/TemplateTest";
|
||||
import { PromptStatus } from "../../Editor/PromptResult";
|
||||
import { CoordinateSystem } from "../../Geometry/CoordinateSystem";
|
||||
import { getEulerAngle, isPerpendicularityTo } from "../../Geometry/GeUtils";
|
||||
import { HotCMD } from "../../Hot/HotCommand";
|
||||
import { AppToaster } from "../../UI/Components/Toaster";
|
||||
|
||||
@HotCMD
|
||||
export class Command_RotateTemplateSpace
|
||||
{
|
||||
async exec()
|
||||
{
|
||||
let t = await SelectTempate();
|
||||
if (!t) return;
|
||||
|
||||
if (t.Parent?.Object?.IsErase !== false)
|
||||
{
|
||||
Log("顶层模块使用Rotate命令直接旋转!");
|
||||
return;
|
||||
}
|
||||
|
||||
let cs = await GetSpaceCSFrom3Point();
|
||||
if (!cs) return;
|
||||
|
||||
let isNoPos = t.PXParam.value === 0 && t.PYParam.value === 0 && t.PZParam.value === 0;
|
||||
let parent = t.Parent.Object as TemplateRecord;
|
||||
if (parent.Children.length === 1 && isNoPos)
|
||||
{
|
||||
let tcs = parent.GetTemplateSpaceCS(true);
|
||||
let tcsInv = new Matrix4().getInverse(tcs);
|
||||
|
||||
cs.multiply(tcsInv);
|
||||
|
||||
let cds = new CoordinateSystem().CopyForm(cs);
|
||||
let ro = getEulerAngle(cds.XAxis, cds.YAxis, cds.ZAxis);
|
||||
t.RXParam.expr = ro.roX;
|
||||
t.RYParam.expr = ro.roY;
|
||||
t.RZParam.expr = ro.roZ;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
let tcs = t.GetTemplateSpaceCS(true);
|
||||
let tcsInv = new Matrix4().getInverse(tcs);
|
||||
|
||||
cs.multiply(tcsInv);
|
||||
|
||||
let cds = new CoordinateSystem().CopyForm(cs);
|
||||
let ro = getEulerAngle(cds.XAxis, cds.YAxis, cds.ZAxis);
|
||||
|
||||
//判断子层空间是否被旋转过,如果是,那么直接修改子层空间
|
||||
if (t.Children.length === 1)
|
||||
{
|
||||
let ct = t.Children[0].Object as TemplateRecord;
|
||||
if (ct instanceof TemplateVisualSpace)
|
||||
{
|
||||
ct.LParam.expr = "_L";
|
||||
ct.WParam.expr = "_W";
|
||||
ct.HParam.expr = "_H";
|
||||
|
||||
ct.RXParam.expr = ro.roX;
|
||||
ct.RYParam.expr = ro.roY;
|
||||
ct.RZParam.expr = ro.roZ;
|
||||
await t.UpdateTemplateTree();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let nt = new TemplateVisualSpace().InitBaseParams();
|
||||
nt.Name = "旋转空间";
|
||||
nt.LParam.expr = "_L";
|
||||
nt.WParam.expr = "_W";
|
||||
nt.HParam.expr = "_H";
|
||||
|
||||
nt.RXParam.expr = ro.roX;
|
||||
nt.RYParam.expr = ro.roY;
|
||||
nt.RZParam.expr = ro.roZ;
|
||||
|
||||
//如果有子层空间,那么移植到下一层
|
||||
nt.Children.push(...t.Children);
|
||||
t.Children.length = 0;
|
||||
|
||||
app.Database.TemplateTable.Append(nt);
|
||||
t.Children.push(nt.Id);
|
||||
|
||||
await t.UpdateTemplateTree();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//拾取一个基点2个轴方向确定空间姿态
|
||||
async function GetSpaceCSFrom3Point(): Promise<Matrix4 | undefined>
|
||||
{
|
||||
let ptRes = await app.Editor.GetPoint({
|
||||
Msg: "选择基点"
|
||||
});
|
||||
if (ptRes.Status !== PromptStatus.OK)
|
||||
return;
|
||||
|
||||
let basePt = ptRes.Point;
|
||||
|
||||
let xRes = await app.Editor.GetPoint({
|
||||
Msg: "选择长度方向终点(x轴):",
|
||||
BasePoint: basePt,
|
||||
AllowDrawRubberBand: true,
|
||||
});
|
||||
|
||||
if (ptRes.Status !== PromptStatus.OK)
|
||||
return;
|
||||
let xVec = xRes.Point.sub(basePt).normalize();
|
||||
|
||||
let zRes = await app.Editor.GetPoint({
|
||||
Msg: "选择高度方向终点(Z轴):",
|
||||
BasePoint: basePt,
|
||||
AllowDrawRubberBand: true,
|
||||
});
|
||||
|
||||
if (ptRes.Status !== PromptStatus.OK)
|
||||
return;
|
||||
|
||||
let zVec = zRes.Point.sub(basePt).normalize();
|
||||
let yVec = zVec.clone().cross(xVec);
|
||||
|
||||
if (!isPerpendicularityTo(xVec, zVec))
|
||||
{
|
||||
AppToaster.show({
|
||||
message: "x轴和z轴必须垂直!",
|
||||
timeout: 2000
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
return new Matrix4().makeBasis(xVec, yVec, zVec);
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
import { app } from "../../ApplicationServices/Application";
|
||||
import { TemplateVisualSpace } from "../../DatabaseServices/Template/ProgramTempate/TemplateVisualSpace";
|
||||
import { SelectTempate } from "../../DatabaseServices/Template/TemplateTest";
|
||||
import { Command } from "../../Editor/CommandMachine";
|
||||
import { PromptStatus } from "../../Editor/PromptResult";
|
||||
import { HotCMD } from "../../Hot/HotCommand";
|
||||
|
||||
@HotCMD
|
||||
export class Command_SplitTemplate implements Command
|
||||
{
|
||||
async exec()
|
||||
{
|
||||
let t = await SelectTempate();
|
||||
|
||||
if (t === undefined) return;
|
||||
|
||||
if (t.Children.length === 0)
|
||||
{
|
||||
let typeRes = await app.Editor.GetKeyWords({
|
||||
KeyWordList: [
|
||||
{ msg: "X", key: "1" },
|
||||
{ msg: "Y", key: "2" },
|
||||
{ msg: "Z", key: "3" },
|
||||
]
|
||||
});
|
||||
if (typeRes.Status !== PromptStatus.Keyword) return;
|
||||
|
||||
let countRes = await app.Editor.GetDistance({ Msg: "个数" });
|
||||
if (countRes.Status !== PromptStatus.OK || countRes.Distance < 1) return;
|
||||
|
||||
t.SplitType = parseInt(typeRes.StringResult) - 1;
|
||||
|
||||
for (let i = 0; i < countRes.Distance; i++)
|
||||
{
|
||||
let tc = new TemplateVisualSpace().InitBaseParams();
|
||||
tc.LParam.expr = "_L";
|
||||
tc.WParam.expr = "_W";
|
||||
tc.HParam.expr = "_H";
|
||||
|
||||
tc.Params[t.SplitType].expr = "_DIV";
|
||||
tc.Params[3 + t.SplitType].expr = "_POS";
|
||||
|
||||
app.Database.TemplateTable.Append(tc);
|
||||
t.Children.push(tc.Id);
|
||||
}
|
||||
|
||||
await t.UpdateTemplateTree();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,32 +1,51 @@
|
||||
import { HotCMD } from "../../Hot/HotCommand";
|
||||
import { Command } from "../../Editor/CommandMachine";
|
||||
import { app } from "../../ApplicationServices/Application";
|
||||
import { PromptStatus } from "../../Editor/PromptResult";
|
||||
import { Board } from "../../DatabaseServices/Entity/Board";
|
||||
import { Production } from "../../Production/Product";
|
||||
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
|
||||
import { Matrix4 } from "three";
|
||||
import { ParagraphSealinglist } from "../../GraphicsSystem/CalcEdgeSealing";
|
||||
import { Curve } from "../../DatabaseServices/Entity/Curve";
|
||||
import { IHighSealedItem } from "../../UI/Store/BoardInterface";
|
||||
import { TemplateVisualSpace } from "../../DatabaseServices/Template/ProgramTempate/TemplateVisualSpace";
|
||||
import { Command } from "../../Editor/CommandMachine";
|
||||
import { HotCMD } from "../../Hot/HotCommand";
|
||||
import { TemplateSplitType } from "../../DatabaseServices/Template/TemplateType";
|
||||
|
||||
@HotCMD
|
||||
export class Test implements Command
|
||||
{
|
||||
async exec()
|
||||
{
|
||||
let enRes = await app.Editor.GetSelection({});
|
||||
|
||||
if (enRes.Status === PromptStatus.OK)
|
||||
{
|
||||
let en = enRes.SelectSet.SelectEntityList;
|
||||
// let ent = new VisualSpaceBox(1000, 1000, 1000);
|
||||
// TestDraw(ent);
|
||||
|
||||
let template = new TemplateVisualSpace();
|
||||
template.InitBaseParams();
|
||||
template.LParam.expr = 2000;
|
||||
template.HParam.expr = 1800;
|
||||
template.WParam.expr = 600;
|
||||
|
||||
app.Database.TemplateTable.Append(template);
|
||||
|
||||
for (let e of en)
|
||||
if (true)
|
||||
{
|
||||
// if (e.IsClockWise) e.ColorIndex = 1;
|
||||
if (e instanceof Board)
|
||||
console.log(Production.GetBoardSplitOrderData(e));
|
||||
await template.UpdateTemplateTree();
|
||||
return;
|
||||
};
|
||||
let t = template;
|
||||
if (t.Children.length === 0)
|
||||
{
|
||||
t.SplitType = TemplateSplitType.X;
|
||||
for (let i = 0; i < 3; i++)
|
||||
{
|
||||
let tc = new TemplateVisualSpace().InitBaseParams();
|
||||
tc.LParam.expr = "_DIV";
|
||||
tc.WParam.expr = "_W";
|
||||
tc.HParam.expr = "_H";
|
||||
|
||||
tc.PXParam.expr = "_POS";
|
||||
|
||||
app.Database.TemplateTable.Append(tc);
|
||||
t.Children.push(tc.Id);
|
||||
}
|
||||
|
||||
await t.UpdateTemplateTree();
|
||||
}
|
||||
|
||||
await template.UpdateTemplateTree();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,70 @@
|
||||
import { CADFiler } from "../../CADFiler";
|
||||
import { TemplateRecord } from "../TemplateRecord";
|
||||
import { AutoRecord } from "../../AutoRecord";
|
||||
import { VisualSpaceBox } from "../../../Editor/VisualSpaceBox";
|
||||
import { app } from "../../../ApplicationServices/Application";
|
||||
import { Factory } from "../../CADFactory";
|
||||
|
||||
@Factory
|
||||
export class TemplateVisualSpace extends TemplateRecord
|
||||
{
|
||||
@AutoRecord IsVisible = true;
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
this.Name = "可视化模块空间";
|
||||
}
|
||||
|
||||
protected async Update()
|
||||
{
|
||||
await super.Update();
|
||||
if (this.Objects.length === 0 || this.Objects[0].Object === undefined)
|
||||
{
|
||||
this.Objects.length = 0;
|
||||
let visualEntity = new VisualSpaceBox(this.LParam.value as number, this.WParam.value as number, this.HParam.value as number);
|
||||
visualEntity.ApplyMatrix(this._CacheSpaceCS);
|
||||
visualEntity.SpaceOCS = this._CacheSpaceCS;
|
||||
app.Database.ModelSpace.Append(visualEntity);
|
||||
this.Objects.push(visualEntity.Id);
|
||||
}
|
||||
let visualEntity = this.Objects[0].Object as VisualSpaceBox;
|
||||
|
||||
let IsRoot = this.Parent === undefined;
|
||||
let isVisual = IsRoot || this.Children.length === 0;
|
||||
|
||||
visualEntity.Visible = this.IsVisible && isVisual;
|
||||
visualEntity.SetSize(this.LParam.value as number, this.WParam.value as number, this.HParam.value as number);
|
||||
visualEntity.IsRoot = this.Children.length !== 0;
|
||||
|
||||
if (!IsRoot)
|
||||
{
|
||||
let root = this.Root;
|
||||
visualEntity.DisplayLength = this.LParam.value !== root.LParam.value;
|
||||
visualEntity.DisplayWidth = this.WParam.value !== root.WParam.value;
|
||||
visualEntity.DisplayHeight = this.HParam.value !== root.HParam.value;
|
||||
}
|
||||
}
|
||||
|
||||
//#region -------------------------File-------------------------
|
||||
|
||||
//对象从文件中读取数据,初始化自身
|
||||
ReadFile(file: CADFiler)
|
||||
{
|
||||
let ver = file.Read();
|
||||
super.ReadFile(file);
|
||||
this.IsVisible = file.Read();
|
||||
}
|
||||
//对象将自身数据写入到文件.
|
||||
WriteFile(file: CADFiler)
|
||||
{
|
||||
file.Write(1);
|
||||
super.WriteFile(file);
|
||||
file.Write(this.IsVisible);
|
||||
}
|
||||
// //局部撤销
|
||||
// ApplyPartialUndo(undoData: CADObject)
|
||||
// {
|
||||
// super.ApplyPartialUndo(undoData);
|
||||
// }
|
||||
//#endregion
|
||||
}
|
@ -0,0 +1,390 @@
|
||||
import { BufferGeometry, Float32BufferAttribute, LineSegments, Matrix3, Matrix4, Mesh, Object3D, Vector3, Box3 } from "three";
|
||||
import { ColorMaterial } from "../Common/ColorPalette";
|
||||
import { FixedNotZero } from "../Common/Utils";
|
||||
import { AutoRecord } from "../DatabaseServices/AutoRecord";
|
||||
import { Factory } from "../DatabaseServices/CADFactory";
|
||||
import { CADFiler } from "../DatabaseServices/CADFiler";
|
||||
import { Entity } from "../DatabaseServices/Entity/Entity";
|
||||
import { TemplateRecord } from "../DatabaseServices/Template/TemplateRecord";
|
||||
import { Text, TextAligen } from "../DatabaseServices/Text/Text";
|
||||
import { GenerateBoxEdgeGeometry } from "../Geometry/ExtrudeEdgeGeometry";
|
||||
import { XAxis, XAxisN, YAxis, YAxisN, ZAxis, ZeroVec } from "../Geometry/GeUtils";
|
||||
import { RenderType } from "../GraphicsSystem/RenderType";
|
||||
import { ObjectSnapMode } from "./ObjectSnapMode";
|
||||
import { Box3Ext } from "../Geometry/Box";
|
||||
|
||||
const EmptyArray = [];
|
||||
|
||||
@Factory
|
||||
export class VisualSpaceBox extends Entity
|
||||
{
|
||||
OnlyRenderType = true;
|
||||
|
||||
private _LText = new Text;
|
||||
private _WText = new Text;
|
||||
private _HText = new Text;
|
||||
|
||||
@AutoRecord private _IsRoot = false;
|
||||
|
||||
@AutoRecord private _DisplayLength = true;
|
||||
@AutoRecord private _DisplayWidth = true;
|
||||
@AutoRecord private _DisplayHeight = true;
|
||||
|
||||
|
||||
constructor(
|
||||
protected _Length: number = 1,
|
||||
protected _Width: number = 1,
|
||||
protected _Height: number = 1,
|
||||
)
|
||||
{
|
||||
super();
|
||||
this._LText.IsEmbedEntity = true;
|
||||
this._WText.IsEmbedEntity = true;
|
||||
this._HText.IsEmbedEntity = true;
|
||||
|
||||
this._LText.TextAligen = TextAligen.Down;
|
||||
this._WText.TextAligen = TextAligen.Top;
|
||||
this._HText.TextAligen = TextAligen.Top;
|
||||
(<VisualSpaceBox><unknown>this._LText)._Matrix.makeBasis(XAxis, ZAxis, YAxis);
|
||||
(<VisualSpaceBox><unknown>this._WText)._Matrix.makeBasis(YAxis, XAxisN, ZAxis);
|
||||
(<VisualSpaceBox><unknown>this._HText)._Matrix.makeBasis(ZAxis, XAxisN, YAxisN);
|
||||
}
|
||||
|
||||
get Length() { return this._Length; }
|
||||
get Width() { return this._Width; }
|
||||
get Height() { return this._Height; }
|
||||
|
||||
|
||||
set IsRoot(b: boolean)
|
||||
{
|
||||
if (this._IsRoot !== b)
|
||||
{
|
||||
this._IsRoot = b;
|
||||
for (let [, obj] of this._CacheDrawObject)
|
||||
{
|
||||
let [box, edge, lobj, wobj, hobj] = obj.children;
|
||||
if (this._IsRoot)
|
||||
box.visible = false;
|
||||
|
||||
if (this._IsRoot)
|
||||
{
|
||||
this._LText.TextAligen = TextAligen.Top;
|
||||
this._WText.TextAligen = TextAligen.Down;
|
||||
this._HText.TextAligen = TextAligen.Down;
|
||||
}
|
||||
else
|
||||
{
|
||||
this._LText.TextAligen = TextAligen.Down;
|
||||
this._WText.TextAligen = TextAligen.Top;
|
||||
this._HText.TextAligen = TextAligen.Top;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set DisplayWidth(b: boolean)
|
||||
{
|
||||
for (let [, obj] of this._CacheDrawObject)
|
||||
{
|
||||
let [box, edge, lobj, wobj, hobj] = obj.children;
|
||||
wobj.visible = b;
|
||||
}
|
||||
this._DisplayWidth = b;
|
||||
}
|
||||
set DisplayLength(b: boolean)
|
||||
{
|
||||
for (let [, obj] of this._CacheDrawObject)
|
||||
{
|
||||
let [box, edge, lobj, wobj, hobj] = obj.children;
|
||||
lobj.visible = b;
|
||||
}
|
||||
this._DisplayLength = b;
|
||||
}
|
||||
set DisplayHeight(b: boolean)
|
||||
{
|
||||
for (let [, obj] of this._CacheDrawObject)
|
||||
{
|
||||
let [box, edge, lobj, wobj, hobj] = obj.children;
|
||||
hobj.visible = b;
|
||||
}
|
||||
this._DisplayHeight = b;
|
||||
}
|
||||
|
||||
SetSize(l: number, w: number, h: number)
|
||||
{
|
||||
if (l !== this._Length || w !== this._Width || h !== this._Height)
|
||||
{
|
||||
this.WriteAllObjectRecord();
|
||||
this._Length = l;
|
||||
this._Width = w;
|
||||
this._Height = h;
|
||||
this.Update();
|
||||
}
|
||||
}
|
||||
get BoundingBoxInOCS()
|
||||
{
|
||||
return new Box3Ext(new Vector3, new Vector3(this._Length, this._Width, this._Height));
|
||||
}
|
||||
|
||||
//#region 捕捉
|
||||
/**
|
||||
*
|
||||
* @param snapMode 捕捉模式(单一)
|
||||
* @param pickPoint const
|
||||
* @param lastPoint const
|
||||
* @param viewXform const 最近点捕捉需要这个变量
|
||||
* @returns object snap points
|
||||
*/
|
||||
GetObjectSnapPoints(
|
||||
snapMode: ObjectSnapMode,
|
||||
pickPoint: Vector3,
|
||||
lastPoint: Vector3,
|
||||
viewXform?: Matrix3
|
||||
): Vector3[]
|
||||
{
|
||||
switch (snapMode)
|
||||
{
|
||||
case ObjectSnapMode.End:
|
||||
{
|
||||
let pts: Vector3[] = [
|
||||
new Vector3(),
|
||||
new Vector3(this._Length),
|
||||
new Vector3(this._Length, this._Width),
|
||||
new Vector3(0, this._Width),
|
||||
|
||||
new Vector3(0, 0, this._Height),
|
||||
new Vector3(this._Length, 0, this._Height),
|
||||
new Vector3(this._Length, this._Width, this._Height),
|
||||
new Vector3(0, this._Width, this._Height),
|
||||
];
|
||||
|
||||
for (let p of pts)
|
||||
p.applyMatrix4(this._Matrix);
|
||||
return pts;
|
||||
}
|
||||
}
|
||||
return EmptyArray;
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//#region Draw
|
||||
InitDrawObject(renderType: RenderType = RenderType.Wireframe)
|
||||
{
|
||||
let obj = new Object3D();
|
||||
|
||||
//box
|
||||
let mat = ColorMaterial.GetBasicMaterialTransparent2(7, 0.5);
|
||||
obj.add(new Mesh(backGeo, mat));
|
||||
//edge
|
||||
obj.add(new LineSegments(edgeGeo, ColorMaterial.GetLineMaterial(7)));
|
||||
|
||||
obj.add(this._LText.DrawObject);
|
||||
obj.add(this._WText.DrawObject);
|
||||
obj.add(this._HText.DrawObject);
|
||||
|
||||
this.UpdateDrawObject(renderType, obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
UpdateDrawObject(type: RenderType, obj: Object3D)
|
||||
{
|
||||
let [box, edge, lobj, wobj, hobj] = obj.children;
|
||||
box.scale.set(this._Length, this._Width, this._Height);
|
||||
box.updateMatrix();
|
||||
|
||||
edge.scale.set(this._Length, this._Width, this._Height);
|
||||
edge.updateMatrix();
|
||||
|
||||
box.visible = !this._IsRoot;
|
||||
|
||||
if (this._IsRoot)
|
||||
{
|
||||
this._LText.TextAligen = TextAligen.Top;
|
||||
this._WText.TextAligen = TextAligen.Down;
|
||||
this._HText.TextAligen = TextAligen.Down;
|
||||
}
|
||||
else
|
||||
{
|
||||
this._LText.TextAligen = TextAligen.Down;
|
||||
this._WText.TextAligen = TextAligen.Top;
|
||||
this._HText.TextAligen = TextAligen.Top;
|
||||
}
|
||||
|
||||
this._LText.TextString = FixedNotZero(this._Length, 2);
|
||||
this._WText.TextString = FixedNotZero(this._Width, 2);
|
||||
this._HText.TextString = FixedNotZero(this._Height, 2);
|
||||
|
||||
//实体被错误的Dispose,导致需要这样的更新
|
||||
this._LText.Update();
|
||||
this._WText.Update();
|
||||
this._HText.Update();
|
||||
|
||||
lobj.visible = this._DisplayLength;
|
||||
wobj.visible = this._DisplayWidth;
|
||||
hobj.visible = this._DisplayHeight;
|
||||
|
||||
lobj.position.set(this._Length / 2, 0, 0);
|
||||
lobj.updateMatrix();
|
||||
|
||||
wobj.position.set(0, this._Width / 2, 0);
|
||||
wobj.updateMatrix();
|
||||
|
||||
hobj.position.set(0, 0, this._Height / 2);
|
||||
hobj.updateMatrix();
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region -------------------------File-------------------------
|
||||
|
||||
//对象从文件中读取数据,初始化自身
|
||||
protected _ReadFile(file: CADFiler)
|
||||
{
|
||||
let ver = file.Read();
|
||||
super._ReadFile(file);
|
||||
this._Length = file.Read();
|
||||
this._Width = file.Read();
|
||||
this._Height = file.Read();
|
||||
|
||||
this._IsRoot = file.Read();
|
||||
this._DisplayLength = file.Read();
|
||||
this._DisplayWidth = file.Read();
|
||||
this._DisplayHeight = file.Read();
|
||||
}
|
||||
//对象将自身数据写入到文件.
|
||||
WriteFile(file: CADFiler)
|
||||
{
|
||||
file.Write(1);
|
||||
super.WriteFile(file);
|
||||
file.Write(this._Length);
|
||||
file.Write(this._Width);
|
||||
file.Write(this._Height);
|
||||
|
||||
file.Write(this._IsRoot);
|
||||
file.Write(this._DisplayLength);
|
||||
file.Write(this._DisplayWidth);
|
||||
file.Write(this._DisplayHeight);
|
||||
}
|
||||
|
||||
// //局部撤销
|
||||
// ApplyPartialUndo(undoData: CADObject)
|
||||
// {
|
||||
// super.ApplyPartialUndo(undoData);
|
||||
// }
|
||||
//#endregion
|
||||
|
||||
|
||||
//#region
|
||||
GetGripPoints(): Array<Vector3>
|
||||
{
|
||||
// return EmptyArray;//因为更新模块树是异步的,没办法在拽拖夹点时顺带更新,所以移除这个特性.
|
||||
let x = new Vector3;
|
||||
let y = new Vector3;
|
||||
let z = new Vector3;
|
||||
this._Matrix.extractBasis(x, y, z);
|
||||
x.multiplyScalar(this._Length);
|
||||
y.multiplyScalar(this._Width);
|
||||
z.multiplyScalar(this._Height);
|
||||
|
||||
let p = this.Position;
|
||||
return [p, x.add(p), y.add(p), z.add(p)];
|
||||
}
|
||||
|
||||
MoveGripPoints(indexList: number[], vec: Vector3)
|
||||
{
|
||||
let template = this.Template?.Object as TemplateRecord;
|
||||
if (template && template !== template.Root)
|
||||
return;
|
||||
|
||||
for (let i of indexList)
|
||||
{
|
||||
if (i === 0)
|
||||
{
|
||||
this.WriteAllObjectRecord();
|
||||
this.Position = this.Position.add(vec);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
let ocs = this._Matrix.clone().setPosition(ZeroVec);
|
||||
let ocsinv = new Matrix4().getInverse(ocs);
|
||||
vec.applyMatrix4(ocsinv);
|
||||
if (i === 1)
|
||||
{
|
||||
this._Length += vec.x;
|
||||
template.LParam.expr = this._Length;
|
||||
}
|
||||
else if (i === 2)
|
||||
{
|
||||
this._Width += vec.y;
|
||||
template.WParam.expr = this._Width;
|
||||
}
|
||||
else
|
||||
{
|
||||
this._Height += vec.z;
|
||||
template.HParam.expr = this._Height;
|
||||
}
|
||||
|
||||
template.UpdateTemplateTree(); //TODO:可以弹出个对话框让用户更新. 或者使用反应器?
|
||||
|
||||
this.Update();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
GetStretchPoints(): Array<Vector3>
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 拉伸夹点,用于Stretch命令
|
||||
*
|
||||
* @param {Array<number>} indexList 拉伸点索引列表.
|
||||
* @param {Vector3} vec 移动向量
|
||||
* @memberof Entity
|
||||
*/
|
||||
MoveStretchPoints(indexList: Array<number>, vec: Vector3)
|
||||
{
|
||||
|
||||
}
|
||||
//#endregion
|
||||
|
||||
}
|
||||
|
||||
class BackFaceBoxBufferGeometry extends BufferGeometry
|
||||
{
|
||||
constructor(length: number = 1, width: number = 1, height: number = 1)
|
||||
{
|
||||
super();
|
||||
|
||||
let pts: number[] = [
|
||||
0, width, 0,
|
||||
length, width, 0,
|
||||
length, width, height,
|
||||
0, width, height,
|
||||
];
|
||||
let uvs: number[] = [
|
||||
0, 0,
|
||||
1, 0,
|
||||
1, 1,
|
||||
|
||||
0, 0,
|
||||
1, 1,
|
||||
0, 1,
|
||||
];
|
||||
|
||||
let indices: number[] = [0, 1, 2, 0, 2, 3];
|
||||
|
||||
this.setIndex(indices);
|
||||
this.addAttribute('position', new Float32BufferAttribute(pts, 3));
|
||||
// this.addAttribute('normal', new Float32BufferAttribute(normals, 3));
|
||||
this.addAttribute('uv', new Float32BufferAttribute(uvs, 2));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const backGeo = new BackFaceBoxBufferGeometry();
|
||||
const edgeGeo = GenerateBoxEdgeGeometry(1, 1, 1);
|
@ -0,0 +1,30 @@
|
||||
import { BufferGeometry, Vector3 } from "three";
|
||||
import { arrayLast } from "../Common/ArrayExt";
|
||||
import { equalv3 } from "./GeUtils";
|
||||
import { FixIndex } from "../Common/Utils";
|
||||
|
||||
export function GenerateExtrudeEdgeGeometry(contourPoints: Vector3[], height: number)
|
||||
{
|
||||
if (equalv3(contourPoints[0], arrayLast(contourPoints)))
|
||||
contourPoints.pop();
|
||||
|
||||
let pts: Vector3[] = [];
|
||||
let hpts = contourPoints.map(p => new Vector3(p.x, p.y, height));
|
||||
let count = contourPoints.length;
|
||||
for (let i = 0; i < count; i++)
|
||||
{
|
||||
pts.push(contourPoints[i], contourPoints[FixIndex(i + 1, count)],
|
||||
hpts[i], hpts[FixIndex(i + 1, count)],
|
||||
contourPoints[i], hpts[i]
|
||||
);
|
||||
}
|
||||
|
||||
let geo = new BufferGeometry().setFromPoints(pts);
|
||||
return geo;
|
||||
}
|
||||
|
||||
export function GenerateBoxEdgeGeometry(length: number, width: number, height: number)
|
||||
{
|
||||
let pts = [new Vector3(), new Vector3(length), new Vector3(length, width), new Vector3(0, width)];
|
||||
return GenerateExtrudeEdgeGeometry(pts, height);
|
||||
}
|
Loading…
Reference in new issue