diff --git a/__test__/ALG/reg.test.ts b/__test__/ALG/reg.test.ts index 0dd1ed2d4..ddbd8c615 100644 --- a/__test__/ALG/reg.test.ts +++ b/__test__/ALG/reg.test.ts @@ -1,4 +1,4 @@ -import { Line } from "../../src/api"; +import { Line } from "../../src/DatabaseServices/Entity/Line"; import { RegionParse } from "../../src/Geometry/RegionParse"; import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; diff --git a/__test__/Board/Mirror.test.ts b/__test__/Board/Mirror.test.ts index 2b77eda03..37bfe8174 100644 --- a/__test__/Board/Mirror.test.ts +++ b/__test__/Board/Mirror.test.ts @@ -1,6 +1,6 @@ import { Vector3 } from "three"; -import { CADFiler } from "../../src/api"; import { MakeMirrorMtx } from "../../src/Common/Matrix4Utils"; +import { CADFiler } from "../../src/DatabaseServices/CADFiler"; import { XAxis } from "../../src/Geometry/GeUtils"; import { LoadBoardsFromFileData } from "../Utils/LoadEntity.util"; diff --git a/__test__/Booloperate/board_circle.test.ts b/__test__/Booloperate/board_circle.test.ts index 8e2b72327..5436735b0 100644 --- a/__test__/Booloperate/board_circle.test.ts +++ b/__test__/Booloperate/board_circle.test.ts @@ -1,6 +1,6 @@ -import { BoolOpeartionType } from "../../src/api"; import { Board } from "../../src/DatabaseServices/Entity/Board"; import { Region } from "../../src/DatabaseServices/Entity/Region"; +import { BoolOpeartionType } from "../../src/GraphicsSystem/BoolOperateUtils"; import "../Utils/jest.util"; import { LoadEntityFromFileData, LoadRegionsFromFileData } from "../Utils/LoadEntity.util"; diff --git a/__test__/Booloperate/circlebox.test.ts b/__test__/Booloperate/circlebox.test.ts index 7d82939b5..fa92c040a 100644 --- a/__test__/Booloperate/circlebox.test.ts +++ b/__test__/Booloperate/circlebox.test.ts @@ -1,4 +1,4 @@ -import { Circle } from "../../src/api"; +import { Circle } from "../../src/DatabaseServices/Entity/Circle"; import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; test('圆的包围盒', () => diff --git a/__test__/Booloperate/more_sub.test.ts b/__test__/Booloperate/more_sub.test.ts index fe8588f68..052592df9 100644 --- a/__test__/Booloperate/more_sub.test.ts +++ b/__test__/Booloperate/more_sub.test.ts @@ -1,5 +1,5 @@ -import { Polyline } from "../../src/api"; import { Contour } from "../../src/DatabaseServices/Contour"; +import { Polyline } from "../../src/DatabaseServices/Entity/Polyline"; import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; test('多个布尔错误', () => diff --git a/__test__/EdgeSealing/seal.test.ts b/__test__/EdgeSealing/seal.test.ts index 35ad50026..a28f2c1b8 100644 --- a/__test__/EdgeSealing/seal.test.ts +++ b/__test__/EdgeSealing/seal.test.ts @@ -1,5 +1,5 @@ +import { Board } from "../../src/DatabaseServices/Entity/Board"; import { GetSealedBoardContour } from "../../src/GraphicsSystem/CalcEdgeSealing"; -import { Board } from "../../src/ueapi"; import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; test('无法计算封边', () => diff --git a/__test__/FileSystem/__snapshots__/file.test.ts.snap b/__test__/FileSystem/__snapshots__/file.test.ts.snap index 318efdb93..1557881d4 100644 --- a/__test__/FileSystem/__snapshots__/file.test.ts.snap +++ b/__test__/FileSystem/__snapshots__/file.test.ts.snap @@ -1,8 +1,8 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`changev 1`] = `"[8,101,1,2,1,false,0,1,\\"\\",2,2,false,0,1,\\"Line\\",8,2,100,false,1,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,0,true,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,1,[2,3,4],[0,0,0],2,4,false,0,2,0,2,3,false,0,2,0,1,0,1,\\"CommandHistoryRecord\\",1,\\"\\",2,2,1,\\"HistorycRecord\\",1,\\"RemoveObjectData\\",1,0,\\"CreateObjectData\\",1,[\\"Line\\",8,2,100,false,1,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,0,true,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,1,[0,0,0],[0,0,0]],\\"\\",100,1,\\"ObjectAllDataHistoryRecord\\",1,1,\\"AllObjectData\\",1,[8,2,100,false,1,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,0,true,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,1,[0,0,0],[0,0,0]],\\"\\",\\"\\",100,2,5,false,0,0,1,2,6,false,0,0,1,2,7,false,0,1,\\"\\",2,8,false,0,0,2,9,false,0,0,1,2,10,false,0,1,\\"\\",2,11,false,0,0,0]"`; +exports[`changev 1`] = `"[9,101,1,2,1,false,0,1,\\"\\",2,2,false,0,1,\\"Line\\",8,2,100,false,1,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,0,true,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,1,[2,3,4],[0,0,0],2,4,false,0,2,0,2,3,false,0,2,0,1,0,1,\\"CommandHistoryRecord\\",1,\\"\\",2,2,1,\\"HistorycRecord\\",1,\\"RemoveObjectData\\",1,0,\\"CreateObjectData\\",1,[\\"Line\\",8,2,100,false,1,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,0,true,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,1,[0,0,0],[0,0,0]],\\"\\",100,1,\\"ObjectAllDataHistoryRecord\\",1,1,\\"AllObjectData\\",1,[8,2,100,false,1,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,0,true,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,1,[0,0,0],[0,0,0]],\\"\\",\\"\\",100,2,5,false,0,0,1,2,6,false,0,0,1,2,7,false,0,1,\\"\\",2,8,false,0,0,2,9,false,0,0,1,2,10,false,0,1,\\"\\",2,11,false,0,0,0,1,2,12,false,0,2,0,0]"`; -exports[`创建 修改 撤销撤销 重做重做 撤销 重做 1`] = `"[8,101,1,2,1,false,0,1,\\"\\",2,2,false,0,1,\\"Line\\",8,2,100,false,1,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,0,true,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,1,[1,2,3],[0,0,0],2,4,false,0,2,0,2,3,false,0,2,0,1,0,1,\\"CommandHistoryRecord\\",1,\\"\\",1,2,1,\\"HistorycRecord\\",1,\\"RemoveObjectData\\",1,0,\\"CreateObjectData\\",1,[\\"Line\\",8,2,100,false,1,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,0,true,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,1,[1,2,3],[0,0,0]],\\"\\",2,5,false,0,0,1,2,6,false,0,0,1,2,7,false,0,1,\\"\\",2,8,false,0,0,2,9,false,0,0,1,2,10,false,0,1,\\"\\",2,11,false,0,0,0]"`; +exports[`创建 修改 撤销撤销 重做重做 撤销 重做 1`] = `"[9,101,1,2,1,false,0,1,\\"\\",2,2,false,0,1,\\"Line\\",8,2,100,false,1,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,0,true,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,1,[1,2,3],[0,0,0],2,4,false,0,2,0,2,3,false,0,2,0,1,0,1,\\"CommandHistoryRecord\\",1,\\"\\",1,2,1,\\"HistorycRecord\\",1,\\"RemoveObjectData\\",1,0,\\"CreateObjectData\\",1,[\\"Line\\",8,2,100,false,1,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,0,true,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,1,[1,2,3],[0,0,0]],\\"\\",2,5,false,0,0,1,2,6,false,0,0,1,2,7,false,0,1,\\"\\",2,8,false,0,0,2,9,false,0,0,1,2,10,false,0,1,\\"\\",2,11,false,0,0,0,1,2,12,false,0,2,0,0]"`; exports[`创建 修改 撤销撤销 重做重做 撤销 重做 2`] = `"[\\"HistoricManage\\",1,0,1,\\"CommandHistoryRecord\\",1,\\"\\",1,2,1,\\"HistorycRecord\\",1,\\"RemoveObjectData\\",1,0,\\"CreateObjectData\\",1,[\\"Line\\",8,2,100,false,1,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,0,true,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,1,[1,2,3],[0,0,0]],\\"\\"]"`; diff --git a/__test__/FileSystem/__snapshots__/wblockClone.test.ts.snap b/__test__/FileSystem/__snapshots__/wblockClone.test.ts.snap index 874c66db2..739cdb859 100644 --- a/__test__/FileSystem/__snapshots__/wblockClone.test.ts.snap +++ b/__test__/FileSystem/__snapshots__/wblockClone.test.ts.snap @@ -2,7 +2,7 @@ exports[`wblockClone 1`] = ` Array [ - 8, + 9, 102, 1, 2, @@ -147,12 +147,20 @@ Array [ 0, 0, 0, + 1, + 2, + 12, + false, + 0, + 2, + 0, + 0, ] `; exports[`wblockClone 2`] = ` Array [ - 8, + 9, 104, 1, 2, @@ -372,12 +380,20 @@ Array [ 0, 0, 0, + 1, + 2, + 12, + false, + 0, + 2, + 0, + 0, ] `; exports[`wblockClone 3`] = ` Array [ - 8, + 9, 102, 1, 2, @@ -522,5 +538,13 @@ Array [ 0, 0, 0, + 1, + 2, + 12, + false, + 0, + 2, + 0, + 0, ] `; diff --git a/__test__/Geometry/Euler.test.ts b/__test__/Geometry/Euler.test.ts new file mode 100644 index 000000000..12924e5a5 --- /dev/null +++ b/__test__/Geometry/Euler.test.ts @@ -0,0 +1,59 @@ +import { Euler, Matrix4, Vector3 } from "three"; +import { equaln } from "../../src/Geometry/GeUtils"; + +// file.only + + +//证明 EU和旋转矩阵复合的转换 +test('Euler', () => +{ + let x = 0.5, + y = 2, + z = 1; + + let eu = new Euler(x, y, z, "ZYX"); + let mtxEu = new Matrix4().makeRotationFromEuler(eu);//Eu旋转矩阵 + + let mtxx = new Matrix4().makeRotationX(x); + let mtxy = new Matrix4().makeRotationY(y); + let mtxz = new Matrix4().makeRotationZ(z); + + + let mtxCom = mtxx.clone().premultiply(mtxy).premultiply(mtxz);//复合矩阵 z * y * x + + for (let i = 0; i < mtxEu.elements.length; i++) + expect(equaln(mtxEu.elements[i], mtxCom.elements[i])).toBeTruthy();//证明 z*y*x =Euler("ZYX") + + let p = new Vector3(1, 2, 3); + p.clone().applyMatrix4(mtxCom);//? + p.clone().applyMatrix4(mtxx).applyMatrix4(mtxy).applyMatrix4(mtxz);//? + + //证明了EU角度不可逆转 + new Euler(0, 0, 0, "ZYX").setFromRotationMatrix(mtxCom);//? + + //证明了这个不能逆转.. + let euT = new Euler(Math.PI / 2, Math.PI / 2, 0, "ZYX"); + euT.setFromRotationMatrix(new Matrix4().makeRotationFromEuler(euT));//? +}); + +//证明 mtxa * mtxb = p.apply(mtxb).apply(mtxa) +test('mtx a*b', () => +{ + let mtx1 = new Matrix4().setPosition(100, 0, 0); + let mtx2 = new Matrix4().makeRotationZ(Math.PI / 2);//旋转90度 + let p = new Vector3(100, 0, 0); + mtx1.multiply(mtx2); + p.applyMatrix4(mtx1); + p; //? +}); + + +test('mtx a*b2', () => +{ + let mtx1 = new Matrix4().setPosition(100, 0, 0); + let mtx2 = new Matrix4().makeRotationZ(Math.PI / 2); + mtx1.premultiply(mtx2); + let p = new Vector3(100, 0, 0); + p.applyMatrix4(mtx1); + p; //? +}); diff --git a/__test__/Interfere/intf.test.ts b/__test__/Interfere/intf.test.ts index e42f9e9f0..37713167f 100644 --- a/__test__/Interfere/intf.test.ts +++ b/__test__/Interfere/intf.test.ts @@ -1,5 +1,5 @@ -import { Polyline } from "../../src/api"; import { Contour } from "../../src/DatabaseServices/Contour"; +import { Polyline } from "../../src/DatabaseServices/Entity/Polyline"; import "../Utils/jest.util"; import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; diff --git a/__test__/Polyline/IntersectSelf.test.ts b/__test__/Polyline/IntersectSelf.test.ts index 0a8269e55..2911ca7b8 100644 --- a/__test__/Polyline/IntersectSelf.test.ts +++ b/__test__/Polyline/IntersectSelf.test.ts @@ -1,4 +1,4 @@ -import { Polyline } from "../../src/api"; +import { Polyline } from "../../src/DatabaseServices/Entity/Polyline"; import { LoadCurvesFromFileData } from "../Utils/LoadEntity.util"; describe("多段线自交测试", () => diff --git a/__test__/Polyline/offset4.test.ts b/__test__/Polyline/offset4.test.ts index d35b83f49..5e8a0eb6f 100644 --- a/__test__/Polyline/offset4.test.ts +++ b/__test__/Polyline/offset4.test.ts @@ -1,4 +1,4 @@ -import { Polyline } from "../../src/api"; +import { Polyline } from "../../src/DatabaseServices/Entity/Polyline"; import "../Utils/jest.util"; import { LoadCurvesFromFileData } from "../Utils/LoadEntity.util"; diff --git a/__test__/Polyline/rectOffset.test.ts b/__test__/Polyline/rectOffset.test.ts index ab5f97132..d09a7bafa 100644 --- a/__test__/Polyline/rectOffset.test.ts +++ b/__test__/Polyline/rectOffset.test.ts @@ -1,4 +1,5 @@ -import { IsRect, Polyline } from "../../src/api"; +import { IsRect } from "../../src/Common/CurveUtils"; +import { Polyline } from "../../src/DatabaseServices/Entity/Polyline"; import { RectOffset } from "../../src/GraphicsSystem/ToolPath/OptimizeToolPath"; import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; diff --git a/__test__/Room/RoomHoleDraw.test.ts b/__test__/Room/RoomHoleDraw.test.ts index 5661d817f..992f11296 100644 --- a/__test__/Room/RoomHoleDraw.test.ts +++ b/__test__/Room/RoomHoleDraw.test.ts @@ -1,13 +1,13 @@ -import { CADFiler } from "../../src/api"; import "../Utils/jest.util"; import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; LoadEntityFromFileData; //如果不延迟导入,则导致循环依赖错误 import { inflateBase64 } from "../../src/Common/inflate"; +import { CADFiler } from "../../src/DatabaseServices/CADFiler"; import { Database } from "../../src/DatabaseServices/Database"; import { RoomWallBase } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallBase"; import { RoomWallLine } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallLine"; -import { RoomWallParse } from "../../src/ueapi"; +import { RoomWallParse } from "../../src/DatabaseServices/Room/ParseService/RoomWallParse"; test('网洞绘制错误', () => { diff --git a/__test__/Room/RoomHoleUpdate.test.ts b/__test__/Room/RoomHoleUpdate.test.ts index cc5504ac7..58ce89b63 100644 --- a/__test__/Room/RoomHoleUpdate.test.ts +++ b/__test__/Room/RoomHoleUpdate.test.ts @@ -2,7 +2,6 @@ import { Vector3 } from "three"; import { RoomHolePolyline } from "../../src/DatabaseServices/Room/Entity/Wall/Hole/RoomHolePolyline"; import { RoomWallLine } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallLine"; import { RoomIHoleParseAndModify, RoomLHoleParseAndModify } from "../../src/DatabaseServices/Room/ParseService/Hole/RoomIHoleParseAndModify"; -import { RoomWallParse, UpdateRelevanceWallHole } from "../../src/ueapi"; import "../Utils/jest.util"; import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; LoadEntityFromFileData; @@ -11,6 +10,8 @@ import { CADFiler } from "../../src/DatabaseServices/CADFiler"; import { Database } from "../../src/DatabaseServices/Database"; import { RoomWallArc } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallArc"; import { RoomWallBase } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallBase"; +import { RoomWallParse } from "../../src/DatabaseServices/Room/ParseService/RoomWallParse"; +import { UpdateRelevanceWallHole } from "../../src/Reactor/RoomHoleReactor"; test('墙洞1', () => diff --git a/__test__/Utils/LoadEntity.util.ts b/__test__/Utils/LoadEntity.util.ts index 1eff9eb58..a9fecd2c7 100644 --- a/__test__/Utils/LoadEntity.util.ts +++ b/__test__/Utils/LoadEntity.util.ts @@ -6,6 +6,7 @@ import { Entity } from "../../src/DatabaseServices/Entity/Entity"; import { Polyline } from "../../src/DatabaseServices/Entity/Polyline"; import { Region } from "../../src/DatabaseServices/Entity/Region"; import { HardwareTopline } from "../../src/DatabaseServices/Hardware/HardwareTopline"; +import { RoomHolePolyline } from "../../src/DatabaseServices/Room/Entity/Wall/Hole/RoomHolePolyline"; import { RoomWallArc } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallArc"; import { RoomWallLine } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallLine"; import { TemplateStretchGripAction } from "../../src/DatabaseServices/Template/Action/TemplateStretchGripAction"; @@ -21,6 +22,7 @@ Factory(TemplateLeftRightBoardRecord); TemplateSizeBoard; TemplateStretchGripAction; RoomWallLine; +RoomHolePolyline; RoomWallArc; Text; diff --git a/__test__/VPath/vpath.test.ts b/__test__/VPath/vpath.test.ts index 68a3f6675..74fea5601 100644 --- a/__test__/VPath/vpath.test.ts +++ b/__test__/VPath/vpath.test.ts @@ -1,5 +1,6 @@ import { MathUtils } from "three"; -import { Polyline, VKnifToolPath } from "../../src/api"; +import { Polyline } from "../../src/DatabaseServices/Entity/Polyline"; +import { VKnifToolPath } from "../../src/GraphicsSystem/ToolPath/VKnifToolPath"; import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; test('V型刀测试', () => diff --git a/package.json b/package.json index a908f448f..a2735e950 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "ts-node": "^10.8.1", "tsconfig-paths": "^3.14.1", "tslib": "^2.4.0", - "typescript": "^4.8.2", + "typescript": "^4.8.3", "url-loader": "^4.1.1", "wallaby-webpack": "^3.9.16", "webpack": "^5.74.0", diff --git a/src/Add-on/DrawDim/AutoDimBrs.ts b/src/Add-on/DrawDim/AutoDimBrs.ts index da39fb936..82c2f9783 100644 --- a/src/Add-on/DrawDim/AutoDimBrs.ts +++ b/src/Add-on/DrawDim/AutoDimBrs.ts @@ -1,35 +1,23 @@ -import { Matrix4, Vector2, Vector3 } from "three"; +import { Matrix4, Vector3 } from "three"; import { app } from "../../ApplicationServices/Application"; -import { arrayRemoveDuplicateBySort, arraySortByNumber } from "../../Common/ArrayExt"; -import { AlignedDimension } from "../../DatabaseServices/Dimension/AlignedDimension"; import { Board } from "../../DatabaseServices/Entity/Board"; import { Entity } from "../../DatabaseServices/Entity/Entity"; import { HardwareCompositeEntity } from "../../DatabaseServices/Hardware/HardwareCompositeEntity"; import { TemplateRecord } from "../../DatabaseServices/Template/TemplateRecord"; import { Command } from "../../Editor/CommandMachine"; -import { JigUtils } from "../../Editor/JigUtils"; import { PromptStatus } from "../../Editor/PromptResult"; -import { equaln, equalnn } from "../../Geometry/GeUtils"; -import AutoDimBoardPanel from "../../UI/Components/AutoDimBoard"; -import { BoardModalType } from "../../UI/Components/Board/BoardModalType"; -import { IConfigOption } from "../../UI/Components/Board/UserConfig"; +import { equalv3, MoveMatrix, ZeroVec } from "../../Geometry/GeUtils"; +import { AutoDimBoardPanel } from "../../UI/Components/AutoDimBoard"; import { ModalState } from "../../UI/Components/Modal/ModalInterface"; -import { IConfigStore } from "../../UI/Store/BoardStore"; -import { userConfigStore } from "../../UI/Store/UserConfigStore"; -import { IsHandle } from "../HideSelect/HideSelectUtils"; -import { autoDimBoardTool } from "./AutoDimBrsTool"; +import { BoardType } from "../../UI/Store/BoardInterface"; +import { IsDoor, IsHandle, IsHinge } from "../HideSelect/HideSelectUtils"; +import { autoDimBrsStore } from "./AutoDimBrsStore"; +import { DimBoards } from "./DimBoards"; export class Command_AutoDimBrs implements Command { - maxThickness: number = 0; - - store: AutoDimBrsStore; async exec() { - //加入配置 - if (!this.store) this.store = new AutoDimBrsStore; - let promiseLoadConfig = userConfigStore.UpdateBoardOption(this.store.configName, BoardModalType.AutoDimBrs, this.store); - //选择板件 let enRes = await app.Editor.GetSelection({ Msg: `选择需要标注的柜体`, @@ -53,178 +41,92 @@ export class Command_AutoDimBrs implements Command if (enRes.Status === PromptStatus.Cancel) return; - await promiseLoadConfig;//等待载入配置 - - let brs = enRes.SelectSet.SelectEntityList as Board[]; - brs = this.backBoards(brs);//获取所有板件包括复合实体内的板件 - - app.Editor.ModalManage.RenderModal(AutoDimBoardPanel, { dimType: this.store.config.option.dimType }); + let brs = this.GetAllBoards(enRes.SelectSet.SelectEntityList);//获取所有板件包括复合实体内的板件 + let store = autoDimBrsStore; + app.Editor.ModalManage.RenderModeless(AutoDimBoardPanel, { store: store }, { canMinimize: false }); let res = await app.Editor.ModalManage.Wait(); if (res.Status === ModalState.Ok) { - if (res.Data.type !== this.store.config.option.dimType) - { - //上传配置 - this.store.config.option.dimType = res.Data.type; + let tool = new DimBoards; + tool.EanbleParseGroups = store.m_Option.useParseGroups === "0" ? true : false; - userConfigStore.SaveConfig(BoardModalType.AutoDimBrs, this.store, { toaster: false }); - } - autoDimBoardTool.Do(brs, res.Data.type); - } - } - /** - * 绘制标注 - * @param brs - * @param drawCS 绘制标注的坐标系 - */ - DrawDim(brs: Board[], drawCS: Matrix4, textRotation?: number, needJig: boolean = false, useMaxZ: boolean = false, isLeadOutFlipped: boolean = false) - { - let als: AlignedDimension[] = []; - let foots: number[] = []; - let minY: number = Infinity; - let minZ: number = Infinity; - let maxZ: number = -Infinity; - let drawCSInv = new Matrix4().getInverse(drawCS); - for (let br of brs) - { - let mtx = new Matrix4().multiplyMatrices(drawCSInv, br.OCS); - let box = br.BoundingBoxInOCS.applyMatrix4(mtx); - foots.push(box.min.x, box.max.x); - minY = Math.min(minY, box.min.y); - minZ = Math.min(minZ, box.min.z); - maxZ = Math.max(maxZ, box.max.z); - } + tool.EnableCabinetInsideHeight = store.m_Option.inH; + tool.EnableCabinetInsideWidth = store.m_Option.inW; - arraySortByNumber(foots); - arrayRemoveDuplicateBySort(foots, equalnn(1)); + tool.EnableDimAllSize = store.m_Option.total; + tool.EnableFrontOutDims = store.m_Option.out; - let drawY = minY - 20; - let armY = drawY - 90; - let z = useMaxZ ? maxZ : minZ; + tool.EnableFilterSmallDim = store.m_Option.noSmSize; + tool.EnableFilterAppointDimSize = store.m_Option.noAppointSize; - let maxOffsetY = 0; - //draw - for (let i = 0; i < foots.length - 1; i++) - { - let x1 = foots[i]; - let x2 = foots[i + 1]; - let alDim = new AlignedDimension( - new Vector3(x1, drawY, z), - new Vector3(x2, drawY, z), - new Vector3(x1, armY, z), - new Vector3(x2, armY, z), - ); - if (!equaln(textRotation, 0) && textRotation) - alDim.TextRotation = textRotation; - alDim.DefaultValue = { offset: new Vector2(-30, -72), isFlipped: isLeadOutFlipped }; - alDim.ApplyMatrix(drawCS); - - if (needJig) - JigUtils.Draw(alDim); - else - app.Database.ModelSpace.Append(alDim); - - if (i > 0) - { - let box = alDim.Text.BoundingBox; - //找前4个标注 如果有碰撞就提高一个身位 - let q4gAl = als.length > 4 ? als.slice(als.length - 4) : als;//前4个 - let lastAl = als[als.length - 1];//前1个标注 - for (let al of q4gAl) - { - if (al.Text.BoundingBox.intersectsBox(box)) - { - alDim.LeadOutOffsetX += lastAl.LeadOutOffsetX; - alDim.LeadOutOffsetY += lastAl.LeadOutOffsetY; - break; - } - } - if (Math.abs(alDim.LeadOutOffsetY) > maxOffsetY) - maxOffsetY = alDim.LeadOutOffsetY; - } - als.push(alDim); - } + tool.FilterSmallDimSize = store.m_Option.noShowMinSize; - //draw总长标注 需要拖拽的FastDim不需要总长 仅有一块板时不需要总长 - let drawYTotal = minY - 230 + maxOffsetY; - let armYTotal = drawYTotal - 80 + (maxOffsetY / 2); + tool.FiltereCabinetInsideSmallDim = store.m_Option.noInSize; + tool.EanbleCabinetInsideSmallDimSize = store.m_Option.noShowMinInSize; - if (!needJig && brs.length > 1) - { - let alDimTotal = new AlignedDimension( - new Vector3(foots[0], drawYTotal, z), - new Vector3(foots[foots.length - 1], drawYTotal, z), - new Vector3(foots[0], armYTotal, z), - new Vector3(foots[foots.length - 1], armYTotal, z) - ); - if (textRotation) - alDimTotal.TextRotation = textRotation; - alDimTotal.LeadOutFlipped = isLeadOutFlipped; - - alDimTotal.ApplyMatrix(drawCS); - als.push(alDimTotal); - app.Database.ModelSpace.Append(alDimTotal); - } + if (tool.EnableFilterAppointDimSize && store.m_Option.noShowAppointSizes !== '') + for (let str of store.m_Option.noShowAppointSizes.split(',')) + for (let str2 of str.split(' ')) + for (let str3 of str2.split('|')) + tool.FilterDimSizeSet.add(str3); - return als; + tool.Do(brs); + } } /** - *获取Board[]内所有板件 包括复合实体内的板件 - * - * @param {Entity[]} oldBoard - * @return {*} {Board[]} - * @memberof Command_AutoDimBrs + *获取所有板 包括复合实体内的板件 */ - backBoards(oldBoard: Entity[]): Board[] + GetAllBoards(ents: Entity[], outAllBrs = [], parentOCS: Matrix4 = undefined, parentSCS: Matrix4 = undefined): Board[] { - let newBoards: Board[] = []; - for (let en of oldBoard) + for (let en of ents) { if (en instanceof Board) - newBoards.push(en); + outAllBrs.push(en); else if (en instanceof HardwareCompositeEntity) { - if (IsHandle(en)) continue; //过滤把手五金 - let hardwareCompositeEntitys = this.backBoards(en.GetAllEntity()); - for (let hce of hardwareCompositeEntitys) - newBoards.push(hce); - } - else - continue; - } - return newBoards; - } -} + if (IsHandle(en) || IsHinge(en)) continue; //拉手 铰链 -//只是用来保存配置 -class AutoDimBrsStore implements IConfigStore -{ - configName = "默认"; - configsNames = ['默认']; - config = { - option: { - dimType: 3 - } - }; - InitOption() - { - this.config = { - option: { - dimType: 3 + if (IsDoor(en))//如果是门,就给他一个虚拟板 + { + let box = en.BoundingBoxInOCS; + let size = box.getSize(new Vector3); + let br = Board.CreateBoard(size.z, size.x, size.y, BoardType.Behind); + if (!equalv3(box.min, ZeroVec)) + br.ApplyMatrix(MoveMatrix(box.min.sub(br.BoundingBox.min))); + br.ApplyMatrix(en.OCSNoClone); + br.SpaceOCS = en.SpaceCSNoClone; + + // TestDraw(br); + + outAllBrs.push(br); + } + else if (en.HardwareOption.isSplite)//理论上应该拆解的才应该分裂 + { + let curOCS = en.OCSNoClone; + if (parentOCS) curOCS = new Matrix4().multiplyMatrices(parentOCS, curOCS); + parentSCS = parentSCS ?? en.SpaceCSNoClone; + + for (let e of en.Entitys) + { + if (e instanceof Board) + { + let newBr = e.Clone();//拷贝一个板来更新到外部 + newBr.ApplyMatrix(curOCS); + newBr.SpaceOCS = parentSCS; + outAllBrs.push(newBr); + // TestDraw(newBr); + } + else if (e instanceof HardwareCompositeEntity) + this.GetAllBoards([e], outAllBrs, curOCS, parentSCS); + } + } } - }; - } - SaveConfig() - { - return this.config; - } - UpdateOption(conf: IConfigOption) - { - Object.assign(this.config, conf); + } + return outAllBrs; } } diff --git a/src/Add-on/DrawDim/AutoDimBrsStore.ts b/src/Add-on/DrawDim/AutoDimBrsStore.ts new file mode 100644 index 000000000..a42869a85 --- /dev/null +++ b/src/Add-on/DrawDim/AutoDimBrsStore.ts @@ -0,0 +1,60 @@ +import { observable, toJS } from "mobx"; +import { DefaultAutoDimBrsOption } from "../../Editor/DefaultConfig"; +import { BoardModalType } from "../../UI/Components/Board/BoardModalType"; +import { IConfigOption } from "../../UI/Components/Board/UserConfig"; +import { IAutoDimBrsOption } from "../../UI/Store/BoardInterface"; +import { IConfigStore } from "../../UI/Store/BoardStore"; +import { userConfigStore } from "../../UI/Store/UserConfigStore"; + +export class AutoDimBrsStore implements IConfigStore +{ + @observable configName = "默认"; + @observable configsNames: string[] = []; + @observable m_Option: IAutoDimBrsOption = { ...DefaultAutoDimBrsOption }; + + InitOption() + { + Object.assign(this.m_Option, DefaultAutoDimBrsOption); + } + + InitConfigs() + { + let config: IConfigOption = {}; + config.option = toJS(this.m_Option); + let configs: { [key: string]: IConfigOption; } = {}; + configs["默认"] = config; + + return configs; + } + + SaveConfig() + { + //新的配置 + let newConfig: IConfigOption = {}; + newConfig.option = toJS(this.m_Option); + return newConfig; + }; + + UpdateOption(conf: IConfigOption) + { + if (!conf.option) + { + this.InitOption(); + let config = this.InitConfigs(); + userConfigStore.InitConfigs(config, BoardModalType.AutoDimBrs); + return; + } + + Object.assign(this.m_Option, conf.option); + } + + private static _SingleInstance: AutoDimBrsStore; + static GetInstance(): AutoDimBrsStore + { + if (this._SingleInstance) return this._SingleInstance; + this._SingleInstance = new AutoDimBrsStore; + return this._SingleInstance; + } +} + +export const autoDimBrsStore = AutoDimBrsStore.GetInstance(); diff --git a/src/Add-on/DrawDim/AutoDimBrsTool.ts b/src/Add-on/DrawDim/AutoDimBrsTool.ts index d15f57ebd..1e3351fe9 100644 --- a/src/Add-on/DrawDim/AutoDimBrsTool.ts +++ b/src/Add-on/DrawDim/AutoDimBrsTool.ts @@ -1,520 +1,12 @@ -import { Box3, Intersection, MathUtils, Matrix4, Object3D, Raycaster, Vector2, Vector3 } from "three"; -import { app } from "../../ApplicationServices/Application"; -import { arrayRemoveDuplicateBySort, arrayRemoveIf, arraySortByNumber } from "../../Common/ArrayExt"; -import { FixedNotZero } from "../../Common/Utils"; -import { AlignedDimension } from "../../DatabaseServices/Dimension/AlignedDimension"; -import { Board } from "../../DatabaseServices/Entity/Board"; -import { Curve } from "../../DatabaseServices/Entity/Curve"; -import { Polyline } from "../../DatabaseServices/Entity/Polyline"; -import { Region } from "../../DatabaseServices/Entity/Region"; -import { Raycast } from "../../Editor/PointPick"; -import { Box3Ext } from "../../Geometry/Box"; -import { CoordinateSystem } from "../../Geometry/CoordinateSystem"; -import { equaln, equalnn, isParallelTo, XAxis, YAxis, ZAxis } from "../../Geometry/GeUtils"; -import { OBB } from "../../Geometry/OBB/obb"; -import { SurroundOutlineParse } from "../../Geometry/SpaceParse/SurroundOutlineParse"; -import { BoolOpeartionType } from "../../GraphicsSystem/BoolOperateUtils"; -import { RenderType } from "../../GraphicsSystem/RenderType"; -import { BoardType } from "../../UI/Store/BoardInterface"; -import { ViewChange } from "../ViewChange"; - export enum EDimType { - Total = 0b000001, - Out = 0b000010, - InW = 0b000100, - InH = 0b001000, - NoRepeat = 0b010000, - NoSmSize = 0b100000, - All = ~(~0 << 7) -} - -interface DirPls -{ - left: Curve[]; - right: Curve[]; - top: Curve[]; - bottom: Curve[]; + Total = "total",//整体标注 + Out = "out",//柜外标注(前视图标注) + InW = "inW",//柜内宽标注 + InH = "inH",//柜内高标注 + NoRepeat = "noRepeat",//删除重复 + NoSmSize = "noSmSize",//过滤小尺寸 + NoAppointSize = "noAppointSize",//过滤指定尺寸 + NoInSize = "noInSize",//空间小于该数值时 不标注内空 } -interface DirBrs -{ - left: Board[]; - right: Board[]; - top: Board[]; - bottom: Board[]; -} - -const DEG90 = 90;//90° - - -export class AutoDimBoardsTool -{ - private qsMtx = new Matrix4().makeBasis(XAxis, ZAxis, YAxis.clone().negate()); - private min = new Vector3(); - private maxThickness = 0; - private type: EDimType; - private repeatDim = new Set(); - - Do(boardList: Board[], type: EDimType) - { - this.repeatDim.clear(); - this.type = type; - this.maxThickness = 0; - arrayRemoveIf(boardList, b => - { - this.maxThickness = Math.max(this.maxThickness, b.Thickness); - return !equaln(MathUtils.radToDeg(b.Rotation.x) % (DEG90), 0) - || !equaln(MathUtils.radToDeg(b.Rotation.y) % (DEG90), 0) - || !equaln(MathUtils.radToDeg(b.Rotation.z) % (DEG90), 0); - }); - //原数据转二维数组[[br0],[br1],[br2],[br3],[br4]...],并记录每组的Box - let brBoxs: Box3Ext[] = []; - let brGroups: Board[][] = boardList.map(item => - { - this.maxThickness = Math.max(this.maxThickness, item.Thickness); - brBoxs.push(item.BoundingBox); - return [item]; - }); - for (let i = 0; i < brGroups.length; i++) - { - for (let j = i + 1; j < brGroups.length; j++) - { - //如有合并则重新开始 - if (brBoxs[i].intersectsBox(brBoxs[j], 50)) //柜体间隙在50单位内算一个整体 - { - brGroups[i] = [...brGroups[i], ...brGroups[j]]; - brBoxs[i].union(brBoxs[j]); - brGroups.splice(j, 1); - brBoxs.splice(j, 1); - i = -1; - break; - } - } - } - - for (let i = 0; i < brGroups.length; i++) - { - this.TotalDim(brBoxs[i]); - const brs = brGroups[i]; - this.DimOut(brs); - if ((type & EDimType.InW) || (type & EDimType.InH)) - this.DimIn(brs); - } - } - private TotalDim(box: Box3) - { - let p1 = box.min; - this.min.copy(p1); - if (this.type & EDimType.Total) - { - let p2 = new Vector3(box.min.x, box.max.y, box.min.z); - - let dir = ZAxis.clone().multiplyScalar(-2); - dir.copy(new Vector3(-10)); - let dim3 = new AlignedDimension(); - dim3.FootP1 = p1.clone().add(dir); - dim3.FootP2 = p2.clone().add(dir); - - dir.multiplyScalar(20); - dim3.ArmP1 = p1.clone().add(dir); - dim3.ArmP2 = p2.clone().add(dir); - app.Database.ModelSpace.Append(dim3); - } - return; - // let dim1 = new AlignedDimension(); - // dim1.ApplyMatrix(mat); - // let dir = ZAxis.clone().multiplyScalar(-2); - // dim1.FootP1 = p1.clone().add(dir); - // dim1.FootP2 = p2.clone().add(dir);; - // dir = ZAxis.clone().multiplyScalar(-200); - // dim1.ArmP1 = p1.clone().add(dir); - // dim1.ArmP2 = p2.clone().add(dir); - - // app.Database.ModelSpace.Append(dim1); - - // let dim2 = new AlignedDimension(); - // dim2.ApplyMatrix(mat); - - // dir.copy(new Vector3(-10)); - // dim2.FootP1 = p1.clone().add(dir); - // dim2.FootP2 = p3.clone().add(dir); - - // dir.multiplyScalar(10); - - // dim2.ArmP1 = p1.clone().add(dir); - // dim2.ArmP2 = p3.clone().add(dir); - // app.Database.ModelSpace.Append(dim2); - - // dir.copy(new Vector3(10)); - // let dim3 = new AlignedDimension(); - // dim3.FootP1 = p2.clone().add(dir); - // dim3.FootP2 = p4.clone().add(dir); - - // dir.multiplyScalar(10); - // dim3.ArmP1 = p2.clone().add(dir); - // dim3.ArmP2 = p4.clone().add(dir); - - // app.Database.ModelSpace.Append(dim3); - - } - DimOut(brs: Board[]) - { - this.DrawFrontDim(brs, -Math.PI); - } - private DimIn(brs: Board[]) - { - let bsMap = new Map(); - for (let br of brs) - { - if (bsMap.has(br.BoardType)) - { - bsMap.get(br.BoardType).push(br); - } - else - { - bsMap.set(br.BoardType, [br]); - } - } - - let layers = bsMap.get(BoardType.Layer) ?? []; - let vertials = bsMap.get(BoardType.Vertical) ?? []; - - layers.sort((b1, b2) => b1.Position.z - b2.Position.z); - vertials.sort((b1, b2) => b1.Position.x - b2.Position.x); - - if (this.type & EDimType.InH) - this.DimInBy(layers, vertials, true); - - if (this.type & EDimType.InW) - this.DimInBy(vertials, layers, false); - - } - private RayPoint(p: Vector3, n: Vector3, brs: Object3D[]): Intersection - { - let ray = new Raycaster(p, n); - let intersection = Raycast(ray, brs); - return intersection; - } - private DimInBy(bs: Board[], bs2: Board[], isVertial: boolean) - { - let cache = new Set(); - let ptss: [Vector3, Vector3][] = []; - let brObjects = bs.map(b => b.GetDrawObjectFromRenderType(RenderType.Physical)); - let allObjects = [...brObjects]; - - let dir = isVertial ? ZAxis : XAxis; - let dirInv = dir.clone().negate(); - - for (let i = 0; i < bs.length; i++) - { - let br = bs[i]; - let nor = br.Normal; - let obj = brObjects.shift(); - let intPtsY: number[] = []; - const position = br.Position; - for (let j = 0; j < bs2.length; j++) - { - let br2 = bs2[j]; - if (isVertial) - { - if (br2.Position.z <= position.z) - continue; - } - else - { - if (br2.Position.x <= position.x) continue; - } - let p = new Vector3(br2.Width / 2, 0, br2.Thickness / 2).applyMatrix4(br2.OCS); - let intersection = this.RayPoint(p, dirInv, allObjects); - if (intersection && intersection.object && intersection.object === obj) - { - intPtsY.push(p.applyMatrix4(br.OCSInv).y); - } - } - intPtsY.sort((a, b) => a - b); - intPtsY.unshift(0); - intPtsY.push(br.Height); - let center = new Vector3(); - cache.clear(); - for (let j = 0; j < intPtsY.length - 1; j++) - { - let y1 = intPtsY[j]; - let y2 = intPtsY[j + 1]; - if (Math.abs(y2 - y1) < 50) continue; - center.set(br.Width / 2, (y1 + y2) / 2, br.Thickness - 1).applyMatrix4(br.OCS); - let intersection = this.RayPoint(center, dir, brObjects); - if (intersection - && intersection.object - && !cache.has(intersection.object) - && intersection.distance > 50) - { - cache.add(intersection.object); - ptss.push([center.clone().add(nor), intersection.point]); - } - } - } - - for (let ps of ptss) - { - let dim = new AlignedDimension(); - dim.ApplyMatrix(this.qsMtx); - if (!isVertial && this.type & EDimType.InH) - { - ps[0].z += 100; - ps[1].z += 100; - } - dim.FootP1 = ps[0]; - dim.FootP2 = ps[1]; - if (!this.handleRepeat(ps[0], ps[1])) - continue; - - dim.ArmP1 = ps[0].setY(this.min.y + 50); - dim.ArmP2 = ps[1].setY(this.min.y + 50); - - app.Database.ModelSpace.Append(dim); - } - } - async DrawFrontDim(brs: Board[], textRo: number) - { - //构造绘制坐标 - let spaceOcs = brs[0].SpaceOCS; - let cs = new CoordinateSystem().CopyForm(spaceOcs); - let revX = cs.XAxis.clone().negate(); - let revY = cs.YAxis.clone().negate(); - let revZ = cs.ZAxis.clone().negate(); - - let drawCS_right = new Matrix4() - .makeBasis(revZ, revX, revY) - .copyPosition(spaceOcs); - let drawCS_left = new Matrix4() - .makeBasis(cs.ZAxis, cs.XAxis, revY) - .copyPosition(spaceOcs); - let drawCS_top = new Matrix4() - .makeBasis(revX, revZ, revY) - .copyPosition(spaceOcs); - let drawCS_bottom = new Matrix4() - .makeBasis(cs.XAxis, cs.ZAxis, revY) - .copyPosition(spaceOcs); - - //获得外轮廓 - let viewDir = cs.YAxis; - let oldUCS = app.Editor.UCSMatrix; - let viewChange = new ViewChange(viewDir); - viewChange.UcsLookAt(viewDir); - let spaceParse = new SurroundOutlineParse(brs); - await spaceParse.Parse(); - let outlineParseUCS = app.Editor.UCSMatrixInv; - app.Editor.UCSMatrix = oldUCS; - - if (spaceParse.Polylines.length === 0) - return; - let pls = this.GetOutLineByBoolUnion(spaceParse.Polylines); - let outlinesBox = new Box3(); - spaceParse.Outlines.forEach((ol) => { outlinesBox.union(ol.BoundingBox); }); - pls.forEach((pl) => - { - pl.CloseMark = true; - pl.OCS = spaceParse.Outlines[0].OCS; - let moveMatrix = new Matrix4().setPosition(outlinesBox.min.clone().sub(pl.BoundingBox.min)); - pl.ApplyMatrix(moveMatrix); - }); - - //分析外轮廓上下左右并得到上下左右的板件 - let dirPls = this.JudgeOutlineDirection(pls, cs); - let dirBrs: DirBrs = { right: [], left: [], top: [], bottom: [] }; - - for (let key in dirPls) - { - for (let i = 0; i < dirPls[key].length; i++) - { - let l = dirPls[key][i] as Curve; - let xv = l.EndPoint.sub(l.StartPoint); - let zv = viewDir; - let yv = zv.clone().cross(xv); - let ocs = new Matrix4().makeBasis(xv.normalize(), yv.negate().normalize(), zv.normalize()); - ocs.setPosition(l.StartPoint); - - let cuObb = new OBB(ocs, new Vector3(l.Length, this.maxThickness || 20, this.maxThickness || 20).multiplyScalar(0.5)); - let filterFunc = (b: Board) => - { - if (!dirBrs[key].includes(b)) - if (cuObb.intersectsOBB(b.OBB, true, outlineParseUCS)) - return true; - return false; - }; - dirBrs[key].push(...brs.filter(filterFunc)); - } - } - let als: AlignedDimension[] = []; - //绘制标注 - if (dirBrs.bottom.length > 0) als.push(...this.DrawDim(dirBrs.bottom, drawCS_bottom, undefined, true, true)); - if (dirBrs.right.length > 0) als.push(...this.DrawDim(dirBrs.right, drawCS_right, textRo, true, true)); - if (dirBrs.top.length > 0) als.push(...this.DrawDim(dirBrs.top, drawCS_top, textRo, true)); - if (dirBrs.left.length > 0) als.push(...this.DrawDim(dirBrs.left, drawCS_left, textRo, true)); - - return als; - } - - /** - * 绘制标注 - * @param brs - * @param drawCS 绘制标注的坐标系 - */ - DrawDim(brs: Board[], drawCS: Matrix4, textRotation?: number, useMaxZ: boolean = false, isLeadOutFlipped: boolean = false) - { - let als: AlignedDimension[] = []; - let foots: number[] = []; - let minY: number = Infinity; - let minZ: number = Infinity; - let maxZ: number = -Infinity; - let drawCSInv = new Matrix4().getInverse(drawCS); - for (let br of brs) - { - let mtx = new Matrix4().multiplyMatrices(drawCSInv, br.OCS); - let box = br.BoundingBoxInOCS.applyMatrix4(mtx); - foots.push(box.min.x, box.max.x); - minY = Math.min(minY, box.min.y); - minZ = Math.min(minZ, box.min.z); - maxZ = Math.max(maxZ, box.max.z); - } - - arraySortByNumber(foots); - arrayRemoveDuplicateBySort(foots, equalnn(1)); - - let drawY = minY - 20; - let armY = drawY - 90; - let z = useMaxZ ? maxZ : minZ; - - - let maxOffsetY = 0; - //draw - if (this.type & EDimType.Out) - for (let i = 0; i < foots.length - 1; i++) - { - let x1 = foots[i]; - let x2 = foots[i + 1]; - if (x2 - x1 < 50 && (this.type & EDimType.NoSmSize)) continue; - let alDim = new AlignedDimension( - new Vector3(x1, drawY, z), - new Vector3(x2, drawY, z), - new Vector3(x1, armY, z), - new Vector3(x2, armY, z), - ); - if (!equaln(textRotation, 0) && textRotation) - alDim.TextRotation = textRotation; - alDim.DefaultValue = { offset: new Vector2(-30, -72), isFlipped: isLeadOutFlipped }; - alDim.ApplyMatrix(drawCS); - if (!this.handleRepeat(alDim.FootP1, alDim.FootP2)) - continue; - app.Database.ModelSpace.Append(alDim); - - if (i > 0) - { - let box = alDim.Text.BoundingBox; - //找前4个标注 如果有碰撞就提高一个身位 - let q4gAl = als.length > 4 ? als.slice(als.length - 4) : als;//前4个 - let lastAl = als[als.length - 1];//前1个标注 - for (let al of q4gAl) - { - if (al.Text.BoundingBox.intersectsBox(box)) - { - alDim.LeadOutOffsetX += lastAl.LeadOutOffsetX; - alDim.LeadOutOffsetY += lastAl.LeadOutOffsetY; - break; - } - } - if (Math.abs(alDim.LeadOutOffsetY) > maxOffsetY) - maxOffsetY = alDim.LeadOutOffsetY; - } - als.push(alDim); - } - - //draw总长标注 需要拖拽的FastDim不需要总长 仅有一块板时不需要总长 - let drawYTotal = minY + maxOffsetY; - if (this.type & EDimType.Out) - drawYTotal -= 23; - let armYTotal = drawYTotal - 80 + (maxOffsetY / 2); - - if (brs.length > 0 && (this.type & EDimType.Total)) - { - let alDimTotal = new AlignedDimension( - new Vector3(foots[0], drawYTotal, z), - new Vector3(foots[foots.length - 1], drawYTotal, z), - new Vector3(foots[0], armYTotal, z), - new Vector3(foots[foots.length - 1], armYTotal, z) - ); - if (textRotation) - alDimTotal.TextRotation = textRotation; - alDimTotal.LeadOutFlipped = isLeadOutFlipped; - alDimTotal.ApplyMatrix(drawCS); - als.push(alDimTotal); - if (this.handleRepeat(alDimTotal.FootP1, alDimTotal.FootP2)) - app.Database.ModelSpace.Append(alDimTotal); - } - - return als; - } - - /** - * 判断轮廓的上下左右 - * @param pl 轮廓(多段线) - * @param cs 参照坐标系 - * @memberof Command_AutoDimBrs - */ - JudgeOutlineDirection(pls: Polyline[], cs: CoordinateSystem): DirPls - { - let res: DirPls = { right: [], left: [], top: [], bottom: [] }; - for (let pl of pls) - { - let clockWise = pl.Area2 < 0;//true为顺时针 false为逆时针 - for (let i = 0; i < pl.EndParam; i++) - { - let cu = pl.GetCurveAtParam(i); - let derv = cu.GetFistDeriv(0).normalize(); - if (isParallelTo(derv, cs.XAxis)) - { - if (derv.dot(cs.XAxis) > 0) - clockWise ? res.top.push(cu) : res.bottom.push(cu); - else - clockWise ? res.bottom.push(cu) : res.top.push(cu); - } - else - { - if (derv.dot(cs.ZAxis) < 0) - clockWise ? res.right.push(cu) : res.left.push(cu); - else - clockWise ? res.left.push(cu) : res.right.push(cu); - } - } - } - return res; - } - - /** - * 通过轮廓并集得到最大外轮廓 - * @memberof Command_AutoDimBrs - */ - private GetOutLineByBoolUnion(pls: Polyline[]) - { - let reg = Region.CreateFromCurves([pls.shift()]); - for (let pl of pls) - reg.BooleanOper(Region.CreateFromCurves([pl]), BoolOpeartionType.Union); - - let plsRes = reg.ShapeManager.ShapeList.map(s => s.Outline.Curve) as Polyline[]; - return plsRes; - } - private handleRepeat(p0: Vector3, p1: Vector3) - { - let distance = FixedNotZero(p0.distanceTo(p1)); - if (this.repeatDim.has(distance) && (this.type & EDimType.NoRepeat)) - return false; - - this.repeatDim.add(distance); - return true; - } - -} - - -export const autoDimBoardTool = new AutoDimBoardsTool(); diff --git a/src/Add-on/DrawDim/BreakDimAligen.ts b/src/Add-on/DrawDim/BreakDimAligen.ts index 25835b77b..bb595af02 100644 --- a/src/Add-on/DrawDim/BreakDimAligen.ts +++ b/src/Add-on/DrawDim/BreakDimAligen.ts @@ -16,7 +16,7 @@ export class BreakDimAligen extends BreakDimTool protected CloneDimension(dim: AlignedDimension): AlignedDimension { let ndim = dim.Clone() as AlignedDimension; - this.m_BasePoint = dim.FootP2; + this._BasePoint = dim.FootP2; if (!this.m_line) this.m_line = new Line(dim.ArmP1, dim.ArmP2); if (!this.f_line) @@ -31,7 +31,7 @@ export class BreakDimAligen extends BreakDimTool */ protected UpdateNextPoint(p: Vector3, ndim1: AlignedDimension, ndim2: AlignedDimension) { - let last = this.CloneDimension(this.m_LastDim as AlignedDimension); + let last = this.CloneDimension(this._LastDim as AlignedDimension); let { closestPt, param } = this.m_line.GetClosestAtPoint(p, true); if (param <= 1 && param >= 0) diff --git a/src/Add-on/DrawDim/BreakDimTool.ts b/src/Add-on/DrawDim/BreakDimTool.ts index 7fa494ae2..0730dde77 100644 --- a/src/Add-on/DrawDim/BreakDimTool.ts +++ b/src/Add-on/DrawDim/BreakDimTool.ts @@ -8,21 +8,21 @@ import { PromptStatus } from "../../Editor/PromptResult"; import { Dimension } from "./Command_DimContinue"; export class BreakDimTool { - protected m_LastDim: Dimension; - protected m_BasePoint: Vector3; + protected _LastDim: Dimension; + protected _BasePoint: Vector3; //开始绘制. async StartDraw(lastDim: Dimension) { - this.m_LastDim = lastDim.Clone(); + this._LastDim = lastDim.Clone(); let oldUcs = app.Editor.UCSMatrix; - app.Editor.UCSMatrix = this.m_LastDim.OCS; - let newDim1 = this.CloneDimension(this.m_LastDim) as AlignedDimension | LineAngularDimension; - let newDim2 = this.CloneDimension(this.m_LastDim) as AlignedDimension | LineAngularDimension; + app.Editor.UCSMatrix = this._LastDim.OCS; + let newDim1 = this.CloneDimension(this._LastDim) as AlignedDimension | LineAngularDimension; + let newDim2 = this.CloneDimension(this._LastDim) as AlignedDimension | LineAngularDimension; if (newDim1 instanceof AlignedDimension && newDim2 instanceof AlignedDimension) { - newDim1.LeadOutFlipped = true; - newDim2.LeadOutFlipped = false; + newDim1.LeadInLeft = true; + newDim2.LeadInLeft = false; } lastDim.Visible = false; @@ -31,7 +31,7 @@ export class BreakDimTool let ptRes = await app.Editor.GetPoint({ AllowNone: true, - BasePoint: this.m_BasePoint, + BasePoint: this._BasePoint, Msg: "指定断点原点", Callback: p => this.UpdateNextPoint(p, newDim1, newDim2) }); @@ -84,7 +84,7 @@ export class BreakDimTool */ protected EndDraw() { - this.m_LastDim.GoodBye(); + this._LastDim.GoodBye(); } /** * 重载:停止绘制后,将调用这个函数 diff --git a/src/Add-on/DrawDim/DimBoards.ts b/src/Add-on/DrawDim/DimBoards.ts new file mode 100644 index 000000000..5a55b8e3c --- /dev/null +++ b/src/Add-on/DrawDim/DimBoards.ts @@ -0,0 +1,707 @@ +import { Box3, MathUtils, Matrix4, Vector2, Vector3 } from "three"; +import { arrayLast, arrayRemoveDuplicateBySort, arrayRemoveIf, arraySortByNumber } from "../../Common/ArrayExt"; +import { Draw } from "../../Common/Draw"; +import { AlignedDimension } from "../../DatabaseServices/Dimension/AlignedDimension"; +import { Arc } from "../../DatabaseServices/Entity/Arc"; +import { Board } from "../../DatabaseServices/Entity/Board"; +import { Curve } from "../../DatabaseServices/Entity/Curve"; +import { Entity } from "../../DatabaseServices/Entity/Entity"; +import { Polyline } from "../../DatabaseServices/Entity/Polyline"; +import { Region } from "../../DatabaseServices/Entity/Region"; +import { TemplateRecord } from "../../DatabaseServices/Template/TemplateRecord"; +import { AsVector2, equaln, equalnn, isParallelTo, isPerpendicularityTo, midPoint, ZAxis } from "../../Geometry/GeUtils"; +import { OBB } from "../../Geometry/OBB/obb"; +import { BoolOpeartionType } from "../../GraphicsSystem/BoolOperateUtils"; +import { TestDraw } from "../test/TestUtil"; + +const TEST_DRAW_CURVE = false; + + +/** + * 命令:autodimbrs 的工具类 + * 先对板进行分组,然后进行标注 + */ +export class DimBoards +{ + //#region UI设置 应该应用到这里来 + EnableDimAllSize = true;//整体标注 (全长全宽全高) + EnableFrontOutDims = true;//柜外标注 (前视图的详细外圈标注) + + EnableCabinetInsideWidth = true;//柜内宽 + EnableCabinetInsideHeight = true;//柜内高 + + EnableFilterSmallDim = true;//过滤小尺寸 + FilterSmallDimSize = 50;//过滤小尺寸的最小尺寸 + + EnableFilterAppointDimSize = true; + FilterDimSizeSet = new Set();//过滤指定尺寸列表 + + EnableFrontIgnoreBackBoard = true;//在前视图标注时忽略背板 + EanbleParseGroups = true;//如果不解析分堆,则只有一个堆 + + FiltereCabinetInsideSmallDim = true;//柜内空间小于(150)时不标注 + EanbleCabinetInsideSmallDimSize = 300; + + //#endregion + + private groups: (Board[])[] = []; + private groupsBoxs: Box3[] = [];//box in spacecs + private boardBoxMap = new Map();//box in spacecs + constructor( + ) + { + + } + + Do(brs: Board[]) + { + this.ParseBoardGroups(brs); + + this.DoDim(); + } + + + /** + * 将板件分堆(根据包围盒+模块树) + * 分组依据(1:在同一个树内,2存在交集) + */ + private ParseBoardGroups(brs: Board[]) + { + brs = brs.filter(FilterDimBoardFn); + + while (brs.length) + { + let group = [brs.pop()]; + let spaceCSInv = group[0].SpaceOCSInv; + + let box = group[0].GetBoundingBoxInMtx(spaceCSInv); + this.groupsBoxs.push(box); + + this.boardBoxMap.set(group[0], box.clone()); + + for (let i = 0; i < group.length; i++) + { + let br = group[i]; + + //模块内所有实体成一组 + let templateAllEnts: Set; + if (br.Template?.Object) + { + let template = br.Template.Object as TemplateRecord; + templateAllEnts = new Set(template.Root.AllEntitys); + } + else + templateAllEnts = new Set; + + arrayRemoveIf(brs, _br => + { + let _box = _br.GetBoundingBoxInMtx(spaceCSInv); + + if (!this.EanbleParseGroups || templateAllEnts.has(_br) || box.intersectsBox(_box, 50)) + { + box.union(_box); + group.push(_br); + this.boardBoxMap.set(_br, _box); + return true; + } + + return false; + }); + } + + this.groups.push(group); + } + } + + + + private DoDim() + { + for (let i = 0; i < this.groups.length; i++) + { + let brs = this.groups[i]; + let groupSpaceBox = this.groupsBoxs[i]; + + let spaceCS = brs[0].SpaceOCS; + + let x = new Vector3().setFromMatrixColumn(spaceCS, 0); + let y = new Vector3().setFromMatrixColumn(spaceCS, 1); + let z = new Vector3().setFromMatrixColumn(spaceCS, 2); + let spaceFrontCS = new Matrix4().makeBasis(x, z, y.negate()).copyPosition(spaceCS); + let spaceFrontCSInv = new Matrix4().getInverse(spaceFrontCS); + + const offsetYDist = 130;//标注线距离柜子的距离 + + let backReg = new Region;//背板面域 + let lcReg = new Region;//立板层板面域 + //板件轮廓 + for (let br of brs) + { + let normal = br.Normal; + let brBox = this.boardBoxMap.get(br); + if (isParallelTo(normal, y)) + { + let cu = br.ContourCurve.Clone().ApplyMatrix(br.OCS.premultiply(spaceFrontCSInv)); + cu.Z0(); + backReg.BooleanOper(Region.CreateFromCurves([cu]), BoolOpeartionType.Union); + } + else + { + let pl = new Polyline().RectangleFrom2Pt(new Vector3(brBox.min.x, brBox.min.z), new Vector3(brBox.max.x, brBox.max.z)); + lcReg.BooleanOper(Region.CreateFromCurves([pl]), BoolOpeartionType.Union); + } + } + + //并集 + let reg = backReg.Clone(); + reg.BooleanOper(lcReg.Clone(), BoolOpeartionType.Union); + + //可能有多个吗? + let pls = reg.ShapeManager.ShapeList.map(s => s.Outline.Curve) as Polyline[]; + + //#region 炸开 分析上下左右区域? + let leftCurves: Curve[] = []; + let rightCurves: Curve[] = []; + let topCurves: Curve[] = []; + let downCurves: Curve[] = []; + for (let pl of pls) + { + let dir = Math.sign(pl.Area2); + for (let c of pl.Explode()) + { + let derv = c.GetFistDeriv(0).multiplyScalar(dir); + + if (Math.abs(derv.x) > Math.abs(derv.y)) + { + if (derv.x > 0) + downCurves.push(c); + else + topCurves.push(c); + } + else + { + if (derv.y > 0) + rightCurves.push(c); + else + leftCurves.push(c); + } + } + } + //#endregion + + //所有的脚点(在内空标注时,避免重复) + let alldimkeys: (Set)[] = []; + let alldims: (AlignedDimension[])[] = []; + //#region 外圈标注(前视图) + let startXY = [groupSpaceBox.min.z, groupSpaceBox.max.z, groupSpaceBox.min.x, groupSpaceBox.max.x];//未来某天我们如果改成通用的算法,应该修改这里 + let dirCurves = [downCurves, topCurves, leftCurves, rightCurves]; + let preFoots: number[]; + for (let j = 0; j < 4; j++) + { + //解析相交的板 + let cus = dirCurves[j]; + let dirBrs: Board[] = [];//该方向上有交集的板 + for (let c of cus) + { + let _x = c.GetFistDeriv(0).normalize(); + let _z = ZAxis; + let _y = new Vector3().crossVectors(_z, _x); + let ocs = new Matrix4().makeBasis(_x, _y, _z).setPosition(c.StartPoint.setZ(-5000)) + .premultiply(spaceFrontCS); + + let cuObb = new OBB(ocs, new Vector3(c.Length, 20, 10000)); + + for (let br of brs) + { + if (this.EnableFrontIgnoreBackBoard && isParallelTo(br.Normal, y)) + continue; + + if (cuObb.intersectsOBB(br.OBB)) + dirBrs.push(br); + } + + if (TEST_DRAW_CURVE)//测试绘制轮廓曲线 + { + let cc = c.Clone(); + cc.Move({ x: 0, y: 0, z: 100 }); + cc.ApplyMatrix(spaceFrontCS); + TestDraw(cc, j + 1); + } + } + //解析相交的板end + + let dims = new Set; + alldimkeys.push(dims); + let als: AlignedDimension[] = []; + alldims.push(als); + + //解析脚点 + let xIndex = Math.floor(j / 2);//x y 0 1 + let yIndex = Math.abs(xIndex - 1); + let foots: number[] = []; + for (let br of dirBrs) + { + let brbox = this.boardBoxMap.get(br); + foots.push(brbox.min.getComponent(xIndex * 2), brbox.max.getComponent(xIndex * 2));//y->z轴 + } + + arraySortByNumber(foots); + arrayRemoveDuplicateBySort(foots, equalnn(1)); + + let preF = preFoots; + if (preFoots) + { + preFoots = undefined; + if (preF.every((v, i) => equaln(v, foots[i]))) + continue; + } + else + preFoots = foots; + + //解析脚点end + + //没有允许标注前视图的尺寸 + if (!this.EnableFrontOutDims) continue; + + //生成标注 + let start = startXY[j];//y轴开始位置 + let signDir = Math.sign((j % 2) - 0.5);//-1 1 -1 1 下上左右 + for (let k = 0; k < foots.length - 1; k++) + { + let x1 = foots[k];//假设是x 其实可能是y + let x2 = foots[k + 1]; + + if (preF && (preF.findIndex(x => (equaln(x, x2))) - preF.findIndex(x => (equaln(x, x1))) === 1)) + continue; + + //过滤小尺寸 + if (this.EnableFilterSmallDim && (x2 - x1) < this.FilterSmallDimSize) continue; + + let f1 = new Vector3().setComponent(xIndex, x1).setComponent(yIndex, start); + let f2 = new Vector3().setComponent(xIndex, x2).setComponent(yIndex, start); + + let a1 = f1.clone().setComponent(yIndex, start + signDir * offsetYDist); + let a2 = f2.clone().setComponent(yIndex, start + signDir * offsetYDist); + + let alDim = new AlignedDimension(f1, f2, a1, a2); + + alDim.ApplyMatrix(spaceFrontCS); + + als.push(alDim); + + dims.add(`${x1.toFixed(3)},${x2.toFixed(3)}`); + + //过滤尺寸集(我们还是保留这个标注 以便标注避让的时候正常工作.只是我们不再画它) + if (this.EnableFilterAppointDimSize && this.FilterDimSizeSet.has(alDim.TextString)) + alDim.Visible = false; + else + Draw(alDim); + } + //生成标注end + + //标注避让(从左往右扫略的思路) + DimBoards.DimAvoid(foots, als, j); + //标注避让end + } + //#endregion + + if (this.EnableCabinetInsideHeight || this.EnableCabinetInsideWidth) + { + //#region 内空标注 + // TestDraw(backReg.Clone(), 3); + // TestDraw(lcReg.Clone(), 1); + backReg.BooleanOper(lcReg, BoolOpeartionType.Subtract); + // TestDraw(backReg.Clone(), 1); + + for (let shape of (backReg.ShapeManager.ShapeList)) + { + let pl = shape.Outline.Curve as Polyline; + + let opls = pl.GetOffsetCurves(Math.sign(pl.Area2) * -(this.FiltereCabinetInsideSmallDim ? this.EanbleCabinetInsideSmallDimSize / 2 : 1)); + // TestDraw(pl); + // for (let oo of opls) + // TestDraw(oo, 1); + + if (opls.length !== 1 || opls[0].EndParam !== pl.EndParam) continue; + // let size = opls[0].BoundingBoxInOCS.getSize(new Vector3); + + for (let cu of pl.Explode()) + { + if (cu instanceof Arc) continue; + + let derv = cu.GetFistDeriv(0).normalize(); + + if (equaln(derv.x, 1))//down + { + if (!this.EnableCabinetInsideWidth) continue; + // if (size.y < 300) continue; + + let [p1, p2] = [cu.StartPoint, cu.EndPoint]; + + let key = `${p1.x.toFixed(3)},${p2.x.toFixed(3)}`; + if ([alldimkeys[0], alldimkeys[1]].some(dims => dims.has(key))) + continue; + + let a1 = p1.clone(); + let a2 = p2.clone(); + a1.y += 50; + a2.y += 50; + + let alDim = new AlignedDimension(p1, p2, a1, a2); + alDim.ApplyMatrix(spaceFrontCS); + Draw(alDim); + + alldimkeys[0].add(key); + } + else if (equaln(derv.x, -1))//top + { + if (!this.EnableCabinetInsideWidth) continue; + // if (size.y < 300) continue; + + let [p1, p2] = [cu.StartPoint, cu.EndPoint]; + let key = `${p2.x.toFixed(3)},${p1.x.toFixed(3)}`; + if ([alldimkeys[0], alldimkeys[1]].some(dims => dims.has(key))) + continue; + + let a1 = p1.clone(); + let a2 = p2.clone(); + a1.y -= 50; + a2.y -= 50; + + let alDim = new AlignedDimension(p1, p2, a1, a2); + alDim.ApplyMatrix(spaceFrontCS); + Draw(alDim); + + alldimkeys[1].add(key); + } + else if (equaln(derv.y, 1))//right + { + if (!this.EnableCabinetInsideHeight) continue; + //if (size.x < 300) continue; + + let [p1, p2] = [cu.StartPoint, cu.EndPoint]; + let key = `${p1.y.toFixed(3)},${p2.y.toFixed(3)}`; + if ([alldimkeys[2], alldimkeys[3]].some(dims => dims.has(key))) + continue; + + let a1 = p1.clone(); + let a2 = p2.clone(); + a1.x -= 50; + a2.x -= 50; + + let alDim = new AlignedDimension(p1, p2, a1, a2); + alDim.ApplyMatrix(spaceFrontCS); + Draw(alDim); + + alldimkeys[3].add(key); + } + else if (equaln(derv.y, -1))//left + { + if (!this.EnableCabinetInsideHeight) continue; + //if (size.x < 300) continue; + + let [p1, p2] = [cu.StartPoint, cu.EndPoint]; + let key = `${p2.y.toFixed(3)},${p1.y.toFixed(3)}`; + if ([alldimkeys[2], alldimkeys[3]].some(dims => dims.has(key))) + continue; + + let a1 = p1.clone(); + let a2 = p2.clone(); + a1.x += 50; + a2.x += 50; + + let alDim = new AlignedDimension(p1, p2, a1, a2); + alDim.ApplyMatrix(spaceFrontCS); + Draw(alDim); + + alldimkeys[3].add(key); + } + } + } + //#endregion 内空标注 + } + + //没有允许整体标注 + if (!this.EnableDimAllSize) continue; + + //#region 整体标注 + //前视图 top 1 right 3 + //top + { + let maxLead = 0; + for (let al of alldims[1]) + if (al.LeadVisible && al.NeedLead) + maxLead = Math.max(maxLead, al.LeadY); + + let f1 = new Vector3(groupSpaceBox.min.x, groupSpaceBox.max.z, 0); + let f2 = f1.clone().setX(groupSpaceBox.max.x); + let a1 = f1.clone(); + let a2 = f2.clone(); + let moveY = maxLead; + if (alldims[1].length) moveY += 90; + a1.y += offsetYDist + moveY; + a2.y += offsetYDist + moveY; + let topAl = new AlignedDimension(f1, f2, a1, a2); + topAl.ApplyMatrix(spaceFrontCS); + Draw(topAl); + + + } + //right + { + let maxLead = 0; + for (let al of alldims[3]) + if (al.LeadVisible && al.NeedLead) + maxLead = Math.max(maxLead, al.LeadY); + + let f1 = new Vector3(groupSpaceBox.max.x, groupSpaceBox.min.z, 0); + let f2 = f1.clone().setY(groupSpaceBox.max.z); + let a1 = f1.clone(); + let a2 = f2.clone(); + let moveY = maxLead; + if (alldims[3].length) moveY += 90; + a1.x += offsetYDist + moveY; + a2.x += offsetYDist + moveY; + let rightAl = new AlignedDimension(f1, f2, a1, a2); + rightAl.ApplyMatrix(spaceFrontCS); + Draw(rightAl); + } + + let fsCS = spaceCS.clone(); + if (!equaln(groupSpaceBox.min.z, 0)) + { + fsCS.elements[12] += z.x * groupSpaceBox.min.z; + fsCS.elements[13] += z.y * groupSpaceBox.min.z; + fsCS.elements[14] += z.z * groupSpaceBox.min.z; + } + //俯视图前面 + { + let f1 = new Vector3(groupSpaceBox.min.x, groupSpaceBox.max.y, 0); + let f2 = f1.clone().setX(groupSpaceBox.max.x); + let a1 = f1.clone(); + let a2 = f2.clone(); + a1.y += offsetYDist; + a2.y += offsetYDist; + let fs_front = new AlignedDimension(f1, f2, a1, a2); + fs_front.ApplyMatrix(fsCS); + Draw(fs_front); + } + + //俯视图右 + { + let f1 = new Vector3(groupSpaceBox.max.x, groupSpaceBox.min.y, 0); + let f2 = f1.clone().setY(groupSpaceBox.max.y); + let a1 = f1.clone(); + let a2 = f2.clone(); + a1.x += offsetYDist; + a2.x += offsetYDist; + let fs_right = new AlignedDimension(f1, f2, a1, a2); + fs_right.ApplyMatrix(fsCS); + Draw(fs_right); + } + + //#endregion + } + } + + /** + * 标注避让 + * @param foots + * @param als + * @param j down top left right 0 1 2 3 指定方向类型 + */ + static DimAvoid(foots: number[], als: AlignedDimension[], j: number) + { + //down top left right 0 1 2 3 + let filpLeads = [true, false, false, true]; + let midX = (arrayLast(foots) + foots[0]) * 0.5; + for (let k = 0; k < als.length; k++) + { + let al = als[k]; + if (!al.Visible || !al.NeedLead)//被过滤的实体不需要避让 + continue; + + let nextDim = als[k + 1]; + let nowDist = al.Distance; + + if (k === 0) //最左边的那个 + { + if (!nextDim || ((nextDim.Distance + nowDist) * 0.5) > ((al.TextBoxWidth + nextDim.TextBoxWidth) * 0.5)) + al.LeadVisible = false; //可以被放下 且不和别人冲突 + + else + al.SetLeadData(new Vector2(-30, 30), filpLeads[j]); + continue; + } + + let preDim = als[k - 1]; + let preDist = preDim.Distance; + + if (equaln(preDist, nowDist)) //合并引线(我们总是考虑下一个标注,所以我们可以放心的合并引线) + { + let p = new Vector3(preDim.LeadX, preDim.LeadY, 0); + p.applyMatrix4(preDim.DalUcs); //对象坐标系内 + + let dalUcs = al.DalUcs; //不可用了 + let dalUcsInv = dalUcs.getInverse(dalUcs); + + p.applyMatrix4(dalUcsInv); + + al.SetLeadData(AsVector2(p)); + + continue; + } + + if (k === als.length - 1) //如果是最后一个 + { + if (((preDist + nowDist) * 0.5) > ((al.TextBoxWidth + preDim.TextBoxWidth) * 0.5)) + al.LeadVisible = false; //可以被放下 且不和别人冲突 + + else + al.SetLeadData(new Vector2(30, 30), filpLeads[j]); + continue; + } + + + let nextDist = nextDim.Distance; + if (!preDim.NeedLead && !nextDim.NeedLead + && (((preDist + nowDist) * 0.5) > ((al.TextBoxWidth + preDim.TextBoxWidth) * 0.5)) + && (((nextDist + nowDist) * 0.5) > ((al.TextBoxWidth + nextDim.TextBoxWidth) * 0.5))) + { + al.LeadVisible = false; //可以被放下 且不和别人冲突 + continue; + } + + //#region 因为可放标注不在提供引线后,下面这个查表的代码似乎没有意义了.(左侧优先或者右侧优先? 没意义了 如果两侧都可以放的下的时候 不在需要这个优先了 因为不在飞了) + + //现在开始,我们是第一个(前面必然不需要引线,需要为后续所有需要连续的引线负责) + let xIndex = Math.floor(j / 2);//x y 0 1 + let x = midPoint(al.ArmP1, al.ArmP2).applyMatrix4(al.OCSInv).getComponent(xIndex); //中心点 + + //查表 + let list = [ + [[preDim, nextDim], [preDist, nextDist], [-30, 30]], + [[nextDim, preDim], [nextDist, preDist], [30, -30]] + ]; + if (x > midX) + list.reverse(); //右侧优先 + + if (list.some(lst => + { + return [0, 1].some(i => + { + let otherDim = lst[0][i] as AlignedDimension; + let otherDist = lst[1][i] as number; + if (otherDist > 500 && !otherDim.NeedLead) + { + if (((otherDist + nowDist) * 0.5 - 40) < ((al.TextBoxWidth + otherDim.TextBoxWidth) * 0.5)) + al.SetLeadData(new Vector2(lst[2][i] as number, 80), filpLeads[j]); + else + al.SetLeadData(new Vector2(lst[2][i] as number, 40), filpLeads[j]); + return true; + } + }); + })) + continue; + //#endregion + + //能左移的已经左移,能右移的已经右移,现在我们要对多个堆进行出手了! + let dims = [al]; + for (let l = k + 1; l < als.length; l++) + { + let dim = als[l]; + if (!dim.NeedLead) + break; + dims.push(dim); + } + + //删除重复的标注 + let dims2 = arrayRemoveDuplicateBySort(dims.concat(), (d1, d2) => d1.TextString === d2.TextString); + let midIndex = Math.floor(dims2.length / 2); + if (!preDim.NeedLead && preDist < 450) + midIndex = 0; + + const yMove = 90; + + //左侧 + let p = new Vector3(-30, 110, 0); + if (preDim.NeedLead) + p.y = preDim.LeadY + yMove; + if (filpLeads[j]) + p.x *= -1; + p.applyMatrix4(dims[0].DalUcs); //对象坐标系内 + for (let l = 0; l < midIndex; l++) + { + let dim = dims2[l]; + if (!dim.Visible) continue;//被过滤的实体不影响避让 + let dalUCS = dim.DalUcs; + let dalUcsInv = dalUCS.clone().getInverse(dalUCS); + + let leadP = p.applyMatrix4(dalUcsInv); + dim.SetLeadData(AsVector2(leadP)); + + p.y += yMove; + p.applyMatrix4(dalUCS); + } + + //右侧 + p = new Vector3(30, 110, 0); + if (dims[dims.length - 1] === als[als.length - 1]) + p.y = 30; + if (filpLeads[j]) + p.x *= -1; + p.applyMatrix4(dims[dims.length - 1].DalUcs); //对象坐标系内 + for (let l = dims2.length; l--, l >= midIndex;) + { + let dim = dims2[l]; + if (!dim.Visible) continue;//被过滤的实体不影响避让 + let dalUCS = dim.DalUcs; + let dalUcsInv = dalUCS.clone().getInverse(dalUCS); + + let leadP = p.applyMatrix4(dalUcsInv); + dim.SetLeadData(AsVector2(leadP)); + + p.y += yMove; + p.applyMatrix4(dalUCS); + } + + //合并同尺寸标注 + arrayRemoveDuplicateBySort(dims, (d1, d2) => + { + if (d1.TextString === d2.TextString) + { + let p = new Vector3(d1.LeadX, d1.LeadY, 0); + p.applyMatrix4(d1.DalUcs); //对象坐标系内 + + let dalUcs = d2.DalUcs; //不可用了 + let dalUcsInv = dalUcs.getInverse(dalUcs); + + p.applyMatrix4(dalUcsInv); + d2.SetLeadData(AsVector2(p)); + } + + return false; + }); + + k += dims.length; + } + } +} + +//过滤斜层板和被旋转的板 +export function FilterDimBoardFn(br: Board): boolean +{ + //非正常旋转 + if (!equaln(MathUtils.radToDeg(br.Rotation.x) % 90, 0) + || !equaln(MathUtils.radToDeg(br.Rotation.y) % 90, 0) + || !equaln(MathUtils.radToDeg(br.Rotation.z) % 90, 0)) + return false; + + let normal = br.Normal; + + //过滤掉斜层板? + if (!(isParallelTo(ZAxis, normal) || isPerpendicularityTo(ZAxis, normal))) + return false; + + return true; +} diff --git a/src/Add-on/DrawDim/DimContinue.ts b/src/Add-on/DrawDim/DimContinue.ts index 95d02efaf..b07ccac7b 100644 --- a/src/Add-on/DrawDim/DimContinue.ts +++ b/src/Add-on/DrawDim/DimContinue.ts @@ -1,33 +1,44 @@ import { Vector3 } from "three"; import { app } from "../../ApplicationServices/Application"; +import { UpdateDraw } from "../../Common/Status"; import { JigUtils } from "../../Editor/JigUtils"; import { PromptStatus } from "../../Editor/PromptResult"; import { Dimension } from "./Command_DimContinue"; -import { UpdateDraw } from "../../Common/Status"; -export class DimContinue +export abstract class DimContinue { - protected m_LastDim: Dimension; - protected m_BasePoint: Vector3; + protected _LastDim: Dimension; + protected _BasePoint: Vector3; //开始绘制. async StartDraw(lastDim: Dimension) { - this.m_LastDim = lastDim.Clone(); + this._LastDim = lastDim.Clone(); let oldUcs = app.Editor.UCSMatrix; - app.Editor.UCSMatrix = this.m_LastDim.OCS; + app.Editor.UCSMatrix = this._LastDim.OCS; while (true) { - let newDim = this.CloneDimension(this.m_LastDim); + let newDim = this.CloneDimension(this._LastDim); JigUtils.Draw(newDim); let ptRes = await app.Editor.GetPoint({ AllowNone: true, - BasePoint: this.m_BasePoint, + BasePoint: this._BasePoint, Msg: "指定第二个尺寸原点", - Callback: p => this.UpdateNextPoint(p, newDim) + Callback: p => + { + if (this.UpdateNextPoint(p, newDim)) + newDim.Visible = false; + else + newDim.Visible = true; + } }); if (ptRes.Status === PromptStatus.OK) { let p = ptRes.Point; - this.UpdateNextPoint(p, newDim); + if (this.UpdateNextPoint(p, newDim)) + { + JigUtils.End(); + continue;//点不被接受 + } + newDim.Visible = true; app.Database.ModelSpace.Append(newDim); if (!app.Viewer.UsePass) newDim.Text.Update(UpdateDraw.Geometry); @@ -44,30 +55,25 @@ export class DimContinue * @param dim * @returns and jig draw */ - protected CloneDimension(dim: Dimension): Dimension - { - return undefined; - } + protected abstract CloneDimension(dim: Dimension): Dimension; + /** * 重载:当用户点击的位置改变时,调用这个函数 * @param p * @param dim */ - protected UpdateNextPoint(p: Vector3, dim: Dimension) - { - } + protected abstract UpdateNextPoint(p: Vector3, dim: Dimension); + /** * 重载,当绘制时发生 * @param dim */ - protected Drawed(dim: Dimension, p: Vector3) - { - } + protected abstract Drawed(dim: Dimension, p: Vector3); /** * 重载:绘制结束后,将调用这个函数 */ protected EndDraw() { - this.m_LastDim.GoodBye(); + this._LastDim.GoodBye(); } } diff --git a/src/Add-on/DrawDim/DimContinueAligen.ts b/src/Add-on/DrawDim/DimContinueAligen.ts index 70fdd7f80..1c9c45b37 100644 --- a/src/Add-on/DrawDim/DimContinueAligen.ts +++ b/src/Add-on/DrawDim/DimContinueAligen.ts @@ -5,7 +5,7 @@ import { DimContinue } from "./DimContinue"; //对齐标注的连续标注 export class DimContinueAligen extends DimContinue { - private m_line: Line; + private _line: Line; /** * 重载: 当绘制开始时,会拷贝标注,此时你可以进行一些操作 * @param dim @@ -16,9 +16,9 @@ export class DimContinueAligen extends DimContinue let ndim = dim.Clone(); ndim.FootP1 = dim.FootP2; ndim.ArmP1 = dim.ArmP2; - this.m_BasePoint = dim.FootP2; - if (!this.m_line) - this.m_line = new Line(dim.ArmP1, dim.ArmP2); + this._BasePoint = dim.FootP2; + if (!this._line) + this._line = new Line(dim.ArmP1, dim.ArmP2); return ndim; } /** @@ -28,8 +28,8 @@ export class DimContinueAligen extends DimContinue */ protected UpdateNextPoint(p: Vector3, dim: AlignedDimension) { - let last = this.m_LastDim as AlignedDimension; - let { closestPt, param } = this.m_line.GetClosestAtPoint(p, true); + let last = this._LastDim as AlignedDimension; + let { closestPt, param } = this._line.GetClosestAtPoint(p, true); if (param > 1) { dim.FootP1 = last.FootP2; @@ -51,8 +51,8 @@ export class DimContinueAligen extends DimContinue */ protected Drawed(dim: AlignedDimension, p: Vector3) { - let last = this.m_LastDim as AlignedDimension; - let { param } = this.m_line.GetClosestAtPoint(p, true); + let last = this._LastDim as AlignedDimension; + let { param } = this._line.GetClosestAtPoint(p, true); if (param > 1) { last.FootP2 = p; @@ -63,7 +63,7 @@ export class DimContinueAligen extends DimContinue last.FootP1 = p; last.ArmP1 = dim.ArmP1; } - this.m_line.Join(new Line(dim.ArmP1, dim.ArmP2)); + this._line.Join(new Line(dim.ArmP1, dim.ArmP2)); } /** * 重载:绘制结束后,将调用这个函数 @@ -71,7 +71,7 @@ export class DimContinueAligen extends DimContinue protected EndDraw() { super.EndDraw(); - this.m_line.GoodBye(); - this.m_line = undefined; + this._line.GoodBye(); + this._line = undefined; } } diff --git a/src/Add-on/DrawDim/DimContinueLineAngular.ts b/src/Add-on/DrawDim/DimContinueLineAngular.ts index f9c96d1ed..a39940129 100644 --- a/src/Add-on/DrawDim/DimContinueLineAngular.ts +++ b/src/Add-on/DrawDim/DimContinueLineAngular.ts @@ -1,8 +1,8 @@ import { Vector3 } from "three"; -import { Arc } from "../../DatabaseServices/Entity/Arc"; import { LineAngularDimension } from "../../DatabaseServices/Dimension/2LineAngularDimension"; +import { Arc } from "../../DatabaseServices/Entity/Arc"; import { Line } from "../../DatabaseServices/Entity/Line"; -import { equalv3 } from "../../Geometry/GeUtils"; +import { equaln, equalv3 } from "../../Geometry/GeUtils"; import { DimContinue } from "./DimContinue"; //2直线角度标注的连续标注 export class DimContinueLineAngular extends DimContinue @@ -32,8 +32,8 @@ export class DimContinueLineAngular extends DimContinue */ protected Drawed(dim: LineAngularDimension, p: Vector3) { - this.m_LastDim.GoodBye(); - this.m_LastDim = dim.Clone(); + this._LastDim.GoodBye(); + this._LastDim = dim.Clone(); } /** * 重载:当用户点击的位置改变时,调用这个函数 @@ -45,6 +45,8 @@ export class DimContinueLineAngular extends DimContinue let cp = this._arc.GetClosestPointTo(p, true); let newL1Ep: Vector3; let param = this._arc.GetParamAtPoint(cp); + if (equaln(param, 0) || equaln(param, 1) || equalv3(p, this._arc.Center)) return true; + let arcSpOnL1 = !isNaN(new Line(this._l1Sp, this._l1Ep).GetParamAtPoint(this._arc.StartPoint)); if (param > 0.5) { @@ -56,8 +58,6 @@ export class DimContinueLineAngular extends DimContinue this._narc.StartAngle = this._arc.GetAngleAtParam(1); this._narc.EndAngle = this._arc.GetAngleAtParam(param); } - else if (param === 1) - return; else { this._narc.StartAngle = this._arc.GetAngleAtParam(param); @@ -80,8 +80,7 @@ export class DimContinueLineAngular extends DimContinue this._narc.EndAngle = this._arc.GetAngleAtParam(param); } } - if (equalv3(p, this._arc.Center)) - return; + dim.UpdateDimData(this._arc.Center, newL1Ep, this._arc.Center, p, this._narc.GetPointAtParam(0.5)); } /** diff --git a/src/Add-on/DrawDim/Draw2LineAngularDim.ts b/src/Add-on/DrawDim/Draw2LineAngularDim.ts index 8aeb7a021..63c5b8260 100644 --- a/src/Add-on/DrawDim/Draw2LineAngularDim.ts +++ b/src/Add-on/DrawDim/Draw2LineAngularDim.ts @@ -3,6 +3,7 @@ import { app } from "../../ApplicationServices/Application"; import { UpdateDraw } from "../../Common/Status"; import { LineAngularDimension } from "../../DatabaseServices/Dimension/2LineAngularDimension"; import { Arc } from "../../DatabaseServices/Entity/Arc"; +import { Board } from "../../DatabaseServices/Entity/Board"; import { Circle } from "../../DatabaseServices/Entity/Circle"; import { Curve } from "../../DatabaseServices/Entity/Curve"; import { Line } from "../../DatabaseServices/Entity/Line"; @@ -10,7 +11,6 @@ import { Polyline } from "../../DatabaseServices/Entity/Polyline"; import { JigUtils } from "../../Editor/JigUtils"; import { PromptStatus } from "../../Editor/PromptResult"; import { isParallelTo } from "../../Geometry/GeUtils"; -import { Board } from "../../ueapi"; import { ContinueDrawDimension } from "./Command_DimContinue"; export class Command_Draw2LineAngularDim diff --git a/src/Add-on/DrawDim/DrawAlignedDimension.ts b/src/Add-on/DrawDim/DrawAlignedDimension.ts index 8949ead3c..22d692a5b 100644 --- a/src/Add-on/DrawDim/DrawAlignedDimension.ts +++ b/src/Add-on/DrawDim/DrawAlignedDimension.ts @@ -1,4 +1,4 @@ -import { Matrix4, Vector3 } from 'three'; +import { Vector3 } from 'three'; import { app } from '../../ApplicationServices/Application'; import { AlignedDimension } from '../../DatabaseServices/Dimension/AlignedDimension'; import { LinearDimension } from '../../DatabaseServices/Dimension/LinearDimension'; @@ -20,20 +20,38 @@ export enum DimensionType Linear = 1 //线性标注 } +//dli export class DrawAlignedDimension implements Command { protected DimType = DimensionType.Align; + protected _UseFirstPointUCS = true; async exec() { - let ptRes = await app.Editor.GetPoint({ Msg: "请指定第一条尺寸线原点:", AllowNone: true }); + while (true) + { + let ptRes = await app.Editor.GetPoint({ + Msg: "请指定第一条尺寸线原点:", + AllowNone: true, + KeyWordList: [ + { msg: this._UseFirstPointUCS ? "使用UCS坐标系标注" : "使用第一点所在平面标注", key: "S" } + ] + }); + + if (ptRes.Status === PromptStatus.String) + { + this._UseFirstPointUCS = !this._UseFirstPointUCS; + continue; + } - if (ptRes.Status === PromptStatus.OK) - await this.SelectPointDim(ptRes.Point); - if (ptRes.Status === PromptStatus.None) - await this.PickUpDim(); + if (ptRes.Status === PromptStatus.OK) + await this.GetPointDli(ptRes.Point); + if (ptRes.Status === PromptStatus.None) + await this.GetEntityDli(); + break; + } } - protected async SelectPointDim(footPt1: Vector3) + protected async GetPointDli(footPt1: Vector3) { let ptRes = await app.Editor.GetPoint({ Msg: "请输入第二条尺寸线原点:", @@ -44,14 +62,11 @@ export class DrawAlignedDimension implements Command return; let footPt2 = ptRes.Point; - let ucs = app.Editor.UCSMatrix.clone().setPosition(footPt1); - let ucsInv = new Matrix4().getInverse(ucs); - footPt2.applyMatrix4(ucsInv).setZ(0).applyMatrix4(ucs); await this.BuildDim(footPt1, footPt2); } //选择对象标注 - private async PickUpDim() + private async GetEntityDli() { let enRes = await app.Editor.GetEntity({ Msg: "选择对象", @@ -104,7 +119,10 @@ export class DrawAlignedDimension implements Command else alDim = new LinearDimension(); - alDim.ApplyMatrix(app.Editor.UCSMatrix); + let ocs = app.Editor.UCSMatrix; + if (this._UseFirstPointUCS) + ocs.setPosition(footPt1); + alDim.ApplyMatrix(ocs); alDim.FootP1 = footPt1; alDim.ArmP1 = footPt1; @@ -121,9 +139,6 @@ export class DrawAlignedDimension implements Command if (ptRes.Status == PromptStatus.OK) { alDim.TextPosition = ptRes.Point; - //抬高footers - alDim.RaiseFooters(FootersRaiseValue); - app.Database.ModelSpace.Append(alDim); await ContinueDrawDimension(alDim); } diff --git a/src/Add-on/DrawDim/FastDim.ts b/src/Add-on/DrawDim/FastDim.ts index bafe7bc1b..a2f344853 100644 --- a/src/Add-on/DrawDim/FastDim.ts +++ b/src/Add-on/DrawDim/FastDim.ts @@ -1,13 +1,14 @@ -import { Box3, MathUtils, Matrix4, Vector3 } from "three"; +import { Box3, Vector3 } from "three"; import { app } from "../../ApplicationServices/Application"; +import { arrayRemoveDuplicateBySort, arraySortByNumber } from "../../Common/ArrayExt"; +import { Draw } from "../../Common/Draw"; import { AlignedDimension } from "../../DatabaseServices/Dimension/AlignedDimension"; import { Board } from "../../DatabaseServices/Entity/Board"; import { Command } from "../../Editor/CommandMachine"; import { JigUtils } from "../../Editor/JigUtils"; -import { PromptStatus } from "../../Editor/PromptResult"; -import { CoordinateSystem } from "../../Geometry/CoordinateSystem"; -import { equaln } from "../../Geometry/GeUtils"; -import { Command_AutoDimBrs } from "./AutoDimBrs"; +import { PromptSsgetResult, PromptStatus } from "../../Editor/PromptResult"; +import { equalnn } from "../../Geometry/GeUtils"; +import { DimBoards, FilterDimBoardFn } from "./DimBoards"; enum Direction { @@ -18,28 +19,32 @@ enum Direction top = 8 } -const DEG90 = 90;//90° export class Command_FastDimBrs implements Command { async exec() { - //选择板件 - let enRes = await app.Editor.GetSelection({ - UseSelect: true, - Msg: "选择需要标注的板件", - Filter: { filterTypes: [Board] }, - }); + let enRes: PromptSsgetResult; + let dimAll = false; + while (true) + { + enRes = await app.Editor.GetSelection({ + UseSelect: true, + Msg: "选择需要标注的板件", + KeyWordList: [{ msg: dimAll ? "关闭整体标注" : "整体标注", key: "S" }], + Filter: { filterTypes: [Board] }, + }); + if (enRes.Status === PromptStatus.Keyword) + dimAll = !dimAll; + else + break; + } if (enRes.Status === PromptStatus.Cancel) return; let brs = enRes.SelectSet.SelectEntityList as Board[]; //排除旋转角度非90度倍数的板件 - brs = brs.filter(b => ( - equaln(MathUtils.radToDeg(b.Rotation.x) % (DEG90), 0) - && equaln(MathUtils.radToDeg(b.Rotation.y) % (DEG90), 0) - && equaln(MathUtils.radToDeg(b.Rotation.z) % (DEG90), 0) - )); + brs = brs.filter(FilterDimBoardFn); if (brs.length === 0) { @@ -49,91 +54,165 @@ export class Command_FastDimBrs implements Command app.Editor.Prompt(`可标注板件数: ${brs.length}`); - let autoDim = new Command_AutoDimBrs(); + let tool = new FastDimTool(brs); + tool.enableDimAll = dimAll; - let ucs = app.Editor.UCSMatrix; - let ucsInv = app.Editor.UCSMatrixInv; - let ucsDir = new Vector3().setFromMatrixColumn(app.Editor.UCSMatrix, 2); - let isFS = ucsDir.equals(new Vector3(-0, -0, 1)); + let oldState = Direction.left; - let brBoxs = brs.map(br => + const CreateDims = (p: Vector3) => { - return br.BoundingBoxInOCS.applyMatrix4(ucsInv.clone().multiply(br.OCS)); - }); - let boxAll = new Box3(); - for (let box of brBoxs) - boxAll.union(box); + let pUcs = p.clone().applyMatrix4(tool.ucsInv); + let state = 0; + + if (pUcs.x > tool.allBox.max.x) + state |= Direction.right; + if (pUcs.y > tool.allBox.max.y) + state |= Direction.top; + if (pUcs.y < tool.allBox.min.y) + state |= Direction.down; + if (pUcs.x < tool.allBox.min.x) + state |= Direction.left; + + if (oldState & state) + state = oldState; + else if (state === 0) + state = oldState; + + JigUtils.Destroy(); + let als: AlignedDimension[] = []; + for (let dir of [Direction.down, Direction.top, Direction.left, Direction.right]) + if (dir & state) + { + als = tool.CreateDims(dir, pUcs); + oldState = dir; + break; + } - let cs = new CoordinateSystem().CopyForm(ucs); + return als; + }; - let state = Direction.None; + while (true) + { + let ptRes = await app.Editor.GetPoint({ + Msg: "指定尺寸线位置:", + KeyWordList: [{ msg: tool.enableDimAll ? "关闭整体标注" : "整体标注", key: "S" }], + Callback: p => + { + let als = CreateDims(p); + for (let al of als) + JigUtils.Draw(al); + } + }); - let als: AlignedDimension[] = []; - let ptRes = await app.Editor.GetPoint({ - Msg: "指定尺寸线位置:", - Callback: p => + if (ptRes.Status === PromptStatus.Keyword) + tool.enableDimAll = !tool.enableDimAll; + else { - let pUcs = p.clone().applyMatrix4(ucsInv); - let drawCS = new Matrix4(); - let textRo = 0; + if (ptRes.Status === PromptStatus.OK) + { + let als = CreateDims(ptRes.Point); + for (let al of als) + Draw(al); + } + return; + } + } - let oldState = state; - state = 0; + } +} - if (pUcs.x > boxAll.max.x) - state |= Direction.right; - if (pUcs.y > boxAll.max.y) - state |= Direction.top; +export class FastDimTool +{ - if (pUcs.y < boxAll.min.y) - state |= Direction.down; - if (pUcs.x < boxAll.min.x) - state |= Direction.left; + //这个UCS会比适当的修改,保证绘图平面和选择的板在一个平面内 + ucs = app.Editor.UCSMatrix; + ucsInv = app.Editor.UCSMatrixInv; + allBox = new Box3; + footss: [number[], number[]] = [[], []]; + enableDimAll = true;//全长标注 + constructor( + public brs: Board[] + ) + { + //x,y + for (let br of brs) + { + let box = br.GetBoundingBoxInMtx(this.ucsInv); - if (oldState & state) - state = oldState; - else if (state === 0) - state = oldState; + for (let i = 0; i < 2; i++) + this.footss[i].push(box.min.getComponent(i), box.max.getComponent(i)); - if (state & Direction.left) - { - textRo = Math.PI; - drawCS.makeBasis(cs.YAxis.clone().negate(), cs.XAxis, cs.ZAxis); - } - else if (state & Direction.right) - { - textRo = Math.PI; - drawCS.makeBasis(cs.YAxis, cs.XAxis.clone().negate(), cs.ZAxis); - } - else if (state & Direction.down) - { - textRo = 0; - drawCS.copy(ucs); - } - else if (state & Direction.top) - { - textRo = Math.PI; - drawCS.makeBasis(cs.XAxis.clone().negate(), cs.YAxis.clone().negate(), cs.ZAxis); - } + this.allBox.union(box); + } - JigUtils.Destroy(); + //绘图平面对齐 + let z = new Vector3().setFromMatrixColumn(this.ucs, 2); + this.ucs.elements[12] += z.x * this.allBox.max.z; + this.ucs.elements[13] += z.y * this.allBox.max.z; + this.ucs.elements[14] += z.z * this.allBox.max.z; - als = autoDim.DrawDim(brs, drawCS, textRo, true, !isFS); + //排序和去重 + for (let i = 0; i < 2; i++) + { + arraySortByNumber(this.footss[i]); + arrayRemoveDuplicateBySort(this.footss[i], equalnn(3)); + } + } - for (let aldim of als) - { - aldim.TextPosition = p; - } - } - }); - if (ptRes.Status === PromptStatus.OK) + CreateDims(dir: Direction, pUcs: Vector3) + { + //左右上下0 1 2 3 + let index = [Direction.down, Direction.top, Direction.left, Direction.right].indexOf(dir); + + let xIndex = Math.floor(index / 2); + let yIndex = Math.abs(1 - xIndex); + + let armY = pUcs.getComponent(yIndex); + let sign = Math.sign(index % 2 - 0.5); + let footY = armY - (sign * 130);//y offset(move) dist = 130 + + let foots = this.footss[xIndex]; + + let als: AlignedDimension[] = []; + + for (let i = 0; i < foots.length - 1; i++) { - for (let aldim of als) - { - aldim.TextPosition = ptRes.Point; - app.Database.ModelSpace.Append(aldim); - } + let x1 = foots[i];//假设是x 其实可能是y + let x2 = foots[i + 1]; + let f1 = new Vector3().setComponent(xIndex, x1).setComponent(yIndex, footY); + let f2 = new Vector3().setComponent(xIndex, x2).setComponent(yIndex, footY); + + let a1 = f1.clone().setComponent(yIndex, armY); + let a2 = f2.clone().setComponent(yIndex, armY); + + let alDim = new AlignedDimension(f1, f2, a1, a2); + alDim.ApplyMatrix(this.ucs); + als.push(alDim); + } + + DimBoards.DimAvoid(foots, als, index);//标注避让 + + //标注全长 + if (this.enableDimAll && foots.length > 2) + { + let maxLead = 0; + for (let al of als) + if (al.LeadVisible && al.NeedLead) + maxLead = Math.max(maxLead, al.LeadY); + + let moveY = (maxLead + 90) * sign; + + let f1 = new Vector3().setComponent(xIndex, foots[0]).setComponent(yIndex, footY + moveY); + let f2 = new Vector3().setComponent(xIndex, foots[foots.length - 1]).setComponent(yIndex, footY + moveY); + + let a1 = f1.clone().setComponent(yIndex, armY + moveY); + let a2 = f2.clone().setComponent(yIndex, armY + moveY); + + let alDim = new AlignedDimension(f1, f2, a1, a2); + alDim.ApplyMatrix(this.ucs); + als.push(alDim); } + return als; } } diff --git a/src/Add-on/ExportData.tsx b/src/Add-on/ExportData.tsx index ebb448c9a..bc8fd00f1 100644 --- a/src/Add-on/ExportData.tsx +++ b/src/Add-on/ExportData.tsx @@ -3,7 +3,6 @@ import * as React from 'react'; import { MathUtils, Vector3 } from 'three'; import { OBJExporter } from 'three/examples/jsm/exporters/OBJExporter'; import { begin } from 'xaop'; -import { CADFiler } from '../api'; import { app } from "../ApplicationServices/Application"; import { IsDev } from '../Common/Deving'; import { CURRENT_HOST, RenderUrl } from "../Common/HostUrl"; @@ -17,6 +16,7 @@ import { CylinderHole } from '../DatabaseServices/3DSolid/CylinderHole'; import { ExtrudeHole } from '../DatabaseServices/3DSolid/ExtrudeHole'; import { RevolveSolid } from '../DatabaseServices/3DSolid/RevolveSolid'; import { SweepSolid } from "../DatabaseServices/3DSolid/SweepSolid"; +import { CADFiler } from '../DatabaseServices/CADFiler'; import { Arc } from '../DatabaseServices/Entity/Arc'; import { Board } from "../DatabaseServices/Entity/Board"; import { Circle } from "../DatabaseServices/Entity/Circle"; @@ -39,6 +39,7 @@ import { PhysicalMaterialRecord } from "../DatabaseServices/PhysicalMaterialReco import { RoomFlatBase } from '../DatabaseServices/Room/Entity/Flat/RoomFlatBase'; import { RoomHolePolyline } from '../DatabaseServices/Room/Entity/Wall/Hole/RoomHolePolyline'; import { CURVE_FACE_TYPE_KEY, RoomWallBase } from '../DatabaseServices/Room/Entity/Wall/RoomWallBase'; +import { RoomWallParse } from '../DatabaseServices/Room/ParseService/RoomWallParse'; import { Shape } from "../DatabaseServices/Shape"; import { TextureTableRecord } from "../DatabaseServices/Texture"; import { Command } from "../Editor/CommandMachine"; @@ -47,7 +48,6 @@ import { IdentityMtx4 } from '../Geometry/GeUtils'; import { Orbit } from '../Geometry/Orbit'; import { RenderType } from '../GraphicsSystem/RenderType'; import { arrayPushArray } from '../Nest/Common/ArrayExt'; -import { RoomWallParse } from '../ueapi'; import { GetCompoentObjectIdString } from '../UI/Components/ComponentObjectId'; import { ModalFooter, ModalHeader } from '../UI/Components/Modal/ModalContainer'; import { ModalPosition } from '../UI/Components/Modal/ModalInterface'; diff --git a/src/Add-on/Fix/Fix2DPath.ts b/src/Add-on/Fix/Fix2DPath.ts index f33c04957..f501fda09 100644 --- a/src/Add-on/Fix/Fix2DPath.ts +++ b/src/Add-on/Fix/Fix2DPath.ts @@ -1,8 +1,8 @@ import { app } from "../../ApplicationServices/Application"; import { Board } from "../../DatabaseServices/Entity/Board"; +import { Polyline } from "../../DatabaseServices/Entity/Polyline"; import { Command } from "../../Editor/CommandMachine"; import { PromptStatus } from "../../Editor/PromptResult"; -import { Polyline } from "../../ueapi"; export class Command_Fix2DPath implements Command { diff --git a/src/Add-on/KJL/Import/KJLUtils.ts b/src/Add-on/KJL/Import/KJLUtils.ts index ab15f6c40..e840d3e5c 100644 --- a/src/Add-on/KJL/Import/KJLUtils.ts +++ b/src/Add-on/KJL/Import/KJLUtils.ts @@ -1,9 +1,9 @@ import { EBoardKeyList } from "../../../Common/BoardKeyList"; import { IsMeshMaterialEntity } from "../../../Common/IsMeshMaterialEntity"; +import { Board } from "../../../DatabaseServices/Entity/Board"; import { Entity } from "../../../DatabaseServices/Entity/Entity"; import { HardwareCompositeEntity } from "../../../DatabaseServices/Hardware/HardwareCompositeEntity"; import { PhysicalMaterialRecord } from "../../../DatabaseServices/PhysicalMaterialRecord"; -import { Board } from "../../../ueapi"; import { ApplyGoodInfo } from "../../../UI/Components/ApplyGoodInfo"; import { KJL_Parameter, KJL_ParamModel_Hardware } from "./KJLInterface"; diff --git a/src/Add-on/Room/Curve2Wall.ts b/src/Add-on/Room/Curve2Wall.ts index 26e425b8b..7eeddf29d 100644 --- a/src/Add-on/Room/Curve2Wall.ts +++ b/src/Add-on/Room/Curve2Wall.ts @@ -1,7 +1,8 @@ -import { Arc, Polyline } from "../../api"; import { app } from "../../ApplicationServices/Application"; import { Draw } from "../../Common/Draw"; +import { Arc } from "../../DatabaseServices/Entity/Arc"; import { Line } from "../../DatabaseServices/Entity/Line"; +import { Polyline } from "../../DatabaseServices/Entity/Polyline"; import { RoomWallArc } from "../../DatabaseServices/Room/Entity/Wall/RoomWallArc"; import { RoomWallLine } from "../../DatabaseServices/Room/Entity/Wall/RoomWallLine"; import { Command } from "../../Editor/CommandMachine"; diff --git a/src/Add-on/SuperCopy.ts b/src/Add-on/SuperCopy.ts index 02822606e..7bd8b30c3 100644 --- a/src/Add-on/SuperCopy.ts +++ b/src/Add-on/SuperCopy.ts @@ -1,9 +1,9 @@ import { Intent } from "@blueprintjs/core"; -import { CADFiler } from "../api"; import { app } from "../ApplicationServices/Application"; import { deflate } from "../Common/SerializeMaterial"; import { DuplicateRecordCloning } from "../Common/Status"; import { copyTextToClipboard } from "../Common/Utils"; +import { CADFiler } from "../DatabaseServices/CADFiler"; import { Database } from "../DatabaseServices/Database"; import { Entity } from "../DatabaseServices/Entity/Entity"; import { IdMaping } from "../DatabaseServices/IdMaping"; diff --git a/src/Add-on/TestFb.ts b/src/Add-on/TestFb.ts index 35b52eb23..1c8398d52 100644 --- a/src/Add-on/TestFb.ts +++ b/src/Add-on/TestFb.ts @@ -1,10 +1,10 @@ import { Vector3 } from "three"; -import { Polyline } from "../api"; import { app } from "../ApplicationServices/Application"; import { Intent } from "../Common/Toaster"; import { FixedNotZero } from "../Common/Utils"; import { Board } from "../DatabaseServices/Entity/Board"; import { Curve } from "../DatabaseServices/Entity/Curve"; +import { Polyline } from "../DatabaseServices/Entity/Polyline"; import { Text, TextAligen } from "../DatabaseServices/Text/Text"; import { Command } from "../Editor/CommandMachine"; import { PromptStatus } from "../Editor/PromptResult"; diff --git a/src/Add-on/testEntity/test.ts b/src/Add-on/testEntity/test.ts index 3e8e5c326..c10ac9934 100644 --- a/src/Add-on/testEntity/test.ts +++ b/src/Add-on/testEntity/test.ts @@ -7,6 +7,5 @@ export class Test implements Command { async exec() { - } } diff --git a/src/ApplicationServices/HostApplicationServices.ts b/src/ApplicationServices/HostApplicationServices.ts index f559a59fa..704149f44 100644 --- a/src/ApplicationServices/HostApplicationServices.ts +++ b/src/ApplicationServices/HostApplicationServices.ts @@ -1,5 +1,6 @@ import { MeshBasicMaterial, MeshStandardMaterial, Texture } from 'three'; import { FractionDigitsType } from '../Common/SystemEnum'; +import { ObjectId } from '../DatabaseServices/ObjectId'; import { ICursorConfig } from '../Editor/ICursorConfig'; import { RenderType } from '../GraphicsSystem/RenderType'; import { DrillingOption } from '../UI/Store/drillInterface'; @@ -7,6 +8,7 @@ import { DrillingOption } from '../UI/Store/drillInterface'; export class IHostApplicationServices { DefaultMeshMaterial?: MeshBasicMaterial | MeshStandardMaterial; + CurrentDimStyle: ObjectId; @ProxyValue isShowLightShadow: boolean = true;//灯光阴影 (除太阳光外) ShowHistoryLog: boolean = true; diff --git a/src/Common/CommandNames.ts b/src/Common/CommandNames.ts index 86016fa32..bfc5c32de 100644 --- a/src/Common/CommandNames.ts +++ b/src/Common/CommandNames.ts @@ -117,7 +117,7 @@ export enum CommandNames AddPtOnBoard = "ADDPTONBOARD", DeletePtOnBoard = "DELETEPTONBOARD", BoardFindModify = "BOARDFINDMODIFY", - LookOverBoardInfos = "LOOKOVERBOARDINFOS", + LookOverBoardInfos = "LOOKOVERBOARDINFOS",//BBS BoardBatchCurtail = "BOARDBATCHCURTAIL", AutoDimBrs = "AUTODIMBRS", FastDimBrs = "FASTDIMBRS", diff --git a/src/DatabaseServices/BlockTable.ts b/src/DatabaseServices/BlockTable.ts index a43e8ce8a..ca2b169d7 100644 --- a/src/DatabaseServices/BlockTable.ts +++ b/src/DatabaseServices/BlockTable.ts @@ -1,5 +1,5 @@ -import { SymbolTable } from "./SymbolTable"; import { Factory } from "./CADFactory"; +import { SymbolTable } from "./SymbolTable"; @Factory export class BlockTable extends SymbolTable diff --git a/src/DatabaseServices/BlockTableRecord.ts b/src/DatabaseServices/BlockTableRecord.ts index 7c3698382..fcabae09d 100644 --- a/src/DatabaseServices/BlockTableRecord.ts +++ b/src/DatabaseServices/BlockTableRecord.ts @@ -3,6 +3,7 @@ import { Status } from '../Common/Status'; import { Factory } from './CADFactory'; import { CADFiler } from './CADFiler'; import { Database } from './Database'; +import { Dimension } from './Dimension/Dimension'; import { Entity } from './Entity/Entity'; import { ObjectCollection } from './ObjectCollection'; import { SymbolTableRecord } from './SymbolTableRecord'; @@ -24,10 +25,9 @@ export class BlockTableRecord extends SymbolTableRecord return this; } - get Entitys() - { - return this.EntityCol.Objects; - } + get Entitys() { return this.EntityCol.Objects; } + + /** 提供通用的Add方法(以便在WblockClone时能统一调用.Add) */ Add(obj: Entity, isCheckObjectCleanly = true): Status { this.Append(obj, isCheckObjectCleanly); @@ -36,13 +36,16 @@ export class BlockTableRecord extends SymbolTableRecord Append(entity: Entity, isCheckObjectCleanly = true) { + if (this._db) + if (entity instanceof Dimension && !entity.DimStyle) + entity.DimStyle = this._db.DimStyleTable.Current;//设置默认的标注样式 + this.EntityCol.Append(entity, isCheckObjectCleanly); entity.Owner = this.objectId; } - AppendEvent(entity: Entity) - { - } + /**添加实体实现(通过转发) */ + AppendEvent(entity: Entity) { } Remove(entity: Entity) { diff --git a/src/DatabaseServices/Database.ts b/src/DatabaseServices/Database.ts index 3a1ab78ee..423fc72ea 100644 --- a/src/DatabaseServices/Database.ts +++ b/src/DatabaseServices/Database.ts @@ -7,6 +7,8 @@ import { CADFiler } from './CADFiler'; import { CADObject } from './CADObject'; import { CameraSnapshootRecord } from './CameraSnapshoot/CameraSnapshootRecord'; import { DeepCloneFiler } from './DeepCloneFiler'; +import { DimStyleRecord } from './DimStyle/DimStyleRecord'; +import { DimStyleTable } from './DimStyle/DimStyleTable'; import { Entity } from './Entity/Entity'; import { GroupTable } from './GroupTable'; import { HistoricManage } from './HistoricManage'; @@ -39,6 +41,7 @@ export class Database TemplateTable: TemplateTable; GroupTable: GroupTable; ProcessingGroupTable: ProcessingGroupTable; + DimStyleTable: DimStyleTable; //模型空间(里面有模型空间的实体列表) ModelSpace: BlockTableRecord; @@ -72,29 +75,17 @@ export class Database this.hm = new HistoricManage().SetDefaultDb(this); this.hm.Enable = false; this.LayoutSpace = new BlockTableRecord().SetOwnerDatabase(this); + this.DimStyleTable = new DimStyleTable().SetOwnerDatabase(this); if (buildDefaultDrawing) { - this.idIndex = 70; - this.DefaultMaterial = new PhysicalMaterialRecord(); - this.DefaultMaterial.Name = "默认"; - let texture = new TextureTableRecord(); - texture.WrapS = MirroredRepeatWrapping; - texture.WrapT = MirroredRepeatWrapping; - texture.repeatX = 1; - texture.repeatY = 1; - this.TextureTable.Add(texture); - this.DefaultMaterial.map = texture.Id; - this.DefaultMaterial.roughnessMap = texture.Id; - this.DefaultMaterial.bumpMap = texture.Id; - - this.MaterialTable.Add(this.DefaultMaterial); - - texture.Update(); - this.SettingDefaultMaterial(); - - //初始化灯光 + this.InitDimStyle(); + + this.InitMaterial(); + this.InitLight(); + + this.SettingDefaultStyleAndMaterial(); } this.hm.Enable = !disableHistoric; @@ -103,6 +94,38 @@ export class Database this.idIndex = 100; } + private InitDimStyle() + { + this.idIndex = 60; + + let styleRd = new DimStyleRecord; + styleRd.Name = "默认"; + + this.DimStyleTable.Add(styleRd); + + this.DimStyleTable.Current = styleRd.Id; + } + + private InitMaterial() + { + this.idIndex = 70; + this.DefaultMaterial = new PhysicalMaterialRecord(); + this.DefaultMaterial.Name = "默认"; + let texture = new TextureTableRecord(); + texture.WrapS = MirroredRepeatWrapping; + texture.WrapT = MirroredRepeatWrapping; + texture.repeatX = 1; + texture.repeatY = 1; + this.TextureTable.Add(texture); + this.DefaultMaterial.map = texture.Id; + this.DefaultMaterial.roughnessMap = texture.Id; + this.DefaultMaterial.bumpMap = texture.Id; + + this.MaterialTable.Add(this.DefaultMaterial); + + texture.Update(); + } + private InitLight() { this.idIndex = 80; @@ -118,7 +141,7 @@ export class Database this.Lights.Add(this.HemisphereLight); } - SettingDefaultMaterial() + SettingDefaultStyleAndMaterial() { if (!this.defaultDatabase) return; @@ -126,6 +149,9 @@ export class Database this.DefaultMaterial = this.GetObjectId(71)?.Object as PhysicalMaterialRecord ?? this.DefaultMaterial; this.DefaultMaterial.Update(); HostApplicationServices.DefaultMeshMaterial = this.DefaultMaterial.Material; + + let styleRd = this.GetObjectId(60)?.Object as DimStyleRecord; + HostApplicationServices.CurrentDimStyle = styleRd.Id; } Destroy() @@ -139,6 +165,7 @@ export class Database this.GroupTable.Destroy(); this.Lights.Destroy(); this.ProcessingGroupTable.Destroy(); + this.DimStyleTable.Destroy(); this.hm.Destroy(); this.CameraSnapshoots.length = 0; this.hm.historyRecord.length = 0; @@ -151,6 +178,7 @@ export class Database this.GroupTable.SetOwnerDatabase(this); this.Lights.SetOwnerDatabase(this); this.ProcessingGroupTable.SetOwnerDatabase(this); + this.DimStyleTable.SetOwnerDatabase(this); this.hm.SetDefaultDb(this); this.LayoutSpace.SetOwnerDatabase(this); this.idIndex = 100; @@ -160,7 +188,7 @@ export class Database FileWrite(file = new CADFiler): CADFiler { - file.Write(8);//ver; + file.Write(9);//ver; file.Write(this.idIndex); this.ModelSpace.WriteFile(file); this.TextureTable.WriteFile(file); @@ -177,6 +205,7 @@ export class Database for (let r of this.CameraSnapshoots) r.WriteFile(file); + this.DimStyleTable.WriteFile(file); return file; } FileRead(file: CADFiler) @@ -234,7 +263,16 @@ export class Database } } - this.SettingDefaultMaterial(); + if (ver > 8) + this.DimStyleTable.ReadFile(file); + else + { + let indexBak = this.idIndex; + this.InitDimStyle(); + this.idIndex = indexBak; + } + + this.SettingDefaultStyleAndMaterial(); this.hm.doing = false; Entity.__ReadFileIng__ = false; diff --git a/src/DatabaseServices/DimStyle/DimStyleRecord.ts b/src/DatabaseServices/DimStyle/DimStyleRecord.ts new file mode 100644 index 000000000..ce6d5234e --- /dev/null +++ b/src/DatabaseServices/DimStyle/DimStyleRecord.ts @@ -0,0 +1,100 @@ +import { AutoRecord } from "../AutoRecord"; +import { Factory } from "../CADFactory"; +import { CADFiler } from "../CADFiler"; +import { SymbolTableRecord } from "../SymbolTableRecord"; + +//ref https://ezdxf.readthedocs.io/en/stable/dxfinternals/tables/dimstyle_table.html + +export enum DimTextPosDir +{ + Top = 1,//上 + Out = 2,//外部 +} + +/** + * 标注样式 + */ +@Factory +export class DimStyleRecord extends SymbolTableRecord +{ + /** 如果设置为 1,延长线(脚线)具有固定长度 DIMFXLON 290 */ + @AutoRecord DIMFXLON: boolean = true;//1 + + /** DIMFXL 49 尺寸线下方的延长线长度如果固定(DIMFXLON 为 1),DIMEXE 定义尺寸线上方的长度 */ + @AutoRecord DIMFXL: number = 100; + + /** 控制尺寸中换算单位的显示 DIMALT 170 */ + @AutoRecord DIMALT: boolean = true;//2 + // + /** 控制换算单位的小数位数。如果打开 DIMALT,DIMALTD 会设置交替测量中小数点右侧显示的位数。 DIMALTD 171 */ + @AutoRecord DIMALTD: number = 2;//控制对齐标注的小数位精度 + + @AutoRecord DIMADEC: number = 2;//控制在角度尺寸中显示的精度位置的数量。 + + /** DIMASZ 41 控制尺寸线和引线箭头的大小。还控制钩线的大小。箭头大小的倍数决定尺寸线和文本是否应适合尺寸界线。如果由 DIMBLK 设置,DIMASZ 也用于缩放箭头块。当 DIMTSZ 不为零时,DIMASZ 无效。 */ + @AutoRecord DIMASZ: number = 10; + + /**147 尺寸线距离文字的距离(从尺寸线偏移) */ + @AutoRecord DIMGAP: number = 2; + + /**42 指定尺寸界线与原点的偏移距离。对于固定长度的延长线,此值确定最小偏移量。 */ + @AutoRecord DIMEXO: number = 20; + + /**43 */ + @AutoRecord DIMDLI: number = 20; + + /**44 肩膀上面的延伸线长度 */ + @AutoRecord DIMEXE: number = 20; + + /** 140 文字高度 */ + @AutoRecord DIMTXT: number = 60; + /**77 控制文本相对于尺寸线的垂直位置。 */ + @AutoRecord DIMTAD: DimTextPosDir = DimTextPosDir.Out; + + + // DIMTMOVE 279 设置标注文字移动规则。0 = 使用尺寸文本移动尺寸线 1 = 在移动尺寸文本时添加引线 2 = 允许文本在没有引线的情况下自由移动 + + //#region -------------------------File------------------------- + //对象从文件中读取数据,初始化自身 + override ReadFile(file: CADFiler) + { + let ver = file.Read(); + super.ReadFile(file); + + let bitV = file.Read() as number; + this.DIMFXLON = (bitV & 1) > 0; + this.DIMALT = (bitV & 2) > 0; + + this.DIMFXL = file.Read(); + this.DIMALTD = file.Read(); + this.DIMASZ = file.Read(); + this.DIMGAP = file.Read(); + this.DIMEXO = file.Read(); + this.DIMDLI = file.Read(); + this.DIMEXE = file.Read(); + this.DIMTXT = file.Read(); + this.DIMTAD = file.Read(); + } + //对象将自身数据写入到文件. + override WriteFile(file: CADFiler) + { + file.Write(1); + super.WriteFile(file); + + let bitV = 0;//压缩布尔值到里面 + if (this.DIMFXLON) bitV += 1; + if (this.DIMALT) bitV += 2; + + file.Write(bitV); + file.Write(this.DIMFXL); + file.Write(this.DIMALTD); + file.Write(this.DIMASZ); + file.Write(this.DIMGAP); + file.Write(this.DIMEXO); + file.Write(this.DIMDLI); + file.Write(this.DIMEXE); + file.Write(this.DIMTXT); + file.Write(this.DIMTAD); + } + //#endregion +} diff --git a/src/DatabaseServices/DimStyle/DimStyleTable.ts b/src/DatabaseServices/DimStyle/DimStyleTable.ts new file mode 100644 index 000000000..766f7cb5d --- /dev/null +++ b/src/DatabaseServices/DimStyle/DimStyleTable.ts @@ -0,0 +1,27 @@ +import { CADFiler } from "../CADFiler"; +import { ObjectId } from "../ObjectId"; +import { Factory } from "./../CADFactory"; +import { SymbolTable } from "./../SymbolTable"; + + +@Factory +export class DimStyleTable extends SymbolTable +{ + Current: ObjectId; + //#region -------------------------File------------------------- + //对象从文件中读取数据,初始化自身 + override ReadFile(file: CADFiler) + { + let ver = file.Read(); + super.ReadFile(file); + this.Current = file.ReadObjectId(); + } + //对象将自身数据写入到文件. + override WriteFile(file: CADFiler) + { + file.Write(1); + super.WriteFile(file); + file.WriteObjectId(this.Current); + } + //#endregion +} diff --git a/src/DatabaseServices/DimStyle/DimstyleKeyCodeEnum.ts b/src/DatabaseServices/DimStyle/DimstyleKeyCodeEnum.ts new file mode 100644 index 000000000..91a5d4894 --- /dev/null +++ b/src/DatabaseServices/DimStyle/DimstyleKeyCodeEnum.ts @@ -0,0 +1,26 @@ + +export enum DimStyleKeyCode +{ + DIMEXO = 20, + /**如果设置为 1,延长线具有固定长度 */ + DIMFXL = 49, + /**延长线长度 */ + DIMFXLON = 290, + /**控制尺寸中换算单位的显示 */ + DIMALT = 170, + /**控制换算单位的小数位数。 */ + DIMALTD = 171, + DIMADEC = 179, + /**箭头尺寸 */ + DIMASZ = 41, + + DIMEXE = 44, + DIMTAD = 77, + DIMTXT = 140, +} + + +//enum to string +// let code = DimStyleKeyCode[DimStyleKeyCode.DIMALT]; +//enum keys +// type keys = keyof typeof DimStyleKeyCode diff --git a/src/DatabaseServices/Dimension/2LineAngularDimension.ts b/src/DatabaseServices/Dimension/2LineAngularDimension.ts index 5e33ce085..5524193e1 100644 --- a/src/DatabaseServices/Dimension/2LineAngularDimension.ts +++ b/src/DatabaseServices/Dimension/2LineAngularDimension.ts @@ -8,11 +8,12 @@ import { reviseMirrorMatrix } from "../../Common/Matrix4Utils"; import { FixedNotZero, FixIndex } from "../../Common/Utils"; import { ObjectSnapMode } from "../../Editor/ObjectSnapMode"; import { BufferGeometryUtils } from "../../Geometry/BufferGeometryUtils"; -import { angle, equaln, equalv3 } from "../../Geometry/GeUtils"; +import { angle, equaln, equalv3, polar } from "../../Geometry/GeUtils"; import { IntersectOption } from "../../GraphicsSystem/IntersectWith"; import { RenderType } from "../../GraphicsSystem/RenderType"; import { Factory } from "../CADFactory"; import { CADFiler } from "../CADFiler"; +import { DimStyleKeyCode } from "../DimStyle/DimstyleKeyCodeEnum"; import { Arc } from "../Entity/Arc"; import { Line } from "../Entity/Line"; import { TextAligen } from "../Text/Text"; @@ -40,9 +41,16 @@ export class LineAngularDimension extends Dimension this._Text.Height = HostApplicationServices.dimTextHeight; } - protected GetString() + + override get FractionDigits() { return this.GetDimStyleValue(DimStyleKeyCode.DIMADEC); } + override set FractionDigits(length: number) + { + this.SetDimStyleOverrideValue(DimStyleKeyCode.DIMADEC, length); + } + + protected GetPrimitiveString() { - return FixedNotZero(MathUtils.radToDeg(this._Arc.AllAngle), this._FractionDigits) + "°"; + return FixedNotZero(MathUtils.radToDeg(this._Arc.AllAngle), this.FractionDigits) + "°"; } UpdateDimData(l1sp: Vector3, l1ep: Vector3, l2sp: Vector3, l2ep: Vector3, dimp: Vector3) @@ -318,10 +326,13 @@ export class LineAngularDimension extends Dimension this._Text.AutoUpdate = false;//更新标记 - this._Text.Height = this._TextSize; + this._Text.Height = this.TextSize; this._Text.TextString = this.TextString; - this._Text.Position = this._Arc.GetPointAtParam(0.5); - this._Text.TextRotation = this._Arc.GetAngleAtParam(0.5) % (Math.PI) - Math.PI / 2; + let midAngle = this._Arc.GetAngleAtParam(0.5); + this._Text.Position = polar(this._Arc.GetPointAtParam(0.5), midAngle, 10); + this._Text.TextRotation = midAngle % (Math.PI) - Math.PI / 2; + + this._Text.TextAligen = midAngle > Math.PI ? TextAligen.Top : TextAligen.Down; this._Text.AutoUpdate = true;//更新标记 this._Text.DeferUpdate(); @@ -378,20 +389,23 @@ export class LineAngularDimension extends Dimension this._L2EndPoint.fromArray(file.Read()); this._DimPoint.fromArray(file.Read()); if (ver > 1) this._TextString = file.Read(); - if (ver > 2) this._TextSize = file.Read(); + if (ver > 2 && ver < 4) this.TextSize = file.Read(); + + if (ver > 3) this.ReadDimStyle(file); } //对象将自身数据写入到文件. WriteFile(file: CADFiler) { super.WriteFile(file); - file.Write(3); + file.Write(4); file.Write(this._L1StartPoint.toArray()); file.Write(this._L1EndPoint.toArray()); file.Write(this._L2StartPoint.toArray()); file.Write(this._L2EndPoint.toArray()); file.Write(this._DimPoint.toArray()); file.Write(this._TextString); - file.Write(this._TextSize); + + this.WriteDimStyle(file); } //#endregion diff --git a/src/DatabaseServices/Dimension/AlignedDimension.ts b/src/DatabaseServices/Dimension/AlignedDimension.ts index 8f5f8e42a..7ad398d49 100644 --- a/src/DatabaseServices/Dimension/AlignedDimension.ts +++ b/src/DatabaseServices/Dimension/AlignedDimension.ts @@ -4,53 +4,41 @@ import { LineGeometry } from "three/examples/jsm/lines/LineGeometry"; import { HostApplicationServices } from "../../ApplicationServices/HostApplicationServices"; import { AddEntityDrawObject } from "../../Common/AddEntityDrawObject"; import { ColorMaterial } from "../../Common/ColorPalette"; -import { safeEval } from "../../Common/eval"; import { reviseMirrorMatrix } from "../../Common/Matrix4Utils"; import { UpdateDraw } from "../../Common/Status"; import { FixedNotZero } from "../../Common/Utils"; import { ObjectSnapMode } from "../../Editor/ObjectSnapMode"; import { BufferGeometryUtils } from "../../Geometry/BufferGeometryUtils"; -import { angle, angleAndX, AsVector2, equaln, equalv3, isParallelTo, midPoint, ZAxis } from "../../Geometry/GeUtils"; +import { angle, angleAndX, AsVector2, AsVector3, equaln, equalv3, isParallelTo, midPoint, ZAxis } from "../../Geometry/GeUtils"; +import { ROTATE_MTX2 } from "../../Geometry/RotateUV"; import { RenderType } from "../../GraphicsSystem/RenderType"; import { Factory } from "../CADFactory"; import { CADFiler } from "../CADFiler"; +import { DimStyleKeyCode } from "../DimStyle/DimstyleKeyCodeEnum"; +import { DimTextPosDir } from "../DimStyle/DimStyleRecord"; import { Line } from "../Entity/Line"; import { Polyline } from "../Entity/Polyline"; -import { ObjectId } from "../ObjectId"; import { TextAligen } from "../Text/Text"; import { Dimension } from "./Dimension"; import { GetDimLineMaterial } from "./GetDimLineMaterial"; +/**用于提供捕捉的多段线 */ let snapPolyline = new Polyline([{ pt: new Vector2, bul: 0 }, { pt: new Vector2, bul: 0 }, { pt: new Vector2, bul: 0 }, { pt: new Vector2, bul: 0 }]); -interface LeadOutLinePts -{ - dragPt: Vector3; - endPt: Vector3; -} -interface DefaultValue -{ - offset: Vector2; - isFlipped: boolean; -} + + /** * 对齐标注 * 存在子类重载(线性标注 LinearDimension) - * @class AlignedDimension */ @Factory export class AlignedDimension extends Dimension { - //引线 - private _LeadOutLine = new Polyline(); - private _LeadOutOffsetY = 72; - private _LeadOutOffsetX = 30; - private _DefaultVal: DefaultValue = { offset: new Vector2(30, 72), isFlipped: false }; - //引线的拖拽点和终点 - private _LeadOutPts: LeadOutLinePts = { dragPt: midPoint(this._ArmP1, this._ArmP2), endPt: new Vector3() }; - //引线是否反向(往左伸/往右伸) - private _LeadOutIsFlipped: boolean = false; - //是否由拖拽更新_LeadOutPts.dragPt. 关系到引线的update - private isDragLeadOutPt: boolean = false; + //引线(用于绘制) + private _LeadLine = new Polyline(); + /**引线的起始位置,在引线坐标系+使用中点 */ + private _LeadPos: Vector2 = new Vector2(30, this.TextSize * 1.2); + + /**构造函数提供的点在对象坐标系内部 */ constructor( //针脚 protected _FootP1: Vector3 = new Vector3(), @@ -58,64 +46,58 @@ export class AlignedDimension extends Dimension //肩膀 protected _ArmP1: Vector3 = new Vector3(), protected _ArmP2: Vector3 = new Vector3(), - protected _TextRotation: number = undefined, - //是否显示引线 - protected _LeadOutVisible: boolean = true, + protected _TextRotation: number = null, + //当尺寸线放不下文字时,使用引线 + protected _UseLead: boolean = true, ) { super(); - this._Text.TextAligen = TextAligen.Down; - this._Text.Height = HostApplicationServices.dimTextHeight; + + this._ArmP1.setZ(0); + this._ArmP2.setZ(0); } - set Material(materialId: ObjectId) { } + get Distance() { return this._ArmP1.distanceTo(this._ArmP2); } + get FootP1() { return this._FootP1.clone().applyMatrix4(this._Matrix); } set FootP1(v: Vector3) { this._FootP1.copy(v).applyMatrix4(this.OCSInv); this.Update(); } - get FootP1() - { - return this._FootP1.clone().applyMatrix4(this._Matrix); - } + + get FootP2() { return this._FootP2.clone().applyMatrix4(this._Matrix); } set FootP2(v: Vector3) { this._FootP2.copy(v).applyMatrix4(this.OCSInv); this.Update(); } - get FootP2() - { - return this._FootP2.clone().applyMatrix4(this._Matrix); - } + + get ArmP1() { return this._ArmP1.clone().applyMatrix4(this._Matrix); } set ArmP1(v: Vector3) { + this.WriteAllObjectRecord(); this._ArmP1.copy(v).applyMatrix4(this.OCSInv); + this._ArmP1.setZ(0); this.Update(); } - get ArmP1() - { - return this._ArmP1.clone().applyMatrix4(this._Matrix); - } + + get ArmP2() { return this._ArmP2.clone().applyMatrix4(this._Matrix); } set ArmP2(v: Vector3) { + this.WriteAllObjectRecord(); this._ArmP2.copy(v).applyMatrix4(this.OCSInv); + this._ArmP2.setZ(0); this.Update(); } - get ArmP2() - { - return this._ArmP2.clone().applyMatrix4(this._Matrix); - } - get TextPosition() - { - return midPoint(this._ArmP1, this._ArmP2).applyMatrix4(this._Matrix); - } + get TextPosition() { return midPoint(this._ArmP1, this._ArmP2).applyMatrix4(this._Matrix); } + /**实际上这个是BasePoint 用来定位尺寸线的位置 */ set TextPosition(p: Vector3) { - p = p.clone().applyMatrix4(this.OCSInv); - let l = new Line(this._ArmP1.clone(), this._ArmP2.clone()); - p.setZ(this._ArmP1.z); + this.WriteAllObjectRecord(); + p = p.clone().applyMatrix4(this.OCSInv).setZ(0); + let l = new Line(this._ArmP1, this._ArmP2); let cp = l.GetClosestPointTo(p, true); let v = p.clone().sub(cp); @@ -129,59 +111,22 @@ export class AlignedDimension extends Dimension get DalUcs() { let dalUcs = new Matrix4(); - if (!equaln(this._ArmP1.distanceTo(this._ArmP2), 0)) + if (!equalv3(this._ArmP1, this._ArmP2)) { - let vx = this._ArmP2.clone().sub(this._ArmP1); - if (equaln(this._ArmP1.x, this._ArmP2.x)) - { - if (this._ArmP1.y < this._ArmP2.y) - vx.negate(); - } - else if (this._ArmP1.x < this._ArmP2.x) - vx.negate(); - - if (isParallelTo(vx, ZAxis)) - return new Matrix4().setPosition(this._FootP1); - - let vy = vx.clone().cross(ZAxis); - dalUcs = new Matrix4().makeBasis(vx.normalize(), vy.normalize(), ZAxis); - dalUcs.setPosition(this._FootP1); + let vy = this.ParseTopDir()[0]; + let vx = new Vector3().crossVectors(vy, ZAxis); + dalUcs = new Matrix4().makeBasis(vx, vy, ZAxis); } + dalUcs.setPosition(midPoint(this._ArmP1, this._ArmP2)); return dalUcs; } - RaiseFooters(num: number) - { - let dalucs = this.DalUcs; - let dalUcsInv = new Matrix4().getInverse(dalucs); - - let p = new Vector3(0, num, 0); - let f1 = this._FootP1.clone().applyMatrix4(dalucs); - let f2 = this._FootP2.clone().applyMatrix4(dalucs); - let a1 = this._ArmP1.clone().applyMatrix4(dalucs); - if (a1.y < f1.y) - p.negate(); - this._FootP1 = f1.add(p).applyMatrix4(dalUcsInv); - this._FootP2 = f2.add(p).applyMatrix4(dalUcsInv); - - this.Update(); - } - set TextRotation(angle: number) { this._TextRotation = angle; this.Update(); } - set TextAligen(al: TextAligen) - { - if (al !== this._Text.TextAligen) - { - this.WriteAllObjectRecord(); - this._Text.TextAligen = al; - } - } - get Text() { if (!this._Text.TextString) @@ -190,9 +135,9 @@ export class AlignedDimension extends Dimension return this._Text; } - protected GetString(): string + protected GetPrimitiveString(): string { - return FixedNotZero(this._ArmP1.distanceTo(this._ArmP2), this._FractionDigits); + return FixedNotZero(this._ArmP1.distanceTo(this._ArmP2), this.FractionDigits); } get BoundingBox() @@ -204,77 +149,65 @@ export class AlignedDimension extends Dimension return snapPolyline.BoundingBox; } - set LeadOutVisible(visible: boolean) + get LeadVisible() { return this._UseLead; } + /**设置引线可见 */ + set LeadVisible(visible: boolean) { - if (this._LeadOutVisible === visible) return; + if (this._UseLead === visible) return; this.WriteAllObjectRecord(); - this._LeadOutVisible = visible; + this._UseLead = visible; this.Update(); } - //引线朝右视为未翻转 - set LeadOutFlipped(isFlipped: boolean) + set LeadInLeft(isLeft: boolean) { - if (this._LeadOutIsFlipped === isFlipped) return; - this.WriteAllObjectRecord(); - this._LeadOutIsFlipped = isFlipped; - this.Update(); - } + if (this._LeadPos.x < 0 === isLeft) + return; - get LeadOutFlipped() - { - return this._LeadOutIsFlipped; + this.FlippeLead(); } - toggleLeadOutVisible() + /**切换引线可见性 */ + ToggleLeadVisible() { this.WriteAllObjectRecord(); - this.LeadOutVisible = !this._LeadOutVisible; + this.LeadVisible = !this._UseLead; } - toggleLeadOutFlipped() + /**切换引线翻转 */ + FlippeLead() { this.WriteAllObjectRecord(); - this.LeadOutFlipped = !this._LeadOutIsFlipped; + this._LeadPos.x = -this._LeadPos.x; + this.Update(); } - set LeadOutOffsetY(size: number) + get LeadY() { return this._LeadPos.y; } + /**引线偏移 */ + set LeadY(y: number) { - if (this._LeadOutOffsetY === size) return; + if (this.LeadY === y) return; this.WriteAllObjectRecord(); - this._LeadOutOffsetY = size; + this._LeadPos.y = y; this.Update(); } - get LeadOutOffsetY() + get LeadX() { return this._LeadPos.x; } + set LeadX(x: number) { - return this._LeadOutOffsetY; - } - - set LeadOutOffsetX(size: number) - { - if (this._LeadOutOffsetX === size) return; + if (this.LeadX === x) return; this.WriteAllObjectRecord(); - this._LeadOutOffsetX = size; + this._LeadPos.x = x; this.Update(); } - get LeadOutOffsetX() + /**设置引线数据 */ + SetLeadData(offset: Vector2, isFlipped = false) { - return this._LeadOutOffsetX; - } - - set DefaultValue(val: DefaultValue) - { - this._DefaultVal = val; - this._LeadOutOffsetX = val.offset.x; - this._LeadOutOffsetY = val.offset.y; - this.LeadOutFlipped = val.isFlipped; - } - - get DefaultValue() - { - return this._DefaultVal; + this.WriteAllObjectRecord(); + this._LeadPos.copy(offset); + if (isFlipped) this._LeadPos.x *= -1; + this.Update(); } Explode() @@ -287,13 +220,17 @@ export class AlignedDimension extends Dimension new Line(this._ArmP2.clone(), this._FootP2.clone()), this._Text.Clone() ]; - if (!equalv3(this._LeadOutPts.dragPt, midPoint(this._ArmP1, this._ArmP2))) + if (this._UseLead && this.NeedLead) + { + let mp = midPoint(this._ArmP1, this._ArmP2); res.push( - new Line(midPoint(this._ArmP1, this._ArmP2), this._LeadOutPts.dragPt.clone()), - new Line(this._LeadOutPts.dragPt.clone(), this._LeadOutPts.endPt.clone()) + new Line(mp.clone(), AsVector3(this._LeadPos).add(mp)), + new Line(AsVector3(this._LeadPos).add(mp), AsVector3(this._LeadPos).add(mp).add(new Vector3(this.TextBoxWidth, 0, 0))) ); + } return res.map(en => en.ApplyMatrix(this._Matrix)); } + protected ApplyMirrorMatrix(m: Matrix4) { this.WriteAllObjectRecord(); @@ -312,6 +249,7 @@ export class AlignedDimension extends Dimension this.Update(UpdateDraw.Geometry); return this; } + Clone(): this { let ent = super.Clone(); @@ -337,7 +275,7 @@ export class AlignedDimension extends Dimension } else line = new TLine( - BufferGeometryUtils.CreateFromPts([this._FootP1, this._FootP2, this._ArmP1, this._ArmP2]), + BufferGeometryUtils.CreateFromPts([this._FootP1, this._FootP2, this._ArmP1, this._ArmP2, this._ArmP2, this._ArmP2]), colorMaterial ); @@ -351,31 +289,101 @@ export class AlignedDimension extends Dimension return obj; } + ParseTopDir(): [Vector3, Vector3, Vector3] + { + let [f1, f2, a1, a2] = [this._FootP1, this._FootP2, this._ArmP1, this._ArmP2].map(p => p.clone().setZ(0)); + + let armV = a1.clone().sub(a2); + + //#region 头部延伸线 + let topDir1: Vector3, topDir2: Vector3;//↑头顶部的向量 用来突出肩膀(文字或者肩膀的线) + if (!equalv3(f1, a1)) + topDir1 = a1.clone().sub(f1).normalize(); + if (!equalv3(f2, a2)) + topDir2 = a2.clone().sub(f2).normalize(); + + let topDir = topDir1 ?? topDir2; + if (!topDir) + { + topDir = armV.clone().normalize(); + ROTATE_MTX2.applyVector(topDir); + } + + if (!topDir1) topDir1 = topDir; + if (!topDir2) topDir2 = topDir; + + return [topDir, topDir1, topDir2]; + } + UpdateDrawObject(renderType: RenderType, obj: Object3D) { obj.remove(...obj.children.slice(3)); let [line, arrow1, arrow2] = obj.children; - let arrowSize = 10; + + let [f1, f2, a1, a2] = [this._FootP1, this._FootP2, this._ArmP1, this._ArmP2].map(p => p.clone().setZ(0)); + + let armV = a1.clone().sub(a2); + + //#region 头部延伸线 + let [topDir, topDir1, topDir2] = this.ParseTopDir(); + + let topExt = this.GetDimStyleValue(DimStyleKeyCode.DIMEXE) ?? 10; + let a11 = topDir1.clone().multiplyScalar(topExt).add(a1); + let a21 = topDir2.clone().multiplyScalar(topExt).add(a2); + //#endregion + + //#region 固定延伸线的尺寸 + let length1 = f1.distanceTo(a1); + let length2 = f2.distanceTo(a2); + let newLength1 = length1; + let newLength2 = length2; + + let dimexo = this.GetDimStyleValue(DimStyleKeyCode.DIMEXO) ?? 20;//脚线的偏移距离 + newLength1 = Math.max(0, newLength1 - dimexo); + newLength2 = Math.max(0, newLength2 - dimexo); + + if (this.GetDimStyleValue(DimStyleKeyCode.DIMFXLON))//固定脚线长度 + { + let fixLength = this.GetDimStyleOverrideValue(DimStyleKeyCode.DIMFXL) ?? 100;//固定脚线长度 + if (newLength1 > fixLength) + newLength1 = fixLength; + + if (newLength2 > fixLength) + newLength2 = fixLength; + } + + if (newLength1 !== length1) + f1.sub(a1).normalize().multiplyScalar(newLength1).add(a1); + + if (newLength2 !== length2) + f2.sub(a2).normalize().multiplyScalar(newLength2).add(a2); + //#endregion + + //#region 更新线部分 + let linePts = [f1, a11, a1, a2, a21, f2]; if (renderType === RenderType.WireframePrint) { - arrowSize *= HostApplicationServices.lineWidth * 0.5; const geometry = (line).geometry; let nums: number[] = []; - for (let p of [this._FootP1, this._ArmP1, this._ArmP2, this._FootP2]) + for (let p of linePts) nums.push(p.x, p.y, p.z); geometry.setPositions(nums); } else - BufferGeometryUtils.UpdatePts((line).geometry as BufferGeometry, [this._FootP1, this._ArmP1, this._ArmP2, this._FootP2], true); + BufferGeometryUtils.UpdatePts((line).geometry as BufferGeometry, linePts, true); + //#endregion + //#region 箭头部分 + let arrowSize = this.GetDimStyleValue(DimStyleKeyCode.DIMASZ) ?? 10; + if (renderType === RenderType.WireframePrint)//在打印模式下,改变箭头的大小? + arrowSize *= HostApplicationServices.lineWidth * 0.5; arrow1.scale.set(arrowSize, arrowSize, arrowSize); arrow2.scale.set(arrowSize, arrowSize, arrowSize); - let armV = this._ArmP1.clone().sub(this._ArmP2); - let armAn = angle(armV); - arrow1.position.copy(this._ArmP1); arrow2.position.copy(this._ArmP2); + + let armAn = angle(armV); if (this._ArmP1.distanceTo(this._ArmP2) < 36) { arrow1.rotation.z = armAn + Math.PI / 2; @@ -388,95 +396,109 @@ export class AlignedDimension extends Dimension } arrow1.updateMatrix(); arrow2.updateMatrix(); + //#endregion + //#region 文字和引线 //更新引线this._LeadOutLine 并返回新的字体位置 - let textPos = this.UpdateLeadOutLine(renderType); - if (this._LeadOutLine.EndParam > 0 && this._LeadOutLine.Visible) - AddEntityDrawObject(obj, this._LeadOutLine, renderType); + let textPos = this.UpdateLeadLine(); + let hasLead = this._UseLead && this.NeedLead; + + let textPosDir = this.GetDimStyleValue(DimStyleKeyCode.DIMTAD) as DimTextPosDir ?? DimTextPosDir.Out; + if (textPosDir === DimTextPosDir.Out)//文字在尺寸线(或引线)外部 + { + let textDir = topDir;//文字相对于基准线(引线) 的位置方向向量 + if (hasLead && this._LeadPos.y < 0)//引线方向和头部方向相反 则逆转方向(dir = 引线的朝向) + textDir = textDir.clone().negate(); + + if (equaln(textDir.y, 0))//水平标注 + this.Text.TextAligen = textDir.x > 0 ? TextAligen.Top : TextAligen.Down; + else + this._Text.TextAligen = textDir.y < 0 ? TextAligen.Top : TextAligen.Down; + + textPos.add(textDir.multiplyScalar(10)); + } + else//文字在尺寸线(或引线)上方 + { + this._Text.TextAligen = TextAligen.Down; + textPos.add(topDir.multiplyScalar(10)); + } + + if (hasLead) + AddEntityDrawObject(obj, this._LeadLine, renderType); this.UpdateText(textPos); AddEntityDrawObject(obj, this._Text, renderType); - this.isDragLeadOutPt = false; + //#endregion + } + + get NeedLead(): boolean + { + let distance = this._ArmP1.distanceTo(this._ArmP2); + let textBoxWidth = this.TextBoxWidth; + let needLead = (distance < textBoxWidth - 2) && !(equaln(distance, 0));//文字宽度是否比托盘更宽 是 则需要引线 + return needLead; } /** * 更新引线并返回textPosition - * @returns textPosition(Vector3) - * @memberof AlignedDimension */ - UpdateLeadOutLine(renderType: RenderType): Vector3 + UpdateLeadLine(): Vector3 { - let textPosition: Vector3 = midPoint(this._ArmP1, this._ArmP2); - - let distance = this._ArmP1.distanceTo(this._ArmP2); - let distanceStr = FixedNotZero(distance, 2); - let strWidth = distanceStr.length * (~~(Math.abs(this.TextSize) / 2));//文字总宽度 - let needLeadOut = (safeEval(distanceStr) < strWidth + 1e-6) && !(equaln(distance, 0));//文字宽度是否比托盘更宽 是 则需要引线 + let armMidP: Vector3 = midPoint(this._ArmP1, this._ArmP2); + let textPosition = armMidP; - if (this._LeadOutVisible && needLeadOut) //引线可见且需要引线 + if (this._UseLead && this.NeedLead) //引线可见且需要引线 { let dalUcs = this.DalUcs; - let dalUcsInv = new Matrix4().getInverse(dalUcs); - let textWidthVec = new Vector3(strWidth); - let isLeft = (v) => { return v.x < midPoint(this._ArmP1, this._ArmP2).applyMatrix4(dalUcs).x; }; - //确定引线的点的位置 - if (this.isDragLeadOutPt)//是否拖拽了dragPt(拖拽dragPt需要更新endPt) - { - let dragPtInDalUcs = this._LeadOutPts.dragPt.clone().applyMatrix4(dalUcs); - let isleft = isLeft(dragPtInDalUcs.clone()); - if (isleft)//已经拖过中线 更新endPt 改变IsFlipped - this._LeadOutPts.endPt = dragPtInDalUcs.clone().sub(textWidthVec); - else - this._LeadOutPts.endPt = dragPtInDalUcs.clone().add(textWidthVec); - this._LeadOutIsFlipped = !isleft; - } - else //没有拖拽 - { - this._LeadOutPts.dragPt = textPosition.clone().applyMatrix4(dalUcs).add(new Vector3(this._LeadOutIsFlipped ? this._LeadOutOffsetX : -this._LeadOutOffsetX, this._LeadOutOffsetY)); - if (isLeft(this._LeadOutPts.dragPt)) - this._LeadOutPts.endPt = this._LeadOutPts.dragPt.clone().sub(textWidthVec); - else - this._LeadOutPts.endPt = this._LeadOutPts.dragPt.clone().add(textWidthVec); - this._LeadOutPts.dragPt.applyMatrix4(dalUcsInv); - } - - this._LeadOutPts.endPt.applyMatrix4(dalUcsInv); + let leadP1 = AsVector3(this._LeadPos).applyMatrix4(dalUcs); + let leadP2 = AsVector3(this._LeadPos).add(new Vector3(this.TextBoxWidth * Math.sign(this._LeadPos.x))).applyMatrix4(dalUcs); + textPosition.setFromMatrixColumn(dalUcs, 3); - this._LeadOutLine.AutoUpdate = false; - this._LeadOutLine.LineData = [textPosition, this._LeadOutPts.dragPt, this._LeadOutPts.endPt].map(p => { return { pt: AsVector2(p), bul: 0 }; }); - this._LeadOutLine.Position = new Vector3(0, 0, textPosition.z); - this._LeadOutLine.ColorIndex = this.ColorIndex; - this._LeadOutLine.Visible = true; - this._LeadOutLine.AutoUpdate = true; - this._LeadOutLine.DeferUpdate(); + this._LeadLine.AutoUpdate = false; + this._LeadLine.IsEmbedEntity = true;//使它可以捕捉 + this._LeadLine.LineData = [textPosition, leadP1, leadP2].map(p => { return { pt: AsVector2(p), bul: 0 }; }); + this._LeadLine.ColorIndex = this.ColorIndex; + this._LeadLine.Visible = true;//可见性设置 + this._LeadLine.AutoUpdate = true; + this._LeadLine.DeferUpdate(); - textPosition = midPoint(this._LeadOutPts.dragPt, this._LeadOutPts.endPt); + textPosition.copy(leadP1).add(leadP2).divideScalar(2);//引线中点 } else //引线不可见或不需要引线 { - //使引线不可见 并将dragPt隐藏于托盘中点 - this._LeadOutPts.dragPt = midPoint(this._ArmP1, this._ArmP2); - this._LeadOutLine.Visible = false; + this._LeadLine.Visible = false;//可见性设置 } return textPosition; } - UpdateText(pos?: Vector3) + UpdateText(textPos?: Vector3) { this._Text.AutoUpdate = false; let textRo = this._TextRotation ?? angleAndX(this._ArmP1.clone().sub(this._ArmP2)); this._Text.TextString = this.TextString; - this._Text.Position = pos ?? midPoint(this._ArmP1, this._ArmP2); + this._Text.Position = textPos ?? midPoint(this._ArmP1, this._ArmP2); this._Text.TextRotation = textRo; this._Text.ColorIndex = this._Color; - this._Text.Height = this._TextSize; + this._Text.Height = this.TextSize * 0.923;//雅黑数字*0.923 this._Text.DeferUpdate(); this._Text.AutoUpdate = true; } + protected OnChangeFootPt() + { + let l = new Line(this._FootP1.clone().setZ(0), this._FootP2.clone().setZ(0)); + + let cp = l.GetClosestPointTo(this._ArmP1, true); + + let v = cp.subVectors(this._ArmP1, cp); + + this._ArmP1.copy(this._FootP1.clone().add(v)); + this._ArmP2.copy(this._FootP2.clone().add(v)); + } + GetObjectSnapPoints( snapMode: ObjectSnapMode, pickPoint: Vector3, @@ -485,7 +507,24 @@ export class AlignedDimension extends Dimension ): Vector3[] { this.SetDataToTempPolyline(); - return snapPolyline.GetObjectSnapPoints(snapMode, pickPoint, lastPoint, viewXform); + let pts = snapPolyline.GetObjectSnapPoints(snapMode, pickPoint, lastPoint, viewXform); + + if (this._UseLead && this.NeedLead) + { + let dalUcs = this.DalUcs; + let armMidP: Vector3 = midPoint(this._ArmP1, this._ArmP2); + let leadP1 = AsVector3(this._LeadPos).applyMatrix4(dalUcs); + let leadP2 = AsVector3(this._LeadPos).add(new Vector3(this.TextBoxWidth * Math.sign(this._LeadPos.x))).applyMatrix4(dalUcs); + + snapPolyline.LineData[0].pt.set(armMidP.x, armMidP.y); + snapPolyline.LineData[1].pt.set(leadP1.x, leadP1.y); + snapPolyline.LineData[2].pt.set(leadP2.x, leadP2.y); + snapPolyline.LineData[3].pt.set(leadP2.x, leadP2.y); + + for (let p of snapPolyline.GetObjectSnapPoints(snapMode, pickPoint, lastPoint, viewXform)) + pts.push(p); + } + return pts; } private SetDataToTempPolyline() @@ -507,22 +546,23 @@ export class AlignedDimension extends Dimension if (renderType === RenderType.WireframePrint) return; this.WriteAllObjectRecord(); - let colorMat = GetDimLineMaterial(this, renderType); - this._LeadOutLine.ColorIndex = this._Color; + let mtl = GetDimLineMaterial(this, renderType); + this._LeadLine.ColorIndex = this._Color; let [line, arrow1, arrow2] = obj.children; - (line).material = colorMat; - (arrow1).material = colorMat; - (arrow2).material = colorMat; + (line).material = mtl; + (arrow1).material = mtl; + (arrow2).material = mtl; this._Text.ColorIndex = this._Color; } GetGripPoints(): Array { - return [this._FootP1, this._FootP2, this._ArmP1, this._ArmP2, midPoint(this._ArmP1, this._ArmP2), this._LeadOutPts.dragPt].map(p => - { - return p.clone().applyMatrix4(this._Matrix); - }); + let pts = [this._FootP1, this._FootP2, this._ArmP1, this._ArmP2, midPoint(this._ArmP1, this._ArmP2)].map(p => p.clone().applyMatrix4(this._Matrix)); + if (this._UseLead && this.NeedLead) + pts.push(AsVector3(this._LeadPos).applyMatrix4(this.DalUcs).applyMatrix4(this._Matrix)); + return pts; } + MoveGripPoints(indexList: number[], vec: Vector3) { this.WriteAllObjectRecord(); @@ -531,17 +571,16 @@ export class AlignedDimension extends Dimension let vec0 = vec.clone().applyMatrix4(inv0); for (let i of indexList) { - if (i === 5) + if (i === 5)//引线 { - let dalucs = this.DalUcs; - //开始拖拽引线dragPt - this.isDragLeadOutPt = true; - this._LeadOutPts.dragPt.add(vec0); - let calcV = this._LeadOutPts.dragPt.clone().applyMatrix4(dalucs).sub(midPoint(this._ArmP1, this._ArmP2).applyMatrix4(dalucs)); - this._LeadOutOffsetY = calcV.y; - this._LeadOutOffsetX = Math.abs(calcV.x); + let dalUCS = this.DalUcs.setPosition(0, 0, 0); + dalUCS.getInverse(dalUCS); + vec0.applyMatrix4(dalUCS); + + this._LeadPos.x += vec0.x; + this._LeadPos.y += vec0.y; } - else if (i >= 2) + else if (i >= 2)//肩膀点 文字点(拽拖这个点不会把标注变大) { let p = this.TextPosition.add(vec).applyMatrix4(inv); let l = new Line(this._ArmP1, this._ArmP2); @@ -550,24 +589,25 @@ export class AlignedDimension extends Dimension this._ArmP1.add(v); this._ArmP2.add(v); - this._LeadOutPts.dragPt.add(v); } - else + else//脚线 { if (i === 0) this._FootP1.add(vec0); else this._FootP2.add(vec0); - this.ChangeFootPt(); + this.OnChangeFootPt(); } } this.Update(); } + GetStretchPoints(): Array { return this.GetGripPoints(); } + MoveStretchPoints(indexList: Array, vec: Vector3) { this.WriteAllObjectRecord(); @@ -585,16 +625,6 @@ export class AlignedDimension extends Dimension if (bChangeText) this.MoveGripPoints([2], vec); } - protected ChangeFootPt() - { - let l = new Line(this._FootP1, this._FootP2); - let cp = l.GetClosestPointTo(this._ArmP1, true); - - let v = this._ArmP1.clone().sub(cp); - - this._ArmP1.copy(this._FootP1.clone().add(v)); - this._ArmP2.copy(this._FootP2.clone().add(v)); - } //#region -------------------------File------------------------- //对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化 @@ -610,23 +640,86 @@ export class AlignedDimension extends Dimension this._FootP2.fromArray(file.Read()); this._TextRotation = file.Read(); if (ver > 2) this._TextString = file.Read(); - if (ver > 3) + + if (ver < 7)//升级到版本7之后 标注统一在OCS平面绘制 (脚线允许在不同的平面) { - this._LeadOutVisible = file.Read(); - this._LeadOutIsFlipped = file.Read(); - this._LeadOutPts.dragPt.fromArray(file.Read()); - this._LeadOutOffsetY = file.Read(); - this._LeadOutOffsetX = file.Read(); + //升级文件版本,将z轴移除 + let z = this._ArmP1.z; + if (!equaln(z, 0)) + { + this._Matrix.elements[12] += this._Matrix.elements[8] * z; + this._Matrix.elements[13] += this._Matrix.elements[9] * z; + this._Matrix.elements[14] += this._Matrix.elements[10] * z; + + this._ArmP1.z = 0; + this._ArmP2.z = 0; + this._FootP1.z -= z; + this._FootP2.z -= z; + } + + this.SetDimStyleOverrideValue(DimStyleKeyCode.DIMEXO, 0);//原始图纸脚线偏移为9 + this.SetDimStyleOverrideValue(DimStyleKeyCode.DIMTAD, DimTextPosDir.Top);//原始图纸的文字位置为上 + //虽然原始的标注也没有文字偏移,但是太丑了,所以不还原这个设置 } - if (ver > 4) this._TextSize = file.Read(); - if (ver > 5) this._FractionDigits = file.Read() ?? HostApplicationServices.fractionDigitsType ?? 2; + if (ver > 3 && ver < 7) + { + this._UseLead = file.Read(); + let leadFlipped = file.Read(); + let leadStartP = new Vector3().fromArray(file.Read()); + let y = file.Read(); + let x = file.Read(); + + if (!leadFlipped) x = -x; + + /**旧的引线坐标系 在OCS内部 */ + const GetOldDalUcs = () => + { + let dalUcs = new Matrix4(); + if (!equalv3(this._ArmP1, this._ArmP2)) + { + let vx = this._ArmP2.clone().sub(this._ArmP1).normalize(); + if (equaln(this._ArmP1.x, this._ArmP2.x)) + { + if (this._ArmP1.y < this._ArmP2.y) + vx.negate(); + } + else if (this._ArmP1.x < this._ArmP2.x) + vx.negate(); + + if (isParallelTo(vx, ZAxis)) + return dalUcs.setPosition(midPoint(this._ArmP1, this._ArmP2)); + + let vy = vx.clone().cross(ZAxis); + dalUcs = new Matrix4().makeBasis(vx, vy, ZAxis); + dalUcs.setPosition(midPoint(this._ArmP1, this._ArmP2)); + } + return dalUcs; + }; + + let p = new Vector3(x, y); + p.applyMatrix4(GetOldDalUcs()); + let cs = this.DalUcs; + p.applyMatrix4(cs.getInverse(cs)); + + this._LeadPos.copy(p as any as Vector2); + } + if (ver > 4 && ver < 7) this.TextSize = file.Read(); + if (ver > 5 && ver < 7) this.FractionDigits = file.Read() ?? 2; + + if (ver >= 7) + { + this._UseLead = file.Read(); + this._LeadPos.set(file.Read(), file.Read()); + + this.ReadDimStyle(file); + } } //对象将自身数据写入到文件. WriteFile(file: CADFiler) { super.WriteFile(file); - file.Write(6); + file.Write(7); file.Write(this._ArmP1.toArray()); file.Write(this._ArmP2.toArray()); file.Write(this._FootP1.toArray()); @@ -634,14 +727,10 @@ export class AlignedDimension extends Dimension file.Write(this._TextRotation); file.Write(this._TextString); - file.Write(this._LeadOutVisible); - file.Write(this._LeadOutIsFlipped); - file.Write(this._LeadOutPts.dragPt.toArray()); - file.Write(this._LeadOutOffsetY); - file.Write(this._LeadOutOffsetX); - - file.Write(this._TextSize); - file.Write(this._FractionDigits); + file.Write(this._UseLead); + file.Write(this._LeadPos.x); + file.Write(this._LeadPos.y); + this.WriteDimStyle(file); } //#endregion } diff --git a/src/DatabaseServices/Dimension/ArcDimension.ts b/src/DatabaseServices/Dimension/ArcDimension.ts index 8ecc6b00d..2c55fa990 100644 --- a/src/DatabaseServices/Dimension/ArcDimension.ts +++ b/src/DatabaseServices/Dimension/ArcDimension.ts @@ -52,9 +52,9 @@ export class ArcDimension extends Dimension get TextRadiusAdd() { return this._TextRadiusAdd; } - protected GetString(): string + protected GetPrimitiveString(): string { - return FixedNotZero(this._Arc.Length, this._FractionDigits); + return FixedNotZero(this._Arc.Length, this.FractionDigits); } //#region 拉伸相关 @@ -185,7 +185,7 @@ export class ArcDimension extends Dimension let textOCS = new Matrix4().makeRotationZ(ang + Math.PI * 3 / 2).setPosition(textP); this._Text.TextAligen = TextAligen.Down; this._Text.OCS = textOCS; - this._Text.Height = this._TextSize; + this._Text.Height = this.TextSize; } UpdateDrawObjectMaterial(type: RenderType, obj: Object3D, material?: Material) @@ -228,13 +228,15 @@ export class ArcDimension extends Dimension this._StartAngle = file.Read(); this._EndAngle = file.Read(); this._TextString = file.Read(); - this._TextSize = file.Read(); - if (ver > 1) this._FractionDigits = file.Read(); + if (ver < 3) this.TextSize = file.Read(); + if (ver > 1 && ver < 3) this.FractionDigits = file.Read(); + + if (ver > 2) this.ReadDimStyle(file); } //对象将自身数据写入到文件. WriteFile(file: CADFiler) { - file.Write(2); + file.Write(3); super.WriteFile(file); file.Write(this._Center.toArray()); file.Write(this._Radius); @@ -243,8 +245,8 @@ export class ArcDimension extends Dimension file.Write(this._StartAngle); file.Write(this._EndAngle); file.Write(this._TextString); - file.Write(this._TextSize); - file.Write(this._FractionDigits); + + this.WriteDimStyle(file); } //#endregion } diff --git a/src/DatabaseServices/Dimension/Dimension.ts b/src/DatabaseServices/Dimension/Dimension.ts index 693a262e3..2eaf2e60f 100644 --- a/src/DatabaseServices/Dimension/Dimension.ts +++ b/src/DatabaseServices/Dimension/Dimension.ts @@ -1,6 +1,10 @@ import { HostApplicationServices } from "../../ApplicationServices/HostApplicationServices"; import { Factory } from "../CADFactory"; +import { CADFiler } from "../CADFiler"; +import { DimStyleKeyCode } from "../DimStyle/DimstyleKeyCodeEnum"; +import { DimStyleRecord } from "../DimStyle/DimStyleRecord"; import { Entity } from "../Entity/Entity"; +import { ObjectId } from "../ObjectId"; import { Text } from "../Text/Text"; @Factory @@ -8,12 +12,79 @@ export abstract class Dimension extends Entity { OnlyRenderType = true; protected _TextString: string; - protected _TextSize: number = HostApplicationServices.dimTextHeight; protected _Text = new Text(undefined, undefined, "yahei"); - protected _FractionDigits: number = HostApplicationServices.fractionDigitsType; + + //避免标注实体使用材质 + get Material() { return this._MaterialId; } + set Material(materialId: ObjectId) { } + + //#region 标注样式 + protected _DimStyle: ObjectId;//标注样式 + protected _DimStyleOverride: Map = new Map;//标注样式替代 + + //获取覆盖的标注样式(来自Key) + GetDimStyleOverrideValue(key: DimStyleKeyCode): any { return this._DimStyleOverride.get(key); } + //设置覆盖的标注样式 + SetDimStyleOverrideValue(key: DimStyleKeyCode, value: any) + { + if (this.GetDimStyleOverrideValue(key) === value) return; + + this.WriteAllObjectRecord(); + + let oldV = this.GetDimStyleValue(key); + + this._DimStyleOverride.set(key, value); + + if (oldV !== value) + this.Update(); + } + DeleteDimStyleOverrideValue(key: DimStyleKeyCode) + { + if (!this._DimStyleOverride.has(key)) return; + this.WriteAllObjectRecord(); + this._DimStyleOverride.delete(key); + this.Update(); + } + ClearDimStyleOverride() + { + if (this._DimStyleOverride.size === 0) return; + + this.WriteAllObjectRecord(); + this._DimStyleOverride.clear(); + this.Update(); + } + + //获取当前的标注样式值 + GetDimStyleValue(key: DimStyleKeyCode) + { + let value = this.GetDimStyleOverrideValue(key); + if (value !== undefined) return value; + + if (this._DimStyle?.Object) + return this._DimStyle.Object[DimStyleKeyCode[key]]; + + if (HostApplicationServices.CurrentDimStyle && HostApplicationServices.CurrentDimStyle.Object instanceof DimStyleRecord) + return HostApplicationServices.CurrentDimStyle.Object[DimStyleKeyCode[key]]; + } + + get DimStyle() { return this._DimStyle; } + /**设置标注样式 */ + set DimStyle(styleId: ObjectId) + { + if (styleId === this._DimStyle) return; + + this.WriteAllObjectRecord(); + + this._DimStyle = styleId; + + this.Update(); + } + + //#endregion + set TextString(txt: string) { - let str = this.GetString(); + let str = this.GetPrimitiveString(); let tstr = this._TextString ? this._TextString.replace("<>", str) : str; if (txt !== tstr) { @@ -28,38 +99,50 @@ export abstract class Dimension extends Entity get TextString() { - return this._TextString ? this._TextString.replace("<>", this.GetString()) : this.GetString(); + return this._TextString ? this._TextString.replace("<>", this.GetPrimitiveString()) : this.GetPrimitiveString(); + } + /**计算文字盒子占用的宽度 */ + get TextBoxWidth() + { + return this.TextString.length * Math.abs(this.TextSize / 2) * 1.35; } + get TextSize() { return this.GetDimStyleValue(DimStyleKeyCode.DIMTXT); } set TextSize(size: number) { - if (this._Text.Height !== size) - { - this.WriteAllObjectRecord(); - this._TextSize = size; - this.Update(); - } + this.SetDimStyleOverrideValue(DimStyleKeyCode.DIMTXT, size); } - get TextSize() + + get FractionDigits() { return this.GetDimStyleValue(DimStyleKeyCode.DIMALTD); } + set FractionDigits(length: number) { - return this._TextSize; + this.SetDimStyleOverrideValue(DimStyleKeyCode.DIMALTD, length); } - set FractionDigits(length: number) + + /**未被修改过的 原始显示字符串,供内部使用 实际文字需要使用.TextString */ + protected abstract GetPrimitiveString(): string; + + + protected ReadDimStyle(file: CADFiler) { - if (this._FractionDigits !== length) + this._DimStyleOverride.clear(); + let size = file.Read(); + for (let i = 0; i < size; i++) { - this.WriteAllObjectRecord(); - this._FractionDigits = length; - this.Update(); + let k = file.Read(); + let v = file.Read(); + this._DimStyleOverride.set(k, v); } } - - get FractionDigits() + protected WriteDimStyle(file: CADFiler) { - return this._FractionDigits; + file.Write(this._DimStyleOverride.size); + for (let [k, v] of this._DimStyleOverride) + { + file.Write(k); + file.Write(v); + } } - - protected abstract GetString(): string; } diff --git a/src/DatabaseServices/Dimension/LinearDimension.ts b/src/DatabaseServices/Dimension/LinearDimension.ts index 7f8428c54..51c2a983a 100644 --- a/src/DatabaseServices/Dimension/LinearDimension.ts +++ b/src/DatabaseServices/Dimension/LinearDimension.ts @@ -7,16 +7,17 @@ import { AlignedDimension } from "./AlignedDimension"; enum DimDir { - /** - * 水平 - */ + /**水平 */ H = 0, - /** - * 垂直 - */ + /**垂直 */ V = 1 } +/** + * 线性标注 http://docs.autodesk.com/ACD/2011/ENU/filesDXF/WS1a9193826455f5ff18cb41610ec0a2e719-7a23.htm + * 如果按照Autodesk实现的线性标注,这个其实应该叫做AcDbRotatedDimension,而且提供50祖玛(旋转角度) 52(暂时不知道有啥用) + * 现在的实现是根据ArmPt来实现固定的垂直标注或者水平标注 + */ @Factory export class LinearDimension extends AlignedDimension { @@ -26,9 +27,11 @@ export class LinearDimension extends AlignedDimension { return super.TextPosition; } + + //在设置TextPos时,同时会影响标注的方向(H水平 V竖直) (严格来说,这个点应该是标注线的位置,因为文字位置总是总中心.) set TextPosition(p: Vector3) { - p = p.clone().applyMatrix4(this.OCSInv); + p = p.clone().applyMatrix4(this.OCSInv).setZ(0); let bit = 0;//x 1 y 2 if (isBetweenNums(this._FootP1.x, this._FootP2.x, p.x)) bit |= 1; @@ -39,31 +42,35 @@ export class LinearDimension extends AlignedDimension this._DimDir = DimDir.H; else if (bit === 2) this._DimDir = DimDir.V; + //else 叠加态(在中间时,不做变更) if (this._DimDir === DimDir.H) { - this._ArmP1.copy(this._FootP1).setY(p.y); - this._ArmP2.copy(this._FootP2).setY(p.y); + this._ArmP1.copy(this._FootP1).setY(p.y).setZ(0); + this._ArmP2.copy(this._FootP2).setY(p.y).setZ(0); } else { - this._ArmP1.copy(this._FootP1).setX(p.x); - this._ArmP2.copy(this._FootP2).setX(p.x); + this._ArmP1.copy(this._FootP1).setX(p.x).setZ(0); + this._ArmP2.copy(this._FootP2).setX(p.x).setZ(0); } this.Update(); } - ChangeFootPt() + + override OnChangeFootPt() { let l = new Line(this._ArmP1, this._ArmP2); + + //这个代码有个bug,当footPt在肩线(标注线)上时,这个无法更新,更稳妥似乎应该用 if(!equalv2())??? if (!equaln(this._FootP1.x, this._ArmP1.x) && !equaln(this._FootP1.y, this._ArmP1.y)) { let cp1 = l.GetClosestPointTo(this._FootP1, true); - this._ArmP1.copy(cp1); + this._ArmP1.copy(cp1).setZ(0); } if (!equaln(this._FootP2.x, this._ArmP2.x) && !equaln(this._FootP2.y, this._ArmP2.y)) { let cp2 = l.GetClosestPointTo(this._FootP2, true); - this._ArmP2.copy(cp2); + this._ArmP2.copy(cp2).setZ(0); } } } diff --git a/src/DatabaseServices/Dimension/RadiusDimension.ts b/src/DatabaseServices/Dimension/RadiusDimension.ts index adfee24af..3c0c17e53 100644 --- a/src/DatabaseServices/Dimension/RadiusDimension.ts +++ b/src/DatabaseServices/Dimension/RadiusDimension.ts @@ -14,7 +14,6 @@ import { Factory } from "../CADFactory"; import { CADFiler } from "../CADFiler"; import { Circle } from "../Entity/Circle"; import { Line } from "../Entity/Line"; -import { ObjectId } from "../ObjectId"; import { Dimension } from "./Dimension"; import { GetDimLineMaterial } from "./GetDimLineMaterial"; @@ -43,23 +42,23 @@ export class RadiusDimension extends Dimension return this._Text; } - protected GetString(): string + protected GetPrimitiveString(): string { - return FixedNotZero(this._Center.distanceTo(this._DiameterOrRadiusPoint), this._FractionDigits); + return FixedNotZero(this._Center.distanceTo(this._DiameterOrRadiusPoint), this.FractionDigits); } - set Material(materialId: ObjectId) { } - get Center() { return this._Center.clone().applyMatrix4(this._Matrix); } + set Center(v: Vector3) { this.WriteAllObjectRecord(); this._Center.copy(v).applyMatrix4(this.OCSInv); this.Update(); } + get DiameterOrRadiusPoint() { return this._DiameterOrRadiusPoint.clone().applyMatrix4(this._Matrix); @@ -189,7 +188,7 @@ export class RadiusDimension extends Dimension this._Text.TextString = this.TextString; this._Text.Position = this._TextPoint; this._Text.TextRotation = angleAndX(armV); - this._Text.Height = this._TextSize; + this._Text.Height = this.TextSize; this._Text.DeferUpdate(); this._Text.AutoUpdate = true; @@ -280,18 +279,20 @@ export class RadiusDimension extends Dimension this._DiameterOrRadiusPoint.fromArray(file.Read()); this._TextPoint.fromArray(file.Read()); if (ver > 1) this._TextString = file.Read(); - if (ver > 2) this._TextSize = file.Read(); - if (ver > 3) this._FractionDigits = file.Read(); + if (ver > 2 && ver < 5) this.TextSize = file.Read(); + if (ver > 3 && ver < 5) this.FractionDigits = file.Read(); + + if (ver > 4) this.ReadDimStyle(file); } WriteFile(file: CADFiler) { super.WriteFile(file); - file.Write(4); + file.Write(5); file.Write(this._Center.toArray()); file.Write(this._DiameterOrRadiusPoint.toArray()); file.Write(this._TextPoint.toArray()); file.Write(this._TextString); - file.Write(this._TextSize); - file.Write(this._FractionDigits); + + this.WriteDimStyle(file); } } diff --git a/src/DatabaseServices/Entity/Board.ts b/src/DatabaseServices/Entity/Board.ts index 4d59c5380..191f3c60b 100644 --- a/src/DatabaseServices/Entity/Board.ts +++ b/src/DatabaseServices/Entity/Board.ts @@ -1,4 +1,4 @@ -import { Geometry, Line as TLine, LineSegments, Matrix3, Matrix4, Mesh, Object3D, ShapeGeometry, UVGenerator, Vector3 } from 'three'; +import { Euler, Geometry, Line as TLine, LineSegments, Matrix3, Matrix4, Mesh, Object3D, ShapeGeometry, UVGenerator, Vector3 } from 'three'; import { Board2Regions } from '../../Add-on/BoardEditor/Board2Regions'; import { DeserializationBoard2DModeingData, DeserializationBoard3DModeingData, deserializationBoardData, SerializeBoard2DModeingData, SerializeBoard3DModeingData, serializeBoardData } from '../../Add-on/BoardEditor/SerializeBoardData'; import { CyHoleInBoard, ParseBoardRectHoleType, SetBrHighHoleTypeFromRectHoleType, TempRectHoleOption } from '../../Add-on/DrawDrilling/HoleUtils'; @@ -919,10 +919,28 @@ export class Board extends ExtrudeSolid this._SpaceOCS.copy(spcocs); this.Update(); } + + /**实际上这个值可能被改变,应该适当的去校验它(仅在重新设计模块时,这个值会被改变!) */ get Rotation() { - return this._Rotation; + let roMtx = this.RotateMat; + let roMtxInv = roMtx.getInverse(roMtx); + + let csInSpace = this.SpaceOCSInv.multiply(this.OCSNoClone);//逆到模块坐标系 + csInSpace.multiply(roMtxInv);//(正确) + csInSpace.setPosition(0, 0, 0); + + let euRoMtx = new Matrix4().makeRotationFromEuler(new Euler(this._Rotation.x, this._Rotation.y, this._Rotation.z, "ZYX")); + + if (euRoMtx.elements.every((v, i) => equaln(v, csInSpace.elements[i]))) + return this._Rotation; + else + { + let eu = new Euler(0, 0, 0, "ZYX").setFromRotationMatrix(csInSpace); + return eu; + } } + protected ApplyMirrorMatrix(m: Matrix4) { if (!this.Id) diff --git a/src/DatabaseServices/Entity/Entity.ts b/src/DatabaseServices/Entity/Entity.ts index 05c09cf94..c722e9714 100644 --- a/src/DatabaseServices/Entity/Entity.ts +++ b/src/DatabaseServices/Entity/Entity.ts @@ -97,10 +97,7 @@ export class Entity extends CADObject this.UpdateDrawObjectMaterial(type, obj); } - get Material() - { - return this._MaterialId; - } + get Material() { return this._MaterialId; } set ColorIndex(color: number) { diff --git a/src/DatabaseServices/Room/Entity/Wall/RoomWallLine.ts b/src/DatabaseServices/Room/Entity/Wall/RoomWallLine.ts index c0cdbaeb2..f0f2a84f7 100644 --- a/src/DatabaseServices/Room/Entity/Wall/RoomWallLine.ts +++ b/src/DatabaseServices/Room/Entity/Wall/RoomWallLine.ts @@ -6,9 +6,9 @@ import { EntityUpdateWrap } from "../../../../Common/EntityUpdateWrap"; import { ObjectSnapMode } from "../../../../Editor/ObjectSnapMode"; import { Box3Ext } from "../../../../Geometry/Box"; import { BufferGeometryUtils } from "../../../../Geometry/BufferGeometryUtils"; +import { SubtractRange, Tape } from "../../../../Geometry/ExtrudeMeshGeomBuilder/ExtrudeEdgeGeometry2"; import { equaln, equalv3, midPoint, MoveMatrix, ZAxis, ZeroVec } from "../../../../Geometry/GeUtils"; import { RenderType } from "../../../../GraphicsSystem/RenderType"; -import { SubtractRange, Tape } from "../../../../ueapi"; import { Factory } from "../../../CADFactory"; import { CADFiler } from "../../../CADFiler"; import { Curve } from "../../../Entity/Curve"; diff --git a/src/DatabaseServices/Room/ParseService/RoomRegionParse.ts b/src/DatabaseServices/Room/ParseService/RoomRegionParse.ts index 40cd116c9..7b981bbe0 100644 --- a/src/DatabaseServices/Room/ParseService/RoomRegionParse.ts +++ b/src/DatabaseServices/Room/ParseService/RoomRegionParse.ts @@ -1,8 +1,8 @@ import { EntitysUpdateWrap } from "../../../Common/EntityUpdateWrap"; import { Route } from "../../../Geometry/CurveMap"; +import { ContourTreeNode } from "../../../Geometry/ExtrudeMeshGeomBuilder/ExtrudeEdgeGeometry2"; import { RegionParse } from "../../../Geometry/RegionParse"; import { Polyline2Points } from "../../../Nest/Converter/Curves2Points"; -import { ContourTreeNode } from "../../../ueapi"; import { Contour } from "../../Contour"; import { Database } from "../../Database"; import { Curve } from "../../Entity/Curve"; diff --git a/src/DatabaseServices/SymbolTable.ts b/src/DatabaseServices/SymbolTable.ts index 8d9c9ed34..a512a2d82 100644 --- a/src/DatabaseServices/SymbolTable.ts +++ b/src/DatabaseServices/SymbolTable.ts @@ -51,6 +51,12 @@ export class SymbolTable extends CADObject } } + override Destroy(): void + { + super.Destroy(); + this.Symbols.clear(); + } + GetAt(name: string): SymbolTableRecord | undefined { return this.Symbols.get(name); diff --git a/src/DatabaseServices/SymbolTableRecord.ts b/src/DatabaseServices/SymbolTableRecord.ts index ff82d268e..2a2b23444 100644 --- a/src/DatabaseServices/SymbolTableRecord.ts +++ b/src/DatabaseServices/SymbolTableRecord.ts @@ -1,9 +1,9 @@ -import { CADObject } from "./CADObject"; +import { Status } from "../Common/Status"; import { CADFiler } from "./CADFiler"; +import { CADObject } from "./CADObject"; import { SymbolTable } from "./SymbolTable"; -import { Status } from "../Common/Status"; -export class SymbolTableRecord extends CADObject +export abstract class SymbolTableRecord extends CADObject { protected name: string = ""; get Name() diff --git a/src/DatabaseServices/Text/Text.ts b/src/DatabaseServices/Text/Text.ts index 9f919ab0c..85496c708 100644 --- a/src/DatabaseServices/Text/Text.ts +++ b/src/DatabaseServices/Text/Text.ts @@ -1,6 +1,5 @@ -import { Geometry, MathUtils, Matrix4, Mesh, Object3D, ShapeGeometry, Vector3 } from 'three'; +import { Geometry, Matrix4, Mesh, Object3D, ShapeGeometry, Vector3 } from 'three'; import { ColorMaterial } from '../../Common/ColorPalette'; -import { setRotationOnAxis } from '../../Common/Matrix4Utils'; import { UpdateDraw } from '../../Common/Status'; import { Box3Ext } from '../../Geometry/Box'; import { GetBox, MoveMatrix } from '../../Geometry/GeUtils'; @@ -44,7 +43,6 @@ export class Text extends Entity { super(); pos && this._Matrix.setPosition(pos); - this._TextRotation && setRotationOnAxis(this._Matrix, this.Normal, MathUtils.degToRad(this._TextRotation)); } get TextRotation() { diff --git a/src/DatabaseServices/ViewportEntity/ViewportEntity2.ts b/src/DatabaseServices/ViewportEntity/ViewportEntity2.ts index 1e2c79bf1..918f1e3cf 100644 --- a/src/DatabaseServices/ViewportEntity/ViewportEntity2.ts +++ b/src/DatabaseServices/ViewportEntity/ViewportEntity2.ts @@ -1,5 +1,4 @@ import { Geometry, Mesh, MeshBasicMaterial, Object3D, Scene, ShapeGeometry, Vector3, WebGLRenderer, WebGLRenderTarget } from "three"; -import { CADFiler } from "../../api"; import { app } from "../../ApplicationServices/Application"; import { ColorMaterial } from "../../Common/ColorPalette"; import { clamp } from "../../Common/Utils"; @@ -7,6 +6,7 @@ import { GetBox } from "../../Geometry/GeUtils"; import { CameraUpdate } from "../../GraphicsSystem/CameraUpdate"; import { RenderType } from "../../GraphicsSystem/RenderType"; import { Factory } from "../CADFactory"; +import { CADFiler } from "../CADFiler"; import { Entity } from "../Entity/Entity"; import { Polyline } from "../Entity/Polyline"; import { ObjectId } from "../ObjectId"; diff --git a/src/Editor/BoardMoveTool.ts b/src/Editor/BoardMoveTool.ts index fae4088d2..34aefd940 100644 --- a/src/Editor/BoardMoveTool.ts +++ b/src/Editor/BoardMoveTool.ts @@ -258,7 +258,7 @@ export class BoardMoveTool { let dim = new AlignedDimension(); dim.TextSize = 20; - dim.LeadOutVisible = false; + dim.LeadVisible = false; this._DrawDims.push(dim); app.Viewer.PreViewer.Scene.add(dim.DrawObject); } diff --git a/src/Editor/DefaultConfig.ts b/src/Editor/DefaultConfig.ts index 196f2684b..57c5d7a5f 100644 --- a/src/Editor/DefaultConfig.ts +++ b/src/Editor/DefaultConfig.ts @@ -5,7 +5,7 @@ import { IUpdateBoardInfosOption } from "../UI/Components/Board/UpdateBoardInfoi import { EMetalsType, ICompHardwareOption, ICylMetalsOption, IExtMetalsOption, IToplineOption } from "../UI/Components/RightPanel/RightPanelInterface"; import { IKuGangDrawOption } from "../UI/Components/Template/TemplateInterface"; import { ECompareType, IBoardFindOption } from "../UI/Store/BoardFindInterface"; -import { BehindBoardOption, BehindHeightPositon, BoardProcessOption, BoardType, BrRelativePos, ClosingStripOption, CommonPanelConfigOption, ComposingType, CurtailType, FaceDirection, IBatchModifyPanelOption, IBoardBatchCurtailOption, KJLImportConfigOption, LayerBoardOption, LayerNailOption, LinesType, ModifyTextsConfigOption, PointLightOption, RadioType, RectAreaLightOption, RightPlaneLightOption, SideBoardOption, SingleBoardOption, SpotLightOption, StripType, TBBoardOption, VerticalBoardOption, Viewport2ConfigOption, Viewport3ConfigOption, Viewport4ConfigOption, ViewportConfigOption } from "../UI/Store/BoardInterface"; +import { BehindBoardOption, BehindHeightPositon, BoardProcessOption, BoardType, BrRelativePos, ClosingStripOption, CommonPanelConfigOption, ComposingType, CurtailType, FaceDirection, IAutoDimBrsOption, IBatchModifyPanelOption, IBoardBatchCurtailOption, KJLImportConfigOption, LayerBoardOption, LayerNailOption, LinesType, ModifyTextsConfigOption, PointLightOption, RadioType, RectAreaLightOption, RightPlaneLightOption, SideBoardOption, SingleBoardOption, SpotLightOption, StripType, TBBoardOption, VerticalBoardOption, Viewport2ConfigOption, Viewport3ConfigOption, Viewport4ConfigOption, ViewportConfigOption } from "../UI/Store/BoardInterface"; import { DoorPosType, HandleHorPos, HandleVePos, IDoorConfigOption, IDrawerConfigOption, IHingeConfigOption } from "../UI/Store/DoorInterface"; import { IHSOption } from "../UI/Store/HSInterface"; import { ELatticeArrayType, ILatticeOption } from "../UI/Store/LatticeInterface"; @@ -863,3 +863,19 @@ export const DefaultCommonPanelOption: CommonPanelConfigOption = { orderType: EOrderType.ByUpdate, }; Object.freeze(DefaultCommonPanelOption); + +export const DefaultAutoDimBrsOption: IAutoDimBrsOption = { + total: true, + out: true, + inW: false, + inH: false, + noRepeat: false, + noSmSize: false, + noAppointSize: false, + noInSize: false, + noShowMinSize: 20, + noShowMinInSize: 300, + noShowAppointSizes: "", + useParseGroups: "0" +}; +Object.freeze(DefaultAutoDimBrsOption); diff --git a/src/Editor/UserConfig.ts b/src/Editor/UserConfig.ts index d7ec9a688..73da89795 100644 --- a/src/Editor/UserConfig.ts +++ b/src/Editor/UserConfig.ts @@ -36,7 +36,7 @@ export interface IUCSGridConfig extends IBaseOption export class UserConfig implements IConfigStore { - private readonly _version = 30; //🌟🌟每次更新必须向上添加一次版本号🌟🌟 + private readonly _version = 31; //🌟🌟每次更新必须向上添加一次版本号🌟🌟 _renderType: RenderType = RenderType.Wireframe; @observable maxSize: IMaxSizeProps = { isShow: false, @@ -112,7 +112,6 @@ export class UserConfig implements IConfigStore }; @observable autoLines = false; @observable dimTextHeight = 60; - @observable performanceConfig = { fakersweep: false, disablerefcut: false, diff --git a/src/Geometry/RotateUV.ts b/src/Geometry/RotateUV.ts index 2c560cd34..8c4135546 100644 --- a/src/Geometry/RotateUV.ts +++ b/src/Geometry/RotateUV.ts @@ -1,17 +1,14 @@ import { Matrix2 } from './Matrix2'; -let r = new Matrix2(); +export const ROTATE_MTX2 = new Matrix2().set(0, -1, 1, 0); export function RotateUVs(geo: THREE.Geometry) { - r.set(0, -1, - 1, 0); - for (let uvs of geo.faceVertexUvs) { for (let uv of uvs) { for (let v of uv) - r.applyVector(v); + ROTATE_MTX2.applyVector(v); } } geo.uvsNeedUpdate = true; diff --git a/src/Geometry/SpaceParse/SurroundOutlineParse.ts b/src/Geometry/SpaceParse/SurroundOutlineParse.ts index 3527becd0..2c25696fe 100644 --- a/src/Geometry/SpaceParse/SurroundOutlineParse.ts +++ b/src/Geometry/SpaceParse/SurroundOutlineParse.ts @@ -15,16 +15,17 @@ import { ISpaceParse } from "./ISpaceParse"; */ export class SurroundOutlineParse extends ISpaceParse { - Polylines: Polyline[] = []; - Outlines: Curve[] = []; + Polylines: Polyline[] = [];//完整轮廓(ucs z0) + Outlines: Curve[] = [];//完整轮廓炸开后的线(ucs zMax) async Parse() { let ucsNormal = new Vector3().setFromMatrixColumn(app.Editor.UCSMatrix, 2); let ucsInv = app.Editor.UCSMatrixInv; - let boardList = this.ParseBoardList(); - for (let brs of boardList) + let groups = this.GroupBoards(); + for (let brs of groups) { - let pls: Polyline[] = []; + //板转多段线轮廓 + let brPls: Polyline[] = []; let maxZ = -Infinity; for (let br of brs) { @@ -40,9 +41,9 @@ export class SurroundOutlineParse extends ISpaceParse new Vector3(min.x, max.y, max.z), max ]; //br->ucs - let mtx = new Matrix4().multiplyMatrices(ucsInv, br.OCS); + let mtx = new Matrix4().multiplyMatrices(ucsInv, br.OCSNoClone); pts.forEach(p => p.applyMatrix4(mtx)); - pts.sort((p1, p2) => p1.z - p2.z); + pts.sort((p1, p2) => p1.z - p2.z);//下面4个点 上面4个点 if (isParallelTo(brNormal, ucsNormal)) { let cu = br.ContourCurve; @@ -50,88 +51,90 @@ export class SurroundOutlineParse extends ISpaceParse { let pl = cu.Clone().ApplyMatrix(mtx); pl.Position = pl.Position.setZ(0); - pls.push(pl); + brPls.push(pl); } } else if (isPerpendicularityTo(brNormal, ucsNormal)) - pls.push(getRectFrom4Pts(pts.slice(0, 4))); + brPls.push(getRectFrom4Pts(pts.slice(0, 4))); else continue; maxZ = Math.max(maxZ, arrayLast(pts).z); } - if (pls.length === 0) return; - let retCus = this.GetOutline(pls); - //变换到最高点 + if (brPls.length === 0) continue; + + + //并集轮廓 + let reg = Region.CreateFromCurves([brPls.shift()]); + for (let pl of brPls) + { + let plreg = Region.CreateFromCurves([pl]); + if (plreg) + reg.BooleanOper(plreg, BoolOpeartionType.Union); + } + + let unionPls = reg.ShapeManager.ShapeList.map(s => s.Outline.Curve as Polyline); + for (let pl of unionPls) + this.Polylines.push(pl); + + //变换到最高点矩阵 let ucs = app.Editor.UCSMatrix; - let p = new Vector3().setFromMatrixPosition(ucs); - p.add(ucsNormal.clone().multiplyScalar(maxZ)); + let p = new Vector3().setFromMatrixPosition(ucs) + .add(ucsNormal.clone().multiplyScalar(maxZ)); ucs.setPosition(p); - for (let cu of retCus) - cu.ApplyMatrix(ucs); - this.Outlines.push(...retCus); - } - } - private GetOutline(cus: Curve[]) - { - let reg = Region.CreateFromCurves([cus.shift()]); - for (let pl of cus) - { - let plreg = Region.CreateFromCurves([pl]); - if (plreg) - reg.BooleanOper(plreg, BoolOpeartionType.Union); - } - - let pls = reg.ShapeManager.ShapeList.map(s => s.Outline.Curve) as Polyline[]; - this.Polylines.push(...pls); - let retCus: Curve[] = []; - for (let pl of pls) - { - let cus = pl.Explode().filter(cu => !equaln(cu.Length, 0, 1e-6)); - retCus.push(...cus); + //炸开 + for (let pl of unionPls) + { + for (let cu of pl.Explode()) + if (!equaln(cu.Length, 0, 1e-6)) + { + cu.ApplyMatrix(ucs);//move max z + this.Outlines.push(cu); + } + } } - return retCus; } - private ParseBoardList() + //根据包围盒对板进行分堆 + private GroupBoards() { - let boxMap: Map = new Map(); - let boxes: Box3[] = []; + let boxMap: Map = new Map(); for (let br of this.Boards) + boxMap.set(br, br.GetBoundingBoxInMtx(this.SpaceOCSInv)); + + let brGroups: (Board[])[] = []; + let brs = this.Boards.concat(); + while (brs.length) { - let box = br.GetBoundingBoxInMtx(this.SpaceOCSInv); - boxes.push(box); - boxMap.set(box, br); - } - let boardList: Board[][] = []; - while (boxes.length > 0) - { - let originBox = boxes.shift(); - let brs = [boxMap.get(originBox)]; - while (true) + let group = [brs.pop()]; + let groupBox = boxMap.get(group[0]).clone(); + + while (brs.length) { - let remBoxes = boxes.filter(b => + let index = brs.findIndex(br => { - if (originBox.intersectsBox(b)) + let box = boxMap.get(br); + if (box.intersectsBox(groupBox)) { - originBox.union(b); - brs.push(boxMap.get(b)); - return false; + groupBox.union(box); + group.push(br); + return true; } - return true; + return false; }); - if (remBoxes.length === boxes.length) + if (index !== -1) { - boardList.push(brs); - break; + brs.splice(index, 1); + continue; } - else - boxes = remBoxes; + break; } + + brGroups.push(group); } - return boardList; + return brGroups; } } diff --git a/src/GraphicsSystem/Viewer.ts b/src/GraphicsSystem/Viewer.ts index 4a41bbd25..14411f860 100644 --- a/src/GraphicsSystem/Viewer.ts +++ b/src/GraphicsSystem/Viewer.ts @@ -49,11 +49,15 @@ export class Viewer //前置渲染 PreViewer: PreViewer; + /**使用后期渲染器 */ UsePass = false; + /**后期渲染器 */ + Composer: EffectComposer; + _AAType: AAType = AAType.FXAA; RenderPass: RenderPass; OutlinePass: OutlinePass; - Composer: EffectComposer; + private _SMAAPass: SMAAPass; private _Scene: Scene = new Scene; diff --git a/src/Reactor/RoomHoleReactor.ts b/src/Reactor/RoomHoleReactor.ts index c5960edc3..a58c8a401 100644 --- a/src/Reactor/RoomHoleReactor.ts +++ b/src/Reactor/RoomHoleReactor.ts @@ -1,7 +1,7 @@ import { MathUtils } from "three"; -import { Arc } from "../api"; import { arrayLast } from "../Common/ArrayExt"; import { CADObject } from "../DatabaseServices/CADObject"; +import { Arc } from "../DatabaseServices/Entity/Arc"; import { Curve } from "../DatabaseServices/Entity/Curve"; import { RoomHolePolyline } from "../DatabaseServices/Room/Entity/Wall/Hole/RoomHolePolyline"; import { RoomWallArc } from "../DatabaseServices/Room/Entity/Wall/RoomWallArc"; diff --git a/src/UI/Components/AutoDimBoard.tsx b/src/UI/Components/AutoDimBoard.tsx index 30efb5aaf..f3a62e062 100644 --- a/src/UI/Components/AutoDimBoard.tsx +++ b/src/UI/Components/AutoDimBoard.tsx @@ -1,89 +1,260 @@ -import { Button, Card, Checkbox, H5, Intent } from '@blueprintjs/core'; -import React, { Component } from 'react'; +import { Button, Checkbox, Classes, Intent, Position, Radio, RadioGroup, Tooltip } from '@blueprintjs/core'; +import { autorun, observable } from 'mobx'; +import { observer } from 'mobx-react'; +import React from 'react'; import { begin } from 'xaop'; +import { AutoDimBrsStore } from '../../Add-on/DrawDim/AutoDimBrsStore'; import { EDimType } from '../../Add-on/DrawDim/AutoDimBrsTool'; import { app } from '../../ApplicationServices/Application'; +import { safeEval } from '../../Common/eval'; import { KeyBoard } from '../../Common/KeyEnum'; -import { GetCompoentObjectIdString } from './ComponentObjectId'; +import { BoardModalType } from './Board/BoardModalType'; +import { UserConfig } from './Board/UserConfig'; +import { ModalHeader } from './Modal/ModalContainer'; import { ModalState } from './Modal/ModalInterface'; -interface IAutoDimBoardPanel -{ - dimType: EDimType; -} +@observer +export class AutoDimBoardPanel extends React.Component<{ store: AutoDimBrsStore; }> { + _Event: Function[] = []; + @observable _StrIllegal = false; + _NoShowMinSizeInput: React.RefObject = React.createRef(); + _NoShowMinInSizeInput: React.RefObject = React.createRef(); + _NoShowAppointDimSizeInput: React.RefObject = React.createRef(); -export default class AutoDimBoardPanel extends Component { - private dimType: EDimType; - private event: Function; - constructor(props) - { - super(props); - this.state = { - type: this.props.dimType - }; - this.dimType = this.props.dimType; - } componentDidMount() { - this.event = begin(app.Editor.ModalManage, app.Editor.ModalManage.OnKeyDown, (e: KeyboardEvent) => - { - if (GetCompoentObjectIdString(AutoDimBoardPanel) !== app.Editor.ModalManage.CurrentModalKey) return; - let el = e.target as HTMLInputElement; - if (e.keyCode === KeyBoard.Enter || e.keyCode === KeyBoard.Space) + this._Event.push( + begin(app.Editor.ModalManage, app.Editor.ModalManage.OnKeyDown, (e: KeyboardEvent) => + { + if (e.keyCode === KeyBoard.Enter || e.keyCode === KeyBoard.Space) + { + this._OnOk(); + e.preventDefault(); + } + e.stopPropagation(); + return true; + }) + ); + + this._Event.push( + autorun(() => { - this.onOk(); - //使用左右侧板时,该事件会使 拾取点的动态输入框响应到这个键盘事件. - //导致进入交互时,马上有个空格. - e.preventDefault(); - } - e.stopPropagation(); - return true; - }); + if (this._NoShowAppointDimSizeInput) + this._NoShowAppointDimSizeInput.current.value = this.props.store.m_Option.noShowAppointSizes; + if (this._NoShowMinInSizeInput) + this._NoShowMinInSizeInput.current.value = this.props.store.m_Option.noShowMinInSize.toFixed(); + if (this._NoShowMinSizeInput) + this._NoShowMinSizeInput.current.value = this.props.store.m_Option.noShowMinSize.toFixed(); + }) + ); } + componentWillUnmount() { - if (this.event) - { - this.event(); - this.event = null; - } + for (let f of this._Event) f(); + this._Event.length = 0; } + render() { + let option = this.props.store.m_Option; + return ( - -
自动标注配置
- - - - - - -
-
-
+ ); } - private onChange = (e: React.ChangeEvent) => + + _CheckStr = (e: React.ChangeEvent) => { - let target = e.target; - let type = parseInt(target.getAttribute("data-type")); - if (target.checked) - { - this.dimType |= type; - } - else - { - this.dimType &= (~type); - } + if (e.currentTarget.value === '') return; + let str = e.currentTarget.value.replaceAll(/,/g, ','); + + //支持 ',' '|' '空格' + this._StrIllegal = !str.split(',').every(str1 => str1.split('|').every(str2 => str2.split(' ').every(str3 => { return !isNaN(safeEval(str3)) && safeEval(str3) > 0; }))); }; - private onOk = () => + + _OnChange = (key: string) => { - app.Editor.ModalManage.DestoryAndExec({ Status: ModalState.Ok, Data: { type: this.dimType } }); + this.props.store.m_Option[key] = !this.props.store.m_Option[key]; }; - private onCancel = () => + + _OnOk = () => + { + app.Editor.ModalManage.DestoryAndExec({ Status: ModalState.Ok, }); + }; + + _Cancel = () => { app.Editor.ModalManage.Destory(); }; diff --git a/src/UI/Components/Gallery/GalleryStore.tsx b/src/UI/Components/Gallery/GalleryStore.tsx index 27a513e42..09711e6a4 100644 --- a/src/UI/Components/Gallery/GalleryStore.tsx +++ b/src/UI/Components/Gallery/GalleryStore.tsx @@ -1,12 +1,12 @@ import { BreadcrumbProps, Button, Intent, Toaster } from "@blueprintjs/core"; import { observable } from "mobx"; import React, { createRef, RefObject } from "react"; -import { CADFiler } from "../../../api"; import { app } from "../../../ApplicationServices/Application"; import { CommandNames } from "../../../Common/CommandNames"; import { CoolDownTime } from "../../../Common/CoolDownTime"; import { inflateBase64 } from "../../../Common/inflate"; import { IResponseData } from "../../../Common/Request"; +import { CADFiler } from "../../../DatabaseServices/CADFiler"; import { FileServer } from "../../../DatabaseServices/FileServer"; import { commandMachine } from "../../../Editor/CommandMachine"; import { CommandState } from "../../../Editor/CommandState"; diff --git a/src/UI/Components/Modal/OptionModal/ConfigDialog.tsx b/src/UI/Components/Modal/OptionModal/ConfigDialog.tsx index 63337c1c5..218d9c7e2 100644 --- a/src/UI/Components/Modal/OptionModal/ConfigDialog.tsx +++ b/src/UI/Components/Modal/OptionModal/ConfigDialog.tsx @@ -18,7 +18,6 @@ import { userConfigStore } from "../../../Store/UserConfigStore"; import { BoardModalType } from "../../Board/BoardModalType"; import { GetCompoentObjectIdString } from "../../ComponentObjectId"; import { ChaiDanPanel } from "./ChaiDanModal"; -import { DimConfigPanel } from "./DimConfigPanel"; import { DisplayConfigPanel } from "./DisplayConfigPanel"; import { DrawConfigPanel } from "./DrawConfigPanel"; import { FileConfigPanel } from "./FileConfigPanel"; @@ -33,7 +32,6 @@ export enum EOptionTabId Draw = "ht", ChaiDan = "chaidan", Perf = "perf", - DimStyle = "dimstyle", TextStyle = "textstyle", } @@ -251,7 +249,6 @@ export class ConfigDialog extends React.Component<{ store: ConfigStore; selected } /> } /> } /> - } /> } /> diff --git a/src/UI/Components/Modal/OptionModal/DimConfigPanel.tsx b/src/UI/Components/Modal/OptionModal/DimConfigPanel.tsx deleted file mode 100644 index a650b38fa..000000000 --- a/src/UI/Components/Modal/OptionModal/DimConfigPanel.tsx +++ /dev/null @@ -1,130 +0,0 @@ -import { Card, Classes, HTMLSelect, Intent, Label, Position, Slider, Tooltip } from "@blueprintjs/core"; -import { observable } from "mobx"; -import { observer } from "mobx-react"; -import * as React from 'react'; -import { app } from "../../../../ApplicationServices/Application"; -import { safeEval } from "../../../../Common/eval"; -import { KeyBoard } from "../../../../Common/KeyEnum"; -import { FractionDigitsType } from "../../../../Common/SystemEnum"; -import { userConfig } from "../../../../Editor/UserConfig"; - -const WDCss: React.CSSProperties = { - width: 100 -}; - -const Padding: React.CSSProperties = { - padding: "4px 0", - margin: 0 -}; - -@observer -export class DimConfigPanel extends React.Component<{}> -{ - @observable _isPopoverOpen: boolean = false; - @observable _dimTextHeight: number = userConfig.dimTextHeight; - _dimInputEl = React.createRef(); - render() - { - return ( - -
-
- 文字高度: -
-
- - - { - if (e.keyCode === KeyBoard.Escape) - { - //@ts-ignore - e.target.blur(); - } - else if (e.keyCode === KeyBoard.Enter || e.keyCode === KeyBoard.Space) - { - if (!this._isPopoverOpen) - //@ts-ignore - e.target.blur(); - else - //@ts-ignore - e.target.focus(); - e.preventDefault(); - } - e.stopPropagation(); - }} - onFocus={() => - { - this._dimInputEl.current.setSelectionRange(0, this._dimInputEl.current.value.length); - }} - onBlur={(e) => - { - let val = safeEval(e.target.value); - if (!isNaN(val)) - { - if (val <= 0 || val > 300) - { - e.target.value = userConfig.dimTextHeight.toString(); - app.Editor.Prompt('文字尺寸仅限1-300!'); - } - else - { - this._dimTextHeight = val; - userConfig.dimTextHeight = this._dimTextHeight; - } - } - else - { - e.target.value = userConfig.dimTextHeight.toString(); - app.Editor.Prompt('文字尺寸仅限1-300间的数字!'); - } - }} - /> - -
-
-
- - { - this._dimInputEl.current.value = value.toString(); - this._dimTextHeight = value; - userConfig.dimTextHeight = this._dimTextHeight; - }} - value={this._dimTextHeight} - vertical={false} - /> -
- -
- ); - } -} diff --git a/src/UI/Components/RightPanel/RightPanelInterface.ts b/src/UI/Components/RightPanel/RightPanelInterface.ts index 8df7614dd..a1033b080 100644 --- a/src/UI/Components/RightPanel/RightPanelInterface.ts +++ b/src/UI/Components/RightPanel/RightPanelInterface.ts @@ -1,5 +1,5 @@ -import { IBaseOption } from "../../Store/BoardInterface"; import { EBoardKeyList } from "../../../Common/BoardKeyList"; +import { IBaseOption } from "../../Store/BoardInterface"; export interface IHardwareOption extends IBaseOption { @@ -42,7 +42,7 @@ export enum EMetalsType export interface ICompHardwareOption extends IHardwareOption { type: EMetalsType; - isSplite: boolean; + isSplite: boolean;//拆解 isSplitePrice: boolean; color: string; [EBoardKeyList.Mat]: string; diff --git a/src/UI/Components/SourceManage/ImportFile.tsx b/src/UI/Components/SourceManage/ImportFile.tsx index 45fd8986b..0126ce29d 100644 --- a/src/UI/Components/SourceManage/ImportFile.tsx +++ b/src/UI/Components/SourceManage/ImportFile.tsx @@ -3,12 +3,12 @@ import { observable } from "mobx"; import { observer } from "mobx-react"; import pako from "pako"; import React from "react"; -import { CADFiler } from "../../../api"; import { app } from "../../../ApplicationServices/Application"; import { FileSystem } from '../../../Common/FileSystem'; import { TemplateUrls } from "../../../Common/HostUrl"; import { PostJson } from "../../../Common/Request"; import { StoreageKeys } from "../../../Common/StoreageKeys"; +import { CADFiler } from "../../../DatabaseServices/CADFiler"; import { FileServer } from "../../../DatabaseServices/FileServer"; import { TopPanelStore } from "../../Store/TopPanelStore"; import { AppToaster } from "../Toaster"; diff --git a/src/UI/Components/Template/InsertTemplateByBasePoint.ts b/src/UI/Components/Template/InsertTemplateByBasePoint.ts index 49a3d888c..87a8ce826 100644 --- a/src/UI/Components/Template/InsertTemplateByBasePoint.ts +++ b/src/UI/Components/Template/InsertTemplateByBasePoint.ts @@ -4,7 +4,9 @@ import { app } from "../../../ApplicationServices/Application"; import { EBoardKeyList } from "../../../Common/BoardKeyList"; import { TransformVector } from "../../../Common/Matrix4Utils"; import { Sleep } from "../../../Common/Sleep"; +import { DuplicateRecordCloning } from "../../../Common/Status"; import { GetEntity } from "../../../Common/Utils"; +import { Board } from "../../../DatabaseServices/Entity/Board"; import { Entity } from "../../../DatabaseServices/Entity/Entity"; import { HardwareCompositeEntity } from "../../../DatabaseServices/Hardware/HardwareCompositeEntity"; import { HardwareTopline } from "../../../DatabaseServices/Hardware/HardwareTopline"; @@ -17,7 +19,6 @@ import { PromptStatus } from "../../../Editor/PromptResult"; import { ParsePlaceEntitys } from "../../../Editor/TranstrolControl/ParsePlaceEntitys"; import { ParsePlacePos, ParsePlacePosWithTemplate, ParsePlacePosWithTemplate2 } from "../../../Editor/TranstrolControl/ParsePlacePos"; import { equaln, equalv3, ZeroVec } from "../../../Geometry/GeUtils"; -import { Board, DuplicateRecordCloning } from "../../../ueapi"; import { DownPanelStore } from "../../Store/DownPanelStore"; import { IGetRoomInfo } from "./GetRoomCabName"; diff --git a/src/UI/Components/Template/TemplateActionDiglog.tsx b/src/UI/Components/Template/TemplateActionDiglog.tsx index 90e123884..a7b4a4baa 100644 --- a/src/UI/Components/Template/TemplateActionDiglog.tsx +++ b/src/UI/Components/Template/TemplateActionDiglog.tsx @@ -6,6 +6,7 @@ import { app } from '../../../ApplicationServices/Application'; import { safeEval } from '../../../Common/eval'; import { IsMeshMaterialEntity } from '../../../Common/IsMeshMaterialEntity'; import { KeyBoard } from '../../../Common/KeyEnum'; +import { Board } from '../../../DatabaseServices/Entity/Board'; import { Curve } from '../../../DatabaseServices/Entity/Curve'; import { Entity } from '../../../DatabaseServices/Entity/Entity'; import { HardwareCompositeEntity } from '../../../DatabaseServices/Hardware/HardwareCompositeEntity'; @@ -20,7 +21,6 @@ import { CommandWrap } from '../../../Editor/CommandMachine'; import { JigUtils } from '../../../Editor/JigUtils'; import { PromptStatus } from '../../../Editor/PromptResult'; import { GetBoardHighSeal, GetBoardSealingCurves } from '../../../GraphicsSystem/CalcEdgeSealing'; -import { Board } from '../../../ueapi'; import { ITemplateParam } from "../../Store/RightPanelStore/ITemplateParam"; import { RightPanelStore } from '../../Store/RightPanelStore/RightPanelStore'; import { TempalteEditorStore } from '../../Store/TemplateEditorStore'; diff --git a/src/UI/Components/Template/TemplateDrawHandleTool.ts b/src/UI/Components/Template/TemplateDrawHandleTool.ts index 40f9530cc..de8e5422c 100644 --- a/src/UI/Components/Template/TemplateDrawHandleTool.ts +++ b/src/UI/Components/Template/TemplateDrawHandleTool.ts @@ -1,9 +1,10 @@ import { app } from "../../../ApplicationServices/Application"; import { EBoardKeyList } from "../../../Common/BoardKeyList"; +import { DuplicateRecordCloning } from "../../../Common/Status"; +import { Board } from "../../../DatabaseServices/Entity/Board"; import { HardwareCompositeEntity } from "../../../DatabaseServices/Hardware/HardwareCompositeEntity"; import { PositioningHandleSpace } from "../../../DatabaseServices/Template/Positioning/PositioningHandleSpace"; import { TemplateRecord } from "../../../DatabaseServices/Template/TemplateRecord"; -import { Board, DuplicateRecordCloning } from "../../../ueapi"; import { BoardOpenDir } from "../../Store/BoardInterface"; import { DoorStore } from "../../Store/DoorDrawerStore/DoorStore"; import { HandleHorPos, HandleVePos } from "../../Store/DoorInterface"; diff --git a/src/UI/Components/ToolBar/DimParamsPanel.tsx b/src/UI/Components/ToolBar/DimParamsPanel.tsx new file mode 100644 index 000000000..eef062a6d --- /dev/null +++ b/src/UI/Components/ToolBar/DimParamsPanel.tsx @@ -0,0 +1,179 @@ +import { Intent, Position, Slider, Tooltip } from "@blueprintjs/core"; +import { observable } from "mobx"; +import { observer } from "mobx-react"; +import React from "react"; +import { app } from "../../../ApplicationServices/Application"; +import { safeEval } from "../../../Common/eval"; +import { KeyBoard } from "../../../Common/KeyEnum"; +import { FixedNotZero } from "../../../Common/Utils"; +import { AlignedDimension } from "../../../DatabaseServices/Dimension/AlignedDimension"; +import { Dimension } from "../../../DatabaseServices/Dimension/Dimension"; +import { DimStyleKeyCode } from "../../../DatabaseServices/DimStyle/DimstyleKeyCodeEnum"; +import { commandMachine, CommandWrap } from "../../../Editor/CommandMachine"; +import { CommandState } from "../../../Editor/CommandState"; +import { AppToaster } from "../Toaster"; +import { DimParamsList } from "./Properties_Dim"; + +interface DimParamsPanelProps +{ + dims: Dimension[]; + dimParam: [string, string]; + changeFunction: (dim: AlignedDimension, length: number, keys: string[]) => void; +} + +@observer +export class DimParamsPanel extends React.Component +{ + @observable _ParamValue: number = 0; + @observable _MinValue: number = 0; + @observable _MaxValue: number = 0; + @observable _IsPopoverOpen: boolean = false; + @observable _StepSize: number = 1; + _InputRef: React.RefObject = React.createRef();; + _SilderRef: React.RefObject = React.createRef();; + + constructor(props) + { + super(props); + let dim = (this.props.dims[0] as AlignedDimension); + switch (this.props.dimParam[0]) + { + case DimParamsList.FootLineLength: + this._ParamValue = dim.GetDimStyleValue(DimStyleKeyCode.DIMFXL); + this._MaxValue = 500; + this._StepSize = 1; + break; + case DimParamsList.ArrowSize: + this._ParamValue = dim.GetDimStyleValue(DimStyleKeyCode.DIMASZ); + this._MaxValue = 20; + this._StepSize = 1; + break; + } + } + + changeElValue(value: number) + { + this._ParamValue = value; + this._InputRef.current.value = FixedNotZero(value, 1); + } + + render() + { + return ( +
+
+ {this.props.dimParam[1]}: +
+ + + { + let val = safeEval(e.target.value); + if (!isNaN(val)) + { + if (val < this._MinValue || val > this._MaxValue) + this._IsPopoverOpen = true; + else + this._IsPopoverOpen = false; + } + else + this._IsPopoverOpen = true; + }} + onKeyDown={(e) => + { + if (e.keyCode === KeyBoard.Escape) + { + this._InputRef.current.value = this._ParamValue.toString(); + //@ts-ignore + e.target.blur(); + } + else if (e.keyCode === KeyBoard.Enter || e.keyCode === KeyBoard.Space) + { + if (!this._IsPopoverOpen) + //@ts-ignore + e.target.blur(); + e.preventDefault(); + } + e.stopPropagation(); + }} + onFocus={(e) => + { + this._InputRef.current.setSelectionRange(0, this._InputRef.current.value.length); + }} + onBlur={(e) => + { + if (!this._IsPopoverOpen) + { + let val = safeEval(e.target.value); + if (val === this._ParamValue) return; + CommandWrap(() => + { + for (let dim of this.props.dims) + { + if (dim instanceof AlignedDimension) + { + this.props.changeFunction(dim, val, [this.props.dimParam[0]]); + } + } + }, "修改标注" + this.props.dimParam[1]); + this._ParamValue = val; + } + else + { + e.target.value = FixedNotZero(this._ParamValue, 1); + this._IsPopoverOpen = false; + } + }} + /> + +
+
+ + { + if (!CommandState.CommandIng) + commandMachine.CommandStart("更改标注" + this.props.dimParam[1]); + else + if (app.Database.hm.UndoData.CommandName !== "更改标注" + this.props.dimParam[1]) + { + AppToaster.show({ + message: "命令执行中,无法修改标注" + this.props.dimParam[1], + timeout: 5000, + intent: Intent.WARNING, + }, "change_dim_text"); + return false; + } + + this._InputRef.current.value = FixedNotZero(value, 1); + this._ParamValue = value; + for (let dim of this.props.dims) + { + if (dim instanceof AlignedDimension) + this.props.changeFunction(dim, value, [this.props.dimParam[0]]); + } + }} + value={this._ParamValue > this._MaxValue ? this._MaxValue : this._ParamValue} + onRelease={() => + { + if (CommandState.CommandIng && app.Database.hm.UndoData.CommandName === "更改标注" + this.props.dimParam[1]) + commandMachine.CommandEnd(); + }} + vertical={false} + /> +
+ ); + } +} diff --git a/src/UI/Components/ToolBar/PropertiesPanel.less b/src/UI/Components/ToolBar/PropertiesPanel.less index fc6d7122b..03ffee394 100644 --- a/src/UI/Components/ToolBar/PropertiesPanel.less +++ b/src/UI/Components/ToolBar/PropertiesPanel.less @@ -144,6 +144,29 @@ align-items: center; } } + + .leadLength-editor{ + .paramPanel{ + &:hover { + background: #E1E8ED; + cursor : pointer; + } + + margin-top: 10px; + } + + .input_group{ + display : flex; + justify-content: space-between; + + .numeric_input { + width: 60%; + } + } + } + .bp3-slider.bp3-slider-unlabeled{ + margin-top: 5px; + } } } } diff --git a/src/UI/Components/ToolBar/Properties_AlignedDim.tsx b/src/UI/Components/ToolBar/Properties_AlignedDim.tsx index 09100e919..494080644 100644 --- a/src/UI/Components/ToolBar/Properties_AlignedDim.tsx +++ b/src/UI/Components/ToolBar/Properties_AlignedDim.tsx @@ -1,9 +1,9 @@ -import React from "react"; -import { observer } from "mobx-react"; -import { observable } from "mobx"; -import { CommandWrap } from "../../../Editor/CommandMachine"; import { Button, Card, Classes } from "@blueprintjs/core"; +import { observable } from "mobx"; +import { observer } from "mobx-react"; +import React from "react"; import { AlignedDimension } from "../../../DatabaseServices/Dimension/AlignedDimension"; +import { CommandWrap } from "../../../Editor/CommandMachine"; export interface Properties_AlignedDimPanelProps { ents: AlignedDimension[]; @@ -38,7 +38,7 @@ export class Properties_AlignedDimPanel extends React.Component @@ -48,7 +48,7 @@ export class Properties_AlignedDimPanel extends React.Component diff --git a/src/UI/Components/ToolBar/Properties_Dim.tsx b/src/UI/Components/ToolBar/Properties_Dim.tsx index 1becca654..734e8acff 100644 --- a/src/UI/Components/ToolBar/Properties_Dim.tsx +++ b/src/UI/Components/ToolBar/Properties_Dim.tsx @@ -2,19 +2,34 @@ import { Button, Card, Classes, HTMLSelect, Intent, Position, Slider, Tooltip } import hotkeys from "hotkeys-js-ext"; import { observable } from "mobx"; import { observer } from "mobx-react"; -import React from "react"; +import React, { RefObject } from "react"; import { Object3D } from "three"; import { end } from "xaop"; import { app } from "../../../ApplicationServices/Application"; import { safeEval } from "../../../Common/eval"; import { KeyBoard, KeyCode } from "../../../Common/KeyEnum"; import { clamp } from "../../../Common/Utils"; +import { AlignedDimension } from "../../../DatabaseServices/Dimension/AlignedDimension"; import { Dimension } from "../../../DatabaseServices/Dimension/Dimension"; +import { DimStyleKeyCode } from "../../../DatabaseServices/DimStyle/DimstyleKeyCodeEnum"; import { commandMachine, CommandWrap } from "../../../Editor/CommandMachine"; import { CommandState } from "../../../Editor/CommandState"; import { AppToaster } from "../Toaster"; +import { DimParamsPanel } from "./DimParamsPanel"; import { PropertiesStore } from "./PropertiesStore"; +export enum DimParamsList +{ + FootLineLength = "footLineLength", + ArrowSize = "arrowSize", +} + +const ParList: [string, string][] = + [ + [DimParamsList.FootLineLength, "尺寸界线"], + [DimParamsList.ArrowSize, "箭头尺寸"] + ]; + export interface Properties_DimPanelProps { ents: Dimension[]; @@ -23,12 +38,14 @@ export interface Properties_DimPanelProps @observer export class Properties_DimPanel extends React.Component { - private removeFuncs: Function[] = []; + _RemoveFuncs: Function[] = []; + _DimInputEl = React.createRef(); + _DimParamRefs = new Map>(); @observable outlineCheckDims: boolean = true; - @observable private dim_TextSize: number = 60; - @observable private dim_Exact: number = 2; - private dim_InputEl = React.createRef(); - @observable private isPopoverOpen: boolean = false; + @observable _DimTextSize: number = 60; + @observable _DimExact: number = 2; + @observable _IsPopoverOpen: boolean = false; + constructor(p) { super(p); @@ -36,8 +53,8 @@ export class Properties_DimPanel extends React.Component 0) { let numval = this.props.ents[0].TextSize; - this.dim_TextSize = numval; - this.dim_Exact = this.props.ents[0].FractionDigits; + this._DimTextSize = numval; + this._DimExact = this.props.ents[0].FractionDigits; } } @@ -51,14 +68,14 @@ export class Properties_DimPanel extends React.Component 0); let selectCtrl = app.Editor.SelectCtrl; - this.removeFuncs.push( + this._RemoveFuncs.push( end(selectCtrl, selectCtrl.UpdateSelectEvent, () => { this.outlineCheckDims = false; @@ -73,42 +90,77 @@ export class Properties_DimPanel extends React.Component 0) { let numval = this.props.ents[0].TextSize; - this.dim_TextSize = numval; - this.dim_InputEl.current.value = numval.toString(); + this._DimTextSize = numval; + this._DimInputEl.current.value = numval.toString(); } } componentWillUnmount() { - for (let f of this.removeFuncs) + for (let f of this._RemoveFuncs) f(); - this.removeFuncs.length = 0; + this._RemoveFuncs.length = 0; + this._DimParamRefs = undefined; } private Dim_UseDefault(als: Dimension[]) { let propsStore = PropertiesStore.GetInstance() as PropertiesStore; CommandWrap(() => { - this.dim_TextSize = 60; - this.dim_Exact = 2; for (let al of als) { - al.FractionDigits = 2; - al.TextSize = 60; al.ColorIndex = 7; - propsStore.colorIndex = 7;//todo 撤销的时候UI颜色没有同步更改 - this.dim_InputEl.current.value = "60"; - // this.dim_InputEl.setState({ value: "60" }); + al.ClearDimStyleOverride(); + } + + this._DimTextSize = als[0].TextSize; + this._DimExact = als[0].FractionDigits; + //颜色 + propsStore.colorIndex = 7;//todo 撤销的时候UI颜色没有同步更改 + //文字尺寸 + this._DimInputEl.current.value = als[0].TextSize.toString(); + + for (let [str, ref] of this._DimParamRefs) + { + switch (str) + { + case DimParamsList.FootLineLength: + ref.current.changeElValue(als[0].GetDimStyleValue(DimStyleKeyCode.DIMFXL)); + break; + case DimParamsList.ArrowSize: + ref.current.changeElValue(als[0].GetDimStyleValue(DimStyleKeyCode.DIMASZ)); + break; + default: + break; + } } }, "重置标注形态"); } + + private Dim_ChangeLeadLength(dim: AlignedDimension, length: number, keys: string[]) + { + for (let key of keys) + { + if (key === DimParamsList.FootLineLength) + { + dim.SetDimStyleOverrideValue(DimStyleKeyCode.DIMFXL, length); + } + else if (key === DimParamsList.ArrowSize) + { + dim.SetDimStyleOverrideValue(DimStyleKeyCode.DIMASZ, length); + } + } + app.Viewer.UpdateRender(); + } + + render() { let ents = this.props.ents; @@ -152,7 +204,7 @@ export class Properties_DimPanel extends React.Component 小数点后数字个数: this.HandleSelectOnChange(e, ents)} /> @@ -166,11 +218,11 @@ export class Properties_DimPanel extends React.Component { @@ -181,7 +233,7 @@ export class Properties_DimPanel extends React.Component { - this.dim_InputEl.current.setSelectionRange(0, this.dim_InputEl.current.value.length); + this._DimInputEl.current.setSelectionRange(0, this._DimInputEl.current.value.length); }} onBlur={(e) => { @@ -204,7 +256,7 @@ export class Properties_DimPanel extends React.Component { for (let al of this.props.ents) @@ -225,7 +277,7 @@ export class Properties_DimPanel extends React.Component { if (!CommandState.CommandIng) @@ -241,14 +293,14 @@ export class Properties_DimPanel extends React.Component { if (CommandState.CommandIng && app.Database.hm.UndoData.CommandName === "更改标注文字尺寸") @@ -257,6 +309,23 @@ export class Properties_DimPanel extends React.Component + { + ents[0] instanceof AlignedDimension &&
+ { + ParList.map((e) => + { + let paramRef = React.createRef(); + this._DimParamRefs.set(e[0], paramRef); + return ; + }) + } +
+ }
  • diff --git a/src/UI/Components/ToolBar/ResourceLibrary/RsourceStore.ts b/src/UI/Components/ToolBar/ResourceLibrary/RsourceStore.ts index 6a9581d4c..d23aa2127 100644 --- a/src/UI/Components/ToolBar/ResourceLibrary/RsourceStore.ts +++ b/src/UI/Components/ToolBar/ResourceLibrary/RsourceStore.ts @@ -75,6 +75,7 @@ export default class ResourceStore InitClassList = async (class_type: number) => { let res = await getClassList(class_type); + if (!res) return; this.resourceClass = res.class; this.resourceParams = res.params; this.resourceBrands = res.brands; @@ -485,7 +486,8 @@ export default class ResourceStore InitUserCollectDir = async (order: string) => { let res = await GetUserCollectDir(order); - this.userFolder = res.dirs; + if (res) + this.userFolder = res.dirs; }; /** diff --git a/src/UI/Css/style.less b/src/UI/Css/style.less index b0c0a2fe7..227afa2ce 100644 --- a/src/UI/Css/style.less +++ b/src/UI/Css/style.less @@ -1232,3 +1232,49 @@ img { text-overflow: ellipsis; } } + +#dimConfig{ + .bp3-icon.bp3-icon-double-caret-vertical{ + margin-top: -1px; + } +} + +#AutoDimBoardConfig{ + .bp3-dialog-body{ + padding : 20px 0 5px 20px; + background-color : white; + + .dimGroup{ + display : flex; + height : 30px; + margin-bottom : 3px; + + &>:first-child{ + width : 145px; + } + } + + .dimInputGroup{ + display : flex; + height : 30px; + margin-bottom : 3px; + + &>:first-child{ + width : 145px; + } + + input{ + margin-top : -5px; + } + } + + } + + .bp3-dialog-footer{ + button{ + margin-left: 5px; + } + padding: 0 17px 7px; + background-color: white; + } +} diff --git a/src/UI/Store/BoardInterface.ts b/src/UI/Store/BoardInterface.ts index 38b280ad8..828668c93 100644 --- a/src/UI/Store/BoardInterface.ts +++ b/src/UI/Store/BoardInterface.ts @@ -482,3 +482,19 @@ export interface CommonPanelConfigOption { orderType: string; } + +export interface IAutoDimBrsOption extends IBaseOption +{ + total: boolean;//整体标注 + out: boolean;//柜外标注(前视图标注) + inW: boolean;//柜内宽标注 + inH: boolean;//柜内高标注 + noRepeat: boolean;//删除重复 + noSmSize: boolean;//过滤小尺寸 + noAppointSize: boolean;//过滤指定尺寸 + noInSize: boolean;//空间小于该数值时 不标注内空 + noShowMinSize: number; + noShowMinInSize: number; + noShowAppointSizes: string; + useParseGroups: string; +} diff --git a/src/api.ts b/src/api.ts index 3609ca8ad..edc89fb62 100644 --- a/src/api.ts +++ b/src/api.ts @@ -1,3 +1,7 @@ +//del_exp_start +/* +//del_exp_end + export { IsRect } from "./Common/CurveUtils"; export * from "./DatabaseServices/CADFiler"; export * from "./DatabaseServices/Entity/Arc"; @@ -9,3 +13,7 @@ export * from "./GraphicsSystem/BoolOperateUtils"; export { FeedingToolPath } from "./GraphicsSystem/ToolPath/FeedingToolPath"; export * from "./GraphicsSystem/ToolPath/VKnifToolPath"; export * from "./Production/Product"; + +//del_exp_start +*/ +//del_exp_end diff --git a/src/ueapi.ts b/src/ueapi.ts index 1a31fbcca..34fcff83e 100644 --- a/src/ueapi.ts +++ b/src/ueapi.ts @@ -1,3 +1,7 @@ +//del_exp_start +/* +//del_exp_end + export * from "./DatabaseServices/Entity/Board"; //避免类型错误 export * from "./DatabaseServices/Entity/Circle"; export * from "./DatabaseServices/Entity/Extrude"; @@ -19,4 +23,8 @@ export * from "./Nest/Common/ClipperCpp"; export * from "./Reactor/RoomHoleReactor"; //Db Status export * from "./Common/Status"; -export * from "./Add-on/Purge"; \ No newline at end of file +export * from "./Add-on/Purge"; + +//del_exp_start +*/ +//del_exp_end