diff --git a/__test__/Booloperate/BoardCutting.test.ts b/__test__/Booloperate/BoardCutting.test.ts index e08589561..9aa958a84 100644 --- a/__test__/Booloperate/BoardCutting.test.ts +++ b/__test__/Booloperate/BoardCutting.test.ts @@ -152,6 +152,19 @@ test('布尔运算导致的切割错误', () => { let d = { "file": [2, "Board", 8, 2, 101, false, 1, 11, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 145.70588235294053, 55.24369747899152, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 145.70588235294053, 55.24369747899152, 0, 1], 0, 3, 2000, 600, 18, true, "Polyline", 8, 2, 0, false, 0, 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, 2, 4, [0, 0], 0, [600, 0], 0, [600, 2000], 0, [0, 2000], 0, true, 2, 3, 2000, 9, 5, true, "Polyline", 8, 2, 0, false, 0, 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, 2, 4, [0, 0], 0, [9, 0], 0, [9, 2000], 0, [0, 2000], 0, true, 0, 3, 6, 1, 1, 0, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 158.70588235294053, 628.2436974789915, 0, 1], 3, 18, 588.3901659112175, 18, true, "Polyline", 8, 2, 0, false, 0, 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, 2, 4, [0, 0], 0, [588.3901659112175, 0], 0, [588.3901659112175, 18], 0, [0, 18], 0, true, 0, 3, 0, 0, 0, 0, 0, [0, 0.9659258262890683, -0.25881904510252074, 0, 0, 0.25881904510252074, 0.9659258262890683, 0, 1, 0, 0, 0, 145.7058823529403, 55.24369747899152, 990.9999999999998, 1], 3, 0, 0, 0, 0, 0, 10, 1, "左侧板", "主卧", "下柜", "", "", "", 0, 0, "测试", 2, 0, "1", "1", "1", "1", "", "", "", 4, "测试", "测试", "测试", "测试", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true, 0, 0, "Board", 8, 2, 100, false, 1, 2, 0, [0, 0.9659258262890683, -0.25881904510252074, 0, -1, 0, 0, 0, 0, 0.25881904510252074, 0.9659258262890683, 0, 1327.7058823529405, 55.24369747899152, 990.9999999999998, 1], 0, 0, true, [1, 0, 0, 0, 0, 0.9659258262890683, -0.25881904510252074, 0, 0, 0.25881904510252074, 0.9659258262890683, 0, 163.70588235294053, -201.24597621760648, 33.76750614753291, 1], 0, 3, 1364, 588.3901659112173, 18, true, "Polyline", 8, 2, 0, false, 0, 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, 2, 4, [0, 0], 0, [588.3901659112173, 0], 0, [588.3901659112173, 1364], 0, [0, 1364], 0, true, 0, 3, 0, 0, 0, 0, 0, 10, 0, "层板", "主卧", "下柜", "", "", "", 0, 1, "测试", 2, 0, "1", "1", "1", "1", "", "", "", 4, "测试", "测试", "测试", "测试", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true, 0, 0], "basePt": { "x": -36.294117647059466, "y": 55.24369747899152, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + let [br0, br1] = LoadBoardsFromFileData(d) as Board[]; + let splitBrs = CuttingBoard(br0, [br1]); + splitBrs.push(br0); + for (let b of splitBrs) + { + expect(b.Volume).toMatchNumberSnapshot(); + } +}); + +test('板件切割因为csg计算错误导致的切割错误', () => +{ + let d = + { "file": [2, "Board", 8, 2, 103, false, 1, 2, 0, [0, 0.9999999999999999, 0, 0, -0.8860509631594647, 0, -0.4635878457036862, 0, -0.46358784570377454, 0, 0.8860509631594184, 0, 1762.4153704413025, 0, 1040.0002246857875, 1], 0, 0, true, [0.8860509631594647, 0, 0.4635878457036862, 0, 0, 0.9999999999999999, 0, 0, -0.46358784570377454, 0, 0.8860509631594184, 0, 1762.4153704413025, -18, 1040.0002246857875, 1], 0, 3, 1979.65, 882.0000000000001, 18, true, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -18, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -18, 0, 0, 1], 0, 2, 4, [18, 0], 0, [900.0000000000001, 0], 0, [900.0000000000001, 1979.65], 0, [18, 1979.65], 0, true, 0, 3, 0, 0, 0, 0, 0, 10, 0, "层板", "", "", "", "", "", 0, 1, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 4, "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true, 0, 0, "Board", 8, 2, 102, false, 1, 11, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1166.6250332856093, 2, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1166.6250332856093, -18, 0, 1], 0, 3, 738.2, 880, 18, true, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -20, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -20, 0, 0, 1], 0, 2, 4, [20, 0], 0, [900, 0], 0, [900, 738.2], 0, [20, 738.2], 0, true, 2, 3, 7, 738.2, 5.250000000116415, true, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -5.25, 0, 0, 1], 0, 0, true, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 881.5, 0, 1], 0, 2, 4, [743.4499999999998, 7], 0, [5.25, 7], 0, [5.25, 0], 0, [743.45, 0], 0, true, 0, 3, 6, 1, 0.15, 0, 0, [0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 1179.375033285493, 863.5, 0, 1], 3, 7, 737.7971530380617, 5.2500000000001705, true, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -5.250000000059116, 0, 0, 1], 0, 0, true, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 8.881784197001252e-16, 881.5, 0, 1], 0, 2, 4, [5.250000000059116, 0], 0, [743.0471530381208, 0], 0, [743.0471530381208, 7], 0, [5.250000000059117, 7], 0, true, 0, 3, 6, 1, 0.15, 0, 0, [0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 1166.6250332856093, 863.5, 0, 1], 3, 0, 0, 0, 0, 0, 10, 1, "立板", "", "", "", "", "", 0, 1, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 4, "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true, 0, 0], "basePt": { "x": 0, "y": 0, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; let [br0, br1] = LoadBoardsFromFileData(d) as Board[]; let splitBrs = CuttingBoard(br0, [br1]); diff --git a/__test__/Booloperate/__snapshots__/BoardCutting.test.ts.snap b/__test__/Booloperate/__snapshots__/BoardCutting.test.ts.snap index cfbe03204..0474067be 100644 --- a/__test__/Booloperate/__snapshots__/BoardCutting.test.ts.snap +++ b/__test__/Booloperate/__snapshots__/BoardCutting.test.ts.snap @@ -32,6 +32,8 @@ exports[`板件与板件切割_分裂成多个 4`] = `"5558571.43374"`; exports[`板件分裂后槽需要在正确的位置 1`] = `"6248188.54979"`; +exports[`板件切割因为csg计算错误导致的切割错误 1`] = `"31269963.76655"`; + exports[`板件切割测试2 1`] = `"1081121.00089"`; exports[`板件切割测试2 2`] = `"1707974.98308"`; diff --git a/__test__/Geometry/EdgeGeometry.test.ts b/__test__/Geometry/EdgeGeometry.test.ts index 3a69470ba..572d087b2 100644 --- a/__test__/Geometry/EdgeGeometry.test.ts +++ b/__test__/Geometry/EdgeGeometry.test.ts @@ -1,7 +1,7 @@ import { Line } from "three"; +import { ExtrudeGeometryBuilder } from "../../src/Geometry/ExtrudeMeshGeomBuilder/ExtrudeEdgeGeometry2"; import { RenderType } from "../../src/GraphicsSystem/RenderType"; import { LoadBoardsFromFileData } from "../Utils/LoadEntity.util"; -import { ExtrudeGeometryBuilder } from "../../src/Geometry/ExtrudeEdgeGeometry2"; test('EdgeGeometry生成', () => { diff --git a/package.json b/package.json index 8874f5984..cf6e6cf93 100644 --- a/package.json +++ b/package.json @@ -95,6 +95,7 @@ "@blueprintjs/core": "^3.52.0", "@blueprintjs/popover2": "^0.12.9", "@blueprintjs/table": "^3.9.13", + "@jscad/modeling": "^2.7.1", "@types/react-virtualized-auto-sizer": "^1.0.1", "@types/react-window": "^1.8.5", "blueimp-md5": "^2.19.0", @@ -107,9 +108,9 @@ "mobx": "^5.15.7", "mobx-react": "^6.3.1", "monotone-convex-hull-2d": "^1.0.1", - "polylabel": "^1.1.0", "p-queue": "^6.6.2", "pako": "^1.0.11", + "polylabel": "^1.1.0", "react": "^17.0.2", "react-color": "^2.19.3", "react-dom": "^17.0.2", diff --git a/src/Add-on/ExportData.tsx b/src/Add-on/ExportData.tsx index 0b6584902..f790a250d 100644 --- a/src/Add-on/ExportData.tsx +++ b/src/Add-on/ExportData.tsx @@ -174,7 +174,10 @@ export function Entitys2Data(ents: Iterable): Data { let index = d.Entitys.length; if (e instanceof Board) - arrayPushArray(d.Entitys, e.SplitExtrudes.map(e => ConvertBoard2Data(e))); + if (e.SplitExtrudes) + arrayPushArray(d.Entitys, e.SplitExtrudes.map(e => ConvertBoard2Data(e))); + else + d.Entitys.push(ConvertBoard2Data(e)); else if (e instanceof SweepSolid) d.Entitys.push(ConverSweep2Data(e)); else if (e instanceof Region) diff --git a/src/Add-on/test/TestTape.ts b/src/Add-on/test/TestTape.ts index 3670753b7..3299b9479 100644 --- a/src/Add-on/test/TestTape.ts +++ b/src/Add-on/test/TestTape.ts @@ -1,11 +1,8 @@ -import { Vector3 } from "three"; -import { TestDraw } from "./TestUtil"; import { app } from "../../ApplicationServices/Application"; import { Board } from "../../DatabaseServices/Entity/Board"; import { PromptStatus } from "../../Editor/PromptResult"; +import { ExtrudeGeometryBuilder } from "../../Geometry/ExtrudeMeshGeomBuilder/ExtrudeEdgeGeometry2"; import { HotCMD } from "../../Hot/HotCommand"; -import { MoveMatrix } from "../../Geometry/GeUtils"; -import { ExtrudeGeometryBuilder } from "../../Geometry/ExtrudeEdgeGeometry2"; @HotCMD export class Command_TestTape { diff --git a/src/Common/CSGIntersect.ts b/src/Common/CSGIntersect.ts new file mode 100644 index 000000000..a90123d3c --- /dev/null +++ b/src/Common/CSGIntersect.ts @@ -0,0 +1,33 @@ +import { Geom3 } from "@jscad/modeling/src/geometries/types"; +import { Mat4 } from "@jscad/modeling/src/maths/mat4"; +import { Vec3 } from "@jscad/modeling/src/maths/vec3"; +import { intersect } from "@jscad/modeling/src/operations/booleans"; +import { Matrix4 } from "three"; + +export interface Geom3Res +{ + polygons: Array<{ + vertices: Array, + plane: [number, number, number, number]; + }>; +} + +export function CSGIntersect(csg1: Geom3, csg2: Geom3, csg2tranfrom: Matrix4): Geom3Res +{ + let bak1 = csg1.polygons; + let bak2 = csg2.polygons; + + let bakMtx = csg2.transforms; + + csg2.transforms = csg2tranfrom.elements as Mat4; + + csg1.polygons = bak1.concat(); + csg2.polygons = bak2.concat(); + + let res = intersect(csg1, csg2) as unknown as Geom3Res; + + csg1.polygons = bak1; + csg2.polygons = bak2; + csg2.transforms = bakMtx; + return res; +} diff --git a/src/Common/InterfereUtil.ts b/src/Common/InterfereUtil.ts index caecab564..8fd02de42 100644 --- a/src/Common/InterfereUtil.ts +++ b/src/Common/InterfereUtil.ts @@ -1,8 +1,7 @@ +import { Geom3 } from "@jscad/modeling/src/geometries/types"; import { Box3, Material, Mesh } from "three"; -import { CSG } from "../csg/core/CSG"; -import { FuzzyCSGFactory } from "../csg/core/FuzzyFactory3d"; -import { CSG2Geometry, Geometry2CSG } from "../csg/core/Geometry2CSG"; -import { Plane } from "../csg/core/math/Plane"; +import { FuzzyFactory } from "../csg/core/FuzzyFactory"; +import { CSG2Geometry2, Geometry2CSG2 } from "../csg/core/Geometry2CSG"; import { ExtrudeHole } from "../DatabaseServices/3DSolid/ExtrudeHole"; import { SweepSolid } from "../DatabaseServices/3DSolid/SweepSolid"; import { Board } from "../DatabaseServices/Entity/Board"; @@ -13,8 +12,10 @@ import { ObjectId } from "../DatabaseServices/ObjectId"; import { ProcessingGroupRecord } from "../DatabaseServices/ProcessingGroup/ProcessingGroupRecord"; import { TemplateLatticeRecord } from "../DatabaseServices/Template/ProgramTempate/TemplateLatticeRecord"; import { TemplateWineRackRecord } from "../DatabaseServices/Template/ProgramTempate/TemplateWineRackRecord"; +import { BoxIsSolid } from "../Geometry/Box"; import { OBB } from "../Geometry/OBB/obb"; import { ColorMaterial } from "./ColorPalette"; +import { CSGIntersect } from "./CSGIntersect"; import { Log } from "./Log"; import { Sleep } from "./Sleep"; @@ -162,16 +163,20 @@ export class CheckInterfereTool continue; } - let interCsg = csg1.intersect(csg2.transform1(e1.OCSInv.multiply(e2.OCSNoClone))); - - let planeSet = new Set(); - let f = new FuzzyCSGFactory; + let interCsg = CSGIntersect(csg1, csg2, e1.OCSInv.multiply(e2.OCSNoClone)); + let planeSet = new Set(); + let f = new FuzzyFactory; for (let polygon of interCsg.polygons) - planeSet.add(f.getPlane(polygon.plane)); + planeSet.add(f.lookupOrCreate(polygon.plane, polygon.plane)); if (planeSet.size >= 4)//最少4个面围成一个三维实体 { - let geo = CSG2Geometry(interCsg).applyMatrix4(e1.OCSNoClone); + let geo = CSG2Geometry2(interCsg); + geo.computeBoundingBox(); + if (!BoxIsSolid(geo.boundingBox, 0.1)) + continue; + + geo.applyMatrix4(e1.OCSNoClone); let mesh = new Mesh(geo, this._MeshMaterial); objMap.push([mesh, [e1, e2]]); } @@ -189,10 +194,10 @@ export class CheckInterfereTool this.objMap.length = 0; } - csgCache: Map = new Map(); + csgCache: Map = new Map(); private GetCSG(en: Solid3D) { - let csg: CSG = this.csgCache.get(en); + let csg: Geom3 = this.csgCache.get(en); if (csg) return csg; if (en instanceof ExtrudeSolid) @@ -202,7 +207,7 @@ export class CheckInterfereTool csg = en.CSG; } else - csg = Geometry2CSG(en.MeshGeometry); + csg = Geometry2CSG2(en.MeshGeometry); this.csgCache.set(en, csg); return csg; diff --git a/src/DatabaseServices/3DSolid/ExtrudeHole.ts b/src/DatabaseServices/3DSolid/ExtrudeHole.ts index 6dfa739c2..6b49d898c 100644 --- a/src/DatabaseServices/3DSolid/ExtrudeHole.ts +++ b/src/DatabaseServices/3DSolid/ExtrudeHole.ts @@ -8,8 +8,8 @@ import { Vector2ApplyMatrix4 } from "../../Common/Matrix4Utils"; import { ObjectSnapMode } from "../../Editor/ObjectSnapMode"; import { Box3Ext } from "../../Geometry/Box"; import { FastWireframe2 } from "../../Geometry/CreateWireframe"; -import { GenerateExtrudeEdgeGeometry } from "../../Geometry/ExtrudeEdgeGeometry"; import { AsVector3, equaln, equalv2, equalv3, ZeroVec } from "../../Geometry/GeUtils"; +import { GenerateExtrudeEdgeGeometry } from "../../Geometry/SimpleExtrudeEdgeGeometry"; import { ScaleUV } from "../../Geometry/UVUtils"; import { RenderType } from "../../GraphicsSystem/RenderType"; import { AutoRecord } from "../AutoRecord"; diff --git a/src/DatabaseServices/Entity/CompositeEntity.ts b/src/DatabaseServices/Entity/CompositeEntity.ts index 85d19de58..b711e6abb 100644 --- a/src/DatabaseServices/Entity/CompositeEntity.ts +++ b/src/DatabaseServices/Entity/CompositeEntity.ts @@ -69,7 +69,7 @@ export class CompositeEntity extends Entity { let cloneE = e.Clone(); cloneE.Material = e.Material; - return cloneE.ApplyMatrix(this.OCS); + return cloneE.ApplyMatrix(this.OCSNoClone); }); } Traverse(callback: (arg0: Entity) => void) diff --git a/src/DatabaseServices/Entity/Extrude.ts b/src/DatabaseServices/Entity/Extrude.ts index 227563ed8..60a37b25a 100644 --- a/src/DatabaseServices/Entity/Extrude.ts +++ b/src/DatabaseServices/Entity/Extrude.ts @@ -1,24 +1,25 @@ +import { Geom3 } from '@jscad/modeling/src/geometries/types'; import Flatbush from 'flatbush'; import { Box3, BoxGeometry, BufferGeometry, ExtrudeGeometry, ExtrudeGeometryOptions, Float32BufferAttribute, Geometry, InstancedInterleavedBuffer, InterleavedBufferAttribute, Line as TLine, LineSegments, Matrix3, Matrix4, Mesh, Object3D, UVGenerator, Vector3 } from "three"; import { Line2 } from "three/examples/jsm/lines/Line2"; import { LineGeometry } from "three/examples/jsm/lines/LineGeometry"; import { arrayClone, arrayLast, arrayPushArray, arrayRemoveIf, arrayRemoveOnce, arraySortByNumber, arraySum } from "../../Common/ArrayExt"; import { ColorMaterial } from "../../Common/ColorPalette"; +import { CSGIntersect } from '../../Common/CSGIntersect'; import { equalCurve, PolylineSpliteRect } from "../../Common/CurveUtils"; import { DisposeThreeObj, Object3DRemoveAll } from "../../Common/Dispose"; import { Log } from "../../Common/Log"; import { matrixSetVector, reviseMirrorMatrix, Vector2ApplyMatrix4 } from "../../Common/Matrix4Utils"; import { Status, UpdateDraw } from "../../Common/Status"; -import { CSG } from "../../csg/core/CSG"; -import { Geometry2CSG } from "../../csg/core/Geometry2CSG"; +import { Geometry2CSG2 } from "../../csg/core/Geometry2CSG"; import { ObjectSnapMode } from "../../Editor/ObjectSnapMode"; import { boardUVGenerator } from "../../Geometry/BoardUVGenerator"; import { Box3Ext } from "../../Geometry/Box"; -import { BSPGroupParse } from "../../Geometry/BSPGroupParse"; +import { BSPGroupParse } from '../../Geometry/BSPGroupParse'; import { BufferGeometryUtils } from "../../Geometry/BufferGeometryUtils"; import { FastExtrudeEdgeGeometry, FastWireframe } from "../../Geometry/CreateWireframe"; import { EdgesGeometry } from "../../Geometry/EdgeGeometry"; -import { ExtrudeGeometryBuilder } from "../../Geometry/ExtrudeEdgeGeometry2"; +import { ExtrudeGeometryBuilder } from "../../Geometry/ExtrudeMeshGeomBuilder/ExtrudeEdgeGeometry2"; import { AsVector2, equaln, equalv2, equalv3, IdentityMtx4, isIntersect, isParallelTo, isPerpendicularityTo, MoveMatrix, XAxis, YAxis, ZAxis, ZeroVec } from "../../Geometry/GeUtils"; import { OBB } from "../../Geometry/OBB/obb"; import { ScaleUV, ScaleUV2 } from "../../Geometry/UVUtils"; @@ -1072,13 +1073,13 @@ export class ExtrudeSolid extends Entity /** * 当调用Draw时,可以生成bsp信息 */ - private csg: CSG; - get CSG() + + private csg: Geom3; + get CSG(): Geom3 { - if (this.csg) - return this.csg; + if (this.csg) return this.csg; - this.csg = Geometry2CSG(this.MeshGeometry); + this.csg = Geometry2CSG2(this.MeshGeometry); return this.csg; } @@ -1158,8 +1159,12 @@ export class ExtrudeSolid extends Entity let m = new Matrix4().makeBasis(xv, yv, zv).copyPosition(this.OCS); let mi = new Matrix4().getInverse(m).multiply(this.OCS); - let interBSP = this.CSG.intersect(target.CSG.transform1(this.OCSInv.multiply(target.OCS))); - let topology = new BSPGroupParse(interBSP); + let interCSG = CSGIntersect(this.CSG, target.CSG, this.OCSInv.multiply(target.OCSNoClone)); + + //测试绘制 + // TestDraw(new Mesh(CSG2Geometry2(interBSP), ColorMaterial.GetConceptualMaterial(1, DoubleSide))); + + let topology = new BSPGroupParse(interCSG); let grooves: ExtrudeSolid[] = []; for (let pts of topology.Parse()) { diff --git a/src/DatabaseServices/Hardware/HardwareCompositeEntity.ts b/src/DatabaseServices/Hardware/HardwareCompositeEntity.ts index 829debaaa..226de21d8 100644 --- a/src/DatabaseServices/Hardware/HardwareCompositeEntity.ts +++ b/src/DatabaseServices/Hardware/HardwareCompositeEntity.ts @@ -1,9 +1,9 @@ -import { CompositeEntity } from "../Entity/CompositeEntity"; -import { Factory } from "../CADFactory"; -import { AutoRecord } from "../AutoRecord"; +import { DefaultCompositeMetalsOption } from "../../Editor/DefaultConfig"; import { ICompHardwareOption } from "../../UI/Components/RightPanel/RightPanelInterface"; +import { AutoRecord } from "../AutoRecord"; +import { Factory } from "../CADFactory"; import { CADFiler } from "../CADFiler"; -import { DefaultCompositeMetalsOption } from "../../Editor/DefaultConfig"; +import { CompositeEntity } from "../Entity/CompositeEntity"; import { Entity } from "../Entity/Entity"; import { ObjectId } from "../ObjectId"; @@ -13,30 +13,32 @@ export class HardwareCompositeEntity extends CompositeEntity @AutoRecord HardwareOption: ICompHardwareOption = { ...DefaultCompositeMetalsOption }; @AutoRecord DataList: [string, string][] = []; @AutoRecord RelevanceBoards: ObjectId[] = []; - constructor() - { - super(); - } - GetAllEntity(isHole: boolean = false, filter?: (e: Entity) => boolean) + + /** + * + * @param [checkIsHole=false] true:只获取是孔的实体 false:返回所有实体 + * @param [checkFilter] 过滤函数 + * @returns + */ + GetAllEntity(checkIsHole: boolean = false, checkFilter?: (e: Entity) => boolean) { let holes: Entity[] = []; for (let e of this.Entitys) { if (e instanceof HardwareCompositeEntity) { - if (!isHole || e.HardwareOption.isHole) - holes.push(...e.GetAllEntity(isHole, filter).map(h => h.ApplyMatrix(this.OCS))); + if (!checkIsHole || e.HardwareOption.isHole) + holes.push(...e.GetAllEntity(checkIsHole, checkFilter).map(h => h.ApplyMatrix(this.OCSNoClone))); } else { - if (!filter || filter(e)) - { - holes.push(e.Clone().ApplyMatrix(this.OCS)); - } + if (!checkFilter || checkFilter(e)) + holes.push(e.Clone().ApplyMatrix(this.OCSNoClone)); } } return holes; } + protected _ReadFile(file: CADFiler) { super._ReadFile(file); @@ -83,6 +85,7 @@ export class HardwareCompositeEntity extends CompositeEntity } } } + //对象将自身数据写入到文件. WriteFile(file: CADFiler) { diff --git a/src/Editor/VisualSpaceBox.ts b/src/Editor/VisualSpaceBox.ts index 0718021fa..aab46b6f1 100644 --- a/src/Editor/VisualSpaceBox.ts +++ b/src/Editor/VisualSpaceBox.ts @@ -1,4 +1,4 @@ -import { BufferGeometry, Float32BufferAttribute, LineSegments, Matrix3, Matrix4, Mesh, Object3D, Vector3, Box3 } from "three"; +import { BufferGeometry, Float32BufferAttribute, LineSegments, Matrix3, Matrix4, Mesh, Object3D, Vector3 } from "three"; import { ColorMaterial } from "../Common/ColorPalette"; import { FixedNotZero } from "../Common/Utils"; import { AutoRecord } from "../DatabaseServices/AutoRecord"; @@ -7,11 +7,11 @@ import { CADFiler } from "../DatabaseServices/CADFiler"; import { Entity } from "../DatabaseServices/Entity/Entity"; import { TemplateRecord } from "../DatabaseServices/Template/TemplateRecord"; import { Text, TextAligen } from "../DatabaseServices/Text/Text"; -import { GenerateBoxEdgeGeometry } from "../Geometry/ExtrudeEdgeGeometry"; +import { Box3Ext } from "../Geometry/Box"; import { XAxis, XAxisN, YAxis, YAxisN, ZAxis, ZeroVec } from "../Geometry/GeUtils"; +import { GenerateBoxEdgeGeometry } from "../Geometry/SimpleExtrudeEdgeGeometry"; import { RenderType } from "../GraphicsSystem/RenderType"; import { ObjectSnapMode } from "./ObjectSnapMode"; -import { Box3Ext } from "../Geometry/Box"; const EmptyArray = []; diff --git a/src/Geometry/BSPGroupParse.ts b/src/Geometry/BSPGroupParse.ts index 79c979ad4..5d7f5f903 100644 --- a/src/Geometry/BSPGroupParse.ts +++ b/src/Geometry/BSPGroupParse.ts @@ -1,29 +1,29 @@ +import { Poly3 } from "@jscad/modeling/src/geometries/types"; +import { Vec3 } from "@jscad/modeling/src/maths/vec3"; import { Vector3 } from "three"; +import { Geom3Res } from "../Common/CSGIntersect"; import { ToFixed } from "../Common/Utils"; -import { CSG } from "../csg/core/CSG"; -import { Polygon } from "../csg/core/math/Polygon3"; -import { Vec3 } from "./IVec3"; /** * 解决 THREEBSP(CSG) 产生的结果没有办法得到分裂的个数. * 本类分析了THREEBSP的组合情况. - * + * * Example: - * + * * let topology = new BSPGroupParse(csg); * topology.parse(); */ export class BSPGroupParse { - constructor(bsp?: CSG, public fractionDigits = 1) + constructor(bsp?: Geom3Res, public fractionDigits = 1) { if (bsp) for (let poly of bsp.polygons) this.Add(poly); } - Add(poly: Polygon) + Add(poly: Poly3) { - let strs = poly.vertices.map(p => this.GenerateP(p.pos)); + let strs = poly.vertices.map(p => this.GenerateP(p)); let str0 = strs[0]; let s0 = this.Get(str0); for (let i = 1; i < strs.length; i++) @@ -51,7 +51,7 @@ export class BSPGroupParse let pts = [...cset].map(str => { let v3 = this.vecMap.get(str); - return new Vector3(v3.x, v3.y, v3.z); + return new Vector3().fromArray(v3); }); res.push(pts); } @@ -81,10 +81,10 @@ export class BSPGroupParse } } } - private vecMap = new Map(); + private vecMap: Map = new Map(); private GenerateP(v: Vec3) { - let str = [v.x, v.y, v.z].map(n => ToFixed(n, this.fractionDigits)).join(","); + let str = v.map(n => ToFixed(n, this.fractionDigits)).join(","); this.vecMap.set(str, v); return str; } diff --git a/src/Geometry/Box.ts b/src/Geometry/Box.ts index e8e354dd9..a8760ce18 100644 --- a/src/Geometry/Box.ts +++ b/src/Geometry/Box.ts @@ -25,7 +25,7 @@ export class Box3Ext extends Box3 //每个轴的大小必须大于最小的size isSolid(minSize = 1) { - return this.getSize(new Vector3()).toArray().every(x => x > minSize); + return BoxIsSolid(this, minSize); } substract(b: Box3Ext, spaceType: SplitType) { @@ -72,3 +72,10 @@ export function IntersectBox2(box1: Box3, box2: Box3, fuzz = 1e-3) return box2.max.x < box1.min.x - fuzz || box2.min.x > box1.max.x + fuzz || box2.max.y < box1.min.y - fuzz || box2.min.y > box1.max.y + fuzz ? false : true; } + +let size = new Vector3; +export function BoxIsSolid(box: Box3, minSize = 1) +{ + box.getSize(size); + return size.x > minSize && size.y > minSize && size.z > minSize; +} diff --git a/src/Geometry/ExtrudeMeshGeomBuilder/ExtrudeCSGGeomBuilder.ts b/src/Geometry/ExtrudeMeshGeomBuilder/ExtrudeCSGGeomBuilder.ts new file mode 100644 index 000000000..a81515350 --- /dev/null +++ b/src/Geometry/ExtrudeMeshGeomBuilder/ExtrudeCSGGeomBuilder.ts @@ -0,0 +1,25 @@ +import { geom2 } from "@jscad/modeling/src/geometries"; +import { Geom3 } from "@jscad/modeling/src/geometries/geom3/"; +import { Mat4 } from "@jscad/modeling/src/maths/mat4"; +import { subtract } from "@jscad/modeling/src/operations/booleans"; +import { extrudeLinear } from "@jscad/modeling/src/operations/extrusions"; +import { ExtrudeSolid } from "../../DatabaseServices/Entity/Extrude"; +import { SplitCurveParams } from "./SplitCurveParams"; + +//使用这个算法会有性能问题 用webworker会好一点,不到必要时刻不使用(例如切斜边 和 二维刀路造型) +export function ExtBuildCSG(ext: ExtrudeSolid): Geom3 +{ + let c = ext.ContourCurve; + let pts = SplitCurveParams(c).map(p => c.GetPointAtParam(p)); + let geo2 = geom2.fromPoints(pts.map(p => [p.x, p.y])); + let geo = extrudeLinear({ height: ext.Thickness }, geo2); + + let grooveGeo: Geom3[] = ext.Grooves.map(ExtBuildCSG); + + geo.transforms = ext.OCSNoClone.elements as Mat4; + + if (grooveGeo.length) + return subtract(geo, grooveGeo); + else + return geo; +} diff --git a/src/Geometry/ExtrudeEdgeGeometry2.ts b/src/Geometry/ExtrudeMeshGeomBuilder/ExtrudeEdgeGeometry2.ts similarity index 93% rename from src/Geometry/ExtrudeEdgeGeometry2.ts rename to src/Geometry/ExtrudeMeshGeomBuilder/ExtrudeEdgeGeometry2.ts index 176d95e61..87efc69ce 100644 --- a/src/Geometry/ExtrudeEdgeGeometry2.ts +++ b/src/Geometry/ExtrudeMeshGeomBuilder/ExtrudeEdgeGeometry2.ts @@ -1,23 +1,23 @@ import Flatbush from 'flatbush'; import { Box3, BufferGeometry, Float32BufferAttribute, MathUtils, Matrix4, Shape as TShape, ShapeUtils, Vector3 } from "three"; -import { arrayPushArray, arrayRemoveDuplicateBySort, arraySortByNumber } from "../Common/ArrayExt"; -import { curveLinkGroup } from "../Common/CurveUtils"; -import { clamp, FixIndex } from "../Common/Utils"; -import { Contour } from "../DatabaseServices/Contour"; -import { Arc } from "../DatabaseServices/Entity/Arc"; -import { Board } from "../DatabaseServices/Entity/Board"; -import { Circle } from "../DatabaseServices/Entity/Circle"; -import { Curve } from "../DatabaseServices/Entity/Curve"; -import { ExtrudeSolid, ExtureContourCurve, MaxDrawGrooveCount } from "../DatabaseServices/Entity/Extrude"; -import { Line } from "../DatabaseServices/Entity/Line"; -import { Polyline, PolylineProps } from "../DatabaseServices/Entity/Polyline"; -import { IntersectOption, IntersectResult } from "../GraphicsSystem/IntersectWith"; -import { LinesType } from "../UI/Store/BoardInterface"; -import { IntersectsBox } from "./Box"; -import { CreateContour2 } from "./CreateContour2"; -import { FastOffset } from "./FastOffset"; -import { AsVector2, equaln, equalv2, equalv3, IdentityMtx4 } from "./GeUtils"; -import { RegionParse } from "./RegionParse"; +import { arrayPushArray, arrayRemoveDuplicateBySort, arraySortByNumber } from "../../Common/ArrayExt"; +import { curveLinkGroup } from "../../Common/CurveUtils"; +import { FixIndex } from "../../Common/Utils"; +import { Contour } from "../../DatabaseServices/Contour"; +import { Board } from "../../DatabaseServices/Entity/Board"; +import { Circle } from "../../DatabaseServices/Entity/Circle"; +import { Curve } from "../../DatabaseServices/Entity/Curve"; +import { ExtrudeSolid, ExtureContourCurve, MaxDrawGrooveCount } from "../../DatabaseServices/Entity/Extrude"; +import { Line } from "../../DatabaseServices/Entity/Line"; +import { Polyline, PolylineProps } from "../../DatabaseServices/Entity/Polyline"; +import { IntersectOption, IntersectResult } from "../../GraphicsSystem/IntersectWith"; +import { LinesType } from "../../UI/Store/BoardInterface"; +import { IntersectsBox } from "../Box"; +import { CreateContour2 } from "../CreateContour2"; +import { FastOffset } from "../FastOffset"; +import { AsVector2, equaln, equalv2, equalv3, IdentityMtx4 } from "../GeUtils"; +import { RegionParse } from "../RegionParse"; +import { SplitCurveParams } from './SplitCurveParams'; export enum DepthType { @@ -557,52 +557,6 @@ export class CurveTapeShape } } -const SplitLength = 4; -const MinSplitCount = 12; -const MaxSplitCount = 360; -function SplitCurveParams(cu: ExtureContourCurve): number[] -{ - let xparams: number[] = []; - if (cu instanceof Circle) - { - let splitCount = cu.Radius / SplitLength; - splitCount = clamp(Math.floor(splitCount), MinSplitCount, MaxSplitCount); - for (let i = 0; i < splitCount; i++) - xparams.push(i / splitCount); - } - else - //分段1 - for (let i = 0; i < cu.EndParam; i++) - { - xparams.push(i); - if (cu.GetBuilgeAt(i) !== 0) - { - let arc = cu.GetCurveAtIndex(i) as Arc; - let splitCount = arc.Radius / SplitLength; - splitCount = clamp(Math.floor(splitCount), MinSplitCount, MaxSplitCount); - if (splitCount === 0) continue; - - let a = Math.PI * 2 / splitCount; - let params: number[] = []; - for (let j = 0; j < splitCount; j++) - { - let param = arc.GetParamAtAngle(a * j); - if (arc.ParamOnCurve(param)) - params.push(param); - } - arraySortByNumber(params); - if (params.length === 0) continue; - - for (let p of params) - { - if (p > 1e-5 && p < 9.99999) - xparams.push(p + i); - } - } - } - xparams.push(cu.EndParam); - return xparams; -} /** * 曲线胶带(一维) @@ -968,14 +922,14 @@ interface CurveSegs reverse: Curve[];//反向 } -function binarySearch(ar: number[], el: number): number +function binarySearch(arr: number[], el: number): number { let m = 0; - let n = ar.length - 1; + let n = arr.length - 1; while (m <= n) { let k = (n + m) >> 1; - let cmp = (el - ar[k]); + let cmp = (el - arr[k]); if (cmp > 1e8) m = k + 1; else if (cmp < -1e8) diff --git a/src/Geometry/ExtrudeMeshGeomBuilder/SplitCurveParams.ts b/src/Geometry/ExtrudeMeshGeomBuilder/SplitCurveParams.ts new file mode 100644 index 000000000..339f1d6a0 --- /dev/null +++ b/src/Geometry/ExtrudeMeshGeomBuilder/SplitCurveParams.ts @@ -0,0 +1,61 @@ +import { arraySortByNumber } from "../../Common/ArrayExt"; +import { clamp } from "../../Common/Utils"; +import { Arc } from "../../DatabaseServices/Entity/Arc"; +import { Circle } from "../../DatabaseServices/Entity/Circle"; +import { ExtureContourCurve } from "../../DatabaseServices/Entity/Extrude"; + +const ARC_SplitLength = 4;//圆的分段长度 +const Arc_MinSplitCount = 12;//圆的最小分段个数 +const ARC_MaxSplitCount = 360;//圆的最大分段个数 + +/** + * + * @param cu + * @returns + */ +export function SplitCurveParams(cu: ExtureContourCurve): number[] +{ + let xparams: number[] = []; + if (cu instanceof Circle) + { + let splitCount = cu.Radius / ARC_SplitLength; + splitCount = clamp(Math.floor(splitCount), Arc_MinSplitCount, ARC_MaxSplitCount); + for (let i = 0; i < splitCount; i++) + xparams.push(i / splitCount); + } + + else + //分段1 + for (let i = 0; i < cu.EndParam; i++) + { + xparams.push(i); + if (cu.GetBuilgeAt(i) !== 0) + { + let arc = cu.GetCurveAtIndex(i) as Arc; + let splitCount = arc.Radius / ARC_SplitLength; + splitCount = clamp(Math.floor(splitCount), Arc_MinSplitCount, ARC_MaxSplitCount); + if (splitCount === 0) + continue; + + let a = Math.PI * 2 / splitCount; + let params: number[] = []; + for (let j = 0; j < splitCount; j++) + { + let param = arc.GetParamAtAngle(a * j); + if (arc.ParamOnCurve(param)) + params.push(param); + } + arraySortByNumber(params); + if (params.length === 0) + continue; + + for (let p of params) + { + if (p > 1e-5 && p < 9.99999) + xparams.push(p + i); + } + } + } + xparams.push(cu.EndParam); + return xparams; +} diff --git a/src/Geometry/ExtrudeEdgeGeometry.ts b/src/Geometry/SimpleExtrudeEdgeGeometry.ts similarity index 93% rename from src/Geometry/ExtrudeEdgeGeometry.ts rename to src/Geometry/SimpleExtrudeEdgeGeometry.ts index 5a5f768d1..d654b46bc 100644 --- a/src/Geometry/ExtrudeEdgeGeometry.ts +++ b/src/Geometry/SimpleExtrudeEdgeGeometry.ts @@ -1,34 +1,37 @@ -import { BufferGeometry, Vector3 } from "three"; -import { arrayLast, arrayPushArray } from "../Common/ArrayExt"; -import { FixIndex } from "../Common/Utils"; -import { equalv3 } from "./GeUtils"; - -export function GenerateExtrudeEdgeGeometry(contourPoints: Vector3[][], height: number): BufferGeometry -{ - let pts: Vector3[] = []; - for (let cs of contourPoints) - arrayPushArray(pts, GenerateExtrudeEdgeGeometryPoints(cs, height)); - let geo = new BufferGeometry().setFromPoints(pts); - return geo; -} - -function GenerateExtrudeEdgeGeometryPoints(contourPoints: Vector3[], height: number): Vector3[] -{ - if (contourPoints.length < 3) return []; - if (equalv3(contourPoints[0], arrayLast(contourPoints))) - contourPoints.pop(); - let pts: Vector3[] = []; - let hpts = contourPoints.map(p => new Vector3(p.x, p.y, height)); - let count = contourPoints.length; - for (let i = 0; i < count; i++) - { - pts.push(contourPoints[i], contourPoints[FixIndex(i + 1, count)], hpts[i], hpts[FixIndex(i + 1, count)], contourPoints[i], hpts[i]); - } - return pts; -} - -export function GenerateBoxEdgeGeometry(length: number, width: number, height: number): BufferGeometry -{ - let pts = [new Vector3(), new Vector3(length), new Vector3(length, width), new Vector3(0, width)]; - return GenerateExtrudeEdgeGeometry([pts], height); -} +import { BufferGeometry, Vector3 } from "three"; +import { arrayLast, arrayPushArray } from "../Common/ArrayExt"; +import { FixIndex } from "../Common/Utils"; +import { equalv3 } from "./GeUtils"; + +//使用轮廓点表快速拉伸 +export function GenerateExtrudeEdgeGeometry(contourPoints: Vector3[][], height: number): BufferGeometry +{ + let pts: Vector3[] = []; + for (let cs of contourPoints) + arrayPushArray(pts, GenerateExtrudeEdgeGeometryPoints(cs, height)); + let geo = new BufferGeometry().setFromPoints(pts); + return geo; +} + +//拉伸点表成为Geom +function GenerateExtrudeEdgeGeometryPoints(contourPoints: Vector3[], height: number): Vector3[] +{ + if (contourPoints.length < 3) return []; + if (equalv3(contourPoints[0], arrayLast(contourPoints))) + contourPoints.pop(); + let pts: Vector3[] = []; + let hpts = contourPoints.map(p => new Vector3(p.x, p.y, height)); + let count = contourPoints.length; + for (let i = 0; i < count; i++) + { + pts.push(contourPoints[i], contourPoints[FixIndex(i + 1, count)], hpts[i], hpts[FixIndex(i + 1, count)], contourPoints[i], hpts[i]); + } + return pts; +} + +//创建一个盒子几何体 +export function GenerateBoxEdgeGeometry(length: number, width: number, height: number): BufferGeometry +{ + let pts = [new Vector3(), new Vector3(length), new Vector3(length, width), new Vector3(0, width)]; + return GenerateExtrudeEdgeGeometry([pts], height); +} diff --git a/src/UI/Components/Board/BoardConfigModal.tsx b/src/UI/Components/Board/BoardConfigModal.tsx index 2228404fe..2ca52a16c 100644 --- a/src/UI/Components/Board/BoardConfigModal.tsx +++ b/src/UI/Components/Board/BoardConfigModal.tsx @@ -23,7 +23,7 @@ import { JigUtils } from "../../../Editor/JigUtils"; import { PromptStatus } from "../../../Editor/PromptResult"; import { SelectBox, SelectType } from "../../../Editor/SelectBox"; import { CreateContours } from "../../../Geometry/CreateContour2"; -import { ContourTreeNode } from "../../../Geometry/ExtrudeEdgeGeometry2"; +import { ContourTreeNode } from "../../../Geometry/ExtrudeMeshGeomBuilder/ExtrudeEdgeGeometry2"; import { AsVector2, equaln, isParallelTo, MoveMatrix } from "../../../Geometry/GeUtils"; import { BoardConfigOption, BoardProcessOption, FaceDirection, IGrooveOption, IUiOption } from '../../Store/BoardInterface'; import { RightPanelStore } from "../../Store/RightPanelStore/RightPanelStore"; diff --git a/src/csg/core/FuzzyFactory.ts b/src/csg/core/FuzzyFactory.ts index e61c09ed8..4851df441 100644 --- a/src/csg/core/FuzzyFactory.ts +++ b/src/csg/core/FuzzyFactory.ts @@ -10,12 +10,15 @@ // Constructor: // numdimensions: the number of parameters for each object // for example for a 2D rectangle this would be 2 + +import { EPS } from "./constants"; + // tolerance: The maximum difference for each parameter allowed to be considered a match export class FuzzyFactory { lookuptable: {}; multiplier: number; - constructor(numdimensions: number, tolerance: number) + constructor(numdimensions: number = 3, tolerance: number = EPS) { this.lookuptable = {}; this.multiplier = 1.0 / tolerance; diff --git a/src/csg/core/Geometry2CSG.ts b/src/csg/core/Geometry2CSG.ts index 0fd1e5039..a30e17238 100644 --- a/src/csg/core/Geometry2CSG.ts +++ b/src/csg/core/Geometry2CSG.ts @@ -1,4 +1,8 @@ +import geom3, { Geom3 } from "@jscad/modeling/src/geometries/geom3"; +import { create, Poly3 } from "@jscad/modeling/src/geometries/poly3"; +import { Vec3 } from "@jscad/modeling/src/maths/vec3"; import { BufferGeometry, Face3, Geometry, Vector2, Vector3 } from "three"; +import { Geom3Res } from "../../Common/CSGIntersect"; import { AsVector2, AsVector3, equalv3, ZeroVec } from "../../Geometry/GeUtils"; import { CSG } from "./CSG"; import { Polygon } from "./math/Polygon3"; @@ -79,6 +83,53 @@ export function CSG2Geometry(csg: CSG): Geometry return geo; } +export function Geometry2CSG2(geometry: Geometry | BufferGeometry): Geom3 +{ + if (geometry instanceof BufferGeometry) + geometry = new Geometry().fromBufferGeometry(geometry); + + let polygons: Poly3[] = []; + for (let i = 0; i < geometry.faces.length; i++) + { + let face = geometry.faces[i]; + let vertices: Vec3[] = []; + if (face instanceof Face3) + { + vertices.push(geometry.vertices[face.a].toArray() as Vec3); + vertices.push(geometry.vertices[face.b].toArray() as Vec3); + vertices.push(geometry.vertices[face.c].toArray() as Vec3); + } + polygons.push(create(vertices)); + } + return geom3.create(polygons); +} + +export function CSG2Geometry2(csg: Geom3 | Geom3Res): Geometry +{ + let geo = new Geometry; + for (let poly of csg.polygons) + { + //@ts-ignore + let normal = new Vector3().fromArray(poly.plane); + + let startIndex = geo.vertices.length; + for (let v of poly.vertices) + geo.vertices.push(new Vector3().fromArray(v)); + + for (let i = poly.vertices.length - 3; i >= 0; i--) + { + let f = new Face3( + startIndex, + startIndex + i + 1, + startIndex + i + 2, + normal); + + geo.faces.push(f); + } + } + return geo; +} + function Vector3ToVector3D(v: Vector3): Vector3D { return new Vector3D(v.x, v.y, v.z); diff --git a/src/ueapi.ts b/src/ueapi.ts index 98e885aac..00f35fa55 100644 --- a/src/ueapi.ts +++ b/src/ueapi.ts @@ -2,4 +2,4 @@ export * from "./DatabaseServices/Entity/Circle"; export * from "./DatabaseServices/Entity/Extrude"; export * from "./DatabaseServices/Entity/Polyline"; export * from "./DatabaseServices/Shape2"; -export * from "./Geometry/ExtrudeEdgeGeometry2"; +export * from "./Geometry/ExtrudeMeshGeomBuilder/ExtrudeEdgeGeometry2";