!1938 重构:标注样式 标注板件(AutoDimBrs,FastDim)

pull/2025/MERGE
林三 2 years ago committed by ChenX
parent 5ad2c7251f
commit 808351edd5

@ -1,4 +1,4 @@
import { Line } from "../../src/api"; import { Line } from "../../src/DatabaseServices/Entity/Line";
import { RegionParse } from "../../src/Geometry/RegionParse"; import { RegionParse } from "../../src/Geometry/RegionParse";
import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; import { LoadEntityFromFileData } from "../Utils/LoadEntity.util";

@ -1,6 +1,6 @@
import { Vector3 } from "three"; import { Vector3 } from "three";
import { CADFiler } from "../../src/api";
import { MakeMirrorMtx } from "../../src/Common/Matrix4Utils"; import { MakeMirrorMtx } from "../../src/Common/Matrix4Utils";
import { CADFiler } from "../../src/DatabaseServices/CADFiler";
import { XAxis } from "../../src/Geometry/GeUtils"; import { XAxis } from "../../src/Geometry/GeUtils";
import { LoadBoardsFromFileData } from "../Utils/LoadEntity.util"; import { LoadBoardsFromFileData } from "../Utils/LoadEntity.util";

@ -1,6 +1,6 @@
import { BoolOpeartionType } from "../../src/api";
import { Board } from "../../src/DatabaseServices/Entity/Board"; import { Board } from "../../src/DatabaseServices/Entity/Board";
import { Region } from "../../src/DatabaseServices/Entity/Region"; import { Region } from "../../src/DatabaseServices/Entity/Region";
import { BoolOpeartionType } from "../../src/GraphicsSystem/BoolOperateUtils";
import "../Utils/jest.util"; import "../Utils/jest.util";
import { LoadEntityFromFileData, LoadRegionsFromFileData } from "../Utils/LoadEntity.util"; import { LoadEntityFromFileData, LoadRegionsFromFileData } from "../Utils/LoadEntity.util";

@ -1,4 +1,4 @@
import { Circle } from "../../src/api"; import { Circle } from "../../src/DatabaseServices/Entity/Circle";
import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; import { LoadEntityFromFileData } from "../Utils/LoadEntity.util";
test('圆的包围盒', () => test('圆的包围盒', () =>

@ -1,5 +1,5 @@
import { Polyline } from "../../src/api";
import { Contour } from "../../src/DatabaseServices/Contour"; import { Contour } from "../../src/DatabaseServices/Contour";
import { Polyline } from "../../src/DatabaseServices/Entity/Polyline";
import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; import { LoadEntityFromFileData } from "../Utils/LoadEntity.util";
test('多个布尔错误', () => test('多个布尔错误', () =>

@ -1,5 +1,5 @@
import { Board } from "../../src/DatabaseServices/Entity/Board";
import { GetSealedBoardContour } from "../../src/GraphicsSystem/CalcEdgeSealing"; import { GetSealedBoardContour } from "../../src/GraphicsSystem/CalcEdgeSealing";
import { Board } from "../../src/ueapi";
import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; import { LoadEntityFromFileData } from "../Utils/LoadEntity.util";
test('无法计算封边', () => test('无法计算封边', () =>

@ -1,8 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // 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]],\\"\\"]"`; 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]],\\"\\"]"`;

@ -2,7 +2,7 @@
exports[`wblockClone 1`] = ` exports[`wblockClone 1`] = `
Array [ Array [
8, 9,
102, 102,
1, 1,
2, 2,
@ -147,12 +147,20 @@ Array [
0, 0,
0, 0,
0, 0,
1,
2,
12,
false,
0,
2,
0,
0,
] ]
`; `;
exports[`wblockClone 2`] = ` exports[`wblockClone 2`] = `
Array [ Array [
8, 9,
104, 104,
1, 1,
2, 2,
@ -372,12 +380,20 @@ Array [
0, 0,
0, 0,
0, 0,
1,
2,
12,
false,
0,
2,
0,
0,
] ]
`; `;
exports[`wblockClone 3`] = ` exports[`wblockClone 3`] = `
Array [ Array [
8, 9,
102, 102,
1, 1,
2, 2,
@ -522,5 +538,13 @@ Array [
0, 0,
0, 0,
0, 0,
1,
2,
12,
false,
0,
2,
0,
0,
] ]
`; `;

@ -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; //?
});

@ -1,5 +1,5 @@
import { Polyline } from "../../src/api";
import { Contour } from "../../src/DatabaseServices/Contour"; import { Contour } from "../../src/DatabaseServices/Contour";
import { Polyline } from "../../src/DatabaseServices/Entity/Polyline";
import "../Utils/jest.util"; import "../Utils/jest.util";
import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; import { LoadEntityFromFileData } from "../Utils/LoadEntity.util";

@ -1,4 +1,4 @@
import { Polyline } from "../../src/api"; import { Polyline } from "../../src/DatabaseServices/Entity/Polyline";
import { LoadCurvesFromFileData } from "../Utils/LoadEntity.util"; import { LoadCurvesFromFileData } from "../Utils/LoadEntity.util";
describe("多段线自交测试", () => describe("多段线自交测试", () =>

@ -1,4 +1,4 @@
import { Polyline } from "../../src/api"; import { Polyline } from "../../src/DatabaseServices/Entity/Polyline";
import "../Utils/jest.util"; import "../Utils/jest.util";
import { LoadCurvesFromFileData } from "../Utils/LoadEntity.util"; import { LoadCurvesFromFileData } from "../Utils/LoadEntity.util";

@ -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 { RectOffset } from "../../src/GraphicsSystem/ToolPath/OptimizeToolPath";
import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; import { LoadEntityFromFileData } from "../Utils/LoadEntity.util";

@ -1,13 +1,13 @@
import { CADFiler } from "../../src/api";
import "../Utils/jest.util"; import "../Utils/jest.util";
import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; import { LoadEntityFromFileData } from "../Utils/LoadEntity.util";
LoadEntityFromFileData; LoadEntityFromFileData;
//如果不延迟导入,则导致循环依赖错误 //如果不延迟导入,则导致循环依赖错误
import { inflateBase64 } from "../../src/Common/inflate"; import { inflateBase64 } from "../../src/Common/inflate";
import { CADFiler } from "../../src/DatabaseServices/CADFiler";
import { Database } from "../../src/DatabaseServices/Database"; import { Database } from "../../src/DatabaseServices/Database";
import { RoomWallBase } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallBase"; import { RoomWallBase } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallBase";
import { RoomWallLine } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallLine"; import { RoomWallLine } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallLine";
import { RoomWallParse } from "../../src/ueapi"; import { RoomWallParse } from "../../src/DatabaseServices/Room/ParseService/RoomWallParse";
test('网洞绘制错误', () => test('网洞绘制错误', () =>
{ {

@ -2,7 +2,6 @@ import { Vector3 } from "three";
import { RoomHolePolyline } from "../../src/DatabaseServices/Room/Entity/Wall/Hole/RoomHolePolyline"; import { RoomHolePolyline } from "../../src/DatabaseServices/Room/Entity/Wall/Hole/RoomHolePolyline";
import { RoomWallLine } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallLine"; import { RoomWallLine } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallLine";
import { RoomIHoleParseAndModify, RoomLHoleParseAndModify } from "../../src/DatabaseServices/Room/ParseService/Hole/RoomIHoleParseAndModify"; import { RoomIHoleParseAndModify, RoomLHoleParseAndModify } from "../../src/DatabaseServices/Room/ParseService/Hole/RoomIHoleParseAndModify";
import { RoomWallParse, UpdateRelevanceWallHole } from "../../src/ueapi";
import "../Utils/jest.util"; import "../Utils/jest.util";
import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; import { LoadEntityFromFileData } from "../Utils/LoadEntity.util";
LoadEntityFromFileData; LoadEntityFromFileData;
@ -11,6 +10,8 @@ import { CADFiler } from "../../src/DatabaseServices/CADFiler";
import { Database } from "../../src/DatabaseServices/Database"; import { Database } from "../../src/DatabaseServices/Database";
import { RoomWallArc } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallArc"; import { RoomWallArc } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallArc";
import { RoomWallBase } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallBase"; 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', () => test('墙洞1', () =>

@ -6,6 +6,7 @@ import { Entity } from "../../src/DatabaseServices/Entity/Entity";
import { Polyline } from "../../src/DatabaseServices/Entity/Polyline"; import { Polyline } from "../../src/DatabaseServices/Entity/Polyline";
import { Region } from "../../src/DatabaseServices/Entity/Region"; import { Region } from "../../src/DatabaseServices/Entity/Region";
import { HardwareTopline } from "../../src/DatabaseServices/Hardware/HardwareTopline"; 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 { RoomWallArc } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallArc";
import { RoomWallLine } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallLine"; import { RoomWallLine } from "../../src/DatabaseServices/Room/Entity/Wall/RoomWallLine";
import { TemplateStretchGripAction } from "../../src/DatabaseServices/Template/Action/TemplateStretchGripAction"; import { TemplateStretchGripAction } from "../../src/DatabaseServices/Template/Action/TemplateStretchGripAction";
@ -21,6 +22,7 @@ Factory(TemplateLeftRightBoardRecord);
TemplateSizeBoard; TemplateSizeBoard;
TemplateStretchGripAction; TemplateStretchGripAction;
RoomWallLine; RoomWallLine;
RoomHolePolyline;
RoomWallArc; RoomWallArc;
Text; Text;

@ -1,5 +1,6 @@
import { MathUtils } from "three"; 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"; import { LoadEntityFromFileData } from "../Utils/LoadEntity.util";
test('V型刀测试', () => test('V型刀测试', () =>

@ -83,7 +83,7 @@
"ts-node": "^10.8.1", "ts-node": "^10.8.1",
"tsconfig-paths": "^3.14.1", "tsconfig-paths": "^3.14.1",
"tslib": "^2.4.0", "tslib": "^2.4.0",
"typescript": "^4.8.2", "typescript": "^4.8.3",
"url-loader": "^4.1.1", "url-loader": "^4.1.1",
"wallaby-webpack": "^3.9.16", "wallaby-webpack": "^3.9.16",
"webpack": "^5.74.0", "webpack": "^5.74.0",

@ -1,35 +1,23 @@
import { Matrix4, Vector2, Vector3 } from "three"; import { Matrix4, Vector3 } from "three";
import { app } from "../../ApplicationServices/Application"; import { app } from "../../ApplicationServices/Application";
import { arrayRemoveDuplicateBySort, arraySortByNumber } from "../../Common/ArrayExt";
import { AlignedDimension } from "../../DatabaseServices/Dimension/AlignedDimension";
import { Board } from "../../DatabaseServices/Entity/Board"; import { Board } from "../../DatabaseServices/Entity/Board";
import { Entity } from "../../DatabaseServices/Entity/Entity"; import { Entity } from "../../DatabaseServices/Entity/Entity";
import { HardwareCompositeEntity } from "../../DatabaseServices/Hardware/HardwareCompositeEntity"; import { HardwareCompositeEntity } from "../../DatabaseServices/Hardware/HardwareCompositeEntity";
import { TemplateRecord } from "../../DatabaseServices/Template/TemplateRecord"; import { TemplateRecord } from "../../DatabaseServices/Template/TemplateRecord";
import { Command } from "../../Editor/CommandMachine"; import { Command } from "../../Editor/CommandMachine";
import { JigUtils } from "../../Editor/JigUtils";
import { PromptStatus } from "../../Editor/PromptResult"; import { PromptStatus } from "../../Editor/PromptResult";
import { equaln, equalnn } from "../../Geometry/GeUtils"; import { equalv3, MoveMatrix, ZeroVec } from "../../Geometry/GeUtils";
import AutoDimBoardPanel from "../../UI/Components/AutoDimBoard"; import { AutoDimBoardPanel } from "../../UI/Components/AutoDimBoard";
import { BoardModalType } from "../../UI/Components/Board/BoardModalType";
import { IConfigOption } from "../../UI/Components/Board/UserConfig";
import { ModalState } from "../../UI/Components/Modal/ModalInterface"; import { ModalState } from "../../UI/Components/Modal/ModalInterface";
import { IConfigStore } from "../../UI/Store/BoardStore"; import { BoardType } from "../../UI/Store/BoardInterface";
import { userConfigStore } from "../../UI/Store/UserConfigStore"; import { IsDoor, IsHandle, IsHinge } from "../HideSelect/HideSelectUtils";
import { IsHandle } from "../HideSelect/HideSelectUtils"; import { autoDimBrsStore } from "./AutoDimBrsStore";
import { autoDimBoardTool } from "./AutoDimBrsTool"; import { DimBoards } from "./DimBoards";
export class Command_AutoDimBrs implements Command export class Command_AutoDimBrs implements Command
{ {
maxThickness: number = 0;
store: AutoDimBrsStore;
async exec() 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({ let enRes = await app.Editor.GetSelection({
Msg: `选择需要标注的柜体`, Msg: `选择需要标注的柜体`,
@ -53,178 +41,92 @@ export class Command_AutoDimBrs implements Command
if (enRes.Status === PromptStatus.Cancel) if (enRes.Status === PromptStatus.Cancel)
return; return;
await promiseLoadConfig;//等待载入配置 let brs = this.GetAllBoards(enRes.SelectSet.SelectEntityList);//获取所有板件包括复合实体内的板件
let store = autoDimBrsStore;
let brs = enRes.SelectSet.SelectEntityList as Board[];
brs = this.backBoards(brs);//获取所有板件包括复合实体内的板件
app.Editor.ModalManage.RenderModal(AutoDimBoardPanel, { dimType: this.store.config.option.dimType });
app.Editor.ModalManage.RenderModeless(AutoDimBoardPanel, { store: store }, { canMinimize: false });
let res = await app.Editor.ModalManage.Wait(); let res = await app.Editor.ModalManage.Wait();
if (res.Status === ModalState.Ok) if (res.Status === ModalState.Ok)
{ {
if (res.Data.type !== this.store.config.option.dimType) let tool = new DimBoards;
{ tool.EanbleParseGroups = store.m_Option.useParseGroups === "0" ? true : false;
//上传配置
this.store.config.option.dimType = res.Data.type;
userConfigStore.SaveConfig(BoardModalType.AutoDimBrs, this.store, { toaster: false }); tool.EnableCabinetInsideHeight = store.m_Option.inH;
} tool.EnableCabinetInsideWidth = store.m_Option.inW;
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);
}
arraySortByNumber(foots); tool.EnableDimAllSize = store.m_Option.total;
arrayRemoveDuplicateBySort(foots, equalnn(1)); tool.EnableFrontOutDims = store.m_Option.out;
let drawY = minY - 20; tool.EnableFilterSmallDim = store.m_Option.noSmSize;
let armY = drawY - 90;
let z = useMaxZ ? maxZ : minZ;
tool.EnableFilterAppointDimSize = store.m_Option.noAppointSize;
let maxOffsetY = 0; tool.FilterSmallDimSize = store.m_Option.noShowMinSize;
//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);
}
//draw总长标注 需要拖拽的FastDim不需要总长 仅有一块板时不需要总长 tool.FiltereCabinetInsideSmallDim = store.m_Option.noInSize;
let drawYTotal = minY - 230 + maxOffsetY; tool.EanbleCabinetInsideSmallDimSize = store.m_Option.noShowMinInSize;
let armYTotal = drawYTotal - 80 + (maxOffsetY / 2);
if (!needJig && brs.length > 1) if (tool.EnableFilterAppointDimSize && store.m_Option.noShowAppointSizes !== '')
{ for (let str of store.m_Option.noShowAppointSizes.split(','))
let alDimTotal = new AlignedDimension( for (let str2 of str.split(' '))
new Vector3(foots[0], drawYTotal, z), for (let str3 of str2.split('|'))
new Vector3(foots[foots.length - 1], drawYTotal, z), tool.FilterDimSizeSet.add(str3);
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);
}
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 ents)
for (let en of oldBoard)
{ {
if (en instanceof Board) if (en instanceof Board)
newBoards.push(en); outAllBrs.push(en);
else if (en instanceof HardwareCompositeEntity) else if (en instanceof HardwareCompositeEntity)
{ {
if (IsHandle(en)) continue; //过滤把手五金 if (IsHandle(en) || IsHinge(en)) continue; //拉手 铰链
let hardwareCompositeEntitys = this.backBoards(en.GetAllEntity());
for (let hce of hardwareCompositeEntitys)
newBoards.push(hce);
}
else
continue;
}
return newBoards;
}
}
//只是用来保存配置 if (IsDoor(en))//如果是门,就给他一个虚拟板
class AutoDimBrsStore implements IConfigStore {
{ let box = en.BoundingBoxInOCS;
configName = "默认"; let size = box.getSize(new Vector3);
configsNames = ['默认']; let br = Board.CreateBoard(size.z, size.x, size.y, BoardType.Behind);
config = { if (!equalv3(box.min, ZeroVec))
option: { br.ApplyMatrix(MoveMatrix(box.min.sub(br.BoundingBox.min)));
dimType: 3 br.ApplyMatrix(en.OCSNoClone);
} br.SpaceOCS = en.SpaceCSNoClone;
};
InitOption() // TestDraw(br);
{
this.config = { outAllBrs.push(br);
option: { }
dimType: 3 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);
}
}
} }
}; }
} return outAllBrs;
SaveConfig()
{
return this.config;
}
UpdateOption(conf: IConfigOption<any>)
{
Object.assign(this.config, conf);
} }
} }

@ -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<any>)
{
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();

@ -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 export enum EDimType
{ {
Total = 0b000001, Total = "total",//整体标注
Out = 0b000010, Out = "out",//柜外标注(前视图标注)
InW = 0b000100, InW = "inW",//柜内宽标注
InH = 0b001000, InH = "inH",//柜内高标注
NoRepeat = 0b010000, NoRepeat = "noRepeat",//删除重复
NoSmSize = 0b100000, NoSmSize = "noSmSize",//过滤小尺寸
All = ~(~0 << 7) NoAppointSize = "noAppointSize",//过滤指定尺寸
} NoInSize = "noInSize",//空间小于该数值时 不标注内空
interface DirPls
{
left: Curve[];
right: Curve[];
top: Curve[];
bottom: Curve[];
} }
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<string>();
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<BoardType, Board[]>();
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<Object3D>();
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();

@ -16,7 +16,7 @@ export class BreakDimAligen extends BreakDimTool
protected CloneDimension(dim: AlignedDimension): AlignedDimension protected CloneDimension(dim: AlignedDimension): AlignedDimension
{ {
let ndim = dim.Clone() as AlignedDimension; let ndim = dim.Clone() as AlignedDimension;
this.m_BasePoint = dim.FootP2; this._BasePoint = dim.FootP2;
if (!this.m_line) if (!this.m_line)
this.m_line = new Line(dim.ArmP1, dim.ArmP2); this.m_line = new Line(dim.ArmP1, dim.ArmP2);
if (!this.f_line) if (!this.f_line)
@ -31,7 +31,7 @@ export class BreakDimAligen extends BreakDimTool
*/ */
protected UpdateNextPoint(p: Vector3, ndim1: AlignedDimension, ndim2: AlignedDimension) 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); let { closestPt, param } = this.m_line.GetClosestAtPoint(p, true);
if (param <= 1 && param >= 0) if (param <= 1 && param >= 0)

@ -8,21 +8,21 @@ import { PromptStatus } from "../../Editor/PromptResult";
import { Dimension } from "./Command_DimContinue"; import { Dimension } from "./Command_DimContinue";
export class BreakDimTool export class BreakDimTool
{ {
protected m_LastDim: Dimension; protected _LastDim: Dimension;
protected m_BasePoint: Vector3; protected _BasePoint: Vector3;
//开始绘制. //开始绘制.
async StartDraw(lastDim: Dimension) async StartDraw(lastDim: Dimension)
{ {
this.m_LastDim = lastDim.Clone(); this._LastDim = lastDim.Clone();
let oldUcs = app.Editor.UCSMatrix; let oldUcs = app.Editor.UCSMatrix;
app.Editor.UCSMatrix = this.m_LastDim.OCS; app.Editor.UCSMatrix = this._LastDim.OCS;
let newDim1 = this.CloneDimension(this.m_LastDim) as AlignedDimension | LineAngularDimension; let newDim1 = this.CloneDimension(this._LastDim) as AlignedDimension | LineAngularDimension;
let newDim2 = this.CloneDimension(this.m_LastDim) as AlignedDimension | LineAngularDimension; let newDim2 = this.CloneDimension(this._LastDim) as AlignedDimension | LineAngularDimension;
if (newDim1 instanceof AlignedDimension && newDim2 instanceof AlignedDimension) if (newDim1 instanceof AlignedDimension && newDim2 instanceof AlignedDimension)
{ {
newDim1.LeadOutFlipped = true; newDim1.LeadInLeft = true;
newDim2.LeadOutFlipped = false; newDim2.LeadInLeft = false;
} }
lastDim.Visible = false; lastDim.Visible = false;
@ -31,7 +31,7 @@ export class BreakDimTool
let ptRes = await app.Editor.GetPoint({ let ptRes = await app.Editor.GetPoint({
AllowNone: true, AllowNone: true,
BasePoint: this.m_BasePoint, BasePoint: this._BasePoint,
Msg: "指定断点原点", Msg: "指定断点原点",
Callback: p => this.UpdateNextPoint(p, newDim1, newDim2) Callback: p => this.UpdateNextPoint(p, newDim1, newDim2)
}); });
@ -84,7 +84,7 @@ export class BreakDimTool
*/ */
protected EndDraw() protected EndDraw()
{ {
this.m_LastDim.GoodBye(); this._LastDim.GoodBye();
} }
/** /**
* :, * :,

@ -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<string>();//过滤指定尺寸列表
EnableFrontIgnoreBackBoard = true;//在前视图标注时忽略背板
EanbleParseGroups = true;//如果不解析分堆,则只有一个堆
FiltereCabinetInsideSmallDim = true;//柜内空间小于150时不标注
EanbleCabinetInsideSmallDimSize = 300;
//#endregion
private groups: (Board[])[] = [];
private groupsBoxs: Box3[] = [];//box in spacecs
private boardBoxMap = new Map<Board, Box3>();//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<Entity>;
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<string>)[] = [];
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<string>;
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;
}

@ -1,33 +1,44 @@
import { Vector3 } from "three"; import { Vector3 } from "three";
import { app } from "../../ApplicationServices/Application"; import { app } from "../../ApplicationServices/Application";
import { UpdateDraw } from "../../Common/Status";
import { JigUtils } from "../../Editor/JigUtils"; import { JigUtils } from "../../Editor/JigUtils";
import { PromptStatus } from "../../Editor/PromptResult"; import { PromptStatus } from "../../Editor/PromptResult";
import { Dimension } from "./Command_DimContinue"; import { Dimension } from "./Command_DimContinue";
import { UpdateDraw } from "../../Common/Status"; export abstract class DimContinue
export class DimContinue
{ {
protected m_LastDim: Dimension; protected _LastDim: Dimension;
protected m_BasePoint: Vector3; protected _BasePoint: Vector3;
//开始绘制. //开始绘制.
async StartDraw(lastDim: Dimension) async StartDraw(lastDim: Dimension)
{ {
this.m_LastDim = lastDim.Clone(); this._LastDim = lastDim.Clone();
let oldUcs = app.Editor.UCSMatrix; let oldUcs = app.Editor.UCSMatrix;
app.Editor.UCSMatrix = this.m_LastDim.OCS; app.Editor.UCSMatrix = this._LastDim.OCS;
while (true) while (true)
{ {
let newDim = this.CloneDimension(this.m_LastDim); let newDim = this.CloneDimension(this._LastDim);
JigUtils.Draw(newDim); JigUtils.Draw(newDim);
let ptRes = await app.Editor.GetPoint({ let ptRes = await app.Editor.GetPoint({
AllowNone: true, AllowNone: true,
BasePoint: this.m_BasePoint, BasePoint: this._BasePoint,
Msg: "指定第二个尺寸原点", 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) if (ptRes.Status === PromptStatus.OK)
{ {
let p = ptRes.Point; let p = ptRes.Point;
this.UpdateNextPoint(p, newDim); if (this.UpdateNextPoint(p, newDim))
{
JigUtils.End();
continue;//点不被接受
}
newDim.Visible = true;
app.Database.ModelSpace.Append(newDim); app.Database.ModelSpace.Append(newDim);
if (!app.Viewer.UsePass) if (!app.Viewer.UsePass)
newDim.Text.Update(UpdateDraw.Geometry); newDim.Text.Update(UpdateDraw.Geometry);
@ -44,30 +55,25 @@ export class DimContinue
* @param dim * @param dim
* @returns and jig draw * @returns and jig draw
*/ */
protected CloneDimension(dim: Dimension): Dimension protected abstract CloneDimension(dim: Dimension): Dimension;
{
return undefined;
}
/** /**
* :, * :,
* @param p * @param p
* @param dim * @param dim
*/ */
protected UpdateNextPoint(p: Vector3, dim: Dimension) protected abstract UpdateNextPoint(p: Vector3, dim: Dimension);
{
}
/** /**
* , * ,
* @param dim * @param dim
*/ */
protected Drawed(dim: Dimension, p: Vector3) protected abstract Drawed(dim: Dimension, p: Vector3);
{
}
/** /**
* :, * :,
*/ */
protected EndDraw() protected EndDraw()
{ {
this.m_LastDim.GoodBye(); this._LastDim.GoodBye();
} }
} }

@ -5,7 +5,7 @@ import { DimContinue } from "./DimContinue";
//对齐标注的连续标注 //对齐标注的连续标注
export class DimContinueAligen extends DimContinue export class DimContinueAligen extends DimContinue
{ {
private m_line: Line; private _line: Line;
/** /**
* : ,, * : ,,
* @param dim * @param dim
@ -16,9 +16,9 @@ export class DimContinueAligen extends DimContinue
let ndim = dim.Clone(); let ndim = dim.Clone();
ndim.FootP1 = dim.FootP2; ndim.FootP1 = dim.FootP2;
ndim.ArmP1 = dim.ArmP2; ndim.ArmP1 = dim.ArmP2;
this.m_BasePoint = dim.FootP2; this._BasePoint = dim.FootP2;
if (!this.m_line) if (!this._line)
this.m_line = new Line(dim.ArmP1, dim.ArmP2); this._line = new Line(dim.ArmP1, dim.ArmP2);
return ndim; return ndim;
} }
/** /**
@ -28,8 +28,8 @@ export class DimContinueAligen extends DimContinue
*/ */
protected UpdateNextPoint(p: Vector3, dim: AlignedDimension) protected UpdateNextPoint(p: Vector3, dim: AlignedDimension)
{ {
let last = this.m_LastDim as AlignedDimension; let last = this._LastDim as AlignedDimension;
let { closestPt, param } = this.m_line.GetClosestAtPoint(p, true); let { closestPt, param } = this._line.GetClosestAtPoint(p, true);
if (param > 1) if (param > 1)
{ {
dim.FootP1 = last.FootP2; dim.FootP1 = last.FootP2;
@ -51,8 +51,8 @@ export class DimContinueAligen extends DimContinue
*/ */
protected Drawed(dim: AlignedDimension, p: Vector3) protected Drawed(dim: AlignedDimension, p: Vector3)
{ {
let last = this.m_LastDim as AlignedDimension; let last = this._LastDim as AlignedDimension;
let { param } = this.m_line.GetClosestAtPoint(p, true); let { param } = this._line.GetClosestAtPoint(p, true);
if (param > 1) if (param > 1)
{ {
last.FootP2 = p; last.FootP2 = p;
@ -63,7 +63,7 @@ export class DimContinueAligen extends DimContinue
last.FootP1 = p; last.FootP1 = p;
last.ArmP1 = dim.ArmP1; 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() protected EndDraw()
{ {
super.EndDraw(); super.EndDraw();
this.m_line.GoodBye(); this._line.GoodBye();
this.m_line = undefined; this._line = undefined;
} }
} }

@ -1,8 +1,8 @@
import { Vector3 } from "three"; import { Vector3 } from "three";
import { Arc } from "../../DatabaseServices/Entity/Arc";
import { LineAngularDimension } from "../../DatabaseServices/Dimension/2LineAngularDimension"; import { LineAngularDimension } from "../../DatabaseServices/Dimension/2LineAngularDimension";
import { Arc } from "../../DatabaseServices/Entity/Arc";
import { Line } from "../../DatabaseServices/Entity/Line"; import { Line } from "../../DatabaseServices/Entity/Line";
import { equalv3 } from "../../Geometry/GeUtils"; import { equaln, equalv3 } from "../../Geometry/GeUtils";
import { DimContinue } from "./DimContinue"; import { DimContinue } from "./DimContinue";
//2直线角度标注的连续标注 //2直线角度标注的连续标注
export class DimContinueLineAngular extends DimContinue export class DimContinueLineAngular extends DimContinue
@ -32,8 +32,8 @@ export class DimContinueLineAngular extends DimContinue
*/ */
protected Drawed(dim: LineAngularDimension, p: Vector3) protected Drawed(dim: LineAngularDimension, p: Vector3)
{ {
this.m_LastDim.GoodBye(); this._LastDim.GoodBye();
this.m_LastDim = dim.Clone(); this._LastDim = dim.Clone();
} }
/** /**
* :, * :,
@ -45,6 +45,8 @@ export class DimContinueLineAngular extends DimContinue
let cp = this._arc.GetClosestPointTo(p, true); let cp = this._arc.GetClosestPointTo(p, true);
let newL1Ep: Vector3; let newL1Ep: Vector3;
let param = this._arc.GetParamAtPoint(cp); 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)); let arcSpOnL1 = !isNaN(new Line(this._l1Sp, this._l1Ep).GetParamAtPoint(this._arc.StartPoint));
if (param > 0.5) if (param > 0.5)
{ {
@ -56,8 +58,6 @@ export class DimContinueLineAngular extends DimContinue
this._narc.StartAngle = this._arc.GetAngleAtParam(1); this._narc.StartAngle = this._arc.GetAngleAtParam(1);
this._narc.EndAngle = this._arc.GetAngleAtParam(param); this._narc.EndAngle = this._arc.GetAngleAtParam(param);
} }
else if (param === 1)
return;
else else
{ {
this._narc.StartAngle = this._arc.GetAngleAtParam(param); this._narc.StartAngle = this._arc.GetAngleAtParam(param);
@ -80,8 +80,7 @@ export class DimContinueLineAngular extends DimContinue
this._narc.EndAngle = this._arc.GetAngleAtParam(param); 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)); dim.UpdateDimData(this._arc.Center, newL1Ep, this._arc.Center, p, this._narc.GetPointAtParam(0.5));
} }
/** /**

@ -3,6 +3,7 @@ import { app } from "../../ApplicationServices/Application";
import { UpdateDraw } from "../../Common/Status"; import { UpdateDraw } from "../../Common/Status";
import { LineAngularDimension } from "../../DatabaseServices/Dimension/2LineAngularDimension"; import { LineAngularDimension } from "../../DatabaseServices/Dimension/2LineAngularDimension";
import { Arc } from "../../DatabaseServices/Entity/Arc"; import { Arc } from "../../DatabaseServices/Entity/Arc";
import { Board } from "../../DatabaseServices/Entity/Board";
import { Circle } from "../../DatabaseServices/Entity/Circle"; import { Circle } from "../../DatabaseServices/Entity/Circle";
import { Curve } from "../../DatabaseServices/Entity/Curve"; import { Curve } from "../../DatabaseServices/Entity/Curve";
import { Line } from "../../DatabaseServices/Entity/Line"; import { Line } from "../../DatabaseServices/Entity/Line";
@ -10,7 +11,6 @@ import { Polyline } from "../../DatabaseServices/Entity/Polyline";
import { JigUtils } from "../../Editor/JigUtils"; import { JigUtils } from "../../Editor/JigUtils";
import { PromptStatus } from "../../Editor/PromptResult"; import { PromptStatus } from "../../Editor/PromptResult";
import { isParallelTo } from "../../Geometry/GeUtils"; import { isParallelTo } from "../../Geometry/GeUtils";
import { Board } from "../../ueapi";
import { ContinueDrawDimension } from "./Command_DimContinue"; import { ContinueDrawDimension } from "./Command_DimContinue";
export class Command_Draw2LineAngularDim export class Command_Draw2LineAngularDim

@ -1,4 +1,4 @@
import { Matrix4, Vector3 } from 'three'; import { Vector3 } from 'three';
import { app } from '../../ApplicationServices/Application'; import { app } from '../../ApplicationServices/Application';
import { AlignedDimension } from '../../DatabaseServices/Dimension/AlignedDimension'; import { AlignedDimension } from '../../DatabaseServices/Dimension/AlignedDimension';
import { LinearDimension } from '../../DatabaseServices/Dimension/LinearDimension'; import { LinearDimension } from '../../DatabaseServices/Dimension/LinearDimension';
@ -20,20 +20,38 @@ export enum DimensionType
Linear = 1 //线性标注 Linear = 1 //线性标注
} }
//dli
export class DrawAlignedDimension implements Command export class DrawAlignedDimension implements Command
{ {
protected DimType = DimensionType.Align; protected DimType = DimensionType.Align;
protected _UseFirstPointUCS = true;
async exec() 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) if (ptRes.Status === PromptStatus.OK)
await this.SelectPointDim(ptRes.Point); await this.GetPointDli(ptRes.Point);
if (ptRes.Status === PromptStatus.None) if (ptRes.Status === PromptStatus.None)
await this.PickUpDim(); await this.GetEntityDli();
break;
}
} }
protected async SelectPointDim(footPt1: Vector3) protected async GetPointDli(footPt1: Vector3)
{ {
let ptRes = await app.Editor.GetPoint({ let ptRes = await app.Editor.GetPoint({
Msg: "请输入第二条尺寸线原点:", Msg: "请输入第二条尺寸线原点:",
@ -44,14 +62,11 @@ export class DrawAlignedDimension implements Command
return; return;
let footPt2 = ptRes.Point; 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); await this.BuildDim(footPt1, footPt2);
} }
//选择对象标注 //选择对象标注
private async PickUpDim() private async GetEntityDli()
{ {
let enRes = await app.Editor.GetEntity({ let enRes = await app.Editor.GetEntity({
Msg: "选择对象", Msg: "选择对象",
@ -104,7 +119,10 @@ export class DrawAlignedDimension implements Command
else else
alDim = new LinearDimension(); 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.FootP1 = footPt1;
alDim.ArmP1 = footPt1; alDim.ArmP1 = footPt1;
@ -121,9 +139,6 @@ export class DrawAlignedDimension implements Command
if (ptRes.Status == PromptStatus.OK) if (ptRes.Status == PromptStatus.OK)
{ {
alDim.TextPosition = ptRes.Point; alDim.TextPosition = ptRes.Point;
//抬高footers
alDim.RaiseFooters(FootersRaiseValue);
app.Database.ModelSpace.Append(alDim); app.Database.ModelSpace.Append(alDim);
await ContinueDrawDimension(alDim); await ContinueDrawDimension(alDim);
} }

@ -1,13 +1,14 @@
import { Box3, MathUtils, Matrix4, Vector3 } from "three"; import { Box3, Vector3 } from "three";
import { app } from "../../ApplicationServices/Application"; import { app } from "../../ApplicationServices/Application";
import { arrayRemoveDuplicateBySort, arraySortByNumber } from "../../Common/ArrayExt";
import { Draw } from "../../Common/Draw";
import { AlignedDimension } from "../../DatabaseServices/Dimension/AlignedDimension"; import { AlignedDimension } from "../../DatabaseServices/Dimension/AlignedDimension";
import { Board } from "../../DatabaseServices/Entity/Board"; import { Board } from "../../DatabaseServices/Entity/Board";
import { Command } from "../../Editor/CommandMachine"; import { Command } from "../../Editor/CommandMachine";
import { JigUtils } from "../../Editor/JigUtils"; import { JigUtils } from "../../Editor/JigUtils";
import { PromptStatus } from "../../Editor/PromptResult"; import { PromptSsgetResult, PromptStatus } from "../../Editor/PromptResult";
import { CoordinateSystem } from "../../Geometry/CoordinateSystem"; import { equalnn } from "../../Geometry/GeUtils";
import { equaln } from "../../Geometry/GeUtils"; import { DimBoards, FilterDimBoardFn } from "./DimBoards";
import { Command_AutoDimBrs } from "./AutoDimBrs";
enum Direction enum Direction
{ {
@ -18,28 +19,32 @@ enum Direction
top = 8 top = 8
} }
const DEG90 = 90;//90°
export class Command_FastDimBrs implements Command export class Command_FastDimBrs implements Command
{ {
async exec() async exec()
{ {
//选择板件 let enRes: PromptSsgetResult;
let enRes = await app.Editor.GetSelection({ let dimAll = false;
UseSelect: true, while (true)
Msg: "选择需要标注的板件", {
Filter: { filterTypes: [Board] }, 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; if (enRes.Status === PromptStatus.Cancel) return;
let brs = enRes.SelectSet.SelectEntityList as Board[]; let brs = enRes.SelectSet.SelectEntityList as Board[];
//排除旋转角度非90度倍数的板件 //排除旋转角度非90度倍数的板件
brs = brs.filter(b => ( brs = brs.filter(FilterDimBoardFn);
equaln(MathUtils.radToDeg(b.Rotation.x) % (DEG90), 0)
&& equaln(MathUtils.radToDeg(b.Rotation.y) % (DEG90), 0)
&& equaln(MathUtils.radToDeg(b.Rotation.z) % (DEG90), 0)
));
if (brs.length === 0) if (brs.length === 0)
{ {
@ -49,91 +54,165 @@ export class Command_FastDimBrs implements Command
app.Editor.Prompt(`可标注板件数: ${brs.length}`); app.Editor.Prompt(`可标注板件数: ${brs.length}`);
let autoDim = new Command_AutoDimBrs(); let tool = new FastDimTool(brs);
tool.enableDimAll = dimAll;
let ucs = app.Editor.UCSMatrix; let oldState = Direction.left;
let ucsInv = app.Editor.UCSMatrixInv;
let ucsDir = new Vector3().setFromMatrixColumn(app.Editor.UCSMatrix, 2);
let isFS = ucsDir.equals(new Vector3(-0, -0, 1));
let brBoxs = brs.map(br => const CreateDims = (p: Vector3) =>
{ {
return br.BoundingBoxInOCS.applyMatrix4(ucsInv.clone().multiply(br.OCS)); let pUcs = p.clone().applyMatrix4(tool.ucsInv);
}); let state = 0;
let boxAll = new Box3();
for (let box of brBoxs) if (pUcs.x > tool.allBox.max.x)
boxAll.union(box); 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[] = []; if (ptRes.Status === PromptStatus.Keyword)
let ptRes = await app.Editor.GetPoint({ tool.enableDimAll = !tool.enableDimAll;
Msg: "指定尺寸线位置:", else
Callback: p =>
{ {
let pUcs = p.clone().applyMatrix4(ucsInv); if (ptRes.Status === PromptStatus.OK)
let drawCS = new Matrix4(); {
let textRo = 0; let als = CreateDims(ptRes.Point);
for (let al of als)
Draw(al);
}
return;
}
}
let oldState = state; }
state = 0; }
if (pUcs.x > boxAll.max.x) export class FastDimTool
state |= Direction.right; {
if (pUcs.y > boxAll.max.y)
state |= Direction.top;
if (pUcs.y < boxAll.min.y) //这个UCS会比适当的修改,保证绘图平面和选择的板在一个平面内
state |= Direction.down; ucs = app.Editor.UCSMatrix;
if (pUcs.x < boxAll.min.x) ucsInv = app.Editor.UCSMatrixInv;
state |= Direction.left; 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) for (let i = 0; i < 2; i++)
state = oldState; this.footss[i].push(box.min.getComponent(i), box.max.getComponent(i));
else if (state === 0)
state = oldState;
if (state & Direction.left) this.allBox.union(box);
{ }
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);
}
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) CreateDims(dir: Direction, pUcs: Vector3)
{ {
aldim.TextPosition = p; //左右上下0 1 2 3
} let index = [Direction.down, Direction.top, Direction.left, Direction.right].indexOf(dir);
}
}); let xIndex = Math.floor(index / 2);
if (ptRes.Status === PromptStatus.OK) 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) let x1 = foots[i];//假设是x 其实可能是y
{ let x2 = foots[i + 1];
aldim.TextPosition = ptRes.Point; let f1 = new Vector3().setComponent(xIndex, x1).setComponent(yIndex, footY);
app.Database.ModelSpace.Append(aldim); 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;
} }
} }

@ -3,7 +3,6 @@ import * as React from 'react';
import { MathUtils, Vector3 } from 'three'; import { MathUtils, Vector3 } from 'three';
import { OBJExporter } from 'three/examples/jsm/exporters/OBJExporter'; import { OBJExporter } from 'three/examples/jsm/exporters/OBJExporter';
import { begin } from 'xaop'; import { begin } from 'xaop';
import { CADFiler } from '../api';
import { app } from "../ApplicationServices/Application"; import { app } from "../ApplicationServices/Application";
import { IsDev } from '../Common/Deving'; import { IsDev } from '../Common/Deving';
import { CURRENT_HOST, RenderUrl } from "../Common/HostUrl"; import { CURRENT_HOST, RenderUrl } from "../Common/HostUrl";
@ -17,6 +16,7 @@ import { CylinderHole } from '../DatabaseServices/3DSolid/CylinderHole';
import { ExtrudeHole } from '../DatabaseServices/3DSolid/ExtrudeHole'; import { ExtrudeHole } from '../DatabaseServices/3DSolid/ExtrudeHole';
import { RevolveSolid } from '../DatabaseServices/3DSolid/RevolveSolid'; import { RevolveSolid } from '../DatabaseServices/3DSolid/RevolveSolid';
import { SweepSolid } from "../DatabaseServices/3DSolid/SweepSolid"; import { SweepSolid } from "../DatabaseServices/3DSolid/SweepSolid";
import { CADFiler } from '../DatabaseServices/CADFiler';
import { Arc } from '../DatabaseServices/Entity/Arc'; import { Arc } from '../DatabaseServices/Entity/Arc';
import { Board } from "../DatabaseServices/Entity/Board"; import { Board } from "../DatabaseServices/Entity/Board";
import { Circle } from "../DatabaseServices/Entity/Circle"; import { Circle } from "../DatabaseServices/Entity/Circle";
@ -39,6 +39,7 @@ import { PhysicalMaterialRecord } from "../DatabaseServices/PhysicalMaterialReco
import { RoomFlatBase } from '../DatabaseServices/Room/Entity/Flat/RoomFlatBase'; import { RoomFlatBase } from '../DatabaseServices/Room/Entity/Flat/RoomFlatBase';
import { RoomHolePolyline } from '../DatabaseServices/Room/Entity/Wall/Hole/RoomHolePolyline'; import { RoomHolePolyline } from '../DatabaseServices/Room/Entity/Wall/Hole/RoomHolePolyline';
import { CURVE_FACE_TYPE_KEY, RoomWallBase } from '../DatabaseServices/Room/Entity/Wall/RoomWallBase'; 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 { Shape } from "../DatabaseServices/Shape";
import { TextureTableRecord } from "../DatabaseServices/Texture"; import { TextureTableRecord } from "../DatabaseServices/Texture";
import { Command } from "../Editor/CommandMachine"; import { Command } from "../Editor/CommandMachine";
@ -47,7 +48,6 @@ import { IdentityMtx4 } from '../Geometry/GeUtils';
import { Orbit } from '../Geometry/Orbit'; import { Orbit } from '../Geometry/Orbit';
import { RenderType } from '../GraphicsSystem/RenderType'; import { RenderType } from '../GraphicsSystem/RenderType';
import { arrayPushArray } from '../Nest/Common/ArrayExt'; import { arrayPushArray } from '../Nest/Common/ArrayExt';
import { RoomWallParse } from '../ueapi';
import { GetCompoentObjectIdString } from '../UI/Components/ComponentObjectId'; import { GetCompoentObjectIdString } from '../UI/Components/ComponentObjectId';
import { ModalFooter, ModalHeader } from '../UI/Components/Modal/ModalContainer'; import { ModalFooter, ModalHeader } from '../UI/Components/Modal/ModalContainer';
import { ModalPosition } from '../UI/Components/Modal/ModalInterface'; import { ModalPosition } from '../UI/Components/Modal/ModalInterface';

@ -1,8 +1,8 @@
import { app } from "../../ApplicationServices/Application"; import { app } from "../../ApplicationServices/Application";
import { Board } from "../../DatabaseServices/Entity/Board"; import { Board } from "../../DatabaseServices/Entity/Board";
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
import { Command } from "../../Editor/CommandMachine"; import { Command } from "../../Editor/CommandMachine";
import { PromptStatus } from "../../Editor/PromptResult"; import { PromptStatus } from "../../Editor/PromptResult";
import { Polyline } from "../../ueapi";
export class Command_Fix2DPath implements Command export class Command_Fix2DPath implements Command
{ {

@ -1,9 +1,9 @@
import { EBoardKeyList } from "../../../Common/BoardKeyList"; import { EBoardKeyList } from "../../../Common/BoardKeyList";
import { IsMeshMaterialEntity } from "../../../Common/IsMeshMaterialEntity"; import { IsMeshMaterialEntity } from "../../../Common/IsMeshMaterialEntity";
import { Board } from "../../../DatabaseServices/Entity/Board";
import { Entity } from "../../../DatabaseServices/Entity/Entity"; import { Entity } from "../../../DatabaseServices/Entity/Entity";
import { HardwareCompositeEntity } from "../../../DatabaseServices/Hardware/HardwareCompositeEntity"; import { HardwareCompositeEntity } from "../../../DatabaseServices/Hardware/HardwareCompositeEntity";
import { PhysicalMaterialRecord } from "../../../DatabaseServices/PhysicalMaterialRecord"; import { PhysicalMaterialRecord } from "../../../DatabaseServices/PhysicalMaterialRecord";
import { Board } from "../../../ueapi";
import { ApplyGoodInfo } from "../../../UI/Components/ApplyGoodInfo"; import { ApplyGoodInfo } from "../../../UI/Components/ApplyGoodInfo";
import { KJL_Parameter, KJL_ParamModel_Hardware } from "./KJLInterface"; import { KJL_Parameter, KJL_ParamModel_Hardware } from "./KJLInterface";

@ -1,7 +1,8 @@
import { Arc, Polyline } from "../../api";
import { app } from "../../ApplicationServices/Application"; import { app } from "../../ApplicationServices/Application";
import { Draw } from "../../Common/Draw"; import { Draw } from "../../Common/Draw";
import { Arc } from "../../DatabaseServices/Entity/Arc";
import { Line } from "../../DatabaseServices/Entity/Line"; import { Line } from "../../DatabaseServices/Entity/Line";
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
import { RoomWallArc } from "../../DatabaseServices/Room/Entity/Wall/RoomWallArc"; import { RoomWallArc } from "../../DatabaseServices/Room/Entity/Wall/RoomWallArc";
import { RoomWallLine } from "../../DatabaseServices/Room/Entity/Wall/RoomWallLine"; import { RoomWallLine } from "../../DatabaseServices/Room/Entity/Wall/RoomWallLine";
import { Command } from "../../Editor/CommandMachine"; import { Command } from "../../Editor/CommandMachine";

@ -1,9 +1,9 @@
import { Intent } from "@blueprintjs/core"; import { Intent } from "@blueprintjs/core";
import { CADFiler } from "../api";
import { app } from "../ApplicationServices/Application"; import { app } from "../ApplicationServices/Application";
import { deflate } from "../Common/SerializeMaterial"; import { deflate } from "../Common/SerializeMaterial";
import { DuplicateRecordCloning } from "../Common/Status"; import { DuplicateRecordCloning } from "../Common/Status";
import { copyTextToClipboard } from "../Common/Utils"; import { copyTextToClipboard } from "../Common/Utils";
import { CADFiler } from "../DatabaseServices/CADFiler";
import { Database } from "../DatabaseServices/Database"; import { Database } from "../DatabaseServices/Database";
import { Entity } from "../DatabaseServices/Entity/Entity"; import { Entity } from "../DatabaseServices/Entity/Entity";
import { IdMaping } from "../DatabaseServices/IdMaping"; import { IdMaping } from "../DatabaseServices/IdMaping";

@ -1,10 +1,10 @@
import { Vector3 } from "three"; import { Vector3 } from "three";
import { Polyline } from "../api";
import { app } from "../ApplicationServices/Application"; import { app } from "../ApplicationServices/Application";
import { Intent } from "../Common/Toaster"; import { Intent } from "../Common/Toaster";
import { FixedNotZero } from "../Common/Utils"; import { FixedNotZero } from "../Common/Utils";
import { Board } from "../DatabaseServices/Entity/Board"; import { Board } from "../DatabaseServices/Entity/Board";
import { Curve } from "../DatabaseServices/Entity/Curve"; import { Curve } from "../DatabaseServices/Entity/Curve";
import { Polyline } from "../DatabaseServices/Entity/Polyline";
import { Text, TextAligen } from "../DatabaseServices/Text/Text"; import { Text, TextAligen } from "../DatabaseServices/Text/Text";
import { Command } from "../Editor/CommandMachine"; import { Command } from "../Editor/CommandMachine";
import { PromptStatus } from "../Editor/PromptResult"; import { PromptStatus } from "../Editor/PromptResult";

@ -7,6 +7,5 @@ export class Test implements Command
{ {
async exec() async exec()
{ {
} }
} }

@ -1,5 +1,6 @@
import { MeshBasicMaterial, MeshStandardMaterial, Texture } from 'three'; import { MeshBasicMaterial, MeshStandardMaterial, Texture } from 'three';
import { FractionDigitsType } from '../Common/SystemEnum'; import { FractionDigitsType } from '../Common/SystemEnum';
import { ObjectId } from '../DatabaseServices/ObjectId';
import { ICursorConfig } from '../Editor/ICursorConfig'; import { ICursorConfig } from '../Editor/ICursorConfig';
import { RenderType } from '../GraphicsSystem/RenderType'; import { RenderType } from '../GraphicsSystem/RenderType';
import { DrillingOption } from '../UI/Store/drillInterface'; import { DrillingOption } from '../UI/Store/drillInterface';
@ -7,6 +8,7 @@ import { DrillingOption } from '../UI/Store/drillInterface';
export class IHostApplicationServices export class IHostApplicationServices
{ {
DefaultMeshMaterial?: MeshBasicMaterial | MeshStandardMaterial; DefaultMeshMaterial?: MeshBasicMaterial | MeshStandardMaterial;
CurrentDimStyle: ObjectId;
@ProxyValue isShowLightShadow: boolean = true;//灯光阴影 (除太阳光外) @ProxyValue isShowLightShadow: boolean = true;//灯光阴影 (除太阳光外)
ShowHistoryLog: boolean = true; ShowHistoryLog: boolean = true;

@ -117,7 +117,7 @@ export enum CommandNames
AddPtOnBoard = "ADDPTONBOARD", AddPtOnBoard = "ADDPTONBOARD",
DeletePtOnBoard = "DELETEPTONBOARD", DeletePtOnBoard = "DELETEPTONBOARD",
BoardFindModify = "BOARDFINDMODIFY", BoardFindModify = "BOARDFINDMODIFY",
LookOverBoardInfos = "LOOKOVERBOARDINFOS", LookOverBoardInfos = "LOOKOVERBOARDINFOS",//BBS
BoardBatchCurtail = "BOARDBATCHCURTAIL", BoardBatchCurtail = "BOARDBATCHCURTAIL",
AutoDimBrs = "AUTODIMBRS", AutoDimBrs = "AUTODIMBRS",
FastDimBrs = "FASTDIMBRS", FastDimBrs = "FASTDIMBRS",

@ -1,5 +1,5 @@
import { SymbolTable } from "./SymbolTable";
import { Factory } from "./CADFactory"; import { Factory } from "./CADFactory";
import { SymbolTable } from "./SymbolTable";
@Factory @Factory
export class BlockTable extends SymbolTable export class BlockTable extends SymbolTable

@ -3,6 +3,7 @@ import { Status } from '../Common/Status';
import { Factory } from './CADFactory'; import { Factory } from './CADFactory';
import { CADFiler } from './CADFiler'; import { CADFiler } from './CADFiler';
import { Database } from './Database'; import { Database } from './Database';
import { Dimension } from './Dimension/Dimension';
import { Entity } from './Entity/Entity'; import { Entity } from './Entity/Entity';
import { ObjectCollection } from './ObjectCollection'; import { ObjectCollection } from './ObjectCollection';
import { SymbolTableRecord } from './SymbolTableRecord'; import { SymbolTableRecord } from './SymbolTableRecord';
@ -24,10 +25,9 @@ export class BlockTableRecord extends SymbolTableRecord
return this; return this;
} }
get Entitys() get Entitys() { return this.EntityCol.Objects; }
{
return this.EntityCol.Objects; /** 提供通用的Add方法(以便在WblockClone时能统一调用.Add) */
}
Add(obj: Entity, isCheckObjectCleanly = true): Status Add(obj: Entity, isCheckObjectCleanly = true): Status
{ {
this.Append(obj, isCheckObjectCleanly); this.Append(obj, isCheckObjectCleanly);
@ -36,13 +36,16 @@ export class BlockTableRecord extends SymbolTableRecord
Append(entity: Entity, isCheckObjectCleanly = true) 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); this.EntityCol.Append(entity, isCheckObjectCleanly);
entity.Owner = this.objectId; entity.Owner = this.objectId;
} }
AppendEvent(entity: Entity) /**添加实体实现(通过转发) */
{ AppendEvent(entity: Entity) { }
}
Remove(entity: Entity) Remove(entity: Entity)
{ {

@ -7,6 +7,8 @@ import { CADFiler } from './CADFiler';
import { CADObject } from './CADObject'; import { CADObject } from './CADObject';
import { CameraSnapshootRecord } from './CameraSnapshoot/CameraSnapshootRecord'; import { CameraSnapshootRecord } from './CameraSnapshoot/CameraSnapshootRecord';
import { DeepCloneFiler } from './DeepCloneFiler'; import { DeepCloneFiler } from './DeepCloneFiler';
import { DimStyleRecord } from './DimStyle/DimStyleRecord';
import { DimStyleTable } from './DimStyle/DimStyleTable';
import { Entity } from './Entity/Entity'; import { Entity } from './Entity/Entity';
import { GroupTable } from './GroupTable'; import { GroupTable } from './GroupTable';
import { HistoricManage } from './HistoricManage'; import { HistoricManage } from './HistoricManage';
@ -39,6 +41,7 @@ export class Database
TemplateTable: TemplateTable; TemplateTable: TemplateTable;
GroupTable: GroupTable; GroupTable: GroupTable;
ProcessingGroupTable: ProcessingGroupTable; ProcessingGroupTable: ProcessingGroupTable;
DimStyleTable: DimStyleTable;
//模型空间(里面有模型空间的实体列表) //模型空间(里面有模型空间的实体列表)
ModelSpace: BlockTableRecord; ModelSpace: BlockTableRecord;
@ -72,29 +75,17 @@ export class Database
this.hm = new HistoricManage().SetDefaultDb(this); this.hm = new HistoricManage().SetDefaultDb(this);
this.hm.Enable = false; this.hm.Enable = false;
this.LayoutSpace = new BlockTableRecord().SetOwnerDatabase(this); this.LayoutSpace = new BlockTableRecord().SetOwnerDatabase(this);
this.DimStyleTable = new DimStyleTable().SetOwnerDatabase(this);
if (buildDefaultDrawing) if (buildDefaultDrawing)
{ {
this.idIndex = 70; this.InitDimStyle();
this.DefaultMaterial = new PhysicalMaterialRecord();
this.DefaultMaterial.Name = "默认"; this.InitMaterial();
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.InitLight(); this.InitLight();
this.SettingDefaultStyleAndMaterial();
} }
this.hm.Enable = !disableHistoric; this.hm.Enable = !disableHistoric;
@ -103,6 +94,38 @@ export class Database
this.idIndex = 100; 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() private InitLight()
{ {
this.idIndex = 80; this.idIndex = 80;
@ -118,7 +141,7 @@ export class Database
this.Lights.Add(this.HemisphereLight); this.Lights.Add(this.HemisphereLight);
} }
SettingDefaultMaterial() SettingDefaultStyleAndMaterial()
{ {
if (!this.defaultDatabase) if (!this.defaultDatabase)
return; return;
@ -126,6 +149,9 @@ export class Database
this.DefaultMaterial = this.GetObjectId(71)?.Object as PhysicalMaterialRecord ?? this.DefaultMaterial; this.DefaultMaterial = this.GetObjectId(71)?.Object as PhysicalMaterialRecord ?? this.DefaultMaterial;
this.DefaultMaterial.Update(); this.DefaultMaterial.Update();
HostApplicationServices.DefaultMeshMaterial = this.DefaultMaterial.Material; HostApplicationServices.DefaultMeshMaterial = this.DefaultMaterial.Material;
let styleRd = this.GetObjectId(60)?.Object as DimStyleRecord;
HostApplicationServices.CurrentDimStyle = styleRd.Id;
} }
Destroy() Destroy()
@ -139,6 +165,7 @@ export class Database
this.GroupTable.Destroy(); this.GroupTable.Destroy();
this.Lights.Destroy(); this.Lights.Destroy();
this.ProcessingGroupTable.Destroy(); this.ProcessingGroupTable.Destroy();
this.DimStyleTable.Destroy();
this.hm.Destroy(); this.hm.Destroy();
this.CameraSnapshoots.length = 0; this.CameraSnapshoots.length = 0;
this.hm.historyRecord.length = 0; this.hm.historyRecord.length = 0;
@ -151,6 +178,7 @@ export class Database
this.GroupTable.SetOwnerDatabase(this); this.GroupTable.SetOwnerDatabase(this);
this.Lights.SetOwnerDatabase(this); this.Lights.SetOwnerDatabase(this);
this.ProcessingGroupTable.SetOwnerDatabase(this); this.ProcessingGroupTable.SetOwnerDatabase(this);
this.DimStyleTable.SetOwnerDatabase(this);
this.hm.SetDefaultDb(this); this.hm.SetDefaultDb(this);
this.LayoutSpace.SetOwnerDatabase(this); this.LayoutSpace.SetOwnerDatabase(this);
this.idIndex = 100; this.idIndex = 100;
@ -160,7 +188,7 @@ export class Database
FileWrite(file = new CADFiler): CADFiler FileWrite(file = new CADFiler): CADFiler
{ {
file.Write(8);//ver; file.Write(9);//ver;
file.Write(this.idIndex); file.Write(this.idIndex);
this.ModelSpace.WriteFile(file); this.ModelSpace.WriteFile(file);
this.TextureTable.WriteFile(file); this.TextureTable.WriteFile(file);
@ -177,6 +205,7 @@ export class Database
for (let r of this.CameraSnapshoots) for (let r of this.CameraSnapshoots)
r.WriteFile(file); r.WriteFile(file);
this.DimStyleTable.WriteFile(file);
return file; return file;
} }
FileRead(file: CADFiler) 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; this.hm.doing = false;
Entity.__ReadFileIng__ = false; Entity.__ReadFileIng__ = false;

@ -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 为 1DIMEXE 定义尺寸线上方的长度 */
@AutoRecord DIMFXL: number = 100;
/** 控制尺寸中换算单位的显示 DIMALT 170 */
@AutoRecord DIMALT: boolean = true;//2
//
/** 控制换算单位的小数位数。如果打开 DIMALTDIMALTD 会设置交替测量中小数点右侧显示的位数。 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
}

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

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

@ -8,11 +8,12 @@ import { reviseMirrorMatrix } from "../../Common/Matrix4Utils";
import { FixedNotZero, FixIndex } from "../../Common/Utils"; import { FixedNotZero, FixIndex } from "../../Common/Utils";
import { ObjectSnapMode } from "../../Editor/ObjectSnapMode"; import { ObjectSnapMode } from "../../Editor/ObjectSnapMode";
import { BufferGeometryUtils } from "../../Geometry/BufferGeometryUtils"; 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 { IntersectOption } from "../../GraphicsSystem/IntersectWith";
import { RenderType } from "../../GraphicsSystem/RenderType"; import { RenderType } from "../../GraphicsSystem/RenderType";
import { Factory } from "../CADFactory"; import { Factory } from "../CADFactory";
import { CADFiler } from "../CADFiler"; import { CADFiler } from "../CADFiler";
import { DimStyleKeyCode } from "../DimStyle/DimstyleKeyCodeEnum";
import { Arc } from "../Entity/Arc"; import { Arc } from "../Entity/Arc";
import { Line } from "../Entity/Line"; import { Line } from "../Entity/Line";
import { TextAligen } from "../Text/Text"; import { TextAligen } from "../Text/Text";
@ -40,9 +41,16 @@ export class LineAngularDimension extends Dimension
this._Text.Height = HostApplicationServices.dimTextHeight; 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) 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.AutoUpdate = false;//更新标记
this._Text.Height = this._TextSize; this._Text.Height = this.TextSize;
this._Text.TextString = this.TextString; this._Text.TextString = this.TextString;
this._Text.Position = this._Arc.GetPointAtParam(0.5); let midAngle = this._Arc.GetAngleAtParam(0.5);
this._Text.TextRotation = this._Arc.GetAngleAtParam(0.5) % (Math.PI) - Math.PI / 2; 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.AutoUpdate = true;//更新标记
this._Text.DeferUpdate(); this._Text.DeferUpdate();
@ -378,20 +389,23 @@ export class LineAngularDimension extends Dimension
this._L2EndPoint.fromArray(file.Read()); this._L2EndPoint.fromArray(file.Read());
this._DimPoint.fromArray(file.Read()); this._DimPoint.fromArray(file.Read());
if (ver > 1) this._TextString = 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) WriteFile(file: CADFiler)
{ {
super.WriteFile(file); super.WriteFile(file);
file.Write(3); file.Write(4);
file.Write(this._L1StartPoint.toArray()); file.Write(this._L1StartPoint.toArray());
file.Write(this._L1EndPoint.toArray()); file.Write(this._L1EndPoint.toArray());
file.Write(this._L2StartPoint.toArray()); file.Write(this._L2StartPoint.toArray());
file.Write(this._L2EndPoint.toArray()); file.Write(this._L2EndPoint.toArray());
file.Write(this._DimPoint.toArray()); file.Write(this._DimPoint.toArray());
file.Write(this._TextString); file.Write(this._TextString);
file.Write(this._TextSize);
this.WriteDimStyle(file);
} }
//#endregion //#endregion

@ -4,53 +4,41 @@ import { LineGeometry } from "three/examples/jsm/lines/LineGeometry";
import { HostApplicationServices } from "../../ApplicationServices/HostApplicationServices"; import { HostApplicationServices } from "../../ApplicationServices/HostApplicationServices";
import { AddEntityDrawObject } from "../../Common/AddEntityDrawObject"; import { AddEntityDrawObject } from "../../Common/AddEntityDrawObject";
import { ColorMaterial } from "../../Common/ColorPalette"; import { ColorMaterial } from "../../Common/ColorPalette";
import { safeEval } from "../../Common/eval";
import { reviseMirrorMatrix } from "../../Common/Matrix4Utils"; import { reviseMirrorMatrix } from "../../Common/Matrix4Utils";
import { UpdateDraw } from "../../Common/Status"; import { UpdateDraw } from "../../Common/Status";
import { FixedNotZero } from "../../Common/Utils"; import { FixedNotZero } from "../../Common/Utils";
import { ObjectSnapMode } from "../../Editor/ObjectSnapMode"; import { ObjectSnapMode } from "../../Editor/ObjectSnapMode";
import { BufferGeometryUtils } from "../../Geometry/BufferGeometryUtils"; 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 { RenderType } from "../../GraphicsSystem/RenderType";
import { Factory } from "../CADFactory"; import { Factory } from "../CADFactory";
import { CADFiler } from "../CADFiler"; import { CADFiler } from "../CADFiler";
import { DimStyleKeyCode } from "../DimStyle/DimstyleKeyCodeEnum";
import { DimTextPosDir } from "../DimStyle/DimStyleRecord";
import { Line } from "../Entity/Line"; import { Line } from "../Entity/Line";
import { Polyline } from "../Entity/Polyline"; import { Polyline } from "../Entity/Polyline";
import { ObjectId } from "../ObjectId";
import { TextAligen } from "../Text/Text"; import { TextAligen } from "../Text/Text";
import { Dimension } from "./Dimension"; import { Dimension } from "./Dimension";
import { GetDimLineMaterial } from "./GetDimLineMaterial"; 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 }]); 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) * (线 LinearDimension)
* @class AlignedDimension
*/ */
@Factory @Factory
export class AlignedDimension extends Dimension export class AlignedDimension extends Dimension
{ {
//引线 //引线(用于绘制)
private _LeadOutLine = new Polyline(); private _LeadLine = new Polyline();
private _LeadOutOffsetY = 72; /**引线的起始位置,在引线坐标系+使用中点 */
private _LeadOutOffsetX = 30; private _LeadPos: Vector2 = new Vector2(30, this.TextSize * 1.2);
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;
constructor( constructor(
//针脚 //针脚
protected _FootP1: Vector3 = new Vector3(), protected _FootP1: Vector3 = new Vector3(),
@ -58,64 +46,58 @@ export class AlignedDimension extends Dimension
//肩膀 //肩膀
protected _ArmP1: Vector3 = new Vector3(), protected _ArmP1: Vector3 = new Vector3(),
protected _ArmP2: Vector3 = new Vector3(), protected _ArmP2: Vector3 = new Vector3(),
protected _TextRotation: number = undefined, protected _TextRotation: number = null,
//是否显示引线 //当尺寸线放不下文字时,使用引线
protected _LeadOutVisible: boolean = true, protected _UseLead: boolean = true,
) )
{ {
super(); 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) set FootP1(v: Vector3)
{ {
this._FootP1.copy(v).applyMatrix4(this.OCSInv); this._FootP1.copy(v).applyMatrix4(this.OCSInv);
this.Update(); this.Update();
} }
get FootP1()
{ get FootP2() { return this._FootP2.clone().applyMatrix4(this._Matrix); }
return this._FootP1.clone().applyMatrix4(this._Matrix);
}
set FootP2(v: Vector3) set FootP2(v: Vector3)
{ {
this._FootP2.copy(v).applyMatrix4(this.OCSInv); this._FootP2.copy(v).applyMatrix4(this.OCSInv);
this.Update(); this.Update();
} }
get FootP2()
{ get ArmP1() { return this._ArmP1.clone().applyMatrix4(this._Matrix); }
return this._FootP2.clone().applyMatrix4(this._Matrix);
}
set ArmP1(v: Vector3) set ArmP1(v: Vector3)
{ {
this.WriteAllObjectRecord();
this._ArmP1.copy(v).applyMatrix4(this.OCSInv); this._ArmP1.copy(v).applyMatrix4(this.OCSInv);
this._ArmP1.setZ(0);
this.Update(); this.Update();
} }
get ArmP1()
{ get ArmP2() { return this._ArmP2.clone().applyMatrix4(this._Matrix); }
return this._ArmP1.clone().applyMatrix4(this._Matrix);
}
set ArmP2(v: Vector3) set ArmP2(v: Vector3)
{ {
this.WriteAllObjectRecord();
this._ArmP2.copy(v).applyMatrix4(this.OCSInv); this._ArmP2.copy(v).applyMatrix4(this.OCSInv);
this._ArmP2.setZ(0);
this.Update(); this.Update();
} }
get ArmP2()
{
return this._ArmP2.clone().applyMatrix4(this._Matrix);
}
get TextPosition() get TextPosition() { return midPoint(this._ArmP1, this._ArmP2).applyMatrix4(this._Matrix); }
{ /**实际上这个是BasePoint 用来定位尺寸线的位置 */
return midPoint(this._ArmP1, this._ArmP2).applyMatrix4(this._Matrix);
}
set TextPosition(p: Vector3) set TextPosition(p: Vector3)
{ {
p = p.clone().applyMatrix4(this.OCSInv); this.WriteAllObjectRecord();
let l = new Line(this._ArmP1.clone(), this._ArmP2.clone()); p = p.clone().applyMatrix4(this.OCSInv).setZ(0);
p.setZ(this._ArmP1.z); let l = new Line(this._ArmP1, this._ArmP2);
let cp = l.GetClosestPointTo(p, true); let cp = l.GetClosestPointTo(p, true);
let v = p.clone().sub(cp); let v = p.clone().sub(cp);
@ -129,59 +111,22 @@ export class AlignedDimension extends Dimension
get DalUcs() get DalUcs()
{ {
let dalUcs = new Matrix4(); 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); let vy = this.ParseTopDir()[0];
if (equaln(this._ArmP1.x, this._ArmP2.x)) let vx = new Vector3().crossVectors(vy, ZAxis);
{ dalUcs = new Matrix4().makeBasis(vx, vy, ZAxis);
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);
} }
dalUcs.setPosition(midPoint(this._ArmP1, this._ArmP2));
return dalUcs; 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) set TextRotation(angle: number)
{ {
this._TextRotation = angle; this._TextRotation = angle;
this.Update(); this.Update();
} }
set TextAligen(al: TextAligen)
{
if (al !== this._Text.TextAligen)
{
this.WriteAllObjectRecord();
this._Text.TextAligen = al;
}
}
get Text() get Text()
{ {
if (!this._Text.TextString) if (!this._Text.TextString)
@ -190,9 +135,9 @@ export class AlignedDimension extends Dimension
return this._Text; 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() get BoundingBox()
@ -204,77 +149,65 @@ export class AlignedDimension extends Dimension
return snapPolyline.BoundingBox; 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.WriteAllObjectRecord();
this._LeadOutVisible = visible; this._UseLead = visible;
this.Update(); this.Update();
} }
//引线朝右视为未翻转 set LeadInLeft(isLeft: boolean)
set LeadOutFlipped(isFlipped: boolean)
{ {
if (this._LeadOutIsFlipped === isFlipped) return; if (this._LeadPos.x < 0 === isLeft)
this.WriteAllObjectRecord(); return;
this._LeadOutIsFlipped = isFlipped;
this.Update();
}
get LeadOutFlipped() this.FlippeLead();
{
return this._LeadOutIsFlipped;
} }
toggleLeadOutVisible() /**切换引线可见性 */
ToggleLeadVisible()
{ {
this.WriteAllObjectRecord(); this.WriteAllObjectRecord();
this.LeadOutVisible = !this._LeadOutVisible; this.LeadVisible = !this._UseLead;
} }
toggleLeadOutFlipped() /**切换引线翻转 */
FlippeLead()
{ {
this.WriteAllObjectRecord(); 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.WriteAllObjectRecord();
this._LeadOutOffsetY = size; this._LeadPos.y = y;
this.Update(); this.Update();
} }
get LeadOutOffsetY() get LeadX() { return this._LeadPos.x; }
set LeadX(x: number)
{ {
return this._LeadOutOffsetY; if (this.LeadX === x) return;
}
set LeadOutOffsetX(size: number)
{
if (this._LeadOutOffsetX === size) return;
this.WriteAllObjectRecord(); this.WriteAllObjectRecord();
this._LeadOutOffsetX = size; this._LeadPos.x = x;
this.Update(); this.Update();
} }
get LeadOutOffsetX() /**设置引线数据 */
SetLeadData(offset: Vector2, isFlipped = false)
{ {
return this._LeadOutOffsetX; this.WriteAllObjectRecord();
} this._LeadPos.copy(offset);
if (isFlipped) this._LeadPos.x *= -1;
set DefaultValue(val: DefaultValue) this.Update();
{
this._DefaultVal = val;
this._LeadOutOffsetX = val.offset.x;
this._LeadOutOffsetY = val.offset.y;
this.LeadOutFlipped = val.isFlipped;
}
get DefaultValue()
{
return this._DefaultVal;
} }
Explode() Explode()
@ -287,13 +220,17 @@ export class AlignedDimension extends Dimension
new Line(this._ArmP2.clone(), this._FootP2.clone()), new Line(this._ArmP2.clone(), this._FootP2.clone()),
this._Text.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( res.push(
new Line(midPoint(this._ArmP1, this._ArmP2), this._LeadOutPts.dragPt.clone()), new Line(mp.clone(), AsVector3(this._LeadPos).add(mp)),
new Line(this._LeadOutPts.dragPt.clone(), this._LeadOutPts.endPt.clone()) 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)); return res.map(en => en.ApplyMatrix(this._Matrix));
} }
protected ApplyMirrorMatrix(m: Matrix4) protected ApplyMirrorMatrix(m: Matrix4)
{ {
this.WriteAllObjectRecord(); this.WriteAllObjectRecord();
@ -312,6 +249,7 @@ export class AlignedDimension extends Dimension
this.Update(UpdateDraw.Geometry); this.Update(UpdateDraw.Geometry);
return this; return this;
} }
Clone(): this Clone(): this
{ {
let ent = super.Clone(); let ent = super.Clone();
@ -337,7 +275,7 @@ export class AlignedDimension extends Dimension
} }
else else
line = new TLine( 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 colorMaterial
); );
@ -351,31 +289,101 @@ export class AlignedDimension extends Dimension
return obj; 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) UpdateDrawObject(renderType: RenderType, obj: Object3D)
{ {
obj.remove(...obj.children.slice(3)); obj.remove(...obj.children.slice(3));
let [line, arrow1, arrow2] = obj.children; 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) if (renderType === RenderType.WireframePrint)
{ {
arrowSize *= HostApplicationServices.lineWidth * 0.5;
const geometry = (<Line2>line).geometry; const geometry = (<Line2>line).geometry;
let nums: number[] = []; 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); nums.push(p.x, p.y, p.z);
geometry.setPositions(nums); geometry.setPositions(nums);
} }
else else
BufferGeometryUtils.UpdatePts((<TLine>line).geometry as BufferGeometry, [this._FootP1, this._ArmP1, this._ArmP2, this._FootP2], true); BufferGeometryUtils.UpdatePts((<TLine>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); arrow1.scale.set(arrowSize, arrowSize, arrowSize);
arrow2.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); arrow1.position.copy(this._ArmP1);
arrow2.position.copy(this._ArmP2); arrow2.position.copy(this._ArmP2);
let armAn = angle(armV);
if (this._ArmP1.distanceTo(this._ArmP2) < 36) if (this._ArmP1.distanceTo(this._ArmP2) < 36)
{ {
arrow1.rotation.z = armAn + Math.PI / 2; arrow1.rotation.z = armAn + Math.PI / 2;
@ -388,95 +396,109 @@ export class AlignedDimension extends Dimension
} }
arrow1.updateMatrix(); arrow1.updateMatrix();
arrow2.updateMatrix(); arrow2.updateMatrix();
//#endregion
//#region 文字和引线
//更新引线this._LeadOutLine 并返回新的字体位置 //更新引线this._LeadOutLine 并返回新的字体位置
let textPos = this.UpdateLeadOutLine(renderType); let textPos = this.UpdateLeadLine();
if (this._LeadOutLine.EndParam > 0 && this._LeadOutLine.Visible) let hasLead = this._UseLead && this.NeedLead;
AddEntityDrawObject(obj, this._LeadOutLine, renderType);
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); this.UpdateText(textPos);
AddEntityDrawObject(obj, this._Text, renderType); 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 * 线textPosition
* @returns textPosition(Vector3)
* @memberof AlignedDimension
*/ */
UpdateLeadOutLine(renderType: RenderType): Vector3 UpdateLeadLine(): Vector3
{ {
let textPosition: Vector3 = midPoint(this._ArmP1, this._ArmP2); let armMidP: Vector3 = midPoint(this._ArmP1, this._ArmP2);
let textPosition = armMidP;
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));//文字宽度是否比托盘更宽 是 则需要引线
if (this._LeadOutVisible && needLeadOut) //引线可见且需要引线 if (this._UseLead && this.NeedLead) //引线可见且需要引线
{ {
let dalUcs = this.DalUcs; let dalUcs = this.DalUcs;
let dalUcsInv = new Matrix4().getInverse(dalUcs);
let textWidthVec = new Vector3(strWidth); let leadP1 = AsVector3(this._LeadPos).applyMatrix4(dalUcs);
let isLeft = (v) => { return v.x < midPoint(this._ArmP1, this._ArmP2).applyMatrix4(dalUcs).x; }; let leadP2 = AsVector3(this._LeadPos).add(new Vector3(this.TextBoxWidth * Math.sign(this._LeadPos.x))).applyMatrix4(dalUcs);
//确定引线的点的位置 textPosition.setFromMatrixColumn(dalUcs, 3);
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);
this._LeadOutLine.AutoUpdate = false; this._LeadLine.AutoUpdate = false;
this._LeadOutLine.LineData = [textPosition, this._LeadOutPts.dragPt, this._LeadOutPts.endPt].map(p => { return { pt: AsVector2(p), bul: 0 }; }); this._LeadLine.IsEmbedEntity = true;//使它可以捕捉
this._LeadOutLine.Position = new Vector3(0, 0, textPosition.z); this._LeadLine.LineData = [textPosition, leadP1, leadP2].map(p => { return { pt: AsVector2(p), bul: 0 }; });
this._LeadOutLine.ColorIndex = this.ColorIndex; this._LeadLine.ColorIndex = this.ColorIndex;
this._LeadOutLine.Visible = true; this._LeadLine.Visible = true;//可见性设置
this._LeadOutLine.AutoUpdate = true; this._LeadLine.AutoUpdate = true;
this._LeadOutLine.DeferUpdate(); this._LeadLine.DeferUpdate();
textPosition = midPoint(this._LeadOutPts.dragPt, this._LeadOutPts.endPt); textPosition.copy(leadP1).add(leadP2).divideScalar(2);//引线中点
} }
else //引线不可见或不需要引线 else //引线不可见或不需要引线
{ {
//使引线不可见 并将dragPt隐藏于托盘中点 this._LeadLine.Visible = false;//可见性设置
this._LeadOutPts.dragPt = midPoint(this._ArmP1, this._ArmP2);
this._LeadOutLine.Visible = false;
} }
return textPosition; return textPosition;
} }
UpdateText(pos?: Vector3) UpdateText(textPos?: Vector3)
{ {
this._Text.AutoUpdate = false; this._Text.AutoUpdate = false;
let textRo = this._TextRotation ?? angleAndX(this._ArmP1.clone().sub(this._ArmP2)); let textRo = this._TextRotation ?? angleAndX(this._ArmP1.clone().sub(this._ArmP2));
this._Text.TextString = this.TextString; 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.TextRotation = textRo;
this._Text.ColorIndex = this._Color; this._Text.ColorIndex = this._Color;
this._Text.Height = this._TextSize; this._Text.Height = this.TextSize * 0.923;//雅黑数字*0.923
this._Text.DeferUpdate(); this._Text.DeferUpdate();
this._Text.AutoUpdate = true; 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( GetObjectSnapPoints(
snapMode: ObjectSnapMode, snapMode: ObjectSnapMode,
pickPoint: Vector3, pickPoint: Vector3,
@ -485,7 +507,24 @@ export class AlignedDimension extends Dimension
): Vector3[] ): Vector3[]
{ {
this.SetDataToTempPolyline(); 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() private SetDataToTempPolyline()
@ -507,22 +546,23 @@ export class AlignedDimension extends Dimension
if (renderType === RenderType.WireframePrint) if (renderType === RenderType.WireframePrint)
return; return;
this.WriteAllObjectRecord(); this.WriteAllObjectRecord();
let colorMat = GetDimLineMaterial(this, renderType); let mtl = GetDimLineMaterial(this, renderType);
this._LeadOutLine.ColorIndex = this._Color; this._LeadLine.ColorIndex = this._Color;
let [line, arrow1, arrow2] = obj.children; let [line, arrow1, arrow2] = obj.children;
(<Mesh>line).material = colorMat; (<Mesh>line).material = mtl;
(<Mesh>arrow1).material = colorMat; (<Mesh>arrow1).material = mtl;
(<Mesh>arrow2).material = colorMat; (<Mesh>arrow2).material = mtl;
this._Text.ColorIndex = this._Color; this._Text.ColorIndex = this._Color;
} }
GetGripPoints(): Array<Vector3> GetGripPoints(): Array<Vector3>
{ {
return [this._FootP1, this._FootP2, this._ArmP1, this._ArmP2, midPoint(this._ArmP1, this._ArmP2), this._LeadOutPts.dragPt].map(p => 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)
return p.clone().applyMatrix4(this._Matrix); pts.push(AsVector3(this._LeadPos).applyMatrix4(this.DalUcs).applyMatrix4(this._Matrix));
}); return pts;
} }
MoveGripPoints(indexList: number[], vec: Vector3) MoveGripPoints(indexList: number[], vec: Vector3)
{ {
this.WriteAllObjectRecord(); this.WriteAllObjectRecord();
@ -531,17 +571,16 @@ export class AlignedDimension extends Dimension
let vec0 = vec.clone().applyMatrix4(inv0); let vec0 = vec.clone().applyMatrix4(inv0);
for (let i of indexList) for (let i of indexList)
{ {
if (i === 5) if (i === 5)//引线
{ {
let dalucs = this.DalUcs; let dalUCS = this.DalUcs.setPosition(0, 0, 0);
//开始拖拽引线dragPt dalUCS.getInverse(dalUCS);
this.isDragLeadOutPt = true; vec0.applyMatrix4(dalUCS);
this._LeadOutPts.dragPt.add(vec0);
let calcV = this._LeadOutPts.dragPt.clone().applyMatrix4(dalucs).sub(midPoint(this._ArmP1, this._ArmP2).applyMatrix4(dalucs)); this._LeadPos.x += vec0.x;
this._LeadOutOffsetY = calcV.y; this._LeadPos.y += vec0.y;
this._LeadOutOffsetX = Math.abs(calcV.x);
} }
else if (i >= 2) else if (i >= 2)//肩膀点 文字点(拽拖这个点不会把标注变大)
{ {
let p = this.TextPosition.add(vec).applyMatrix4(inv); let p = this.TextPosition.add(vec).applyMatrix4(inv);
let l = new Line(this._ArmP1, this._ArmP2); let l = new Line(this._ArmP1, this._ArmP2);
@ -550,24 +589,25 @@ export class AlignedDimension extends Dimension
this._ArmP1.add(v); this._ArmP1.add(v);
this._ArmP2.add(v); this._ArmP2.add(v);
this._LeadOutPts.dragPt.add(v);
} }
else else//脚线
{ {
if (i === 0) if (i === 0)
this._FootP1.add(vec0); this._FootP1.add(vec0);
else else
this._FootP2.add(vec0); this._FootP2.add(vec0);
this.ChangeFootPt(); this.OnChangeFootPt();
} }
} }
this.Update(); this.Update();
} }
GetStretchPoints(): Array<Vector3> GetStretchPoints(): Array<Vector3>
{ {
return this.GetGripPoints(); return this.GetGripPoints();
} }
MoveStretchPoints(indexList: Array<number>, vec: Vector3) MoveStretchPoints(indexList: Array<number>, vec: Vector3)
{ {
this.WriteAllObjectRecord(); this.WriteAllObjectRecord();
@ -585,16 +625,6 @@ export class AlignedDimension extends Dimension
if (bChangeText) if (bChangeText)
this.MoveGripPoints([2], vec); 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------------------------- //#region -------------------------File-------------------------
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化 //对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
@ -610,23 +640,86 @@ export class AlignedDimension extends Dimension
this._FootP2.fromArray(file.Read()); this._FootP2.fromArray(file.Read());
this._TextRotation = file.Read(); this._TextRotation = file.Read();
if (ver > 2) this._TextString = file.Read(); if (ver > 2) this._TextString = file.Read();
if (ver > 3)
if (ver < 7)//升级到版本7之后 标注统一在OCS平面绘制 (脚线允许在不同的平面)
{ {
this._LeadOutVisible = file.Read(); //升级文件版本,将z轴移除
this._LeadOutIsFlipped = file.Read(); let z = this._ArmP1.z;
this._LeadOutPts.dragPt.fromArray(file.Read()); if (!equaln(z, 0))
this._LeadOutOffsetY = file.Read(); {
this._LeadOutOffsetX = file.Read(); 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) WriteFile(file: CADFiler)
{ {
super.WriteFile(file); super.WriteFile(file);
file.Write(6); file.Write(7);
file.Write(this._ArmP1.toArray()); file.Write(this._ArmP1.toArray());
file.Write(this._ArmP2.toArray()); file.Write(this._ArmP2.toArray());
file.Write(this._FootP1.toArray()); file.Write(this._FootP1.toArray());
@ -634,14 +727,10 @@ export class AlignedDimension extends Dimension
file.Write(this._TextRotation); file.Write(this._TextRotation);
file.Write(this._TextString); file.Write(this._TextString);
file.Write(this._LeadOutVisible); file.Write(this._UseLead);
file.Write(this._LeadOutIsFlipped); file.Write(this._LeadPos.x);
file.Write(this._LeadOutPts.dragPt.toArray()); file.Write(this._LeadPos.y);
file.Write(this._LeadOutOffsetY); this.WriteDimStyle(file);
file.Write(this._LeadOutOffsetX);
file.Write(this._TextSize);
file.Write(this._FractionDigits);
} }
//#endregion //#endregion
} }

@ -52,9 +52,9 @@ export class ArcDimension extends Dimension
get TextRadiusAdd() { return this._TextRadiusAdd; } 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 拉伸相关 //#region 拉伸相关
@ -185,7 +185,7 @@ export class ArcDimension extends Dimension
let textOCS = new Matrix4().makeRotationZ(ang + Math.PI * 3 / 2).setPosition(textP); let textOCS = new Matrix4().makeRotationZ(ang + Math.PI * 3 / 2).setPosition(textP);
this._Text.TextAligen = TextAligen.Down; this._Text.TextAligen = TextAligen.Down;
this._Text.OCS = textOCS; this._Text.OCS = textOCS;
this._Text.Height = this._TextSize; this._Text.Height = this.TextSize;
} }
UpdateDrawObjectMaterial(type: RenderType, obj: Object3D, material?: Material) UpdateDrawObjectMaterial(type: RenderType, obj: Object3D, material?: Material)
@ -228,13 +228,15 @@ export class ArcDimension extends Dimension
this._StartAngle = file.Read(); this._StartAngle = file.Read();
this._EndAngle = file.Read(); this._EndAngle = file.Read();
this._TextString = file.Read(); this._TextString = file.Read();
this._TextSize = file.Read(); if (ver < 3) this.TextSize = file.Read();
if (ver > 1) this._FractionDigits = file.Read(); if (ver > 1 && ver < 3) this.FractionDigits = file.Read();
if (ver > 2) this.ReadDimStyle(file);
} }
//对象将自身数据写入到文件. //对象将自身数据写入到文件.
WriteFile(file: CADFiler) WriteFile(file: CADFiler)
{ {
file.Write(2); file.Write(3);
super.WriteFile(file); super.WriteFile(file);
file.Write(this._Center.toArray()); file.Write(this._Center.toArray());
file.Write(this._Radius); file.Write(this._Radius);
@ -243,8 +245,8 @@ export class ArcDimension extends Dimension
file.Write(this._StartAngle); file.Write(this._StartAngle);
file.Write(this._EndAngle); file.Write(this._EndAngle);
file.Write(this._TextString); file.Write(this._TextString);
file.Write(this._TextSize);
file.Write(this._FractionDigits); this.WriteDimStyle(file);
} }
//#endregion //#endregion
} }

@ -1,6 +1,10 @@
import { HostApplicationServices } from "../../ApplicationServices/HostApplicationServices"; import { HostApplicationServices } from "../../ApplicationServices/HostApplicationServices";
import { Factory } from "../CADFactory"; import { Factory } from "../CADFactory";
import { CADFiler } from "../CADFiler";
import { DimStyleKeyCode } from "../DimStyle/DimstyleKeyCodeEnum";
import { DimStyleRecord } from "../DimStyle/DimStyleRecord";
import { Entity } from "../Entity/Entity"; import { Entity } from "../Entity/Entity";
import { ObjectId } from "../ObjectId";
import { Text } from "../Text/Text"; import { Text } from "../Text/Text";
@Factory @Factory
@ -8,12 +12,79 @@ export abstract class Dimension extends Entity
{ {
OnlyRenderType = true; OnlyRenderType = true;
protected _TextString: string; protected _TextString: string;
protected _TextSize: number = HostApplicationServices.dimTextHeight;
protected _Text = new Text(undefined, undefined, "yahei"); 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<DimStyleKeyCode, any> = 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) set TextString(txt: string)
{ {
let str = this.GetString(); let str = this.GetPrimitiveString();
let tstr = this._TextString ? this._TextString.replace("<>", str) : str; let tstr = this._TextString ? this._TextString.replace("<>", str) : str;
if (txt !== tstr) if (txt !== tstr)
{ {
@ -28,38 +99,50 @@ export abstract class Dimension extends Entity
get TextString() 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) set TextSize(size: number)
{ {
if (this._Text.Height !== size) this.SetDimStyleOverrideValue(DimStyleKeyCode.DIMTXT, size);
{
this.WriteAllObjectRecord();
this._TextSize = size;
this.Update();
}
} }
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(); let k = file.Read();
this._FractionDigits = length; let v = file.Read();
this.Update(); this._DimStyleOverride.set(k, v);
} }
} }
protected WriteDimStyle(file: CADFiler)
get FractionDigits()
{ {
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;
} }

@ -7,16 +7,17 @@ import { AlignedDimension } from "./AlignedDimension";
enum DimDir enum DimDir
{ {
/** /**水平 */
*
*/
H = 0, H = 0,
/** /**垂直 */
*
*/
V = 1 V = 1
} }
/**
* 线 http://docs.autodesk.com/ACD/2011/ENU/filesDXF/WS1a9193826455f5ff18cb41610ec0a2e719-7a23.htm
* Autodesk线,AcDbRotatedDimension,50() 52()
* ArmPt
*/
@Factory @Factory
export class LinearDimension extends AlignedDimension export class LinearDimension extends AlignedDimension
{ {
@ -26,9 +27,11 @@ export class LinearDimension extends AlignedDimension
{ {
return super.TextPosition; return super.TextPosition;
} }
//在设置TextPos时,同时会影响标注的方向(H水平 V竖直) (严格来说,这个点应该是标注线的位置,因为文字位置总是总中心.)
set TextPosition(p: Vector3) 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 let bit = 0;//x 1 y 2
if (isBetweenNums(this._FootP1.x, this._FootP2.x, p.x)) if (isBetweenNums(this._FootP1.x, this._FootP2.x, p.x))
bit |= 1; bit |= 1;
@ -39,31 +42,35 @@ export class LinearDimension extends AlignedDimension
this._DimDir = DimDir.H; this._DimDir = DimDir.H;
else if (bit === 2) else if (bit === 2)
this._DimDir = DimDir.V; this._DimDir = DimDir.V;
//else 叠加态(在中间时,不做变更)
if (this._DimDir === DimDir.H) if (this._DimDir === DimDir.H)
{ {
this._ArmP1.copy(this._FootP1).setY(p.y); this._ArmP1.copy(this._FootP1).setY(p.y).setZ(0);
this._ArmP2.copy(this._FootP2).setY(p.y); this._ArmP2.copy(this._FootP2).setY(p.y).setZ(0);
} }
else else
{ {
this._ArmP1.copy(this._FootP1).setX(p.x); this._ArmP1.copy(this._FootP1).setX(p.x).setZ(0);
this._ArmP2.copy(this._FootP2).setX(p.x); this._ArmP2.copy(this._FootP2).setX(p.x).setZ(0);
} }
this.Update(); this.Update();
} }
ChangeFootPt()
override OnChangeFootPt()
{ {
let l = new Line(this._ArmP1, this._ArmP2); 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)) if (!equaln(this._FootP1.x, this._ArmP1.x) && !equaln(this._FootP1.y, this._ArmP1.y))
{ {
let cp1 = l.GetClosestPointTo(this._FootP1, true); 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)) if (!equaln(this._FootP2.x, this._ArmP2.x) && !equaln(this._FootP2.y, this._ArmP2.y))
{ {
let cp2 = l.GetClosestPointTo(this._FootP2, true); let cp2 = l.GetClosestPointTo(this._FootP2, true);
this._ArmP2.copy(cp2); this._ArmP2.copy(cp2).setZ(0);
} }
} }
} }

@ -14,7 +14,6 @@ import { Factory } from "../CADFactory";
import { CADFiler } from "../CADFiler"; import { CADFiler } from "../CADFiler";
import { Circle } from "../Entity/Circle"; import { Circle } from "../Entity/Circle";
import { Line } from "../Entity/Line"; import { Line } from "../Entity/Line";
import { ObjectId } from "../ObjectId";
import { Dimension } from "./Dimension"; import { Dimension } from "./Dimension";
import { GetDimLineMaterial } from "./GetDimLineMaterial"; import { GetDimLineMaterial } from "./GetDimLineMaterial";
@ -43,23 +42,23 @@ export class RadiusDimension extends Dimension
return this._Text; 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() get Center()
{ {
return this._Center.clone().applyMatrix4(this._Matrix); return this._Center.clone().applyMatrix4(this._Matrix);
} }
set Center(v: Vector3) set Center(v: Vector3)
{ {
this.WriteAllObjectRecord(); this.WriteAllObjectRecord();
this._Center.copy(v).applyMatrix4(this.OCSInv); this._Center.copy(v).applyMatrix4(this.OCSInv);
this.Update(); this.Update();
} }
get DiameterOrRadiusPoint() get DiameterOrRadiusPoint()
{ {
return this._DiameterOrRadiusPoint.clone().applyMatrix4(this._Matrix); return this._DiameterOrRadiusPoint.clone().applyMatrix4(this._Matrix);
@ -189,7 +188,7 @@ export class RadiusDimension extends Dimension
this._Text.TextString = this.TextString; this._Text.TextString = this.TextString;
this._Text.Position = this._TextPoint; this._Text.Position = this._TextPoint;
this._Text.TextRotation = angleAndX(armV); this._Text.TextRotation = angleAndX(armV);
this._Text.Height = this._TextSize; this._Text.Height = this.TextSize;
this._Text.DeferUpdate(); this._Text.DeferUpdate();
this._Text.AutoUpdate = true; this._Text.AutoUpdate = true;
@ -280,18 +279,20 @@ export class RadiusDimension extends Dimension
this._DiameterOrRadiusPoint.fromArray(file.Read()); this._DiameterOrRadiusPoint.fromArray(file.Read());
this._TextPoint.fromArray(file.Read()); this._TextPoint.fromArray(file.Read());
if (ver > 1) this._TextString = file.Read(); if (ver > 1) this._TextString = file.Read();
if (ver > 2) this._TextSize = file.Read(); if (ver > 2 && ver < 5) this.TextSize = file.Read();
if (ver > 3) this._FractionDigits = file.Read(); if (ver > 3 && ver < 5) this.FractionDigits = file.Read();
if (ver > 4) this.ReadDimStyle(file);
} }
WriteFile(file: CADFiler) WriteFile(file: CADFiler)
{ {
super.WriteFile(file); super.WriteFile(file);
file.Write(4); file.Write(5);
file.Write(this._Center.toArray()); file.Write(this._Center.toArray());
file.Write(this._DiameterOrRadiusPoint.toArray()); file.Write(this._DiameterOrRadiusPoint.toArray());
file.Write(this._TextPoint.toArray()); file.Write(this._TextPoint.toArray());
file.Write(this._TextString); file.Write(this._TextString);
file.Write(this._TextSize);
file.Write(this._FractionDigits); this.WriteDimStyle(file);
} }
} }

@ -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 { Board2Regions } from '../../Add-on/BoardEditor/Board2Regions';
import { DeserializationBoard2DModeingData, DeserializationBoard3DModeingData, deserializationBoardData, SerializeBoard2DModeingData, SerializeBoard3DModeingData, serializeBoardData } from '../../Add-on/BoardEditor/SerializeBoardData'; import { DeserializationBoard2DModeingData, DeserializationBoard3DModeingData, deserializationBoardData, SerializeBoard2DModeingData, SerializeBoard3DModeingData, serializeBoardData } from '../../Add-on/BoardEditor/SerializeBoardData';
import { CyHoleInBoard, ParseBoardRectHoleType, SetBrHighHoleTypeFromRectHoleType, TempRectHoleOption } from '../../Add-on/DrawDrilling/HoleUtils'; import { CyHoleInBoard, ParseBoardRectHoleType, SetBrHighHoleTypeFromRectHoleType, TempRectHoleOption } from '../../Add-on/DrawDrilling/HoleUtils';
@ -919,10 +919,28 @@ export class Board extends ExtrudeSolid
this._SpaceOCS.copy(spcocs); this._SpaceOCS.copy(spcocs);
this.Update(); this.Update();
} }
/**实际上这个值可能被改变,应该适当的去校验它(仅在重新设计模块时,这个值会被改变!) */
get Rotation() 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) protected ApplyMirrorMatrix(m: Matrix4)
{ {
if (!this.Id) if (!this.Id)

@ -97,10 +97,7 @@ export class Entity extends CADObject
this.UpdateDrawObjectMaterial(type, obj); this.UpdateDrawObjectMaterial(type, obj);
} }
get Material() get Material() { return this._MaterialId; }
{
return this._MaterialId;
}
set ColorIndex(color: number) set ColorIndex(color: number)
{ {

@ -6,9 +6,9 @@ import { EntityUpdateWrap } from "../../../../Common/EntityUpdateWrap";
import { ObjectSnapMode } from "../../../../Editor/ObjectSnapMode"; import { ObjectSnapMode } from "../../../../Editor/ObjectSnapMode";
import { Box3Ext } from "../../../../Geometry/Box"; import { Box3Ext } from "../../../../Geometry/Box";
import { BufferGeometryUtils } from "../../../../Geometry/BufferGeometryUtils"; import { BufferGeometryUtils } from "../../../../Geometry/BufferGeometryUtils";
import { SubtractRange, Tape } from "../../../../Geometry/ExtrudeMeshGeomBuilder/ExtrudeEdgeGeometry2";
import { equaln, equalv3, midPoint, MoveMatrix, ZAxis, ZeroVec } from "../../../../Geometry/GeUtils"; import { equaln, equalv3, midPoint, MoveMatrix, ZAxis, ZeroVec } from "../../../../Geometry/GeUtils";
import { RenderType } from "../../../../GraphicsSystem/RenderType"; import { RenderType } from "../../../../GraphicsSystem/RenderType";
import { SubtractRange, Tape } from "../../../../ueapi";
import { Factory } from "../../../CADFactory"; import { Factory } from "../../../CADFactory";
import { CADFiler } from "../../../CADFiler"; import { CADFiler } from "../../../CADFiler";
import { Curve } from "../../../Entity/Curve"; import { Curve } from "../../../Entity/Curve";

@ -1,8 +1,8 @@
import { EntitysUpdateWrap } from "../../../Common/EntityUpdateWrap"; import { EntitysUpdateWrap } from "../../../Common/EntityUpdateWrap";
import { Route } from "../../../Geometry/CurveMap"; import { Route } from "../../../Geometry/CurveMap";
import { ContourTreeNode } from "../../../Geometry/ExtrudeMeshGeomBuilder/ExtrudeEdgeGeometry2";
import { RegionParse } from "../../../Geometry/RegionParse"; import { RegionParse } from "../../../Geometry/RegionParse";
import { Polyline2Points } from "../../../Nest/Converter/Curves2Points"; import { Polyline2Points } from "../../../Nest/Converter/Curves2Points";
import { ContourTreeNode } from "../../../ueapi";
import { Contour } from "../../Contour"; import { Contour } from "../../Contour";
import { Database } from "../../Database"; import { Database } from "../../Database";
import { Curve } from "../../Entity/Curve"; import { Curve } from "../../Entity/Curve";

@ -51,6 +51,12 @@ export class SymbolTable extends CADObject
} }
} }
override Destroy(): void
{
super.Destroy();
this.Symbols.clear();
}
GetAt(name: string): SymbolTableRecord | undefined GetAt(name: string): SymbolTableRecord | undefined
{ {
return this.Symbols.get(name); return this.Symbols.get(name);

@ -1,9 +1,9 @@
import { CADObject } from "./CADObject"; import { Status } from "../Common/Status";
import { CADFiler } from "./CADFiler"; import { CADFiler } from "./CADFiler";
import { CADObject } from "./CADObject";
import { SymbolTable } from "./SymbolTable"; import { SymbolTable } from "./SymbolTable";
import { Status } from "../Common/Status";
export class SymbolTableRecord extends CADObject export abstract class SymbolTableRecord extends CADObject
{ {
protected name: string = ""; protected name: string = "";
get Name() get Name()

@ -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 { ColorMaterial } from '../../Common/ColorPalette';
import { setRotationOnAxis } from '../../Common/Matrix4Utils';
import { UpdateDraw } from '../../Common/Status'; import { UpdateDraw } from '../../Common/Status';
import { Box3Ext } from '../../Geometry/Box'; import { Box3Ext } from '../../Geometry/Box';
import { GetBox, MoveMatrix } from '../../Geometry/GeUtils'; import { GetBox, MoveMatrix } from '../../Geometry/GeUtils';
@ -44,7 +43,6 @@ export class Text extends Entity
{ {
super(); super();
pos && this._Matrix.setPosition(pos); pos && this._Matrix.setPosition(pos);
this._TextRotation && setRotationOnAxis(this._Matrix, this.Normal, MathUtils.degToRad(this._TextRotation));
} }
get TextRotation() get TextRotation()
{ {

@ -1,5 +1,4 @@
import { Geometry, Mesh, MeshBasicMaterial, Object3D, Scene, ShapeGeometry, Vector3, WebGLRenderer, WebGLRenderTarget } from "three"; import { Geometry, Mesh, MeshBasicMaterial, Object3D, Scene, ShapeGeometry, Vector3, WebGLRenderer, WebGLRenderTarget } from "three";
import { CADFiler } from "../../api";
import { app } from "../../ApplicationServices/Application"; import { app } from "../../ApplicationServices/Application";
import { ColorMaterial } from "../../Common/ColorPalette"; import { ColorMaterial } from "../../Common/ColorPalette";
import { clamp } from "../../Common/Utils"; import { clamp } from "../../Common/Utils";
@ -7,6 +6,7 @@ import { GetBox } from "../../Geometry/GeUtils";
import { CameraUpdate } from "../../GraphicsSystem/CameraUpdate"; import { CameraUpdate } from "../../GraphicsSystem/CameraUpdate";
import { RenderType } from "../../GraphicsSystem/RenderType"; import { RenderType } from "../../GraphicsSystem/RenderType";
import { Factory } from "../CADFactory"; import { Factory } from "../CADFactory";
import { CADFiler } from "../CADFiler";
import { Entity } from "../Entity/Entity"; import { Entity } from "../Entity/Entity";
import { Polyline } from "../Entity/Polyline"; import { Polyline } from "../Entity/Polyline";
import { ObjectId } from "../ObjectId"; import { ObjectId } from "../ObjectId";

@ -258,7 +258,7 @@ export class BoardMoveTool
{ {
let dim = new AlignedDimension(); let dim = new AlignedDimension();
dim.TextSize = 20; dim.TextSize = 20;
dim.LeadOutVisible = false; dim.LeadVisible = false;
this._DrawDims.push(dim); this._DrawDims.push(dim);
app.Viewer.PreViewer.Scene.add(dim.DrawObject); app.Viewer.PreViewer.Scene.add(dim.DrawObject);
} }

@ -5,7 +5,7 @@ import { IUpdateBoardInfosOption } from "../UI/Components/Board/UpdateBoardInfoi
import { EMetalsType, ICompHardwareOption, ICylMetalsOption, IExtMetalsOption, IToplineOption } from "../UI/Components/RightPanel/RightPanelInterface"; import { EMetalsType, ICompHardwareOption, ICylMetalsOption, IExtMetalsOption, IToplineOption } from "../UI/Components/RightPanel/RightPanelInterface";
import { IKuGangDrawOption } from "../UI/Components/Template/TemplateInterface"; import { IKuGangDrawOption } from "../UI/Components/Template/TemplateInterface";
import { ECompareType, IBoardFindOption } from "../UI/Store/BoardFindInterface"; 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 { DoorPosType, HandleHorPos, HandleVePos, IDoorConfigOption, IDrawerConfigOption, IHingeConfigOption } from "../UI/Store/DoorInterface";
import { IHSOption } from "../UI/Store/HSInterface"; import { IHSOption } from "../UI/Store/HSInterface";
import { ELatticeArrayType, ILatticeOption } from "../UI/Store/LatticeInterface"; import { ELatticeArrayType, ILatticeOption } from "../UI/Store/LatticeInterface";
@ -863,3 +863,19 @@ export const DefaultCommonPanelOption: CommonPanelConfigOption = {
orderType: EOrderType.ByUpdate, orderType: EOrderType.ByUpdate,
}; };
Object.freeze(DefaultCommonPanelOption); 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);

@ -36,7 +36,7 @@ export interface IUCSGridConfig extends IBaseOption
export class UserConfig implements IConfigStore export class UserConfig implements IConfigStore
{ {
private readonly _version = 30; //🌟🌟每次更新必须向上添加一次版本号🌟🌟 private readonly _version = 31; //🌟🌟每次更新必须向上添加一次版本号🌟🌟
_renderType: RenderType = RenderType.Wireframe; _renderType: RenderType = RenderType.Wireframe;
@observable maxSize: IMaxSizeProps = { @observable maxSize: IMaxSizeProps = {
isShow: false, isShow: false,
@ -112,7 +112,6 @@ export class UserConfig implements IConfigStore
}; };
@observable autoLines = false; @observable autoLines = false;
@observable dimTextHeight = 60; @observable dimTextHeight = 60;
@observable performanceConfig = { @observable performanceConfig = {
fakersweep: false, fakersweep: false,
disablerefcut: false, disablerefcut: false,

@ -1,17 +1,14 @@
import { Matrix2 } from './Matrix2'; 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) export function RotateUVs(geo: THREE.Geometry)
{ {
r.set(0, -1,
1, 0);
for (let uvs of geo.faceVertexUvs) for (let uvs of geo.faceVertexUvs)
{ {
for (let uv of uvs) for (let uv of uvs)
{ {
for (let v of uv) for (let v of uv)
r.applyVector(v); ROTATE_MTX2.applyVector(v);
} }
} }
geo.uvsNeedUpdate = true; geo.uvsNeedUpdate = true;

@ -15,16 +15,17 @@ import { ISpaceParse } from "./ISpaceParse";
*/ */
export class SurroundOutlineParse extends ISpaceParse export class SurroundOutlineParse extends ISpaceParse
{ {
Polylines: Polyline[] = []; Polylines: Polyline[] = [];//完整轮廓(ucs z0)
Outlines: Curve[] = []; Outlines: Curve[] = [];//完整轮廓炸开后的线(ucs zMax)
async Parse() async Parse()
{ {
let ucsNormal = new Vector3().setFromMatrixColumn(app.Editor.UCSMatrix, 2); let ucsNormal = new Vector3().setFromMatrixColumn(app.Editor.UCSMatrix, 2);
let ucsInv = app.Editor.UCSMatrixInv; let ucsInv = app.Editor.UCSMatrixInv;
let boardList = this.ParseBoardList(); let groups = this.GroupBoards();
for (let brs of boardList) for (let brs of groups)
{ {
let pls: Polyline[] = []; //板转多段线轮廓
let brPls: Polyline[] = [];
let maxZ = -Infinity; let maxZ = -Infinity;
for (let br of brs) for (let br of brs)
{ {
@ -40,9 +41,9 @@ export class SurroundOutlineParse extends ISpaceParse
new Vector3(min.x, max.y, max.z), max new Vector3(min.x, max.y, max.z), max
]; ];
//br->ucs //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.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)) if (isParallelTo(brNormal, ucsNormal))
{ {
let cu = br.ContourCurve; let cu = br.ContourCurve;
@ -50,88 +51,90 @@ export class SurroundOutlineParse extends ISpaceParse
{ {
let pl = cu.Clone().ApplyMatrix(mtx); let pl = cu.Clone().ApplyMatrix(mtx);
pl.Position = pl.Position.setZ(0); pl.Position = pl.Position.setZ(0);
pls.push(pl); brPls.push(pl);
} }
} }
else if (isPerpendicularityTo(brNormal, ucsNormal)) else if (isPerpendicularityTo(brNormal, ucsNormal))
pls.push(getRectFrom4Pts(pts.slice(0, 4))); brPls.push(getRectFrom4Pts(pts.slice(0, 4)));
else else
continue; continue;
maxZ = Math.max(maxZ, arrayLast(pts).z); 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 ucs = app.Editor.UCSMatrix;
let p = new Vector3().setFromMatrixPosition(ucs); let p = new Vector3().setFromMatrixPosition(ucs)
p.add(ucsNormal.clone().multiplyScalar(maxZ)); .add(ucsNormal.clone().multiplyScalar(maxZ));
ucs.setPosition(p); ucs.setPosition(p);
for (let cu of retCus) //炸开
cu.ApplyMatrix(ucs); for (let pl of unionPls)
this.Outlines.push(...retCus); {
} for (let cu of pl.Explode())
} if (!equaln(cu.Length, 0, 1e-6))
private GetOutline(cus: Curve[]) {
{ cu.ApplyMatrix(ucs);//move max z
let reg = Region.CreateFromCurves([cus.shift()]); this.Outlines.push(cu);
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);
} }
return retCus;
} }
private ParseBoardList() //根据包围盒对板进行分堆
private GroupBoards()
{ {
let boxMap: Map<Box3, Board> = new Map(); let boxMap: Map<Board, Box3> = new Map();
let boxes: Box3[] = [];
for (let br of this.Boards) 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); let group = [brs.pop()];
boxes.push(box); let groupBox = boxMap.get(group[0]).clone();
boxMap.set(box, br);
} while (brs.length)
let boardList: Board[][] = [];
while (boxes.length > 0)
{
let originBox = boxes.shift();
let brs = [boxMap.get(originBox)];
while (true)
{ {
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); groupBox.union(box);
brs.push(boxMap.get(b)); group.push(br);
return false; return true;
} }
return true; return false;
}); });
if (remBoxes.length === boxes.length) if (index !== -1)
{ {
boardList.push(brs); brs.splice(index, 1);
break; continue;
} }
else break;
boxes = remBoxes;
} }
brGroups.push(group);
} }
return boardList; return brGroups;
} }
} }

@ -49,11 +49,15 @@ export class Viewer
//前置渲染 //前置渲染
PreViewer: PreViewer; PreViewer: PreViewer;
/**使用后期渲染器 */
UsePass = false; UsePass = false;
/**后期渲染器 */
Composer: EffectComposer;
_AAType: AAType = AAType.FXAA; _AAType: AAType = AAType.FXAA;
RenderPass: RenderPass; RenderPass: RenderPass;
OutlinePass: OutlinePass; OutlinePass: OutlinePass;
Composer: EffectComposer;
private _SMAAPass: SMAAPass; private _SMAAPass: SMAAPass;
private _Scene: Scene = new Scene; private _Scene: Scene = new Scene;

@ -1,7 +1,7 @@
import { MathUtils } from "three"; import { MathUtils } from "three";
import { Arc } from "../api";
import { arrayLast } from "../Common/ArrayExt"; import { arrayLast } from "../Common/ArrayExt";
import { CADObject } from "../DatabaseServices/CADObject"; import { CADObject } from "../DatabaseServices/CADObject";
import { Arc } from "../DatabaseServices/Entity/Arc";
import { Curve } from "../DatabaseServices/Entity/Curve"; import { Curve } from "../DatabaseServices/Entity/Curve";
import { RoomHolePolyline } from "../DatabaseServices/Room/Entity/Wall/Hole/RoomHolePolyline"; import { RoomHolePolyline } from "../DatabaseServices/Room/Entity/Wall/Hole/RoomHolePolyline";
import { RoomWallArc } from "../DatabaseServices/Room/Entity/Wall/RoomWallArc"; import { RoomWallArc } from "../DatabaseServices/Room/Entity/Wall/RoomWallArc";

@ -1,89 +1,260 @@
import { Button, Card, Checkbox, H5, Intent } from '@blueprintjs/core'; import { Button, Checkbox, Classes, Intent, Position, Radio, RadioGroup, Tooltip } from '@blueprintjs/core';
import React, { Component } from 'react'; import { autorun, observable } from 'mobx';
import { observer } from 'mobx-react';
import React from 'react';
import { begin } from 'xaop'; import { begin } from 'xaop';
import { AutoDimBrsStore } from '../../Add-on/DrawDim/AutoDimBrsStore';
import { EDimType } from '../../Add-on/DrawDim/AutoDimBrsTool'; import { EDimType } from '../../Add-on/DrawDim/AutoDimBrsTool';
import { app } from '../../ApplicationServices/Application'; import { app } from '../../ApplicationServices/Application';
import { safeEval } from '../../Common/eval';
import { KeyBoard } from '../../Common/KeyEnum'; 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'; import { ModalState } from './Modal/ModalInterface';
interface IAutoDimBoardPanel @observer
{ export class AutoDimBoardPanel extends React.Component<{ store: AutoDimBrsStore; }> {
dimType: EDimType; _Event: Function[] = [];
} @observable _StrIllegal = false;
_NoShowMinSizeInput: React.RefObject<HTMLInputElement> = React.createRef();
_NoShowMinInSizeInput: React.RefObject<HTMLInputElement> = React.createRef();
_NoShowAppointDimSizeInput: React.RefObject<HTMLInputElement> = React.createRef();
export default class AutoDimBoardPanel extends Component<IAutoDimBoardPanel, { type: EDimType; }> {
private dimType: EDimType;
private event: Function;
constructor(props)
{
super(props);
this.state = {
type: this.props.dimType
};
this.dimType = this.props.dimType;
}
componentDidMount() componentDidMount()
{ {
this.event = begin(app.Editor.ModalManage, app.Editor.ModalManage.OnKeyDown, (e: KeyboardEvent) => this._Event.push(
{ 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)
if (e.keyCode === KeyBoard.Enter || e.keyCode === KeyBoard.Space) {
this._OnOk();
e.preventDefault();
}
e.stopPropagation();
return true;
})
);
this._Event.push(
autorun(() =>
{ {
this.onOk(); if (this._NoShowAppointDimSizeInput)
//使用左右侧板时,该事件会使 拾取点的动态输入框响应到这个键盘事件. this._NoShowAppointDimSizeInput.current.value = this.props.store.m_Option.noShowAppointSizes;
//导致进入交互时,马上有个空格. if (this._NoShowMinInSizeInput)
e.preventDefault(); this._NoShowMinInSizeInput.current.value = this.props.store.m_Option.noShowMinInSize.toFixed();
} if (this._NoShowMinSizeInput)
e.stopPropagation(); this._NoShowMinSizeInput.current.value = this.props.store.m_Option.noShowMinSize.toFixed();
return true; })
}); );
} }
componentWillUnmount() componentWillUnmount()
{ {
if (this.event) for (let f of this._Event) f();
{ this._Event.length = 0;
this.event();
this.event = null;
}
} }
render() render()
{ {
let option = this.props.store.m_Option;
return ( return (
<Card> <div id='AutoDimBoardConfig' className={Classes.DIALOG_CONTAINER}>
<H5></H5> <div className={Classes.DIALOG + " autoDimBoardConfig"}>
<Checkbox label="整体标注" data-type={EDimType.Total} defaultChecked={!!(this.dimType & EDimType.Total)} onChange={this.onChange} /> <ModalHeader
<Checkbox label="柜外标注" data-type={EDimType.Out} defaultChecked={!!(this.dimType & EDimType.Out)} onChange={this.onChange} /> title={"自动标注配置"}
<Checkbox label="柜内宽标注" data-type={EDimType.InW} defaultChecked={!!(this.dimType & EDimType.InW)} onChange={this.onChange} /> close={this._Cancel}
<Checkbox label="柜内高标注" data-type={EDimType.InH} defaultChecked={!!(this.dimType & EDimType.InH)} onChange={this.onChange} /> icon="cog"
<Checkbox label="过滤重复标注" data-type={EDimType.NoRepeat} defaultChecked={!!(this.dimType & EDimType.NoRepeat)} onChange={this.onChange} /> />
<Checkbox label="过滤小尺寸标注" data-type={EDimType.NoSmSize} defaultChecked={!!(this.dimType & EDimType.NoSmSize)} onChange={this.onChange} /> <div className={Classes.DIALOG_BODY}>
<div> <RadioGroup
<Button text="确定" intent={Intent.SUCCESS} onClick={this.onOk} /> onChange={(e) =>
<Button text="取消" intent={Intent.DANGER} onClick={this.onCancel} /> {
option.useParseGroups = e.currentTarget.value;
}}
selectedValue={option.useParseGroups}
className='dimGroup'
>
<Radio label="分堆(多组标注)" value="0" />
<Radio label="不分堆(单组标注)" value="1" />
</RadioGroup>
<div className='dimGroup'>
<Checkbox label="整体标注" checked={option.total} onChange={() => this._OnChange(EDimType.Total)} />
<Checkbox label="柜内宽标注" checked={option.inW} onChange={() => this._OnChange(EDimType.InW)} />
</div>
<div className='dimGroup'>
<Checkbox label="柜外标注" checked={option.out} onChange={() => this._OnChange(EDimType.Out)} />
<Checkbox label="柜内高标注" checked={option.inH} onChange={() => this._OnChange(EDimType.InH)} />
</div>
{/* <Checkbox label="过滤重复标注" data-type={EDimType.NoRepeat} defaultChecked={!!(this.dimType & EDimType.NoRepeat)} onChange={this.onChange} /> */}
<div className='dimInputGroup'>
<Checkbox label="过滤小尺寸标注" checked={option.noSmSize} onChange={() => this._OnChange(EDimType.NoSmSize)} />
<input className="bp3-input br-process-input"
ref={this._NoShowMinSizeInput}
defaultValue={option.noShowMinSize}
min={1}
style={{ width: 50, height: 28 }}
onKeyDown={(e) =>
{
switch (e.keyCode)
{
case KeyBoard.Escape:
case KeyBoard.Space:
case KeyBoard.Enter:
e.currentTarget.blur();
e.stopPropagation();
break;
default:
break;
}
}}
onBlur={(e) =>
{
let val = safeEval(e.target.value);
if (!isNaN(val))
option.noShowMinSize = parseFloat(e.currentTarget.value);
else
e.target.value = option.noShowMinSize.toFixed();
}}
/>
</div>
<div className='dimInputGroup'>
<Checkbox label="过滤柜内空间标注" checked={option.noInSize} onChange={() => this._OnChange(EDimType.NoInSize)} />
<input className="bp3-input br-process-input"
ref={this._NoShowMinInSizeInput}
defaultValue={option.noShowMinInSize}
min={1}
style={{ width: 50, height: 28 }}
onKeyDown={(e) =>
{
switch (e.keyCode)
{
case KeyBoard.Escape:
case KeyBoard.Space:
case KeyBoard.Enter:
e.currentTarget.blur();
e.stopPropagation();
break;
default:
break;
}
}}
onBlur={(e) =>
{
let val = safeEval(e.target.value);
if (!isNaN(val) && val > 0)
option.noShowMinInSize = parseFloat(e.currentTarget.value);
else
e.target.value = option.noShowMinInSize.toFixed();
}}
/>
</div>
<div className='dimInputGroup'>
<Checkbox label="过滤指定数值标注" checked={option.noAppointSize} onChange={() => this._OnChange(EDimType.NoAppointSize)} />
<Tooltip
content={"请输入大于0的数字! 多个数字可以用 ' | ' 或 逗号 或 空格 相隔!"}
position={Position.TOP}
intent={Intent.WARNING}
isOpen={this._StrIllegal}
>
<Tooltip content="多个数字可以用 ' | ' 或 逗号 或 空格 相隔">
<input className="bp3-input br-process-input"
type={"text"}
ref={this._NoShowAppointDimSizeInput}
defaultValue={option.noShowAppointSizes}
style={{ height: 28 }}
onKeyDown={(e) =>
{
switch (e.keyCode)
{
case KeyBoard.Escape:
case KeyBoard.Enter:
e.currentTarget.blur();
e.stopPropagation();
break;
case KeyBoard.Space:
e.stopPropagation();
break;
default:
break;
}
}}
onChange={(e) => { this._CheckStr(e); }}
onKeyUp={(e) => { e.currentTarget.value = e.currentTarget.value.replaceAll(//g, ','); }}
onBlur={(e) =>
{
if (this._StrIllegal)
{
e.currentTarget.value = option.noShowAppointSizes;
this._StrIllegal = false;
}
else
{
if (e.currentTarget.value === '')
{
option.noShowAppointSizes = '';
return;
}
//数字简化 0.100 => 0.1
let strArray = [];
let strArray2 = [];
let strArray3 = [];
for (let s1 of e.currentTarget.value.split(','))
{
strArray2 = [];
for (let s2 of s1.split(' '))
{
strArray3 = [];
for (let s3 of s2.split('|'))
{
strArray3.push(safeEval(s3));
}
strArray2.push(strArray3.join('|'));
}
strArray.push(strArray2.join(' '));
}
e.currentTarget.value = strArray.join(',');
option.noShowAppointSizes = e.currentTarget.value;
}
}}
/>
</Tooltip>
</Tooltip>
</div>
</div>
<div className={Classes.DIALOG_FOOTER}>
<UserConfig type={BoardModalType.AutoDimBrs} store={this.props.store} />
<Button text="确定" intent={Intent.SUCCESS} onClick={this._OnOk} />
<Button text="取消" intent={Intent.DANGER} onClick={this._Cancel} />
</div>
</div> </div>
</Card> </div>
); );
} }
private onChange = (e: React.ChangeEvent<HTMLInputElement>) =>
_CheckStr = (e: React.ChangeEvent<HTMLInputElement>) =>
{ {
let target = e.target; if (e.currentTarget.value === '') return;
let type = parseInt(target.getAttribute("data-type")); let str = e.currentTarget.value.replaceAll(//g, ',');
if (target.checked)
{ //支持 ',' '|' '空格'
this.dimType |= type; this._StrIllegal = !str.split(',').every(str1 => str1.split('|').every(str2 => str2.split(' ').every(str3 => { return !isNaN(safeEval(str3)) && safeEval(str3) > 0; })));
}
else
{
this.dimType &= (~type);
}
}; };
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(); app.Editor.ModalManage.Destory();
}; };

@ -1,12 +1,12 @@
import { BreadcrumbProps, Button, Intent, Toaster } from "@blueprintjs/core"; import { BreadcrumbProps, Button, Intent, Toaster } from "@blueprintjs/core";
import { observable } from "mobx"; import { observable } from "mobx";
import React, { createRef, RefObject } from "react"; import React, { createRef, RefObject } from "react";
import { CADFiler } from "../../../api";
import { app } from "../../../ApplicationServices/Application"; import { app } from "../../../ApplicationServices/Application";
import { CommandNames } from "../../../Common/CommandNames"; import { CommandNames } from "../../../Common/CommandNames";
import { CoolDownTime } from "../../../Common/CoolDownTime"; import { CoolDownTime } from "../../../Common/CoolDownTime";
import { inflateBase64 } from "../../../Common/inflate"; import { inflateBase64 } from "../../../Common/inflate";
import { IResponseData } from "../../../Common/Request"; import { IResponseData } from "../../../Common/Request";
import { CADFiler } from "../../../DatabaseServices/CADFiler";
import { FileServer } from "../../../DatabaseServices/FileServer"; import { FileServer } from "../../../DatabaseServices/FileServer";
import { commandMachine } from "../../../Editor/CommandMachine"; import { commandMachine } from "../../../Editor/CommandMachine";
import { CommandState } from "../../../Editor/CommandState"; import { CommandState } from "../../../Editor/CommandState";

@ -18,7 +18,6 @@ import { userConfigStore } from "../../../Store/UserConfigStore";
import { BoardModalType } from "../../Board/BoardModalType"; import { BoardModalType } from "../../Board/BoardModalType";
import { GetCompoentObjectIdString } from "../../ComponentObjectId"; import { GetCompoentObjectIdString } from "../../ComponentObjectId";
import { ChaiDanPanel } from "./ChaiDanModal"; import { ChaiDanPanel } from "./ChaiDanModal";
import { DimConfigPanel } from "./DimConfigPanel";
import { DisplayConfigPanel } from "./DisplayConfigPanel"; import { DisplayConfigPanel } from "./DisplayConfigPanel";
import { DrawConfigPanel } from "./DrawConfigPanel"; import { DrawConfigPanel } from "./DrawConfigPanel";
import { FileConfigPanel } from "./FileConfigPanel"; import { FileConfigPanel } from "./FileConfigPanel";
@ -33,7 +32,6 @@ export enum EOptionTabId
Draw = "ht", Draw = "ht",
ChaiDan = "chaidan", ChaiDan = "chaidan",
Perf = "perf", Perf = "perf",
DimStyle = "dimstyle",
TextStyle = "textstyle", TextStyle = "textstyle",
} }
@ -251,7 +249,6 @@ export class ConfigDialog extends React.Component<{ store: ConfigStore; selected
<Tab id={EOptionTabId.Sys} title="系统" panel={<SystemConfigPanel />} /> <Tab id={EOptionTabId.Sys} title="系统" panel={<SystemConfigPanel />} />
<Tab id={EOptionTabId.Draw} title="绘图" panel={<DrawConfigPanel store={store} />} /> <Tab id={EOptionTabId.Draw} title="绘图" panel={<DrawConfigPanel store={store} />} />
<Tab id={EOptionTabId.ChaiDan} title="拆单" panel={<ChaiDanPanel />} /> <Tab id={EOptionTabId.ChaiDan} title="拆单" panel={<ChaiDanPanel />} />
<Tab id={EOptionTabId.DimStyle} title="标注" panel={<DimConfigPanel />} />
<Tab id={EOptionTabId.TextStyle} title="文本" panel={<TextConfigPanel />} /> <Tab id={EOptionTabId.TextStyle} title="文本" panel={<TextConfigPanel />} />
</Tabs> </Tabs>
</div> </div>

@ -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<HTMLInputElement>();
render()
{
return (
<Card>
<div>
<div style={{ display: "inline-flex", ...Padding }}>
<span style={WDCss}></span>
<div>
<div className="numeric_input">
<Tooltip
content={"仅限1-300间的数字!"}
position={Position.TOP}
intent={Intent.WARNING}
isOpen={this._isPopoverOpen}
>
<input
ref={this._dimInputEl}
defaultValue={this._dimTextHeight}
style={{ width: "80%" }}
onKeyDown={(e) =>
{
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间的数字!');
}
}}
/>
</Tooltip>
</div>
</div>
</div>
<Slider
min={10}
max={300}
stepSize={1}
labelStepSize={40}
onChange={(value) =>
{
this._dimInputEl.current.value = value.toString();
this._dimTextHeight = value;
userConfig.dimTextHeight = this._dimTextHeight;
}}
value={this._dimTextHeight}
vertical={false}
/>
</div>
<Label className={Classes.INLINE} style={Padding}>
<span style={WDCss}></span>
<HTMLSelect
options={
[
{ label: "0", value: FractionDigitsType.zero },
{ label: "1", value: FractionDigitsType.one },
{ label: "2", value: FractionDigitsType.two },
{ label: "3", value: FractionDigitsType.three },
{ label: "4", value: FractionDigitsType.four },
{ label: "5", value: FractionDigitsType.five },
]
}
value={userConfig.fractionDigitsType}
onChange={e => userConfig.fractionDigitsType = parseInt(e.target.value)}
/>
</Label>
</Card >
);
}
}

@ -1,5 +1,5 @@
import { IBaseOption } from "../../Store/BoardInterface";
import { EBoardKeyList } from "../../../Common/BoardKeyList"; import { EBoardKeyList } from "../../../Common/BoardKeyList";
import { IBaseOption } from "../../Store/BoardInterface";
export interface IHardwareOption extends IBaseOption export interface IHardwareOption extends IBaseOption
{ {
@ -42,7 +42,7 @@ export enum EMetalsType
export interface ICompHardwareOption extends IHardwareOption export interface ICompHardwareOption extends IHardwareOption
{ {
type: EMetalsType; type: EMetalsType;
isSplite: boolean; isSplite: boolean;//拆解
isSplitePrice: boolean; isSplitePrice: boolean;
color: string; color: string;
[EBoardKeyList.Mat]: string; [EBoardKeyList.Mat]: string;

@ -3,12 +3,12 @@ import { observable } from "mobx";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import pako from "pako"; import pako from "pako";
import React from "react"; import React from "react";
import { CADFiler } from "../../../api";
import { app } from "../../../ApplicationServices/Application"; import { app } from "../../../ApplicationServices/Application";
import { FileSystem } from '../../../Common/FileSystem'; import { FileSystem } from '../../../Common/FileSystem';
import { TemplateUrls } from "../../../Common/HostUrl"; import { TemplateUrls } from "../../../Common/HostUrl";
import { PostJson } from "../../../Common/Request"; import { PostJson } from "../../../Common/Request";
import { StoreageKeys } from "../../../Common/StoreageKeys"; import { StoreageKeys } from "../../../Common/StoreageKeys";
import { CADFiler } from "../../../DatabaseServices/CADFiler";
import { FileServer } from "../../../DatabaseServices/FileServer"; import { FileServer } from "../../../DatabaseServices/FileServer";
import { TopPanelStore } from "../../Store/TopPanelStore"; import { TopPanelStore } from "../../Store/TopPanelStore";
import { AppToaster } from "../Toaster"; import { AppToaster } from "../Toaster";

@ -4,7 +4,9 @@ import { app } from "../../../ApplicationServices/Application";
import { EBoardKeyList } from "../../../Common/BoardKeyList"; import { EBoardKeyList } from "../../../Common/BoardKeyList";
import { TransformVector } from "../../../Common/Matrix4Utils"; import { TransformVector } from "../../../Common/Matrix4Utils";
import { Sleep } from "../../../Common/Sleep"; import { Sleep } from "../../../Common/Sleep";
import { DuplicateRecordCloning } from "../../../Common/Status";
import { GetEntity } from "../../../Common/Utils"; import { GetEntity } from "../../../Common/Utils";
import { Board } from "../../../DatabaseServices/Entity/Board";
import { Entity } from "../../../DatabaseServices/Entity/Entity"; import { Entity } from "../../../DatabaseServices/Entity/Entity";
import { HardwareCompositeEntity } from "../../../DatabaseServices/Hardware/HardwareCompositeEntity"; import { HardwareCompositeEntity } from "../../../DatabaseServices/Hardware/HardwareCompositeEntity";
import { HardwareTopline } from "../../../DatabaseServices/Hardware/HardwareTopline"; import { HardwareTopline } from "../../../DatabaseServices/Hardware/HardwareTopline";
@ -17,7 +19,6 @@ import { PromptStatus } from "../../../Editor/PromptResult";
import { ParsePlaceEntitys } from "../../../Editor/TranstrolControl/ParsePlaceEntitys"; import { ParsePlaceEntitys } from "../../../Editor/TranstrolControl/ParsePlaceEntitys";
import { ParsePlacePos, ParsePlacePosWithTemplate, ParsePlacePosWithTemplate2 } from "../../../Editor/TranstrolControl/ParsePlacePos"; import { ParsePlacePos, ParsePlacePosWithTemplate, ParsePlacePosWithTemplate2 } from "../../../Editor/TranstrolControl/ParsePlacePos";
import { equaln, equalv3, ZeroVec } from "../../../Geometry/GeUtils"; import { equaln, equalv3, ZeroVec } from "../../../Geometry/GeUtils";
import { Board, DuplicateRecordCloning } from "../../../ueapi";
import { DownPanelStore } from "../../Store/DownPanelStore"; import { DownPanelStore } from "../../Store/DownPanelStore";
import { IGetRoomInfo } from "./GetRoomCabName"; import { IGetRoomInfo } from "./GetRoomCabName";

@ -6,6 +6,7 @@ import { app } from '../../../ApplicationServices/Application';
import { safeEval } from '../../../Common/eval'; import { safeEval } from '../../../Common/eval';
import { IsMeshMaterialEntity } from '../../../Common/IsMeshMaterialEntity'; import { IsMeshMaterialEntity } from '../../../Common/IsMeshMaterialEntity';
import { KeyBoard } from '../../../Common/KeyEnum'; import { KeyBoard } from '../../../Common/KeyEnum';
import { Board } from '../../../DatabaseServices/Entity/Board';
import { Curve } from '../../../DatabaseServices/Entity/Curve'; import { Curve } from '../../../DatabaseServices/Entity/Curve';
import { Entity } from '../../../DatabaseServices/Entity/Entity'; import { Entity } from '../../../DatabaseServices/Entity/Entity';
import { HardwareCompositeEntity } from '../../../DatabaseServices/Hardware/HardwareCompositeEntity'; import { HardwareCompositeEntity } from '../../../DatabaseServices/Hardware/HardwareCompositeEntity';
@ -20,7 +21,6 @@ import { CommandWrap } from '../../../Editor/CommandMachine';
import { JigUtils } from '../../../Editor/JigUtils'; import { JigUtils } from '../../../Editor/JigUtils';
import { PromptStatus } from '../../../Editor/PromptResult'; import { PromptStatus } from '../../../Editor/PromptResult';
import { GetBoardHighSeal, GetBoardSealingCurves } from '../../../GraphicsSystem/CalcEdgeSealing'; import { GetBoardHighSeal, GetBoardSealingCurves } from '../../../GraphicsSystem/CalcEdgeSealing';
import { Board } from '../../../ueapi';
import { ITemplateParam } from "../../Store/RightPanelStore/ITemplateParam"; import { ITemplateParam } from "../../Store/RightPanelStore/ITemplateParam";
import { RightPanelStore } from '../../Store/RightPanelStore/RightPanelStore'; import { RightPanelStore } from '../../Store/RightPanelStore/RightPanelStore';
import { TempalteEditorStore } from '../../Store/TemplateEditorStore'; import { TempalteEditorStore } from '../../Store/TemplateEditorStore';

@ -1,9 +1,10 @@
import { app } from "../../../ApplicationServices/Application"; import { app } from "../../../ApplicationServices/Application";
import { EBoardKeyList } from "../../../Common/BoardKeyList"; import { EBoardKeyList } from "../../../Common/BoardKeyList";
import { DuplicateRecordCloning } from "../../../Common/Status";
import { Board } from "../../../DatabaseServices/Entity/Board";
import { HardwareCompositeEntity } from "../../../DatabaseServices/Hardware/HardwareCompositeEntity"; import { HardwareCompositeEntity } from "../../../DatabaseServices/Hardware/HardwareCompositeEntity";
import { PositioningHandleSpace } from "../../../DatabaseServices/Template/Positioning/PositioningHandleSpace"; import { PositioningHandleSpace } from "../../../DatabaseServices/Template/Positioning/PositioningHandleSpace";
import { TemplateRecord } from "../../../DatabaseServices/Template/TemplateRecord"; import { TemplateRecord } from "../../../DatabaseServices/Template/TemplateRecord";
import { Board, DuplicateRecordCloning } from "../../../ueapi";
import { BoardOpenDir } from "../../Store/BoardInterface"; import { BoardOpenDir } from "../../Store/BoardInterface";
import { DoorStore } from "../../Store/DoorDrawerStore/DoorStore"; import { DoorStore } from "../../Store/DoorDrawerStore/DoorStore";
import { HandleHorPos, HandleVePos } from "../../Store/DoorInterface"; import { HandleHorPos, HandleVePos } from "../../Store/DoorInterface";

@ -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<DimParamsPanelProps, {}>
{
@observable _ParamValue: number = 0;
@observable _MinValue: number = 0;
@observable _MaxValue: number = 0;
@observable _IsPopoverOpen: boolean = false;
@observable _StepSize: number = 1;
_InputRef: React.RefObject<HTMLInputElement> = React.createRef<HTMLInputElement>();;
_SilderRef: React.RefObject<Slider> = React.createRef<Slider>();;
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 (
<div className="paramPanel">
<div className="input_group">
<span>{this.props.dimParam[1]}: </span>
<div className="numeric_input" >
<Tooltip
content={"仅限" + this._MinValue + "-" + this._MaxValue + "间的数字!"}
position={Position.TOP}
intent={Intent.WARNING}
isOpen={this._IsPopoverOpen}
>
<input
ref={this._InputRef}
defaultValue={this._ParamValue}
style={{ width: "100%" }}
onChange={(e) =>
{
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;
}
}}
/>
</Tooltip>
</div>
</div>
<Slider
min={this._MinValue}
max={this._MaxValue}
stepSize={this._StepSize}
ref={this._SilderRef}
labelRenderer={false}
onChange={(value) =>
{
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}
/>
</div>
);
}
}

@ -144,6 +144,29 @@
align-items: center; 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;
}
} }
} }
} }

@ -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 { 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 { AlignedDimension } from "../../../DatabaseServices/Dimension/AlignedDimension";
import { CommandWrap } from "../../../Editor/CommandMachine";
export interface Properties_AlignedDimPanelProps export interface Properties_AlignedDimPanelProps
{ {
ents: AlignedDimension[]; ents: AlignedDimension[];
@ -38,7 +38,7 @@ export class Properties_AlignedDimPanel extends React.Component<Properties_Align
{ {
for (let al of ents) for (let al of ents)
{ {
al.toggleLeadOutFlipped(); al.FlippeLead();
} }
}, "切换标注引线方向"); }, "切换标注引线方向");
}} /> }} />
@ -48,7 +48,7 @@ export class Properties_AlignedDimPanel extends React.Component<Properties_Align
{ {
for (let al of ents) for (let al of ents)
{ {
al.toggleLeadOutVisible(); al.ToggleLeadVisible();
} }
}, "切换标注引线显示"); }, "切换标注引线显示");
}} /> }} />

@ -2,19 +2,34 @@ import { Button, Card, Classes, HTMLSelect, Intent, Position, Slider, Tooltip }
import hotkeys from "hotkeys-js-ext"; import hotkeys from "hotkeys-js-ext";
import { observable } from "mobx"; import { observable } from "mobx";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import React from "react"; import React, { RefObject } from "react";
import { Object3D } from "three"; import { Object3D } from "three";
import { end } from "xaop"; import { end } from "xaop";
import { app } from "../../../ApplicationServices/Application"; import { app } from "../../../ApplicationServices/Application";
import { safeEval } from "../../../Common/eval"; import { safeEval } from "../../../Common/eval";
import { KeyBoard, KeyCode } from "../../../Common/KeyEnum"; import { KeyBoard, KeyCode } from "../../../Common/KeyEnum";
import { clamp } from "../../../Common/Utils"; import { clamp } from "../../../Common/Utils";
import { AlignedDimension } from "../../../DatabaseServices/Dimension/AlignedDimension";
import { Dimension } from "../../../DatabaseServices/Dimension/Dimension"; import { Dimension } from "../../../DatabaseServices/Dimension/Dimension";
import { DimStyleKeyCode } from "../../../DatabaseServices/DimStyle/DimstyleKeyCodeEnum";
import { commandMachine, CommandWrap } from "../../../Editor/CommandMachine"; import { commandMachine, CommandWrap } from "../../../Editor/CommandMachine";
import { CommandState } from "../../../Editor/CommandState"; import { CommandState } from "../../../Editor/CommandState";
import { AppToaster } from "../Toaster"; import { AppToaster } from "../Toaster";
import { DimParamsPanel } from "./DimParamsPanel";
import { PropertiesStore } from "./PropertiesStore"; import { PropertiesStore } from "./PropertiesStore";
export enum DimParamsList
{
FootLineLength = "footLineLength",
ArrowSize = "arrowSize",
}
const ParList: [string, string][] =
[
[DimParamsList.FootLineLength, "尺寸界线"],
[DimParamsList.ArrowSize, "箭头尺寸"]
];
export interface Properties_DimPanelProps export interface Properties_DimPanelProps
{ {
ents: Dimension[]; ents: Dimension[];
@ -23,12 +38,14 @@ export interface Properties_DimPanelProps
@observer @observer
export class Properties_DimPanel extends React.Component<Properties_DimPanelProps, {}> export class Properties_DimPanel extends React.Component<Properties_DimPanelProps, {}>
{ {
private removeFuncs: Function[] = []; _RemoveFuncs: Function[] = [];
_DimInputEl = React.createRef<HTMLInputElement>();
_DimParamRefs = new Map<string, RefObject<DimParamsPanel>>();
@observable outlineCheckDims: boolean = true; @observable outlineCheckDims: boolean = true;
@observable private dim_TextSize: number = 60; @observable _DimTextSize: number = 60;
@observable private dim_Exact: number = 2; @observable _DimExact: number = 2;
private dim_InputEl = React.createRef<HTMLInputElement>(); @observable _IsPopoverOpen: boolean = false;
@observable private isPopoverOpen: boolean = false;
constructor(p) constructor(p)
{ {
super(p); super(p);
@ -36,8 +53,8 @@ export class Properties_DimPanel extends React.Component<Properties_DimPanelProp
if (this.props.ents.length > 0) if (this.props.ents.length > 0)
{ {
let numval = this.props.ents[0].TextSize; let numval = this.props.ents[0].TextSize;
this.dim_TextSize = numval; this._DimTextSize = numval;
this.dim_Exact = this.props.ents[0].FractionDigits; this._DimExact = this.props.ents[0].FractionDigits;
} }
} }
@ -51,14 +68,14 @@ export class Properties_DimPanel extends React.Component<Properties_DimPanelProp
al.FractionDigits = newExact; al.FractionDigits = newExact;
} }
}, "修改标注文字精度"); }, "修改标注文字精度");
this.dim_Exact = newExact; this._DimExact = newExact;
} }
componentDidMount() componentDidMount()
{ {
this.outlineCheckDims = !(app.Viewer.OutlinePass.selectedObjects.length > 0); this.outlineCheckDims = !(app.Viewer.OutlinePass.selectedObjects.length > 0);
let selectCtrl = app.Editor.SelectCtrl; let selectCtrl = app.Editor.SelectCtrl;
this.removeFuncs.push( this._RemoveFuncs.push(
end(selectCtrl, selectCtrl.UpdateSelectEvent, () => end(selectCtrl, selectCtrl.UpdateSelectEvent, () =>
{ {
this.outlineCheckDims = false; this.outlineCheckDims = false;
@ -73,42 +90,77 @@ export class Properties_DimPanel extends React.Component<Properties_DimPanelProp
if (e.code === KeyCode.KeyZ || e.code === KeyCode.KeyY) if (e.code === KeyCode.KeyZ || e.code === KeyCode.KeyY)
{ {
let numval = this.props.ents[0].TextSize; let numval = this.props.ents[0].TextSize;
this.dim_TextSize = numval; this._DimTextSize = numval;
this.dim_InputEl.current.value = numval.toString(); this._DimInputEl.current.value = numval.toString();
} }
}) })
); );
if (this.props.ents.length > 0) if (this.props.ents.length > 0)
{ {
let numval = this.props.ents[0].TextSize; let numval = this.props.ents[0].TextSize;
this.dim_TextSize = numval; this._DimTextSize = numval;
this.dim_InputEl.current.value = numval.toString(); this._DimInputEl.current.value = numval.toString();
} }
} }
componentWillUnmount() componentWillUnmount()
{ {
for (let f of this.removeFuncs) for (let f of this._RemoveFuncs)
f(); f();
this.removeFuncs.length = 0; this._RemoveFuncs.length = 0;
this._DimParamRefs = undefined;
} }
private Dim_UseDefault(als: Dimension[]) private Dim_UseDefault(als: Dimension[])
{ {
let propsStore = PropertiesStore.GetInstance() as PropertiesStore; let propsStore = PropertiesStore.GetInstance() as PropertiesStore;
CommandWrap(() => CommandWrap(() =>
{ {
this.dim_TextSize = 60;
this.dim_Exact = 2;
for (let al of als) for (let al of als)
{ {
al.FractionDigits = 2;
al.TextSize = 60;
al.ColorIndex = 7; al.ColorIndex = 7;
propsStore.colorIndex = 7;//todo 撤销的时候UI颜色没有同步更改 al.ClearDimStyleOverride();
this.dim_InputEl.current.value = "60"; }
// this.dim_InputEl.setState({ value: "60" });
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() render()
{ {
let ents = this.props.ents; let ents = this.props.ents;
@ -152,7 +204,7 @@ export class Properties_DimPanel extends React.Component<Properties_DimPanelProp
<div> <div>
<span>: </span> <span>: </span>
<HTMLSelect <HTMLSelect
value={this.dim_Exact} value={this._DimExact}
options={[0, 1, 2, 3, 4, 5]} options={[0, 1, 2, 3, 4, 5]}
onChange={e => this.HandleSelectOnChange(e, ents)} onChange={e => this.HandleSelectOnChange(e, ents)}
/> />
@ -166,11 +218,11 @@ export class Properties_DimPanel extends React.Component<Properties_DimPanelProp
content={"仅限1-999间的数字!"} content={"仅限1-999间的数字!"}
position={Position.TOP} position={Position.TOP}
intent={Intent.WARNING} intent={Intent.WARNING}
isOpen={this.isPopoverOpen} isOpen={this._IsPopoverOpen}
> >
<input <input
ref={this.dim_InputEl} ref={this._DimInputEl}
defaultValue={this.dim_TextSize} defaultValue={this._DimTextSize}
style={{ width: "100%" }} style={{ width: "100%" }}
onKeyDown={(e) => onKeyDown={(e) =>
{ {
@ -181,7 +233,7 @@ export class Properties_DimPanel extends React.Component<Properties_DimPanelProp
} }
else if (e.keyCode === KeyBoard.Enter || e.keyCode === KeyBoard.Space) else if (e.keyCode === KeyBoard.Enter || e.keyCode === KeyBoard.Space)
{ {
if (!this.isPopoverOpen) if (!this._IsPopoverOpen)
//@ts-ignore //@ts-ignore
e.target.blur(); e.target.blur();
else else
@ -193,7 +245,7 @@ export class Properties_DimPanel extends React.Component<Properties_DimPanelProp
}} }}
onFocus={(e) => onFocus={(e) =>
{ {
this.dim_InputEl.current.setSelectionRange(0, this.dim_InputEl.current.value.length); this._DimInputEl.current.setSelectionRange(0, this._DimInputEl.current.value.length);
}} }}
onBlur={(e) => onBlur={(e) =>
{ {
@ -204,7 +256,7 @@ export class Properties_DimPanel extends React.Component<Properties_DimPanelProp
app.Editor.Prompt('文字尺寸仅限1-999间的数字!'); app.Editor.Prompt('文字尺寸仅限1-999间的数字!');
else else
{ {
this.dim_TextSize = val; this._DimTextSize = val;
CommandWrap(() => CommandWrap(() =>
{ {
for (let al of this.props.ents) for (let al of this.props.ents)
@ -225,7 +277,7 @@ export class Properties_DimPanel extends React.Component<Properties_DimPanelProp
min={20} min={20}
max={150} max={150}
stepSize={5} stepSize={5}
labelStepSize={25} labelRenderer={false}
onChange={(value) => onChange={(value) =>
{ {
if (!CommandState.CommandIng) if (!CommandState.CommandIng)
@ -241,14 +293,14 @@ export class Properties_DimPanel extends React.Component<Properties_DimPanelProp
return false; return false;
} }
this.dim_InputEl.current.value = value.toString(); this._DimInputEl.current.value = value.toString();
this.dim_TextSize = value; this._DimTextSize = value;
for (let al of ents) for (let al of ents)
{ {
al.TextSize = this.dim_TextSize; al.TextSize = this._DimTextSize;
} }
}} }}
value={this.dim_TextSize} value={this._DimTextSize}
onRelease={() => onRelease={() =>
{ {
if (CommandState.CommandIng && app.Database.hm.UndoData.CommandName === "更改标注文字尺寸") if (CommandState.CommandIng && app.Database.hm.UndoData.CommandName === "更改标注文字尺寸")
@ -257,6 +309,23 @@ export class Properties_DimPanel extends React.Component<Properties_DimPanelProp
vertical={false} vertical={false}
/> />
</li> </li>
{
ents[0] instanceof AlignedDimension && <div className="leadLength-editor" style={{ display: "block" }}>
{
ParList.map((e) =>
{
let paramRef = React.createRef<DimParamsPanel>();
this._DimParamRefs.set(e[0], paramRef);
return <DimParamsPanel
dimParam={e}
dims={this.props.ents}
ref={paramRef}
changeFunction={this.Dim_ChangeLeadLength}
/>;
})
}
</div>
}
<li> <li>
<Button className={Classes.INTENT_WARNING} text="重置标注为默认" minimal small onClick={() => this.Dim_UseDefault(ents)} /> <Button className={Classes.INTENT_WARNING} text="重置标注为默认" minimal small onClick={() => this.Dim_UseDefault(ents)} />
</li> </li>

@ -75,6 +75,7 @@ export default class ResourceStore
InitClassList = async (class_type: number) => InitClassList = async (class_type: number) =>
{ {
let res = await getClassList(class_type); let res = await getClassList(class_type);
if (!res) return;
this.resourceClass = res.class; this.resourceClass = res.class;
this.resourceParams = res.params; this.resourceParams = res.params;
this.resourceBrands = res.brands; this.resourceBrands = res.brands;
@ -485,7 +486,8 @@ export default class ResourceStore
InitUserCollectDir = async (order: string) => InitUserCollectDir = async (order: string) =>
{ {
let res = await GetUserCollectDir(order); let res = await GetUserCollectDir(order);
this.userFolder = res.dirs; if (res)
this.userFolder = res.dirs;
}; };
/** /**

@ -1232,3 +1232,49 @@ img {
text-overflow: ellipsis; 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;
}
}

@ -482,3 +482,19 @@ export interface CommonPanelConfigOption
{ {
orderType: string; 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;
}

@ -1,3 +1,7 @@
//del_exp_start
/*
//del_exp_end
export { IsRect } from "./Common/CurveUtils"; export { IsRect } from "./Common/CurveUtils";
export * from "./DatabaseServices/CADFiler"; export * from "./DatabaseServices/CADFiler";
export * from "./DatabaseServices/Entity/Arc"; export * from "./DatabaseServices/Entity/Arc";
@ -9,3 +13,7 @@ export * from "./GraphicsSystem/BoolOperateUtils";
export { FeedingToolPath } from "./GraphicsSystem/ToolPath/FeedingToolPath"; export { FeedingToolPath } from "./GraphicsSystem/ToolPath/FeedingToolPath";
export * from "./GraphicsSystem/ToolPath/VKnifToolPath"; export * from "./GraphicsSystem/ToolPath/VKnifToolPath";
export * from "./Production/Product"; export * from "./Production/Product";
//del_exp_start
*/
//del_exp_end

@ -1,3 +1,7 @@
//del_exp_start
/*
//del_exp_end
export * from "./DatabaseServices/Entity/Board"; //避免类型错误 export * from "./DatabaseServices/Entity/Board"; //避免类型错误
export * from "./DatabaseServices/Entity/Circle"; export * from "./DatabaseServices/Entity/Circle";
export * from "./DatabaseServices/Entity/Extrude"; export * from "./DatabaseServices/Entity/Extrude";
@ -19,4 +23,8 @@ export * from "./Nest/Common/ClipperCpp";
export * from "./Reactor/RoomHoleReactor"; export * from "./Reactor/RoomHoleReactor";
//Db Status //Db Status
export * from "./Common/Status"; export * from "./Common/Status";
export * from "./Add-on/Purge"; export * from "./Add-on/Purge";
//del_exp_start
*/
//del_exp_end

Loading…
Cancel
Save