From efa7d71f9406bb7f854112fe4e1c7e3dfae8f546 Mon Sep 17 00:00:00 2001 From: ChenX Date: Fri, 7 Feb 2020 22:04:42 +0800 Subject: [PATCH] =?UTF-8?q?!728=20=E5=AE=9E=E7=8E=B0=E5=8F=AF=E8=A7=86?= =?UTF-8?q?=E5=8C=96=E7=A9=BA=E9=97=B4=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/CADFiler.code-snippets | 10 + package.json | 10 +- src/Add-on/Entsel.ts | 57 +++ src/Add-on/Export2View.ts | 1 - src/Add-on/KJLImport.ts | 14 +- src/Add-on/OffsetX.ts | 2 - src/Add-on/Print.ts | 7 +- src/Add-on/Purge.ts | 2 - src/Add-on/Template/RotateTemplateSpace.ts | 139 +++++++ src/Add-on/Template/SplitTemplate.ts | 50 +++ src/Add-on/testEntity/TestDrawEdgeGeometry.ts | 2 - src/Add-on/testEntity/TestFilletCode.ts | 1 - src/Add-on/testEntity/TestTemplateDelete.ts | 2 - src/Add-on/testEntity/test.ts | 55 ++- src/Common/ColorPalette.ts | 11 + src/DatabaseServices/Entity/Board.ts | 1 - src/DatabaseServices/Entity/BoxSolid.ts | 12 +- src/DatabaseServices/Entity/Extrude.ts | 10 +- .../ProgramTempate/TemplateVisualSpace.ts | 70 ++++ src/DatabaseServices/Template/TempateUtils.ts | 16 + .../Template/TemplateRecord.ts | 1 + src/Editor/CommandRegister.ts | 5 + src/Editor/VisualSpaceBox.ts | 390 ++++++++++++++++++ src/Geometry/ExtrudeEdgeGeometry.ts | 30 ++ src/Geometry/GeUtils.ts | 2 + src/Geometry/SpaceParse/ISpaceParse.ts | 3 + src/Geometry/SpaceParse/Point3SpaceParse,.ts | 6 +- src/Geometry/SpaceParse/PointSelectSpace.ts | 45 +- src/Nest/Test/TestData.ts | 1 - src/Nest/Test/TestHull.ts | 2 +- src/Nest/Test/TestNFP.ts | 1 - src/Nest/Test/TestOffset.ts | 2 - src/Nest/Test/TestPlace.ts | 1 - src/Nest/Test/TestSimply.ts | 1 - src/Nest/Test/TestYH2.tsx | 1 - src/Nest/Test/TestYH3.tsx | 1 - .../Components/Template/TemplateComponent.tsx | 21 +- 37 files changed, 912 insertions(+), 73 deletions(-) create mode 100644 src/Add-on/Template/RotateTemplateSpace.ts create mode 100644 src/Add-on/Template/SplitTemplate.ts create mode 100644 src/DatabaseServices/Template/ProgramTempate/TemplateVisualSpace.ts create mode 100644 src/Editor/VisualSpaceBox.ts create mode 100644 src/Geometry/ExtrudeEdgeGeometry.ts diff --git a/.vscode/CADFiler.code-snippets b/.vscode/CADFiler.code-snippets index 656c6ad3d..b411b2fb0 100644 --- a/.vscode/CADFiler.code-snippets +++ b/.vscode/CADFiler.code-snippets @@ -8,15 +8,25 @@ " ReadFile(file: CADFiler)", " {", " let ver = file.Read();", + " super.Read(file);", + " }", + "", + " //对象从文件中读取数据,初始化自身", + " protected _ReadFile(file: CADFiler)", + " {", + " let ver = file.Read();", + " super._ReadFile(file);", " }", " //对象将自身数据写入到文件.", " WriteFile(file: CADFiler)", " {", " file.Write(1);", + " super.Write(file);", " }", " //局部撤销", " ApplyPartialUndo(undoData: CADObject)", " {", + " super.ApplyPartialUndo(undoData);", " }", " //#endregion" ] diff --git a/package.json b/package.json index d1d3dfadf..681822305 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "license": "ISC", "devDependencies": { "@types/html-webpack-plugin": "^3.2.2", - "@types/jest": "^25.1.1", + "@types/jest": "^25.1.2", "@types/node": "^13.7.0", "@types/pako": "^1.0.1", "@types/react": "^16.9.19", @@ -29,7 +29,7 @@ "@types/react-dom": "^16.9.5", "@types/stats.js": "^0.17.0", "@types/terser-webpack-plugin": "^2.2.0", - "@types/webpack": "^4.41.4", + "@types/webpack": "^4.41.5", "@types/webpack-dev-server": "^3.10.0", "@types/webpack-env": "^1.15.1", "@types/webpack-merge": "^4.1.5", @@ -60,7 +60,7 @@ "source-map-loader": "^0.2.4", "style-loader": "^1.1.3", "terser-webpack-plugin": "^2.3.4", - "ts-jest": "^25.1.0", + "ts-jest": "^25.2.0", "ts-loader": "^6.2.1", "ts-node": "^8.6.2", "tsconfig-paths": "^3.9.0", @@ -69,7 +69,7 @@ "wallaby-webpack": "^3.9.15", "webpack": "^4.41.5", "webpack-cli": "^3.3.10", - "webpack-dev-server": "^3.10.2", + "webpack-dev-server": "^3.10.3", "webpack-merge": "^4.2.2", "worker-loader": "^2.0.0" }, @@ -80,7 +80,7 @@ "golden-layout": "^1.5.9", "js-angusj-clipper": "^1.0.4", "mobx": "^5.15.4", - "mobx-react": "^6.1.4", + "mobx-react": "^6.1.7", "monotone-convex-hull-2d": "^1.0.1", "p-queue": "^6.2.1", "pako": "^1.0.11", diff --git a/src/Add-on/Entsel.ts b/src/Add-on/Entsel.ts index 757ffd004..4d102fdea 100644 --- a/src/Add-on/Entsel.ts +++ b/src/Add-on/Entsel.ts @@ -1,8 +1,10 @@ import { Vector3 } from 'three'; import { app } from '../ApplicationServices/Application'; import { Entity } from '../DatabaseServices/Entity/Entity'; +import { Line } from '../DatabaseServices/Entity/Line'; import { Command } from '../Editor/CommandMachine'; import { PromptStatus } from '../Editor/PromptResult'; +import { VisualSpaceBox } from '../Editor/VisualSpaceBox'; import { DynamicInputManage } from '../UI/DynamicPrompt/DynamicInputManage'; import { PromptBlock } from '../UI/DynamicPrompt/PromptBlock'; @@ -28,6 +30,61 @@ export class Entsel implements Command dyn.UpdatePrompt(`模版:${res.Entity.Template.Index}`); else dyn.UpdatePrompt(`null`); + + if (res.Entity instanceof VisualSpaceBox) + { + let vbox = res.Entity as VisualSpaceBox; + let [l, w, h] = [vbox.Length, vbox.Width, vbox.Height]; + let pts = [ + new Vector3(),//0 + new Vector3(l),//x 1 + new Vector3(l, w),// 2 + new Vector3(0, w, 0),//y 3 + + new Vector3(0, 0, h),//z 4 + new Vector3(l, 0, h),//5 + new Vector3(l, w, h),//6 + new Vector3(0, w, h),//7 + ]; + let lines = [ + [0, 1], + [0, 3], + [0, 4], + + [3, 2], + [1, 2], + [1, 5], + + [4, 5], + [4, 7], + [2, 6], + + [7, 6], + [5, 6], + [3, 7], + ]; + + let cs = vbox.OCS; + + let dcs = app.Viewer.DCS; + + for (let p of pts) + p.applyMatrix4(cs).applyMatrix4(dcs); + + let vcs = app.Editor.MouseCtrl.m_CurMousePointVCS; + + let line = new Line(); + let dists = lines.map((p1p2: number[]) => + { + let [p1, p2] = p1p2.map(i => pts[i]); + line.StartPoint = p1; + line.EndPoint = p2; + return line.GetClosestPointTo(vcs, true).distanceTo(vcs); + }); + let index = dists.indexOf(Math.min(...dists)) % 3; + + dyn.UpdatePrompt(`猜测鼠标在${["长", "宽", "高"][index]}轴上`); + } } else dyn.Visible = false; diff --git a/src/Add-on/Export2View.ts b/src/Add-on/Export2View.ts index a09a87e5f..fb11c4646 100644 --- a/src/Add-on/Export2View.ts +++ b/src/Add-on/Export2View.ts @@ -8,7 +8,6 @@ import { HotCMD } from "../Hot/HotCommand"; import { CURRENT_HOST } from "../Common/HostUrl"; import { Region } from "../DatabaseServices/Entity/Region"; -@HotCMD export class Command_ExportView implements Command { async exec() diff --git a/src/Add-on/KJLImport.ts b/src/Add-on/KJLImport.ts index bf528300f..bb7e6714e 100644 --- a/src/Add-on/KJLImport.ts +++ b/src/Add-on/KJLImport.ts @@ -1,6 +1,8 @@ import { Euler, Matrix4, Vector2, Vector3 } from "three"; import { app } from "../ApplicationServices/Application"; +import { arrayLast } from "../Common/ArrayExt"; import { EBoardKeyList } from "../Common/BoardKeyList"; +import { safeEval } from "../Common/eval"; import { FileSystem } from "../Common/FileSystem"; import { JigMoveEntity } from "../Common/JigMove"; import { FixIndex, ToFixed } from "../Common/Utils"; @@ -9,15 +11,12 @@ import { ExtrudeSolid } from "../DatabaseServices/Entity/Extrude"; import { Polyline, PolylineProps } from "../DatabaseServices/Entity/Polyline"; import { TemplateRecord } from "../DatabaseServices/Template/TemplateRecord"; import { Command, CommandWrap } from "../Editor/CommandMachine"; +import { userConfig } from "../Editor/UserConfig"; import { Vec2 } from "../Geometry/CheckIntersect"; -import { AsVector2, equaln, equalv2, isParallelTo, XAxis } from "../Geometry/GeUtils"; +import { AsVector2, equaln, equalv2 } from "../Geometry/GeUtils"; import { Vec3 } from "../Geometry/IVec3"; -import { HotCMD } from "../Hot/HotCommand"; -import { FaceDirection, LinesType, IHighSealedItem } from "../UI/Store/BoardInterface"; -import { ParagraphSealinglist, HandleRectBoardSealingData } from "../GraphicsSystem/CalcEdgeSealing"; -import { arrayLast } from "../Common/ArrayExt"; -import { userConfig } from "../Editor/UserConfig"; -import { safeEval } from "../Common/eval"; +import { HandleRectBoardSealingData, ParagraphSealinglist } from "../GraphicsSystem/CalcEdgeSealing"; +import { FaceDirection, IHighSealedItem, LinesType } from "../UI/Store/BoardInterface"; /** 模型类型 */ enum KJL_ModelType @@ -118,7 +117,6 @@ class FuzzPoint } } -@HotCMD export class Command_KJLImport implements Command { async exec() diff --git a/src/Add-on/OffsetX.ts b/src/Add-on/OffsetX.ts index d3f3c13b5..e4f2f16f5 100644 --- a/src/Add-on/OffsetX.ts +++ b/src/Add-on/OffsetX.ts @@ -3,11 +3,9 @@ import { Curve } from "../DatabaseServices/Entity/Curve"; import { Polyline } from "../DatabaseServices/Entity/Polyline"; import { Command } from "../Editor/CommandMachine"; import { PromptStatus } from "../Editor/PromptResult"; -import { HotCMD } from "../Hot/HotCommand"; import { TestDraw } from "./test/TestUtil"; //无限内偏移 -@HotCMD export class OffsetX implements Command { offsetDis: number = 1; diff --git a/src/Add-on/Print.ts b/src/Add-on/Print.ts index b6cdf5ce8..0573ff20a 100644 --- a/src/Add-on/Print.ts +++ b/src/Add-on/Print.ts @@ -1,7 +1,9 @@ import { Object3D, Scene, Vector3 } from "three"; import { SVGRenderer } from "three/examples/jsm/renderers/SVGRenderer"; import { app } from "../ApplicationServices/Application"; +import { DisposeThreeObj } from "../Common/Dispose"; import { Sleep } from "../Common/Sleep"; +import { Hole } from "../DatabaseServices/3DSolid/Hole"; import { CADFiler } from "../DatabaseServices/CADFiler"; import { AlignedDimension } from "../DatabaseServices/Dimension/AlignedDimension"; import { Board } from "../DatabaseServices/Entity/Board"; @@ -11,12 +13,7 @@ import { PromptStatus } from "../Editor/PromptResult"; import { userConfig } from "../Editor/UserConfig"; import { isParallelTo, XAxis, YAxis } from "../Geometry/GeUtils"; import { RenderType } from "../GraphicsSystem/RenderType"; -import { AAType } from "../GraphicsSystem/Viewer"; -import { HotCMD } from "../Hot/HotCommand"; -import { DisposeThreeObj } from "../Common/Dispose"; -import { Hole } from "../DatabaseServices/3DSolid/Hole"; -@HotCMD export class Print implements Command { async exec() diff --git a/src/Add-on/Purge.ts b/src/Add-on/Purge.ts index a7039fccf..f7359b400 100644 --- a/src/Add-on/Purge.ts +++ b/src/Add-on/Purge.ts @@ -1,8 +1,6 @@ import { app } from "../ApplicationServices/Application"; import { arrayRemoveIf } from "../Common/ArrayExt"; -import { HotCMD } from "../Hot/HotCommand"; -@HotCMD export class Command_Purge { async exec() diff --git a/src/Add-on/Template/RotateTemplateSpace.ts b/src/Add-on/Template/RotateTemplateSpace.ts new file mode 100644 index 000000000..8adeb3a69 --- /dev/null +++ b/src/Add-on/Template/RotateTemplateSpace.ts @@ -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 +{ + 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); +} diff --git a/src/Add-on/Template/SplitTemplate.ts b/src/Add-on/Template/SplitTemplate.ts new file mode 100644 index 000000000..47e8a94f5 --- /dev/null +++ b/src/Add-on/Template/SplitTemplate.ts @@ -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(); + } + } +} diff --git a/src/Add-on/testEntity/TestDrawEdgeGeometry.ts b/src/Add-on/testEntity/TestDrawEdgeGeometry.ts index 6a1275f93..7617c1d8a 100644 --- a/src/Add-on/testEntity/TestDrawEdgeGeometry.ts +++ b/src/Add-on/testEntity/TestDrawEdgeGeometry.ts @@ -4,10 +4,8 @@ import { Board } from "../../DatabaseServices/Entity/Board"; import { Line } from "../../DatabaseServices/Entity/Line"; import { Command } from "../../Editor/CommandMachine"; import { PromptStatus } from "../../Editor/PromptResult"; -import { HotCMD } from "../../Hot/HotCommand"; import { TestDraw } from "../test/TestUtil"; -@HotCMD export class Command_TestDrawEdgeGeometry implements Command { async exec() diff --git a/src/Add-on/testEntity/TestFilletCode.ts b/src/Add-on/testEntity/TestFilletCode.ts index aac6d6067..8d417dfa6 100644 --- a/src/Add-on/testEntity/TestFilletCode.ts +++ b/src/Add-on/testEntity/TestFilletCode.ts @@ -6,7 +6,6 @@ import { Command } from "../../Editor/CommandMachine"; import { PromptStatus } from "../../Editor/PromptResult"; import { HotCMD } from "../../Hot/HotCommand"; -@HotCMD export class TestFillet implements Command { async exec() diff --git a/src/Add-on/testEntity/TestTemplateDelete.ts b/src/Add-on/testEntity/TestTemplateDelete.ts index 6d107d2f7..2dd70af67 100644 --- a/src/Add-on/testEntity/TestTemplateDelete.ts +++ b/src/Add-on/testEntity/TestTemplateDelete.ts @@ -6,7 +6,6 @@ import { SelectTempate } from "../../DatabaseServices/Template/TemplateTest"; import { Command, commandMachine } from "../../Editor/CommandMachine"; import { HotCMD } from "../../Hot/HotCommand"; -@HotCMD export class Command_DeleteTemplate implements Command { async exec() @@ -17,7 +16,6 @@ export class Command_DeleteTemplate implements Command } } -@HotCMD export class Command_Template2Tree implements Command { async exec() diff --git a/src/Add-on/testEntity/test.ts b/src/Add-on/testEntity/test.ts index 51ae5b102..401abb215 100644 --- a/src/Add-on/testEntity/test.ts +++ b/src/Add-on/testEntity/test.ts @@ -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) + { + await template.UpdateTemplateTree(); + return; + }; + let t = template; + if (t.Children.length === 0) + { + t.SplitType = TemplateSplitType.X; + for (let i = 0; i < 3; i++) { - // if (e.IsClockWise) e.ColorIndex = 1; - if (e instanceof Board) - console.log(Production.GetBoardSplitOrderData(e)); + 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(); } } diff --git a/src/Common/ColorPalette.ts b/src/Common/ColorPalette.ts index da7fce0f3..81fd72c0f 100644 --- a/src/Common/ColorPalette.ts +++ b/src/Common/ColorPalette.ts @@ -326,6 +326,17 @@ export class ColorMaterial return mat; } + private static _BasicTransparentMaterialMap2: Map = new Map(); + static GetBasicMaterialTransparent2(color: number, opacity: number) + { + let key = `${color},${opacity}`; + let mat = this._BasicTransparentMaterialMap2.get(key); + if (mat) return mat; + mat = new MeshBasicMaterial({ transparent: true, opacity: opacity }); + this._BasicTransparentMaterialMap2.set(key, mat); + return mat; + } + static GetColor(color: number) { let rgb = ColorPalette[color]; diff --git a/src/DatabaseServices/Entity/Board.ts b/src/DatabaseServices/Entity/Board.ts index da09aca2b..6b8c66dc0 100644 --- a/src/DatabaseServices/Entity/Board.ts +++ b/src/DatabaseServices/Entity/Board.ts @@ -6,7 +6,6 @@ import { EBoardKeyList } from '../../Common/BoardKeyList'; import { UpdateDraw } from '../../Common/Status'; import { userConfig } from '../../Editor/UserConfig'; import { boardUVGenerator, boardUVGenerator2 } from '../../Geometry/BoardUVGenerator'; -import { Box3Ext } from '../../Geometry/Box'; import { equaln, MoveMatrix } from '../../Geometry/GeUtils'; import { BoardProcessOption, ComposingType, FaceDirection, LinesType } from '../../UI/Store/BoardInterface'; import { Factory } from '../CADFactory'; diff --git a/src/DatabaseServices/Entity/BoxSolid.ts b/src/DatabaseServices/Entity/BoxSolid.ts index 6de2758f3..05171023c 100644 --- a/src/DatabaseServices/Entity/BoxSolid.ts +++ b/src/DatabaseServices/Entity/BoxSolid.ts @@ -6,7 +6,7 @@ import { RenderType } from "../../GraphicsSystem/RenderType"; let boxGeo: BoxBufferGeometry; -function getBoxGeoBufferGeometry() +export function GetBoxGeoBufferGeometry() { if (!boxGeo) boxGeo = new BoxBufferGeometry(1, 1, 1); @@ -24,13 +24,17 @@ export class BoxSolid extends Entity } set Opacity(o: number) { - this._opacity = o; - this.Update(); + if (o !== this._opacity) + { + this.WriteAllObjectRecord(); + this._opacity = o; + this.Update(); + } } InitDrawObject(renderType: RenderType = RenderType.Wireframe) { let box = new Object3D(); - let geo = getBoxGeoBufferGeometry(); + let geo = GetBoxGeoBufferGeometry(); let mat = ColorMaterial.GetBasicMaterialTransparent(7, this._opacity); box.add(new Mesh(geo, mat)); this.UpdateDrawObject(renderType, box); diff --git a/src/DatabaseServices/Entity/Extrude.ts b/src/DatabaseServices/Entity/Extrude.ts index 6d2d8b4f4..9771b2c0f 100644 --- a/src/DatabaseServices/Entity/Extrude.ts +++ b/src/DatabaseServices/Entity/Extrude.ts @@ -3,7 +3,7 @@ import { arrayClone, arrayLast, arrayRemoveIf, arraySortByNumber, arraySum } fro import { ColorMaterial } from "../../Common/ColorPalette"; import { equalCurve } from "../../Common/CurveUtils"; import { DisposeThreeObj } from "../../Common/Dispose"; -import { Vector2ApplyMatrix4, matrixSetVector } from "../../Common/Matrix4Utils"; +import { matrixSetVector, Vector2ApplyMatrix4 } from "../../Common/Matrix4Utils"; import { Status, UpdateDraw } from "../../Common/Status"; import { CSG } from "../../csg/core/CSG"; import { CSG2Geometry, Geometry2CSG } from "../../csg/core/Geometry2CSG"; @@ -13,7 +13,8 @@ import { Box3Ext } from "../../Geometry/Box"; import { BSPGroupParse } from "../../Geometry/BSPGroupParse"; import { FastWireframe } from "../../Geometry/CreateWireframe"; import { EdgesGeometry } from "../../Geometry/EdgeGeometry"; -import { equaln, equalv2, equalv3, isIntersect, isParallelTo, MoveMatrix, ZeroVec, IdentityMtx4 } from "../../Geometry/GeUtils"; +import { GenerateExtrudeEdgeGeometry } from "../../Geometry/ExtrudeEdgeGeometry"; +import { AsVector3, equaln, equalv2, equalv3, IdentityMtx4, isIntersect, isParallelTo, MoveMatrix, ZeroVec } from "../../Geometry/GeUtils"; import { OBB } from "../../Geometry/OBB/obb"; import { ScaleUV } from "../../Geometry/UVUtils"; import { RenderType } from "../../GraphicsSystem/RenderType"; @@ -1144,6 +1145,9 @@ export class ExtrudeSolid extends Entity { if (this._EdgeGeometry) return this._EdgeGeometry; + + if (this.grooves.length === 0) + return GenerateExtrudeEdgeGeometry(this.contourCurve.Shape.getPoints(6).map(AsVector3), this.thickness).applyMatrix4(this.contourCurve.OCS); this.MeshGeometry; this._EdgeGeometry = new EdgesGeometry().FromCSG(this.CSG); return this._EdgeGeometry; @@ -1338,7 +1342,7 @@ export class ExtrudeSolid extends Entity //#endregion } -function FastMeshGeometry(width: number, height: number, thickness: number) +export function FastMeshGeometry(width: number, height: number, thickness: number) { let geo = new BoxGeometry(width, height, thickness); geo.translate(width * 0.5, height * 0.5, thickness * 0.5); diff --git a/src/DatabaseServices/Template/ProgramTempate/TemplateVisualSpace.ts b/src/DatabaseServices/Template/ProgramTempate/TemplateVisualSpace.ts new file mode 100644 index 000000000..8a2caa801 --- /dev/null +++ b/src/DatabaseServices/Template/ProgramTempate/TemplateVisualSpace.ts @@ -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 +} diff --git a/src/DatabaseServices/Template/TempateUtils.ts b/src/DatabaseServices/Template/TempateUtils.ts index a849bd30b..ca8fb2409 100644 --- a/src/DatabaseServices/Template/TempateUtils.ts +++ b/src/DatabaseServices/Template/TempateUtils.ts @@ -1073,3 +1073,19 @@ export function RemoveTemplate(temp: TemplateRecord) (id.Object as Entity).Template = null; temp.Children.length = 0; } + +/**新模块替换旧模块 */ +export function ReplaceTemplate(oldTemp: TemplateRecord, newTemp: TemplateRecord) +{ + for (let i = 0; i < 9; i++) + { + newTemp.Params[i].expr = oldTemp.Params[i].expr; + } + newTemp.Positioning = oldTemp.Positioning; + if (oldTemp.Parent) + { + let t = oldTemp.Parent.Object as TemplateRecord; + let index = t.Children.indexOf(oldTemp.Id); + t.Children[index] = newTemp.Id; + } +} diff --git a/src/DatabaseServices/Template/TemplateRecord.ts b/src/DatabaseServices/Template/TemplateRecord.ts index 0b5200df7..a1c1d6920 100644 --- a/src/DatabaseServices/Template/TemplateRecord.ts +++ b/src/DatabaseServices/Template/TemplateRecord.ts @@ -171,6 +171,7 @@ export class TemplateRecord extends SymbolTableRecord */ set Positioning(p: Positioning) { + if (!p) return; this.WriteAllObjectRecord(); p.parent = this; this._Positioning = p; diff --git a/src/Editor/CommandRegister.ts b/src/Editor/CommandRegister.ts index 9081aa09c..05a70d656 100644 --- a/src/Editor/CommandRegister.ts +++ b/src/Editor/CommandRegister.ts @@ -123,9 +123,11 @@ import { Sweep } from "../Add-on/Sweep"; import { Command_SwitchCamera } from "../Add-on/SwitchCamera"; import { CMD_Conceptual, CMD_Physical, CMD_Wireframe } from "../Add-on/SwitchVisualStyles"; import { DrawTangentLine } from "../Add-on/Tangent"; +import { Command_RotateTemplateSpace } from "../Add-on/Template/RotateTemplateSpace"; import { ShowTemplate } from "../Add-on/Template/ShowTemplate"; import { ShowTemplateDesign } from "../Add-on/Template/ShowTemplateDesign"; import { ShowTopLine } from "../Add-on/Template/ShowTopline"; +import { Command_SplitTemplate } from "../Add-on/Template/SplitTemplate"; import { Command_TemplateSearch } from "../Add-on/TemplateSearch"; // import { DrawFloor } from '../Add-on/DrawFloor'; // import { RevTarget, SaveTarget } from '../Add-on/RenderTarget'; @@ -390,11 +392,14 @@ export function registerCommand() //绘制复合实体 commandMachine.RegisterCommand("combine", new Command_CombineEntity()); + //Template commandMachine.RegisterCommand("template", new ShowTemplate()); commandMachine.RegisterCommand("templatedesign", new ShowTemplateDesign()); commandMachine.RegisterCommand("TemplateSearch", new Command_TemplateSearch()); commandMachine.RegisterCommand("templateDelete", new Command_DeleteTemplate()); commandMachine.RegisterCommand("templatecheck", new Command_TemplateSearch(true)); + commandMachine.RegisterCommand("SplitTemplate", new Command_SplitTemplate()); + commandMachine.RegisterCommand("RotateTemplateSpace", new Command_RotateTemplateSpace()); //优化算法 commandMachine.RegisterCommand("testNFP", new Command_TestNFP()); diff --git a/src/Editor/VisualSpaceBox.ts b/src/Editor/VisualSpaceBox.ts new file mode 100644 index 000000000..7f23177c1 --- /dev/null +++ b/src/Editor/VisualSpaceBox.ts @@ -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; + (this._LText)._Matrix.makeBasis(XAxis, ZAxis, YAxis); + (this._WText)._Matrix.makeBasis(YAxis, XAxisN, ZAxis); + (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 + { + // 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 + { + return []; + } + + /** + * 拉伸夹点,用于Stretch命令 + * + * @param {Array} indexList 拉伸点索引列表. + * @param {Vector3} vec 移动向量 + * @memberof Entity + */ + MoveStretchPoints(indexList: Array, 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); diff --git a/src/Geometry/ExtrudeEdgeGeometry.ts b/src/Geometry/ExtrudeEdgeGeometry.ts new file mode 100644 index 000000000..bedbe5ff2 --- /dev/null +++ b/src/Geometry/ExtrudeEdgeGeometry.ts @@ -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); +} diff --git a/src/Geometry/GeUtils.ts b/src/Geometry/GeUtils.ts index 6031f4444..32f4baaa2 100644 --- a/src/Geometry/GeUtils.ts +++ b/src/Geometry/GeUtils.ts @@ -4,7 +4,9 @@ import { ToFixed } from '../Common/Utils'; export const IdentityMtx4 = new Matrix4(); export const ZeroVec = new Vector3(); export const XAxis = new Vector3(1, 0, 0); +export const XAxisN = new Vector3(-1, 0, 0); export const YAxis = new Vector3(0, 1, 0); +export const YAxisN = new Vector3(0, -1, 0); export const ZAxis = new Vector3(0, 0, 1); export function AsVector2(p: { x: number, y: number; }) diff --git a/src/Geometry/SpaceParse/ISpaceParse.ts b/src/Geometry/SpaceParse/ISpaceParse.ts index 49b00406c..d7008e0ea 100644 --- a/src/Geometry/SpaceParse/ISpaceParse.ts +++ b/src/Geometry/SpaceParse/ISpaceParse.ts @@ -3,6 +3,7 @@ import { arrayRemoveDuplicateBySort2 } from "../../Common/ArrayExt"; import { Board, BoardType } from "../../DatabaseServices/Entity/Board"; import { Box3Ext, SplitType } from "../Box"; import { equaln, isParallelTo, XAxis, YAxis, ZAxis } from "../GeUtils"; +import { VisualSpaceBox } from './../../Editor/VisualSpaceBox'; export class ISpaceParse { @@ -39,6 +40,8 @@ export class ISpaceParse * 动态中,禁止执行二次操作 */ IsDynamic: Boolean = false; + /**选到的虚拟空间 */ + VisualSpaceBox: VisualSpaceBox; /** * # 构造后请手动调用Parse()方法. diff --git a/src/Geometry/SpaceParse/Point3SpaceParse,.ts b/src/Geometry/SpaceParse/Point3SpaceParse,.ts index c314970ea..1d24482cb 100644 --- a/src/Geometry/SpaceParse/Point3SpaceParse,.ts +++ b/src/Geometry/SpaceParse/Point3SpaceParse,.ts @@ -23,7 +23,7 @@ export class Point3SpaceParse extends ISpaceParse let basePt = ptRes.Point; let xRes = await app.Editor.GetPoint({ - Msg: "选择x方向终点", + Msg: "选择长度方向终点(x轴):", BasePoint: basePt, AllowDrawRubberBand: true, }); @@ -33,7 +33,7 @@ export class Point3SpaceParse extends ISpaceParse let xVec = xRes.Point.sub(basePt).normalize(); let zRes = await app.Editor.GetPoint({ - Msg: "选择z方向终点", + Msg: "选择高度方向终点(Z轴):", BasePoint: basePt, AllowDrawRubberBand: true, }); @@ -47,7 +47,7 @@ export class Point3SpaceParse extends ISpaceParse if (!isPerpendicularityTo(xVec, zVec)) { AppToaster.show({ - message: "x轴和z轴必须垂直", + message: "x轴和z轴必须垂直!", timeout: 2000 }); return; diff --git a/src/Geometry/SpaceParse/PointSelectSpace.ts b/src/Geometry/SpaceParse/PointSelectSpace.ts index 5bf5ff20d..716d7be7e 100644 --- a/src/Geometry/SpaceParse/PointSelectSpace.ts +++ b/src/Geometry/SpaceParse/PointSelectSpace.ts @@ -1,12 +1,17 @@ import { Vector3 } from "three"; import { app } from "../../ApplicationServices/Application"; import { KeyWord } from "../../Common/InputState"; +import { GetEntity } from "../../Common/Utils"; import { Board } from "../../DatabaseServices/Entity/Board"; +import { BoxSolid } from "../../DatabaseServices/Entity/BoxSolid"; +import { Entity } from "../../DatabaseServices/Entity/Entity"; +import { TemplateRecord } from "../../DatabaseServices/Template/TemplateRecord"; import { JigUtils } from "../../Editor/JigUtils"; +import { PointPick } from "../../Editor/PointPick"; import { PromptPointResult, PromptStatus } from "../../Editor/PromptResult"; +import { VisualSpaceBox } from './../../Editor/VisualSpaceBox'; import { ISpaceParse } from "./ISpaceParse"; import { PointSelectBoards } from "./PointSelectBoards"; -import { BoxSolid } from "../../DatabaseServices/Entity/BoxSolid"; export enum EnableSelectType { @@ -82,9 +87,25 @@ export class PointSelectSpace { if (this.GetPointRes.StringResult === "S") { - let ssRes = await app.Editor.GetSelection({ UseSelect: true, Filter: { filterTypes: [Board] } }); + let ssRes = await app.Editor.GetSelection({ + UseSelect: true, + Filter: { + filterFunction: (o, e) => + { + return e instanceof Board || FilterVisualSpaceBox(e); + } + } + }); if (ssRes.Status === PromptStatus.OK) + { + let visiBox = ssRes.SelectSet.SelectEntityList.find(e => e instanceof VisualSpaceBox) as VisualSpaceBox; + if (visiBox) + { + this.PointParseVisualSpace(visiBox); + return; + } await this.ParseBySelect(ssRes.SelectSet.SelectEntityList as Board[]); + } } else if (this.GetPointRes.StringResult === "2") { @@ -135,6 +156,14 @@ export class PointSelectSpace { let view = app.Viewer; let vcs = app.Editor.MouseCtrl.m_CurMousePointVCS; + + let visualBoxPick = PointPick(vcs, view, { filterFunction: (o, e) => FilterVisualSpaceBox(e) }); + if (visualBoxPick.length > 0) + { + this.PointParseVisualSpace(GetEntity(visualBoxPick[0]) as VisualSpaceBox); + return; + } + let ptSelect = new PointSelectBoards(vcs, view, view.VisibleObjects); if (ptSelect.SelectBoards.length === 0 && !isDynamic) @@ -142,6 +171,13 @@ export class PointSelectSpace else await this.ParseByPointSelect(ptSelect, isDynamic); } + private PointParseVisualSpace(spaceBox: VisualSpaceBox) + { + this.SpaceParse = new ISpaceParse([], spaceBox.SpaceOCS); + this.SpaceParse.VisualSpaceBox = spaceBox; + this.SpaceParse.SpaceBox = spaceBox.BoundingBoxInOCS; + this.SpaceParse.ParseOK = true; + } private ShowSpaceBox() { if (this.ParseOK) @@ -170,3 +206,8 @@ export class PointSelectSpace } } } + +function FilterVisualSpaceBox(e: Entity) +{ + return (e instanceof VisualSpaceBox && (e?.Template?.Object as TemplateRecord)?.Children.length === 0); +} diff --git a/src/Nest/Test/TestData.ts b/src/Nest/Test/TestData.ts index 57e1b9d0b..919db7234 100644 --- a/src/Nest/Test/TestData.ts +++ b/src/Nest/Test/TestData.ts @@ -5,7 +5,6 @@ import { Polyline } from "../../DatabaseServices/Entity/Polyline"; import { PromptStatus } from "../../Editor/PromptResult"; import { FileSystem } from "../../Common/FileSystem"; -@HotCMD export class Command_NFPData implements Command { async exec() diff --git a/src/Nest/Test/TestHull.ts b/src/Nest/Test/TestHull.ts index 53c312e1e..659b80a0c 100644 --- a/src/Nest/Test/TestHull.ts +++ b/src/Nest/Test/TestHull.ts @@ -5,7 +5,7 @@ import { ConvexHull2D } from "../ConvexHull2D"; import { Path2Polyline } from "../Converter/Path2Polyline"; import { HotCMD } from "../../Hot/HotCommand"; -@HotCMD + export class Command_TestHull { async exec() diff --git a/src/Nest/Test/TestNFP.ts b/src/Nest/Test/TestNFP.ts index 2370b00ad..8a04f72ef 100644 --- a/src/Nest/Test/TestNFP.ts +++ b/src/Nest/Test/TestNFP.ts @@ -12,7 +12,6 @@ import { InitClipperCpp } from "../ClipperCpp"; const TesetPerformance = true; -@HotCMD export class Command_TestNFP implements Command { async exec() diff --git a/src/Nest/Test/TestOffset.ts b/src/Nest/Test/TestOffset.ts index cba695ecb..a159cb7dd 100644 --- a/src/Nest/Test/TestOffset.ts +++ b/src/Nest/Test/TestOffset.ts @@ -2,14 +2,12 @@ import { EndType as ET, JoinType as JT } from "js-angusj-clipper/web"; import { app } from "../../ApplicationServices/Application"; import { Polyline } from "../../DatabaseServices/Entity/Polyline"; import { PromptStatus } from "../../Editor/PromptResult"; -import { HotCMD } from "../../Hot/HotCommand"; import { clipperCpp } from "../ClipperCpp"; /** * 测试结果 19-20点以上时,使用c++进行偏移会更快 */ -@HotCMD export class Command_TestOffset { async exec() diff --git a/src/Nest/Test/TestPlace.ts b/src/Nest/Test/TestPlace.ts index b754f2700..cf6d009b8 100644 --- a/src/Nest/Test/TestPlace.ts +++ b/src/Nest/Test/TestPlace.ts @@ -13,7 +13,6 @@ import { Part } from "../Part"; import { PathGeneratorSingle } from "../PathGenerator"; import { InitClipperCpp } from "../ClipperCpp"; -@HotCMD export class Command_TestPlace implements Command { async exec() diff --git a/src/Nest/Test/TestSimply.ts b/src/Nest/Test/TestSimply.ts index 599b26f26..ce67a1e8e 100644 --- a/src/Nest/Test/TestSimply.ts +++ b/src/Nest/Test/TestSimply.ts @@ -9,7 +9,6 @@ import { Circle } from "../../DatabaseServices/Entity/Circle"; import { SimplifyDouglasPeucker } from "../Converter/Simplify2"; import { Polylin2Points } from "../Converter/ConverBoard2Part"; -@HotCMD export class Command_TestSimply implements Command { async exec() diff --git a/src/Nest/Test/TestYH2.tsx b/src/Nest/Test/TestYH2.tsx index 581c7faea..478d7a62b 100644 --- a/src/Nest/Test/TestYH2.tsx +++ b/src/Nest/Test/TestYH2.tsx @@ -22,7 +22,6 @@ import { OptimizeMachine } from "../OptimizeMachine"; import { PathGeneratorSingle } from "../PathGenerator"; import { NestVariant } from "./TestVariant"; -@HotCMD export class Command_TestYH2 implements Command { async exec() diff --git a/src/Nest/Test/TestYH3.tsx b/src/Nest/Test/TestYH3.tsx index 37b901510..5b3066579 100644 --- a/src/Nest/Test/TestYH3.tsx +++ b/src/Nest/Test/TestYH3.tsx @@ -24,7 +24,6 @@ import Worker from "../OptimizeWorker.worker"; import { PathGeneratorSingle } from "../PathGenerator"; import { NestVariant } from "./TestVariant"; -@HotCMD export class Command_TestYHWorker implements Command { async exec() diff --git a/src/UI/Components/Template/TemplateComponent.tsx b/src/UI/Components/Template/TemplateComponent.tsx index 028a59a54..19a5fee59 100644 --- a/src/UI/Components/Template/TemplateComponent.tsx +++ b/src/UI/Components/Template/TemplateComponent.tsx @@ -12,7 +12,7 @@ import { StoreageKeys } from '../../../Common/StoreageKeys'; import { Board } from '../../../DatabaseServices/Entity/Board'; import { Entity } from '../../../DatabaseServices/Entity/Entity'; import { PositioningClampSpace } from '../../../DatabaseServices/Template/Positioning/PositioningClampSpace'; -import { GetDeepestTemplate, GetOnlineTemplate, UploadTemplate, EditorOnlineTemplate } from '../../../DatabaseServices/Template/TempateUtils'; +import { GetDeepestTemplate, GetOnlineTemplate, UploadTemplate, EditorOnlineTemplate, ReplaceTemplate } from '../../../DatabaseServices/Template/TempateUtils'; import { TemplateRecord } from '../../../DatabaseServices/Template/TemplateRecord'; import { commandMachine, CommandWrap } from '../../../Editor/CommandMachine'; import { JigUtils } from '../../../Editor/JigUtils'; @@ -26,6 +26,8 @@ import { HandleDirComponent } from '../SourceManage/HandleDirComponent'; import { AppToaster } from '../Toaster'; import { GetRoomCabName, IGetRoomInfo } from './GetRoomCabName'; import { TemplateList } from './TemplateList'; +import { TemplateVisualSpace } from './../../../DatabaseServices/Template/ProgramTempate/TemplateVisualSpace'; +import { DeleteTempate } from './../../../DatabaseServices/Template/TempateUtils'; export interface INeedUpdateParams { @@ -268,7 +270,7 @@ export class TemplateManage extends React.Component<{ store?: TempalteEditorStor return; template = app.Database.WblockCloneObejcts([template], app.Database.TemplateTable, new Map(), DuplicateRecordCloning.Ignore)[0] as TemplateRecord; - let nents = template.Root.AllEntitys; + let nents = template.AllEntitys; let seleteBrs = parse.Boards.filter(b => b.Template !== undefined); @@ -308,9 +310,18 @@ export class TemplateManage extends React.Component<{ store?: TempalteEditorStor } else { - template.LParam.expr = parse.Size.x; - template.WParam.expr = parse.Size.y; - template.HParam.expr = parse.Size.z; + if (parse.VisualSpaceBox) + { + let vstemp = parse.VisualSpaceBox.Template.Object as TemplateVisualSpace; + ReplaceTemplate(vstemp, template); + DeleteTempate(vstemp); + } + else + { + template.LParam.expr = parse.Size.x; + template.WParam.expr = parse.Size.y; + template.HParam.expr = parse.Size.z; + } let ens = template.Objects.map(obj => obj.Object as Board).filter(br => !br.IsErase);