diff --git a/__test__/Booloperate/bool2.test.ts b/__test__/Booloperate/bool2.test.ts new file mode 100644 index 000000000..895bef9bb --- /dev/null +++ b/__test__/Booloperate/bool2.test.ts @@ -0,0 +1,14 @@ +import { Region } from "../../src/DatabaseServices/Region"; +import { LoadRegionsFromFileData } from "../Utils/LoadEntity.util"; +import { BoolOpeartionType } from "../../src/GraphicsSystem/BoolOperateUtils"; + +test("#IRFL2面域消失", () => +{ + let data = + [2, "Region", 2, 1, 102, false, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -284.847850497852, -347.14497813089565, 0, 1], 1, 1, 1, 1, 1, "Polyline", 2, 1, 0, false, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -284.847850497852, -347.14497813089565, 0, 1], 0, 2, 4, [258.7734554093699, 1.1368683772161603e-13], 0, [674.3301771838924, 5.684341886080802e-14], 0, [674.3301771838924, 1091.0460568668868], 0, [258.7734554093699, 1091.0460568668868], 0, true, 0, "Region", 2, 1, 103, false, 7, 0, [-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 389.4823496974607, -74.09892126400852, 0, 1], 1, 1, 1, 1, 1, "Polyline", 2, 1, 0, false, 7, 0, [-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 389.4823496974607, -74.09892126400852, 0, 1], 0, 2, 4, [0, 0], 0, [415.5567321777343, 0], 0, [415.5567321777343, 18], 0, [0, 18], 0, true, 0] + + let regs: Region[] = LoadRegionsFromFileData(data); + expect(regs.length).toBe(2); + regs[0].BooleanOper(regs[1], BoolOpeartionType.Intersection); + expect(regs[0].ShapeManager.ShapeList.length).toBe(2); +}); diff --git a/__test__/EdgeSealing/EdgeSealing.test.ts b/__test__/EdgeSealing/EdgeSealing.test.ts index 3e2eabf14..26d905f59 100644 --- a/__test__/EdgeSealing/EdgeSealing.test.ts +++ b/__test__/EdgeSealing/EdgeSealing.test.ts @@ -6,7 +6,7 @@ import { LoadBoardsFromFileData } from "../Utils/LoadEntity.util"; function testBrSealing(br: Board, sealingSize: number[]) { - let originCurve = br.Shape.Outline.Curve; + let originCurve = br.ContourCurve; let dir = Math.sign(originCurve.Area2) * -1; let calcCus = originCurve.Explode() as Curve[]; paragraphCulist(calcCus); @@ -31,14 +31,14 @@ function testBrSealing(br: Board, sealingSize: number[]) test("常规板件,常规坐标系", () => { let data = - [1, "Board", 1, 1, 0, false, 7, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 145.29914529914527, -290.5982905982906, 0, 1], 1, 1, "Polyline", 1, 1, 0, false, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [0, 0], 0, [600, 0], 0, [600, 1200], 0, [0, 1200], 0, true, 0, 1200, 600, 18, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 145.29914529914527, -290.5982905982906, 0, 1], 0, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1.0\",\"sealedDown\":\"1.0\",\"sealedLeft\":\"1.0\",\"sealedRight\":\"1.0\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, 0] + [1, "Board", 2, 1, 0, false, 7, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 145.29914529914527, -290.5982905982906, 0, 1], 0, 1, 1200, 600, 1, true, "Polyline", 2, 1, 0, false, 7, 0, [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, 1200], 0, [0, 1200], 0, true, 0, null, null, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], null, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0] let layerBr = LoadBoardsFromFileData(data)[0]; let sealingSize = [1, 1, 1, 1]; testBrSealing(layerBr, sealingSize); sealingSize = [3, 2, 3, 2]; testBrSealing(layerBr, sealingSize); data = - [1, "Board", 1, 1, 0, false, 7, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -292.022792022792, -213.67521367521368, 0, 1], 1, 1, "Polyline", 1, 1, 0, false, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [0, 0], 0, [600, 0], 0, [600, 1200], 0, [0, 1200], 0, true, 0, 1200, 600, 18, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -292.022792022792, -213.67521367521368, 0, 1], 1, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1.0\",\"sealedDown\":\"1.0\",\"sealedLeft\":\"1.0\",\"sealedRight\":\"1.0\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, 0] + [1, "Board", 2, 1, 0, false, 7, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -292.022792022792, -213.67521367521368, 0, 1], 0, 1, 1200, 600, 1, true, "Polyline", 2, 1, 0, false, 7, 0, [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, 1200], 0, [0, 1200], 0, true, 0, null, null, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], null, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0] let vBr = LoadBoardsFromFileData(data)[0]; sealingSize = [2, 2, 2, 2]; testBrSealing(vBr, sealingSize); @@ -47,7 +47,7 @@ test("常规板件,常规坐标系", () => test("异型板件,常规坐标系", () => { let data = - [1, "Board", 1, 1, 0, false, 7, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 3681.8686077049847, -1396.263281011676, 0, 1], 1, 1, "Polyline", 1, 1, 0, true, 7, 0, [6.123233995736766e-17, -1, 0, 0, 1, 6.123233995736766e-17, 0, 0, 0, 0, 1, 0, 1396.2632810116759, 3681.8686077049847, 0, 1], 2, 5, [2345.694899782759, -1396.263281011676], 0, [3681.8686077049847, -1396.263281011676], 0, [3681.8686077049847, 443.1597468696174], 0.41421356237309503, [3481.8686077049847, 643.1597468696174], 0, [2345.694899782759, 643.1597468696174], 0, true, 0, 1336.1737079222257, 2039.4230278812934, 18, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3681.8686077049847, -1396.263281011676, 0, 1], 0, "层板", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"sealedUp\":\"1.0\",\"sealedDown\":\"1.0\",\"sealedLeft\":\"1.0\",\"sealedRight\":\"1.0\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, 0] + [1, "Board", 2, 1, 0, false, 7, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 3681.8686077049847, -1396.263281011676, 0, 1], 0, 1, 1336.1737079222257, 2039.4230278812934, 1, false, "Polyline", 2, 1, 0, true, 7, 0, [6.123233995736766e-17, -1, 0, 0, 1, 6.123233995736766e-17, 0, 0, 0, 0, 1, 0, 1396.2632810116759, 3681.8686077049847, 0, 1], 0, 2, 5, [2345.694899782759, -1396.263281011676], 0, [3681.8686077049847, -1396.263281011676], 0, [3681.8686077049847, 443.1597468696174], 0.41421356237309503, [3481.8686077049847, 643.1597468696174], 0, [2345.694899782759, 643.1597468696174], 0, true, 0, null, null, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], null, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0] //第三段为圆弧 let br = LoadBoardsFromFileData(data)[0]; let sealingSize = [1, 1, 1]; @@ -58,7 +58,7 @@ test("异型板件,常规坐标系", () => testBrSealing(br, sealingSize); // 2,4,6,8段为圆弧 data = - [1, "Board", 1, 1, 0, false, 7, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 6239.212423224621, -1330.0896939146003, 0, 1], 1, 1, "Polyline", 1, 1, 0, true, 7, 0, [6.123233995736766e-17, -1, 0, 0, 1, 6.123233995736766e-17, 0, 0, 0, 0, 1, 0, 1330.0896939146, 6239.212423224621, 0, 1], 2, 8, [5263.6654731094095, -1330.0896939146003], 0, [5939.212423224621, -1330.0896939146003], 0.41421356237309503, [6239.212423224621, -1030.0896939146003], 0, [6239.212423224621, 495.8218896107525], 0.41421356237309503, [5939.212423224621, 795.8218896107526], 0, [5263.6654731094095, 795.8218896107526], 0.4142135623730949, [4963.6654731094095, 495.8218896107527], 0, [4963.6654731094095, -1030.0896939146003], 0.4142135623730949, true, 0, 1275.546950115211, 2125.911583525353, 18, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 6239.212423224621, -1330.0896939146003, 0, 1], 0, "层板", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"sealedUp\":\"1.0\",\"sealedDown\":\"1.0\",\"sealedLeft\":\"1.0\",\"sealedRight\":\"1.0\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\",\"highSealed\":[]}", 0, 0] + [1, "Board", 2, 1, 0, false, 7, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 6239.212423224621, -1330.0896939146003, 0, 1], 0, 1, 1275.546950115211, 2125.911583525353, 1, false, "Polyline", 2, 1, 0, true, 7, 0, [6.123233995736766e-17, -1, 0, 0, 1, 6.123233995736766e-17, 0, 0, 0, 0, 1, 0, 1330.0896939146, 6239.212423224621, 0, 1], 0, 2, 8, [5263.6654731094095, -1330.0896939146003], 0, [5939.212423224621, -1330.0896939146003], 0.41421356237309503, [6239.212423224621, -1030.0896939146003], 0, [6239.212423224621, 495.8218896107525], 0.41421356237309503, [5939.212423224621, 795.8218896107526], 0, [5263.6654731094095, 795.8218896107526], 0.4142135623730949, [4963.6654731094095, 495.8218896107527], 0, [4963.6654731094095, -1030.0896939146003], 0.4142135623730949, true, 0, null, null, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], null, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0] br = LoadBoardsFromFileData(data)[0]; sealingSize = [1]; testBrSealing(br, sealingSize); @@ -69,7 +69,7 @@ test("异型板件,常规坐标系", () => test("异型板件,非常规坐标系", () => { let data = - [1, "Board", 1, 1, 0, false, 7, 0, [0, 0, 1, 0, -1, 0, 0, 0, 0, -1, 0, 0, 15844.064994449893, 0, -2833.834144511985, 1], 1, 1, "Polyline", 1, 1, 0, true, 7, 0, [6.123233995736766e-17, -1, 0, 0, 1, 6.123233995736766e-17, 0, 0, 0, 0, 1, 0, 2833.8341445119845, 15844.064994449893, 0, 1], 2, 6, [5008.758238702114, -2833.834144511985], 0, [5008.758238702114, 2775.380162574158], -0.414213562373095, [7222.921780972962, 4989.543704845006], 0, [13759.976048629745, 4989.543704845006], -0.8565683416116343, [14392.594203564273, 919.700241432878], 0, [14076.28512609701, -2833.834144511985], 0, true, 0, 10835.306755747779, 7823.377849356992, 18, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 15844.064994449893, 0, -2833.834144511985, 1], 0, "层板", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1.0\",\"sealedDown\":\"1.0\",\"sealedLeft\":\"1.0\",\"sealedRight\":\"1.0\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, 0] + [1, "Board", 2, 1, 0, false, 7, 0, [0, 0, 1, 0, -1, 0, 0, 0, 0, -1, 0, 0, 15844.064994449893, 0, -2833.834144511985, 1], 0, 1, 10835.306755747779, 7823.377849356992, 1, false, "Polyline", 2, 1, 0, true, 7, 0, [6.123233995736766e-17, -1, 0, 0, 1, 6.123233995736766e-17, 0, 0, 0, 0, 1, 0, 2833.8341445119845, 15844.064994449893, 0, 1], 0, 2, 6, [5008.758238702114, -2833.834144511985], 0, [5008.758238702114, 2775.380162574158], -0.414213562373095, [7222.921780972962, 4989.543704845006], 0, [13759.976048629745, 4989.543704845006], -0.8565683416116343, [14392.594203564273, 919.700241432878], 0, [14076.28512609701, -2833.834144511985], 0, true, 0, null, null, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], null, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0] //第2,4段为圆弧 let br = LoadBoardsFromFileData(data)[0]; let sealingSize = [1, 1, 1, 1, 1, 1]; diff --git a/__test__/FeedingToolPath/FeedingToolPath.test.ts b/__test__/FeedingToolPath/FeedingToolPath.test.ts index b5b1a1203..44055a046 100644 --- a/__test__/FeedingToolPath/FeedingToolPath.test.ts +++ b/__test__/FeedingToolPath/FeedingToolPath.test.ts @@ -19,12 +19,12 @@ function testPathCount(br: Board, count?: number) expect(cu.Length).toMatchSnapshot("曲线长度"); } } -let feedUtil = FeedingToolPath.GetInstance(); +let feedUtil = FeedingToolPath.GetInstance() as FeedingToolPath; test("通孔造型测试", () => { let data = - [1, "Board", 1, 1, -1, false, 7, -1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 126.93136983439945, -7851.102620205904, 0, 1], 1, 1, "Polyline", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [0, 0], 0, [600, 0], 0, [600, 1200], 0, [0, 1200], 0, true, 0, 1200, 600, 18, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 126.93136983439945, -7851.102620205904, 0, 1], 0, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, 1, 1, "Polyline", 1, 1, -1, false, 1, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7822.630590069403, 2129.4641561015833, 0, 1], 2, 4, [-7679.5111852499285, -1949.1412985704153], 0, [-7405.040814734067, -1949.141298570415], 0, [-7405.040814734067, -1275.3032520065758], 0, [-7679.5111852499285, -1275.303252006576], 0, true, 0, 18, 0, 3, 0] + [1, "Board", 2, 1, 0, false, 7, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 126.93136983439945, -7851.102620205904, 0, 1], 0, 1, 1200, 600, 18, true, "Polyline", 2, 1, 0, false, 7, 0, [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, 1200], 0, [0, 1200], 0, true, 1, 1, 673.8380465638395, 274.47037051586176, 18, true, "Polyline", 2, 1, 0, false, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7679.5111852499285, 1949.1412985704153, 0, 1], 0, 2, 4, [-7679.5111852499285, -1949.1412985704153], 0, [-7405.040814734067, -1949.141298570415], 0, [-7405.040814734067, -1275.3032520065758], 0, [-7679.5111852499285, -1275.303252006576], 0, true, 0, 3, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -53.391487696768536, -7707.983215386429, 0, 1], null, null, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], null, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0] let brs = LoadBoardsFromFileData(data); testPathCount(brs[0]); }) @@ -32,12 +32,12 @@ test("通孔造型测试", () => test("带孔造型板件", () => { let data = - [1, "Board", 1, 1, -1, false, 7, -1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 315.04650013028345, -2923.9345412691255, 0, 1], 1, 1, "Polyline", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [0, 0], 0, [600, 0], 0, [600, 1200], 0, [0, 1200], 0, true, 0, 1200, 600, 18, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 315.04650013028345, -2923.9345412691255, 0, 1], 0, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, 1, 1, "Polyline", 1, 1, -1, false, 1, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2916.366392263997, 1987.6074302636166, 0, 1], 2, 4, [-2793.4596524207154, -1846.8398587682314], 0, [-2477.4137499665617, -1846.8398587682314], 0, [-2477.4137499665617, -1064.898703558386], 0, [-2793.4596524207154, -1064.898703558386], 0, true, 1, "Polyline", 1, 1, -1, false, 1, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2916.366392263997, 1987.6074302636166, 0, 1], 2, 4, [-2714.448176807177, -1707.8886430340776], 0, [-2570.047893789331, -1707.8886430340776], 0, [-2570.047893789331, -1247.442457562078], 0, [-2714.448176807177, -1247.442457562078], 0, true, 10, 0, 3, 0] + [1, "Board", 2, 1, 0, false, 7, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 315.04650013028345, -2923.9345412691255, 0, 1], 0, 1, 1200, 600, 18, true, "Polyline", 2, 1, 0, false, 7, 0, [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, 1200], 0, [0, 1200], 0, true, 1, 1, 781.9411552098454, 316.04590245415375, 10, true, "Polyline", 2, 1, 0, false, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2793.4596524207154, 1846.8398587682314, 0, 1], 0, 2, 4, [-2793.4596524207154, -1846.8398587682314], 0, [-2477.4137499665617, -1846.8398587682314], 0, [-2477.4137499665617, -1064.898703558386], 0, [-2793.4596524207154, -1064.898703558386], 0, true, 1, 1, 460.44618547199957, 144.40028301784605, 10, true, "Polyline", 2, 1, 0, false, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2714.448176807177, 1707.8886430340776, 0, 1], 0, 2, 4, [-2714.448176807177, -1707.8886430340776], 0, [-2570.047893789331, -1707.8886430340776], 0, [-2570.047893789331, -1247.442457562078], 0, [-2714.448176807177, -1247.442457562078], 0, true, 0, null, null, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 35.32771290074447, -2722.0163258123052, 0, 1], 3, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 174.2789286348982, -2801.027801425844, 0, 1], null, null, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], null, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0] let brs = LoadBoardsFromFileData(data); testPathCount(brs[0]); data = - [2, "Board", 1, 1, -1, false, 7, -1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 315.04650013028345, -2923.9345412691255, 0, 1], 1, 1, "Polyline", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [0, 0], 0, [600, 0], 0, [600, 1200], 0, [0, 1200], 0, true, 0, 1200, 600, 18, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 315.04650013028345, -2923.9345412691255, 0, 1], 0, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, 1, 1, "Polyline", 1, 1, -1, false, 1, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2916.366392263997, 1987.6074302636166, 0, 1], 2, 4, [-2793.4596524207154, -1846.8398587682314], 0, [-2477.4137499665617, -1846.8398587682314], 0, [-2477.4137499665617, -1064.898703558386], 0, [-2793.4596524207154, -1064.898703558386], 0, true, 1, "Polyline", 1, 1, -1, false, 1, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2916.366392263997, 1987.6074302636166, 0, 1], 2, 4, [-2714.448176807177, -1707.8886430340776], 0, [-2570.047893789331, -1707.8886430340776], 0, [-2570.047893789331, -1247.442457562078], 0, [-2714.448176807177, -1247.442457562078], 0, true, 10, 0, 3, 0, "Board", 1, 1, -1, false, 7, -1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 142.7476665886519, -6652.181401176747, 0, 1], 1, 1, "Polyline", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [0, 0], 0, [600, 0], 0, [600, 1200], 0, [0, 1200], 0, true, 0, 1200, 600, 18, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 142.7476665886519, -6652.181401176747, 0, 1], 0, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, 1, 1, "Polyline", 1, 1, -1, false, 2, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 6646.274106889091, 2021.2672500633112, 0, 1], 2, 6, [-6459.603607399157, -1131.628730342293], 0, [-6168.964728446474, -1131.628730342293], 0, [-6303.651038205035, -1393.9125967142265], 0, [-6186.686611309442, -1702.2733585298784], 0, [-6466.692360544344, -1702.2733585298784], 0, [-6388.716075947283, -1393.9125967142265], 0, true, 2, "Circle", 1, 1, -1, false, 2, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 305.61977726617806, 415.9680345595966, 0, 1], 1, 49.62380364928433, "Circle", 1, 1, -1, false, 2, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 309.447703964579, 788.5528998706459, 0, 1], 1, 43.30804682119281, 15, 0, 0, 0] + [2, "Board", 2, 1, 0, false, 7, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 315.04650013028345, -2923.9345412691255, 0, 1], 0, 1, 1200, 600, 18, true, "Polyline", 2, 1, 0, false, 7, 0, [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, 1200], 0, [0, 1200], 0, true, 1, 1, 781.9411552098454, 316.04590245415375, 10, true, "Polyline", 2, 1, 0, false, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2793.4596524207154, 1846.8398587682314, 0, 1], 0, 2, 4, [-2793.4596524207154, -1846.8398587682314], 0, [-2477.4137499665617, -1846.8398587682314], 0, [-2477.4137499665617, -1064.898703558386], 0, [-2793.4596524207154, -1064.898703558386], 0, true, 1, 1, 460.44618547199957, 144.40028301784605, 10, true, "Polyline", 2, 1, 0, false, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2714.448176807177, 1707.8886430340776, 0, 1], 0, 2, 4, [-2714.448176807177, -1707.8886430340776], 0, [-2570.047893789331, -1707.8886430340776], 0, [-2570.047893789331, -1247.442457562078], 0, [-2714.448176807177, -1247.442457562078], 0, true, 0, null, null, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 35.32771290074447, -2722.0163258123052, 0, 1], 3, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 174.2789286348982, -2801.027801425844, 0, 1], null, null, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], null, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, "Board", 2, 1, 0, false, 7, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 142.7476665886519, -6652.181401176747, 0, 1], 0, 1, 1200, 600, 18, true, "Polyline", 2, 1, 0, false, 7, 0, [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, 1200], 0, [0, 1200], 0, true, 1, 1, 570.6446281875853, 297.7276320978708, 15, false, "Polyline", 2, 1, 0, false, 2, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 6466.692360544344, 1702.2733585298784, 0, 1], 0, 2, 6, [-6459.603607399157, -1131.628730342293], 0, [-6168.964728446474, -1131.628730342293], 0, [-6303.651038205035, -1393.9125967142265], 0, [-6186.686611309442, -1702.2733585298784], 0, [-6466.692360544344, -1702.2733585298784], 0, [-6388.716075947283, -1393.9125967142265], 0, true, 2, 1, 99.24760729856871, 99.24760729856868, 15, false, "Circle", 2, 1, 0, false, 2, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 49.623803649284326, 49.623803649284355, 0, 1], 0, 1, 49.62380364928433, 0, null, null, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -223.59656432166037, -6396.185427559853, 0, 1], 1, 86.61609364238552, 86.61609364238564, 15, false, "Circle", 2, 1, 0, false, 2, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 43.30804682119282, 43.30804682119276, 0, 1], 0, 1, 43.30804682119281, 0, null, null, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -602.4971864608012, -6386.041744033361, 0, 1], 0, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -176.24622494478092, -6472.599654832001, 0, 1], null, null, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], null, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0] brs = LoadBoardsFromFileData(data); testPathCount(brs[0]); }) @@ -45,25 +45,25 @@ test("带孔造型板件", () => test("极限刀半径", () => { let data = - [1, "Board", 1, 1, -1, false, 7, -1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -657.7056127057733, -888.0170782475586, 0, 1], 1, 1, "Polyline", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [0, 0], 0, [600, 0], 0, [600, 1200], 0, [0, 1200], 0, true, 0, 1200, 600, 18, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -657.7056127057733, -888.0170782475586, 0, 1], 0, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, 1, 1, "Polyline", 1, 1, -1, false, 1, -1, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 669.7767195227455, 373.85642669358367, 0, 1], 2, 8, [-269.2307692307692, -223.9316239316239], 0, [-209.23076923076923, -223.9316239316239], 0, [-209.2307692307692, -473.9316239316239], 0, [40.7692307692308, -473.9316239316239], 0, [40.76923076923081, -533.9316239316239], 0, [-519.2307692307692, -533.9316239316238], 0, [-519.2307692307692, -473.9316239316238], 0, [-269.23076923076917, -473.9316239316238], 0, true, 0, 15, 0, 30, 0] + [1, "Board", 2, 1, 0, false, 7, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -657.7056127057733, -888.0170782475586, 0, 1], 0, 1, 1200, 600, 18, true, "Polyline", 2, 1, 0, false, 7, 0, [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, 1200], 0, [0, 1200], 0, true, 1, 1, 560, 310, 15, false, "Polyline", 2, 1, 0, false, 1, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 533.9316239316239, 40.76923076923083, 0, 1], 0, 2, 8, [-269.2307692307692, -223.9316239316239], 0, [-209.23076923076923, -223.9316239316239], 0, [-209.2307692307692, -473.9316239316239], 0, [40.7692307692308, -473.9316239316239], 0, [40.76923076923081, -533.9316239316239], 0, [-519.2307692307692, -533.9316239316238], 0, [-519.2307692307692, -473.9316239316238], 0, [-269.23076923076917, -473.9316239316238], 0, true, 0, 30, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -990.7928086301262, -752.1719826564371, 0, 1], null, null, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], null, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0] let brs = LoadBoardsFromFileData(data); testPathCount(brs[0], 3); data = - [1, "Board", 1, 1, -1, false, 7, -1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -663.8732094729834, -1836.8490686954794, 0, 1], 1, 1, "Polyline", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [0, 0], 0, [600, 0], 0, [600, 1200], 0, [0, 1200], 0, true, 0, 1200, 600, 18, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -663.8732094729834, -1836.8490686954794, 0, 1], 0, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, 1, 1, "Polyline", 1, 1, -1, false, 2, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1784.6350413145396, 919.9380237783905, 0, 1], 2, 4, [-1450.7590848806103, 26.7131494779253], 0, [-1450.7590848806103, -719.3699285130117], 0, [-1480.7590848806103, -719.3699285130117], 0, [-1480.7590848806103, 26.88247329704346], 0, true, 0, 18, 0, 15, 0] + [1, "Board", 2, 1, 0, false, 7, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -663.8732094729834, -1836.8490686954794, 0, 1], 0, 1, 1200, 600, 18, true, "Polyline", 2, 1, 0, false, 7, 0, [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, 1200], 0, [0, 1200], 0, true, 1, 1, 746.2524018100552, 30, 18, false, "Polyline", 2, 1, 0, false, 2, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1480.7590848806103, 719.3699285130117, 0, 1], 0, 2, 4, [-1450.7590848806103, 26.7131494779253], 0, [-1450.7590848806103, -719.3699285130117], 0, [-1480.7590848806103, -719.3699285130117], 0, [-1480.7590848806103, 26.88247329704346], 0, true, 0, 15, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -864.4413047383622, -1532.97311226155, 0, 1], null, null, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], null, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0] brs = LoadBoardsFromFileData(data); testPathCount(brs[0], 3); data = - [1, "Board", 1, 1, -1, false, 7, -1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -1045.5289925195948, 676.3547294712749, 0, 1], 1, 1, "Polyline", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [0, 0], 0, [600, 0], 0, [600, 1200], 0, [0, 1200], 0, true, 0, 1200, 600, 18, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1045.5289925195948, 676.3547294712749, 0, 1], 0, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, 1, 1, "Polyline", 1, 1, -1, false, 3, -1, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, -89.78543368837677, 733.8187514408725, 0, 1], 2, 8, [-269.2307692307692, 119.65811965811966], 0, [-269.23076923076945, 631.2089459697221], 0, [526.6267506621481, 631.2089459697221], 0, [526.6267506621481, 119.65811965811963], 0, [466.6267506621481, 119.65811965811962], 0, [466.62675066214797, 571.2089459697221], 0, [-209.2307692307695, 571.2089459697221], 0, [-209.23076923076923, 119.65811965811966], 0, true, 0, 20, 0, 30, 0] + [1, "Board", 2, 1, 0, false, 7, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -1045.5289925195948, 676.3547294712749, 0, 1], 0, 1, 1200, 600, 18, true, "Polyline", 2, 1, 0, false, 7, 0, [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, 1200], 0, [0, 1200], 0, true, 1, 1, 795.8575198929175, 511.55082631160246, 20, false, "Polyline", 2, 1, 0, false, 3, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, -119.65811965811962, 526.6267506621481, 0, 1], 0, 2, 8, [-269.2307692307692, 119.65811965811966], 0, [-269.23076923076945, 631.2089459697221], 0, [526.6267506621481, 631.2089459697221], 0, [526.6267506621481, 119.65811965811963], 0, [466.6267506621481, 119.65811965811962], 0, [466.62675066214797, 571.2089459697221], 0, [-209.2307692307695, 571.2089459697221], 0, [-209.23076923076923, 119.65811965811966], 0, true, 0, 30, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -1252.7209932983192, 706.2274154410178, 0, 1], null, null, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], null, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0] brs = LoadBoardsFromFileData(data); testPathCount(brs[0], 3); data = - [1, "Board", 1, 1, -1, false, 7, -1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -703.1898726073867, -3031.7293464532195, 0, 1], 1, 1, "Polyline", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [0, 0], 0, [600, 0], 0, [600, 1200], 0, [0, 1200], 0, true, 0, 1200, 600, 18, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -703.1898726073867, -3031.7293464532195, 0, 1], 0, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, 1, 1, "Polyline", 1, 1, -1, false, 4, -1, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 2958.0041022950545, -2782.375300102465, 0, 1], 2, 6, [-445.8689458689459, -202.27920227920225], 0, [-445.8689458689459, -142.27920227920225], 0, [-245.8689458689459, -142.27920227920225], 0, [-245.8689458689459, -82.27920227920225], 0, [-45.8689458689459, -82.27920227920225], 0, [-45.86894586894589, -202.27920227920225], 0, true, 0, 18, 0, 30, 0] + [1, "Board", 2, 1, 0, false, 7, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -703.1898726073867, -3031.7293464532195, 0, 1], 0, 1, 1200, 600, 18, true, "Polyline", 2, 1, 0, false, 7, 0, [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, 1200], 0, [0, 1200], 0, true, 1, 1, 400, 120, 18, false, "Polyline", 2, 1, 0, false, 4, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 202.2792022792023, -45.86894586894596, 0, 1], 0, 2, 6, [-445.8689458689459, -202.27920227920225], 0, [-445.8689458689459, -142.27920227920225], 0, [-245.8689458689459, -142.27920227920225], 0, [-245.8689458689459, -82.27920227920225], 0, [-45.8689458689459, -82.27920227920225], 0, [-45.86894586894589, -202.27920227920225], 0, true, 0, 30, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 2033.3164816261324, -276.0044464373673, 0, 1], null, null, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], null, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0] brs = LoadBoardsFromFileData(data); testPathCount(brs[0], 3); data = - [1, "Board", 1, 1, -1, false, 7, -1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -723.8046937091931, -4479.271007572378, 0, 1], 1, 1, "Polyline", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [0, 0], 0, [600, 0], 0, [600, 1200], 0, [0, 1200], 0, true, 0, 1200, 600, 18, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -723.8046937091931, -4479.271007572378, 0, 1], 0, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, 1, 1, "Polyline", 1, 1, -1, false, 1, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 4420.876631461465, 1125.350549803055, 0, 1], 2, 6, [-4011.700851750289, -387.1968681241217], 0, [-4011.700851750289, -687.1968681241217], 0, [-4161.700851750289, -687.1968681241217], 0, [-4161.700851750289, -657.1968681241217], 0, [-4041.700851750289, -657.1968681241217], 0, [-4041.700851750289, -387.1968681241217], 0, true, 0, 18, 0, 15, 0] + [1, "Board", 2, 1, 0, false, 7, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -723.8046937091931, -4479.271007572378, 0, 1], 0, 1, 1200, 600, 18, true, "Polyline", 2, 1, 0, false, 7, 0, [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, 1200], 0, [0, 1200], 0, true, 1, 1, 300, 150, 18, false, "Polyline", 2, 1, 0, false, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 4161.700851750289, 687.1968681241217, 0, 1], 0, 2, 6, [-4011.700851750289, -387.1968681241217], 0, [-4011.700851750289, -687.1968681241217], 0, [-4161.700851750289, -687.1968681241217], 0, [-4161.700851750289, -657.1968681241217], 0, [-4041.700851750289, -657.1968681241217], 0, [-4041.700851750289, -387.1968681241217], 0, true, 0, 15, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -1161.9583753881263, -4220.095227861202, 0, 1], null, null, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], null, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0] brs = LoadBoardsFromFileData(data); testPathCount(brs[0]); @@ -72,7 +72,7 @@ test("极限刀半径", () => test("复杂极限刀半径", () => { let data = - [1, "Board", 1, 1, -1, false, 7, -1, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -604.0236327121571, -287.85437391994753, 0, 1], 1, 1, "Polyline", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -929.3989071038254, 27.540983606557347, 0, 1], 2, 12, [1090.0546448087434, 872.1311475409834], 0, [1057.9234972677596, 599.0163934426229], 0, [929.3989071038254, 599.016393442623], 0, [929.3989071038254, 354.03292181069946], 0, [1167.7049180327872, 368.74316939890696], 0, [1114.1530054644809, 122.40437158469933], 0, [929.3989071038254, 143.05335904853735], 0, [929.3989071038254, -27.540983606557347], 0, [1529.3989071038254, -27.540983606557404], 0, [1529.3989071038254, 1172.4590163934427], 0, [929.3989071038254, 1172.4590163934427], 0, [929.3989071038254, 872.1311475409834], 0, true, 0, 1200, 600, 18, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -604.0236327121571, -287.85437391994753, 0, 1], 1, "左侧板", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, 2, 1, "Polyline", 1, 1, -1, false, 2, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1045.0710382513657, 11.47540983606541, 0, 1], 2, 12, [1111.5123746027145, 991.5327839891172], 0, [1234.7237593481482, 991.5327839891172], 0, [1234.7237593481482, 985.5327839891172], 0, [1118.2025855391182, 985.5327839891172], 0, [1118.2025855391182, 961.9843523533344], 0, [1238.6263823943837, 961.9843523533344], 0, [1238.6263823943837, 953.9843523533344], 0, [1102.0345757761427, 953.9843523533344], 0, [1102.0345757761427, 938.011096497888], 0, [1243.0865230186528, 938.011096497888], 0, [1243.0865230186528, 929.011096497888], 0, [1068.026003516091, 929.011096497888], 0, true, 0, 7.5, 0, 3, 0, 1, "Polyline", 1, 1, -1, false, 1, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1045.0710382513657, 11.47540983606541, 0, 1], 2, 21, [1045.0710382513657, 988.2305644705416], 0, [1071.838538645684, 1047.9617459060103], 0, [1045.0710382513657, 1056.0304182736754], 0, [1045.0710382513662, 1091.938334606794], 0, [1237.9650273224047, 1083.1256830601092], 0, [1543.8535519125685, 1083.1256830601092], 0, [1543.8535519125685, 1077.1256830601092], 0, [1249.5168174863388, 1077.1256830601092], 0, [1249.5168174863388, 1064.203778797814], 0, [1543.9255256830606, 1064.203778797814], 0, [1543.9255256830606, 1057.203778797814], 0, [1251.5572738797819, 1057.203778797814], 0, [1251.5572738797819, 1046.7141525683055], 0, [1544.800006994536, 1046.7141525683055], 0, [1301.694202404372, 980.8365604371581], 0, [1546.954728946011, 745.6150793512566], 0, [1300.598185827323, 682.4262257591249], 0, [1180.816692501768, 676.4610119480917], 0, [1205.7267759562842, 888.1967213114754], 0, [1205.7267759562842, 888.1967213114754], 0, [1045.0710382513657, 888.1967213114754], 0, true, 0, 6, 0, 3, 0] + [1, "Board", 2, 1, 0, false, 7, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -604.0236327121571, -287.85437391994753, 0, 1], 0, 1, 1200, 600, 18, false, "Polyline", 2, 1, 0, false, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -929.3989071038254, 27.540983606557347, 0, 1], 0, 2, 12, [1090.0546448087434, 872.1311475409834], 0, [1057.9234972677596, 599.0163934426229], 0, [929.3989071038254, 599.016393442623], 0, [929.3989071038254, 354.03292181069946], 0, [1167.7049180327872, 368.74316939890696], 0, [1114.1530054644809, 122.40437158469933], 0, [929.3989071038254, 143.05335904853735], 0, [929.3989071038254, -27.540983606557347], 0, [1529.3989071038254, -27.540983606557404], 0, [1529.3989071038254, 1172.4590163934427], 0, [929.3989071038254, 1172.4590163934427], 0, [929.3989071038254, 872.1311475409834], 0, true, 2, 1, 62.52168749122916, 175.06051950256187, 7.5, false, "Polyline", 2, 1, 0, false, 2, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1068.026003516091, -929.011096497888, 0, 1], 0, 2, 12, [1111.5123746027145, 991.5327839891172], 0, [1234.7237593481482, 991.5327839891172], 0, [1234.7237593481482, 985.5327839891172], 0, [1118.2025855391182, 985.5327839891172], 0, [1118.2025855391182, 961.9843523533344], 0, [1238.6263823943837, 961.9843523533344], 0, [1238.6263823943837, 953.9843523533344], 0, [1102.0345757761427, 953.9843523533344], 0, [1102.0345757761427, 938.011096497888], 0, [1243.0865230186528, 938.011096497888], 0, [1243.0865230186528, 929.011096497888], 0, [1068.026003516091, 929.011096497888], 0, true, 0, 3, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -604.0236327121571, -264.8994086552224, 940.4865063339535, 1], 1, 415.4773226587022, 501.88369069464534, 6, false, "Polyline", 2, 1, 0, false, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1045.0710382513657, -676.4610119480917, 0, 1], 0, 2, 21, [1045.0710382513657, 988.2305644705416], 0, [1071.838538645684, 1047.9617459060103], 0, [1045.0710382513657, 1056.0304182736754], 0, [1045.0710382513662, 1091.938334606794], 0, [1237.9650273224047, 1083.1256830601092], 0, [1543.8535519125685, 1083.1256830601092], 0, [1543.8535519125685, 1077.1256830601092], 0, [1249.5168174863388, 1077.1256830601092], 0, [1249.5168174863388, 1064.203778797814], 0, [1543.9255256830606, 1064.203778797814], 0, [1543.9255256830606, 1057.203778797814], 0, [1251.5572738797819, 1057.203778797814], 0, [1251.5572738797819, 1046.7141525683055], 0, [1544.800006994536, 1046.7141525683055], 0, [1301.694202404372, 980.8365604371581], 0, [1546.954728946011, 745.6150793512566], 0, [1300.598185827323, 682.4262257591249], 0, [1180.816692501768, 676.4610119480917], 0, [1205.7267759562842, 888.1967213114754], 0, [1205.7267759562842, 888.1967213114754], 0, [1045.0710382513657, 888.1967213114754], 0, true, 0, 3, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -604.0236327121571, -287.85437391994753, 687.9364217841571, 1], null, null, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], null, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0] let brs = LoadBoardsFromFileData(data); testPathCount(brs[0]); }) @@ -80,11 +80,11 @@ test("复杂极限刀半径", () => test("刀切到外轮廓情况", () => { let data = - [1, "Board", 1, 1, -1, false, 7, -1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 5026.542613652899, -82.94991876210884, 0, 1], 1, 1, "Polyline", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [0, 0], 0, [600, 0], 0, [600, 1200], 0, [0, 1200], 0, true, 0, 1200, 600, 18, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5026.542613652899, -82.94991876210884, 0, 1], 0, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, 1, 1, "Polyline", 1, 1, -1, false, 1, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 93.09030137237562, 6897.948239526741, 0, 1], 2, 4, [46.493939839332825, -6527.979974776644], 0, [340.601203930893, -6527.979974776644], 0, [340.601203930893, -6082.617546295138], 0, [46.493939839332825, -6082.617546295138], 0, true, 1, "Circle", 1, 1, -1, false, 1, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 257.65748249413025, 589.5547926179952, 0, 1], 1, 116.11448843944343, 15, 0, 3, 0] + [1, "Board", 2, 1, 0, false, 7, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 5026.542613652899, -82.94991876210884, 0, 1], 0, 1, 1200, 600, 18, true, "Polyline", 2, 1, 0, false, 7, 0, [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, 1200], 0, [0, 1200], 0, true, 1, 1, 445.36242848150596, 294.1072640915602, 15, true, "Polyline", 2, 1, 0, false, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -46.493939839332825, 6527.979974776644, 0, 1], 0, 2, 4, [46.493939839332825, -6527.979974776644], 0, [340.601203930893, -6527.979974776644], 0, [340.601203930893, -6082.617546295138], 0, [46.493939839332825, -6082.617546295138], 0, true, 1, 1, 232.2289768788869, 232.2289768788869, 15, false, "Circle", 2, 1, 0, false, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 116.11448843944345, 116.11448843944345, 0, 1], 0, 1, 116.11448843944343, 0, null, null, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 4553.102309474347, 58.593075292577964, 0, 1], 3, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 4656.574348902801, 56.63432244959961, 0, 1], null, null, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], null, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0] let brs = LoadBoardsFromFileData(data); testPathCount(brs[0]); data = - [1, "Board", 1, 1, -1, false, 7, -1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 5057.50249574722, -1024.0000779051127, 0, 1], 1, 1, "Polyline", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [0, 0], 0, [600, 0], 0, [600, 1200], 0, [0, 1200], 0, true, 0, 1200, 600, 18, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5057.50249574722, -1024.0000779051127, 0, 1], 0, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, 1, 1, "Polyline", 1, 1, -1, false, 1, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1042.216784740986, 6887.269493483857, 0, 1], 2, 4, [-442.216784740986, -6287.269493483857], 0, [-742.216784740986, -5687.269493483857], 0, [-1042.216784740986, -6287.269493483857], 0, [-742.216784740986, -6887.269493483857], 0, true, 1, "Polyline", 1, 1, -1, false, 1, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1042.216784740986, 6887.269493483857, 0, 1], 2, 4, [-892.216784740986, -6587.269493483857], 0, [-592.216784740986, -6587.269493483857], 0, [-592.216784740986, -5987.269493483857], 0, [-892.216784740986, -5987.269493483857], 0, true, 15, 0, 3, 0] + [1, "Board", 2, 1, 0, false, 7, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 5057.50249574722, -1024.0000779051127, 0, 1], 0, 1, 1200, 600, 18, true, "Polyline", 2, 1, 0, false, 7, 0, [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, 1200], 0, [0, 1200], 0, true, 1, 1, 1200, 600, 15, false, "Polyline", 2, 1, 0, false, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1042.216784740986, 6887.269493483857, 0, 1], 0, 2, 4, [-442.216784740986, -6287.269493483857], 0, [-742.216784740986, -5687.269493483857], 0, [-1042.216784740986, -6287.269493483857], 0, [-742.216784740986, -6887.269493483857], 0, true, 1, 1, 600, 300, 15, true, "Polyline", 2, 1, 0, false, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 892.216784740986, 6587.269493483857, 0, 1], 0, 2, 4, [-892.216784740986, -6587.269493483857], 0, [-592.216784740986, -6587.269493483857], 0, [-592.216784740986, -5987.269493483857], 0, [-892.216784740986, -5987.269493483857], 0, true, 0, null, null, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 4757.50249574722, -874.0000779051127, 0, 1], 3, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 5057.50249574722, -1024.0000779051127, 0, 1], null, null, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], null, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0] brs = LoadBoardsFromFileData(data); testPathCount(brs[0]); }) @@ -92,11 +92,11 @@ test("刀切到外轮廓情况", () => test("复杂造型测试", () => { let data = - [1, "Board", 1, 1, -1, false, 7, -1, [0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, -919.5114893425489, -2703.8098770005176, -134.6026210568009, 1], 1, 1, "Circle", 1, 1, -1, false, 7, -1, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 382.3715309714528, 382.3715309714528, 0, 1], 1, 382.3715309714528, 0, 764.7430619429056, 764.7430619429056, 18, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -919.5114893425489, -2703.8098770005176, -134.6026210568009, 1], 0, "层板", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, 12, 1, "Polyline", 1, 1, -1, false, 1, -1, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 134.6026210568009, -1224.6532653675133, 0, 1], 2, 4, [-1985.6277286542445, 194.21699734632784], 0, [-1228.4218640236884, 194.21699734632784], 0.06505182506170779, [-1227.3723277647396, 293.288035597694], 0, [-1986.6772649131926, 293.288035597694], 0.06505182506170767, true, 0, 10, 0, 3, 0, 1, "Polyline", 1, 1, -1, false, 1, -1, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 658.4697692228576, 691.9524021857917, 0, 1], 2, 2, [108.09377347199688, 48.88012586045511], -0.6501592260197776, [-36.242715090388515, -112.9601530205507], -0.14475251191859181, true, 0, 10, 0, 3, 0, 1, "Polyline", 1, 1, -1, false, 1, -1, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 90.4398943583576, 629.3207306904399, 0, 1], 2, 2, [-49.8138945074669, 50.80997934732096], -0.9109068504784374, [58.36556874536063, -40.70059547852842], -0.09345012042788828, true, 0, 10, 0, 3, 0, 1, "Polyline", 1, 1, -1, false, 1, -1, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 106.62611044415758, 117.47069904431623, 0, 1], 2, 2, [-53.9075765860091, -43.14301434924033], -0.9134441585739421, [45.27005907439718, 52.13413710723313], -0.09065675641591214, true, 0, 10, 0, 3, 0, 1, "Polyline", 1, 1, -1, false, 2, -1, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 786.5650872556355, 426.693071038251, 0, 1], 2, 2, [106.7018657003265, -26.944722394258406], -0.694630372644427, [-98.32737655143399, -49.427049571531825], -0.13740047935395364, true, 0, 10, 0, 3, 0, 1, "Polyline", 1, 1, -1, false, 2, -1, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 134.6026210568009, -1224.6532653675133, 0, 1], 2, 8, [-1742.842992143469, 270.75339078895075], 0, [-1465.8082380451083, 270.75339078895075], 0, [-1465.8082380451083, 264.75339078895075], 0, [-1734.1675823074033, 264.75339078895075], 0, [-1734.1675823074033, 241.83535800206553], 0, [-1465.8082380451083, 241.83535800206553], 0, [-1465.8082380451083, 234.83535800206553], 0, [-1747.4698773893706, 234.83535800206553], 0, true, 0, 10, 0, 3, 0, 1, "Polyline", 1, 1, -1, false, 3, -1, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 757.0918282392297, 199.97569398907103, 0, 1], 2, 2, [62.728362159705455, -81.25460132972853], -0.6202999489718836, [-102.6478640873703, -0.7574000218211268], -0.12204522179623141, true, 0, 10, 0, 3, 0, 1, "Polyline", 1, 1, -1, false, 3, -1, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 615.3934675834237, 37.87276939890694, 0, 1], 2, 2, [3.062518172307499, -73.61947577910792], -0.5578203020437067, [-67.19070005156576, 30.242619895222106], -0.08254084283422802, true, 0, 10, 0, 3, 0, 1, "Circle", 1, 1, -1, false, 3, -1, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 296.1754006981712, 336.45955497267846, 0, 1], 1, 15.87021639344266, 0, 10, 0, 3, 0, 1, "Circle", 1, 1, -1, false, 3, -1, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 299.3494439768467, 458.660221202186, 0, 1], 1, 5.610968815350429, 0, 10, 0, 3, 0, 1, "Circle", 1, 1, -1, false, 4, -1, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 537.4026898785589, 512.6189569398905, 0, 1], 1, 26.9326503136821, 0, 10, 0, 3, 0, 1, "Circle", 1, 1, -1, false, 6, -1, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 534.2286465998834, 261.869537923498, 0, 1], 1, 25.810456550614163, 0, 10, 0, 3, 0] + [1, "Board", 2, 1, 0, false, 7, 0, [0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, -919.5114893425489, -2703.8098770005176, -134.6026210568009, 1], 0, 1, 764.7430619429056, 764.7430619429056, 18, false, "Circle", 2, 1, 0, false, 7, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 382.3715309714528, 382.3715309714528, 0, 1], 0, 1, 382.3715309714528, 12, 1, 764.7430619429051, 99.0710382513663, 10, false, "Polyline", 2, 1, 0, false, 1, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, -194.21699734632773, -1224.6532653675138, 0, 1], 0, 2, 4, [-1985.6277286542445, 194.21699734632784], 0, [-1228.4218640236884, 194.21699734632784], 0.06505182506170779, [-1227.3723277647396, 293.288035597694], 0, [-1986.6772649131926, 293.288035597694], 0.06505182506170767, true, 0, 3, 0, [0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, -919.5114893425489, -2703.809877000518, 194.21699734632773, 1], 1, 154.87462718637266, 167.51203795643926, 10, false, "Polyline", 2, 1, 0, false, 1, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 118.63191209598415, 118.63191209598415, 0, 1], 0, 2, 2, [108.09377347199688, 48.88012586045511], -0.6501592260197776, [-36.242715090388515, -112.9601530205507], -0.14475251191859181, true, 0, 3, 0, [0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, -919.5114893425489, -3277.1303670903253, 405.2352360700726, 1], 1, 120.96920412857833, 111.85590509963981, 10, false, "Polyline", 2, 1, 0, false, 1, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 40.700595478528435, 71.15530962111143, 0, 1], 0, 2, 2, [-49.8138945074669, 50.80997934732096], -0.9109068504784374, [58.36556874536063, -40.70059547852842], -0.09345012042788828, true, 0, 3, 0, [0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, -919.5114893425489, -3261.975298069846, -84.86332217697174, 1], 1, 114.31603289268145, 112.18898816752466, 10, false, "Polyline", 2, 1, 0, false, 1, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 43.14301434924039, 45.27005907439718, 0, 1], 0, 2, 2, [-53.9075765860091, -43.14301434924033], -0.9134441585739421, [45.27005907439718, 52.13413710723313], -0.09065675641591214, true, 0, 3, 0, [0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, -919.5114893425489, -2776.0105169704366, -71.11952496188371, 1], 1, 205.02924225176048, 88.22935454610763, 10, false, "Polyline", 2, 1, 0, false, 2, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 110.05137985883755, 106.7018657003265, 0, 1], 0, 2, 2, [106.7018657003265, -26.944722394258406], -0.694630372644427, [-98.32737655143399, -49.427049571531825], -0.13740047935395364, true, 0, 3, 0, [0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, -919.5114893425489, -3023.801082338442, 541.911086339997, 1], 1, 281.6616393442623, 35.91803278688525, 10, false, "Polyline", 2, 1, 0, false, 2, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, -234.8353580020655, -1465.8082380451083, 0, 1], 0, 2, 8, [-1742.842992143469, 270.75339078895075], 0, [-1465.8082380451083, 270.75339078895075], 0, [-1465.8082380451083, 264.75339078895075], 0, [-1734.1675823074033, 264.75339078895075], 0, [-1734.1675823074033, 241.83535800206553], 0, [-1465.8082380451083, 241.83535800206553], 0, [-1465.8082380451083, 234.83535800206553], 0, [-1747.4698773893706, 234.83535800206553], 0, true, 0, 3, 0, [0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, -919.5114893425489, -2944.964849678113, 234.8353580020655, 1], 1, 165.37622624707575, 101.8932583126109, 10, false, "Polyline", 2, 1, 0, false, 3, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 102.65065833443202, 62.728362159705455, 0, 1], 0, 2, 2, [62.728362159705455, -81.25460132972853], -0.6202999489718836, [-102.6478640873703, -0.7574000218211268], -0.12204522179623141, true, 0, 3, 0, [0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, -919.5114893425489, -2841.057208829883, 519.8385488479968, 1], 1, 76.74566571329112, 103.92576743620577, 10, false, "Polyline", 2, 1, 0, false, 3, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 73.68314754098367, 3.0625181723074775, 0, 1], 0, 2, 2, [3.062518172307499, -73.61947577910792], -0.5578203020437067, [-67.19070005156576, 30.242619895222106], -0.08254084283422802, true, 0, 3, 0, [0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, -919.5114893425489, -2738.620128227117, 407.1076989856391, 1], 1, 31.74043278688532, 31.74043278688532, 10, false, "Circle", 2, 1, 0, false, 3, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 15.87021639344266, 15.87021639344266, 0, 1], 0, 1, 15.87021639344266, 0, 3, 0, [0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, -919.5114893425489, -3024.399215579753, 145.70256324792763, 1], 1, 11.221937630700836, 11.221937630700836, 10, false, "Circle", 2, 1, 0, false, 3, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 5.610968815350418, 5.610968815350418, 0, 1], 0, 1, 5.610968815350429, 0, 3, 0, [0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, -919.5114893425489, -3156.8591293873533, 159.1358541046954, 1], 1, 53.86530062736415, 53.86530062736415, 10, false, "Circle", 2, 1, 0, false, 4, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 26.932650313682075, 26.932650313682075, 0, 1], 0, 1, 26.9326503136821, 0, 3, 0, [0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, -919.5114893425489, -3189.496183626726, 375.86741850807596, 1], 1, 51.620913101228325, 51.620913101228325, 10, false, "Circle", 2, 1, 0, false, 6, 0, [0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 25.810456550614163, 25.810456550614163, 0, 1], 0, 1, 25.810456550614163, 0, 3, 0, [0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, -919.5114893425489, -2939.8689583734013, 373.81556899246834, 1], null, null, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], null, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0] let brs = LoadBoardsFromFileData(data); testPathCount(brs[0]); data = - [1, "Board", 1, 1, -1, false, 7, -1, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1369.5548078237812, 1023.4201319657191, -0.00000703445402905345, 1], 1, 1, "Polyline", 1, 1, -1, false, 7, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [0, 0], 0, [600, 0], 0, [600, 1200], 0, [0, 1200], 0, true, 0, 1200, 600, 18, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1369.5548078237812, 1023.4201319657191, -0.00000703445402905345, 1], 1, "右侧板", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, 2, 1, "Polyline", 1, 1, -1, false, 1, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1112.552131147541, -16.083529411764744, 0, 1], 2, 4, [1231.0912524651885, 1062.969244235294], 0, [1585.4666497357766, 1062.969244235294], 0, [1585.4666497357766, 128.1994955294116], 0, [1228.3008950063647, 128.1994955294116], 0, true, 1, "Polyline", 1, 1, -1, false, 1, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1112.552131147541, -16.083529411764744, 0, 1], 2, 4, [1404.0934149122481, 647.2059828705881], 0, [1473.852351382836, 647.2059828705881], 0, [1473.852351382836, 809.046715482353], 0, [1404.0934149122481, 809.046715482353], 0, true, 3, 0, 3, 0, 1, "Circle", 1, 1, -1, false, 2, -1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 291.54128376470703, 469.28172084705875, 0, 1], 1, 113.61929894258292, 0, 6, 0, 7, 0] + [1, "Board", 2, 1, 0, false, 7, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1369.5548078237812, 1023.4201319657191, -0.00000703445402905345, 1], 0, 1, 1200, 600, 18, true, "Polyline", 2, 1, 0, false, 7, 0, [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, 1200], 0, [0, 1200], 0, true, 2, 1, 934.7697487058824, 357.1657547294119, 3, false, "Polyline", 2, 1, 0, false, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1228.3008950063647, -128.1994955294116, 0, 1], 0, 2, 4, [1231.0912524651885, 1062.969244235294], 0, [1585.4666497357766, 1062.969244235294], 0, [1585.4666497357766, 128.1994955294116], 0, [1228.3008950063647, 128.1994955294116], 0, true, 1, 1, 161.8407326117649, 69.75893647058797, 3, true, "Polyline", 2, 1, 0, false, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1404.0934149122481, -647.2059828705881, 0, 1], 0, 2, 4, [1404.0934149122481, 647.2059828705881], 0, [1473.852351382836, 647.2059828705881], 0, [1473.852351382836, 809.046715482353], 0, [1404.0934149122481, 809.046715482353], 0, true, 0, null, null, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1369.5548078237812, 1314.961415730426, 631.1224464243693, 1], 3, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1369.5548078237812, 1139.1688958245427, 112.11595908319282, 1], 1, 227.2385978851658, 227.23859788516586, 6, false, "Circle", 2, 1, 0, false, 2, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 113.61929894258293, 113.61929894258293, 0, 1], 0, 1, 113.61929894258292, 0, 7, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1369.5548078237812, 1201.3421167878432, 355.6624148700218, 1], null, null, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], null, "", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"knifeRad\":\"0\",\"grooveAddLength\":\"0\",\"grooveAddWidth\":\"0\",\"grooveAddDepth\":\"0\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0] brs = LoadBoardsFromFileData(data); testPathCount(brs[0]); }) diff --git a/__test__/FileSystem/__snapshots__/file.test.ts.snap b/__test__/FileSystem/__snapshots__/file.test.ts.snap index f77987303..e98a7d4c4 100644 --- a/__test__/FileSystem/__snapshots__/file.test.ts.snap +++ b/__test__/FileSystem/__snapshots__/file.test.ts.snap @@ -1,10 +1,10 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`changev 1`] = `"[1,101,1,1,1,false,1,\\"\\",1,2,false,1,\\"Line\\",1,1,100,false,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],1,[2,3,4],[0,0,0],1,4,false,1,0,1,3,false,1,0,1,0,1,\\"CommandHistoryRecord\\",1,\\"\\",2,2,1,\\"HistorycRecord\\",1,\\"RemoveObjectData\\",1,0,\\"CreateObjectData\\",1,[\\"Line\\",1,1,100,false,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],1,[0,0,0],[0,0,0]],\\"\\",100,1,\\"ObjectAllDataHistoryRecord\\",1,1,\\"AllObjectData\\",1,[1,1,100,false,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],1,[0,0,0],[0,0,0]],\\"\\",\\"\\",100]"`; +exports[`changev 1`] = `"[1,101,1,1,1,false,1,\\"\\",1,2,false,1,\\"Line\\",2,1,100,false,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,1,[2,3,4],[0,0,0],1,4,false,1,0,1,3,false,1,0,1,0,1,\\"CommandHistoryRecord\\",1,\\"\\",2,2,1,\\"HistorycRecord\\",1,\\"RemoveObjectData\\",1,0,\\"CreateObjectData\\",1,[\\"Line\\",2,1,100,false,7,0,[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,[2,1,100,false,7,0,[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]"`; -exports[`创建 修改 撤销撤销 重做重做 撤销 重做 1`] = `"[1,101,1,1,1,false,1,\\"\\",1,2,false,1,\\"Line\\",1,1,100,false,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],1,[1,2,3],[0,0,0],1,4,false,1,0,1,3,false,1,0,1,0,1,\\"CommandHistoryRecord\\",1,\\"\\",2,2,1,\\"HistorycRecord\\",1,\\"RemoveObjectData\\",1,0,\\"CreateObjectData\\",1,[\\"Line\\",1,1,100,false,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],1,[0,0,0],[0,0,0]],\\"\\",100,1,\\"ObjectAllDataHistoryRecord\\",1,1,\\"AllObjectData\\",1,[1,1,100,false,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],1,[0,0,0],[0,0,0]],\\"AllObjectData\\",1,[1,1,100,false,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],1,[1,2,3],[0,0,0]],\\"\\",100]"`; +exports[`创建 修改 撤销撤销 重做重做 撤销 重做 1`] = `"[1,101,1,1,1,false,1,\\"\\",1,2,false,1,\\"Line\\",2,1,100,false,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],1,1,[1,2,3],[0,0,0],1,4,false,1,0,1,3,false,1,0,1,0,1,\\"CommandHistoryRecord\\",1,\\"\\",2,2,1,\\"HistorycRecord\\",1,\\"RemoveObjectData\\",1,0,\\"CreateObjectData\\",1,[\\"Line\\",2,1,100,false,7,0,[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,[2,1,100,false,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],1,1,[0,0,0],[0,0,0]],\\"AllObjectData\\",1,[2,1,100,false,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],1,1,[1,2,3],[0,0,0]],\\"\\",100]"`; -exports[`创建 修改 撤销撤销 重做重做 撤销 重做 2`] = `"[\\"HistoricManage\\",1,0,1,\\"CommandHistoryRecord\\",1,\\"\\",2,2,1,\\"HistorycRecord\\",1,\\"RemoveObjectData\\",1,0,\\"CreateObjectData\\",1,[\\"Line\\",1,1,100,false,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],1,[0,0,0],[0,0,0]],\\"\\",100,1,\\"ObjectAllDataHistoryRecord\\",1,1,\\"AllObjectData\\",1,[1,1,100,false,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],1,[0,0,0],[0,0,0]],\\"AllObjectData\\",1,[1,1,100,false,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],1,[1,2,3],[0,0,0]],\\"\\",100]"`; +exports[`创建 修改 撤销撤销 重做重做 撤销 重做 2`] = `"[\\"HistoricManage\\",1,0,1,\\"CommandHistoryRecord\\",1,\\"\\",2,2,1,\\"HistorycRecord\\",1,\\"RemoveObjectData\\",1,0,\\"CreateObjectData\\",1,[\\"Line\\",2,1,100,false,7,0,[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,[2,1,100,false,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],1,1,[0,0,0],[0,0,0]],\\"AllObjectData\\",1,[2,1,100,false,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],1,1,[1,2,3],[0,0,0]],\\"\\",100]"`; exports[`测试创建 1`] = `"[\\"AllObjectData\\",1,[]]"`; @@ -16,7 +16,7 @@ exports[`测试创建 4`] = `"[\\"CreateObjectData\\",1,[]]"`; exports[`测试创建 5`] = `"[\\"HistorycRecord\\",1,\\"\\",\\"\\",\\"\\"]"`; -exports[`测试创建 6`] = `"[\\"Line\\",1,1,0,false,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],1,[0,0,0],[0,0,0]]"`; +exports[`测试创建 6`] = `"[\\"Line\\",2,1,0,false,7,0,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],0,1,[0,0,0],[0,0,0]]"`; exports[`测试创建 7`] = `"[\\"ObjectAllDataHistoryRecord\\",1,1,\\"\\",\\"\\",\\"\\",0]"`; diff --git a/src/Add-on/BoardCutting/LinearCutting.ts b/src/Add-on/BoardCutting/LinearCutting.ts index b21f4ee6b..b7a28f7b8 100644 --- a/src/Add-on/BoardCutting/LinearCutting.ts +++ b/src/Add-on/BoardCutting/LinearCutting.ts @@ -84,7 +84,7 @@ export class LinearCutting implements Command else nnpts = [pts.map(p => p.clone())]; - let brContour = br.Shape.Outline.Curve.Clone() as Polyline;//提取轮廓 + let brContour = br.ContourCurve.Clone() as Polyline;//提取轮廓 let brOCSInv = br.OCSInv; let allSplitPls: Polyline[] = []; @@ -137,16 +137,10 @@ export class LinearCutting implements Command for (let i = 1; i < cus.length; i++) { let br2 = br.Clone(); - let sp = br2.Shape; - sp.Outline = Contour.CreateContour([cus[i]]); - br2.Shape = sp; - + br2.ContourCurve = cus[i]; app.m_Database.ModelSpace.Append(br2); } - - let sp = br.Shape.Clone(); - sp.Outline = Contour.CreateContour([cus[0]]); - br.Shape = sp; + br.ContourCurve = cus[0]; } } } diff --git a/src/Add-on/BoardCutting/NonAssociativeCutting.ts b/src/Add-on/BoardCutting/NonAssociativeCutting.ts index e453f6a02..1eb77cb8e 100644 --- a/src/Add-on/BoardCutting/NonAssociativeCutting.ts +++ b/src/Add-on/BoardCutting/NonAssociativeCutting.ts @@ -1,16 +1,7 @@ -import { Box3, Matrix4, Mesh, Vector3 } from "three"; import { app } from "../../ApplicationServices/Application"; -import { ToFixed } from "../../Common/Utils"; import { Board } from "../../DatabaseServices/Board"; -import { Contour } from "../../DatabaseServices/Contour"; -import { Point } from "../../DatabaseServices/Point"; -import { Polyline } from "../../DatabaseServices/Polyline"; -import { Shape } from "../../DatabaseServices/Shape"; import { Command } from "../../Editor/CommandMachine"; import { PromptStatus } from "../../Editor/PromptResult"; -import { equalv3, isParallelTo } from "../../Geometry/GeUtils"; -import ThreeBSP, { Polygon } from "../../Geometry/ThreeCSG"; -import { FaceDirection } from "../../UI/Store/BoardInterface"; export class NonAssociativeCutting implements Command { @@ -52,200 +43,19 @@ export class NonAssociativeCutting implements Command async CuttingBoard(orgBoard: Board, cutBoards: Board[]) { - let orgNormal = orgBoard.Normal; - let orgOcsInv = orgBoard.OCSInv; - let orgModeling = orgBoard.BoardModeling; - - let mesh = orgBoard.Draw() as Mesh; - let csgOrg = new ThreeBSP(mesh); - for (let br of cutBoards) { - if (isParallelTo(br.Normal, orgNormal)) - { - let brP = br.Position.applyMatrix4(orgOcsInv); - let brz = [brP.z]; - - let faceDir: FaceDirection; - let thickness: number = 0; - if (equalv3(br.Normal, orgNormal)) - brz.unshift(brP.z - br.Thickness); - else - brz.push(brP.z + br.Thickness); - - if (brz[0] <= -(orgBoard.Thickness + 1e-2)) - { - faceDir = FaceDirection.Back; - thickness = brz[1] + orgBoard.Thickness; - } - else if (brz[1] >= -1e-3 && brz[0] < 0) - { - faceDir = FaceDirection.Front; - thickness = 0 - brz[0]; - } - - if (thickness < 0.1) - continue; - - let cu = br.Shape.Outline.Curve.Clone(); - cu.ApplyMatrix(br.OCS) - .ApplyMatrix(orgOcsInv); - - orgModeling.push({ - shape: new Shape(Contour.CreateContour([cu])), - thickness, - dir: faceDir, - rad: 0, - addLen: 0 - }); - } - else - { - let mesh2 = br.Draw() as THREE.Mesh; - let csg2 = new ThreeBSP(mesh2); - let ncsg = csgOrg.intersect(csg2); - - let polys = ncsg.tree.allPolygons(); - - let topology = new TopologyParse(); - for (let p of polys) - topology.Add(p); - - let yv = br.Normal; - let zv = orgNormal; - let xv = yv.clone().cross(zv); - let m = new Matrix4().makeBasis(xv, yv, zv).copyPosition(orgBoard.OCS); - let mi = new Matrix4().getInverse(m); - - for (let pts of topology.Parse()) - { - for (let p of pts) - p.applyMatrix4(mi); - - let box = new Box3().setFromPoints(pts); - - let faceDir: FaceDirection; - let thickness: number = 0; - if (box.min.z <= -(orgBoard.Thickness + 1e-2)) - { - faceDir = FaceDirection.Back; - thickness = box.max.z + orgBoard.Thickness; - } - else if (box.max.z >= -1e-3 && box.min.z < 0) - { - faceDir = FaceDirection.Front; - thickness = 0 - box.min.z; - } - - if (thickness < 0.1) - continue; - let pl = new Polyline().Create2Pt(box.min, box.max) - .ApplyMatrix(m).ApplyMatrix(orgOcsInv); - orgModeling.push({ - shape: new Shape(Contour.CreateContour([pl])), - thickness, - dir: faceDir, - rad: 0, - addLen: 0 - }); - } - } - } - orgBoard.BoardModeling = orgModeling; - orgBoard.UpdateBoardShape(); - } -} - -interface Vec3 -{ - x: number; - y: number; - z: number; -} - -class TopologyParse -{ - constructor(public fractionDigits = 1) - { - - } - - Add(poly: Polygon) - { - 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++) - { - let stri = strs[i]; - s0.add(stri); - - this.Get(stri).add(str0); + let gs = orgBoard.ConverToLocalGroove(br); + for (let g of gs) + orgBoard.AppendGroove(g); } - } - Parse(): Vector3[][] - { - let set = new Set([...this.map.keys()]); + let splitBoard: Board[] = []; + orgBoard.GrooveCheckAll(splitBoard); - let res: Vector3[][] = []; - while (set.size > 0) + for (let br of splitBoard) { - let fp = set[Symbol.iterator]().next().value; - set.delete(fp); - - let cset = new Set(); - cset.add(fp); - - this.GetPts(fp, cset, set); - - let pts = [...cset].map(str => - { - let v3 = this.vecMap.get(str); - return new Vector3(v3.x, v3.y, v3.z); - }); - res.push(pts); + app.m_Database.ModelSpace.Append(br); } - - return res; } - - private map = new Map>(); - - private Get(vstr: string): Set - { - if (!this.map.has(vstr)) - { - let s = new Set(); - this.map.set(vstr, s); - return s; - } - return this.map.get(vstr); - } - - - private GetPts(p: string, cset: Set, oset: Set) - { - let strs = this.map.get(p); - - for (let str of strs) - { - if (!cset.has(str)) - { - cset.add(str); - oset.delete(str); - this.GetPts(str, cset, oset); - } - } - } - - private vecMap = new Map(); - - private GenerateP(v: Vec3) - { - let str = [v.x, v.y, v.z].map(n => ToFixed(n, this.fractionDigits)).join(","); - this.vecMap.set(str, v); - return str; - } - } diff --git a/src/Add-on/CommandFeeding.ts b/src/Add-on/CommandFeeding.ts index f87ab4908..7467ff4d1 100644 --- a/src/Add-on/CommandFeeding.ts +++ b/src/Add-on/CommandFeeding.ts @@ -25,7 +25,7 @@ export class FeedingCommand implements Command .filter((br: Board) => br.BoardModeling.length > 0) as Board[]; if (brs.length > 0) { - let feedingTool = FeedingToolPath.GetInstance(); + let feedingTool = FeedingToolPath.GetInstance() as FeedingToolPath; let retCus = brs.map(br => feedingTool.CalcPath(br)); diff --git a/src/Add-on/DrawBoard/DrawClosingStrip.ts b/src/Add-on/DrawBoard/DrawClosingStrip.ts index 5da2b821d..c50c04eda 100644 --- a/src/Add-on/DrawBoard/DrawClosingStrip.ts +++ b/src/Add-on/DrawBoard/DrawClosingStrip.ts @@ -113,7 +113,7 @@ export class DrawClosingStrip implements Command } opt.type = br.BoardType; - opt.height = br.Length; + opt.height = br.Height; opt.width = br.Width; br.Name = opt.name; diff --git a/src/Add-on/DrawBoard/DrawSpecialShapeBoardTool.ts b/src/Add-on/DrawBoard/DrawSpecialShapeBoardTool.ts index 1a56fa415..c0b35c79e 100644 --- a/src/Add-on/DrawBoard/DrawSpecialShapeBoardTool.ts +++ b/src/Add-on/DrawBoard/DrawSpecialShapeBoardTool.ts @@ -1,110 +1,16 @@ -import { Vector2, Matrix4 } from "three"; +import { Matrix4, Vector3 } from "three"; import { app } from "../../ApplicationServices/Application"; +import { arrayRemove } from "../../Common/ArrayExt"; import { curveLinkGroup } from "../../Common/CurveUtils"; import { Board } from "../../DatabaseServices/Board"; -import { Circle } from "../../DatabaseServices/Circle"; import { Contour } from "../../DatabaseServices/Contour"; import { Curve } from "../../DatabaseServices/Curve"; -import { Entity } from "../../DatabaseServices/Entity"; +import { ExtureContour, ExtureContourCurve, ExtureSolid } from "../../DatabaseServices/Extrude"; import { Polyline } from "../../DatabaseServices/Polyline"; import { Region } from "../../DatabaseServices/Region"; -import { Shape } from "../../DatabaseServices/Shape"; +import { JigUtils } from "../../Editor/JigUtils"; import { PromptStatus } from "../../Editor/PromptResult"; -import { SelectBox } from "../../Editor/SelectBox"; -import { Filter } from "../../Editor/SelectFilter"; import { isParallelTo, MoveMatrix } from "../../Geometry/GeUtils"; -import { JigUtils } from "../../Editor/JigUtils"; - -/** - *选择实体形状 - * @isErase 是否删除组成轮廓的曲线 - * @originEns 存储选择到的实体 - */ -export async function getEntShape(msg: string = "请选择封闭曲线,面域或者板件", isErase = true, originEns?: Entity[]): Promise -{ - let conRes = await app.m_Editor.GetSelection({ - Msg: msg, - Filter: { filterTypes: [Board, Curve, Region] } - }) - if (conRes.Status === PromptStatus.Cancel) - return; - let enList = conRes.SelectSet.SelectEntityList; - if (originEns) - originEns.push(...enList); - return getCulistShape(enList, isErase); -} -/** - *获得屏幕内的图元 - */ -export function getViewEntiy(filter?: Filter): Entity[] -{ - //屏幕左上角点 - let leftTopPt = new Vector2(); - //屏幕右下角点 - let rightBottomPt = new Vector2(app.m_Viewer.Width, app.m_Viewer.Height); - - let selectBox = new SelectBox(app.m_Viewer, leftTopPt, rightBottomPt); - selectBox.Select(app.m_Viewer.Scene.children, filter) - return selectBox.SelectEntityList; -} - - -/** - *获得实体列表轮廓,优先遍历优先选择 - * @export - * @param {Entity[]} cus - * @param {boolean} [isErase=false] 是否删除形成轮廓的曲线 - * @returns - */ -export function getCulistShape(cus: Entity[], isErase = false): Shape -{ - for (let c of cus) - { - if (c instanceof Board) - { - let s = c.Shape.Clone();; - let cu = s.Outline.Curve; - cu.ApplyMatrix(cu.OCSInv); - return s; - } - else if (c instanceof Region) - { - return c.ShapeManager.ShapeList[0].Clone(); - } - else - { - if ((c instanceof Polyline && c.IsClose) || c instanceof Circle) - { - let shape = new Shape(Contour.CreateContour([c])); - if (isErase) - c.Erase(); - return shape; - } - //获得屏幕内的曲线 - let totalCulist = getViewEntiy({ filterTypes: [Curve] }) as Curve[]; - - let group = curveLinkGroup(totalCulist); - - if (group.length === 0) - return; - - for (let g of group) - { - if (g.includes(c as Curve)) - { - let con = Contour.CreateContour(g); - if (con) - { - //TODO:应该在确定绘制后在删除构建曲线 - if (isErase) - g.forEach(c => c.Erase()) - return new Shape(con); - } - } - } - } - } -} /** * 选择提取轮廓的位置 @@ -129,63 +35,109 @@ export async function selectOutlinePosition(cus: Curve[] | Curve) if (ptRes.Status === PromptStatus.OK) moveCus.forEach(cu => app.m_Database.ModelSpace.Append(cu)); - } /** - * @实体和板件平行,把曲线转换到板件坐标系 - * @如果2实体不平行,先把实体转回二维平面或者指定坐标系 - * @export - * @param {(Curve | Shape)} cu - * @param {Board} br - * @param {Matrix4} [ocsInv] + * 应用轮廓到板件 */ -export function changeShapeUCS(cu: Curve | Shape, br: Board, ocsInv?: Matrix4) +export function BoardApplyContour(contour: ExtureContour, brs: Board[], isKeepSize: boolean) { - let [normal, cuOcsInv] = - cu instanceof Shape ? - [cu.Outline.Curve.Normal, cu.Outline.Curve.OCSInv] : [cu.Normal, cu.OCSInv]; - - //曲线和板件平行,把曲线转换到板件坐标系 - if (isParallelTo(normal, br.Normal)) - cu.ApplyMatrix(br.OCSInv); - else + for (let br of brs) { - //如果2实体不平行,先把曲线转回二维平面 - cu.ApplyMatrix(ocsInv ? ocsInv : cuOcsInv); + let oldLength = br.Height; + let oldWidth = br.Width; + ExtrudeApplyContour(br, contour); + if (isKeepSize) + { + br.Height = oldLength; + br.Width = oldWidth; + } } + app.m_Editor.UpdateScreen(); } + /** - * 应用轮廓到板件 - * @param shape 应用的形状 - * @param brs 需要改变的板件列表 - * @param isKeepSize 是否保持大小 + * 选择可以被拉伸实体引用的轮廓. */ -export function aplicateContour(shape: Shape, brs: Board[], isKeepSize: boolean) +export async function SelectExtrudeContour(selectInside = false) + : Promise<{ + contour?: ExtureContour, + gourp?: Curve[][], + useCurves?: Curve[] + }> { - if (!shape) - return; - for (let br of brs) + let ssRes = await app.m_Editor.GetSelection({ + Msg: "请选择(拉伸实体,面域,曲线):", + Filter: { + filterTypes: [Region, ExtureSolid, Curve] + }, + Once: true + }); + + if (ssRes.Status !== PromptStatus.OK) + return {}; + + let ens = ssRes.SelectSet.SelectEntityList as ExtureContourCurve[]; + let en = ens[0]; + if (en instanceof Curve && (selectInside || !en.IsClose)) { - let cloneShape = shape.Clone(); - let cu = cloneShape.Outline.Curve; + let cus = app.m_Viewer.VisibleEntitys.filter(e => e instanceof Curve) as Curve[]; - changeShapeUCS(cu, br); + let cuGroups = curveLinkGroup(cus); - let box = cu.BoundingBox; - cu.ApplyMatrix(MoveMatrix(box.min.clone().negate())); + for (let g of cuGroups) + { + if (g.includes(en)) + { + let pl = Contour.Combine(g, false) as Polyline; + arrayRemove(cuGroups, g); + return { contour: pl, gourp: cuGroups, useCurves: g }; + } + } + } + else return { contour: en }; +} - let oldLength = br.Length; - let oldWidth = br.Width; +/** + * 应用轮廓到拉伸实体,并且返回轮廓到WCS的应用矩阵. + * @returns 如果轮廓是曲线,那么将返回曲线转换到WCS的矩阵 + */ +export function ExtrudeApplyContour(ext: ExtureSolid, contour: ExtureContour): Matrix4 | undefined +{ + if (contour instanceof ExtureSolid) + { + ext.ContourCurve = contour.ContourCurve.Clone(); + } + else if (contour instanceof Region) + { + //清除所有的内部拉槽,应用面域的网洞. 忽略多组面域 + } + else + { + let applyMatrix: Matrix4; + + contour = contour.Clone(); + if (isParallelTo(ext.Normal, contour.Normal)) + applyMatrix = ext.OCSInv; + else if (isParallelTo( + contour.Normal, + new Vector3().setFromMatrixColumn(app.m_Editor.UCSMatrix, 2) + )) + applyMatrix = app.m_Editor.UCSMatrixInv; + else + applyMatrix = contour.OCSInv; - br.Shape = cloneShape; + contour.ApplyMatrix(applyMatrix); - if (isKeepSize) - { - br.Length = oldLength; - br.Width = oldWidth; - } + let box = contour.BoundingBox; + contour.Position = contour.Position.sub(box.min); + ext.ContourCurve = contour; + + //修正矩阵的基点 + applyMatrix.elements[12] -= box.min.x; + applyMatrix.elements[13] -= box.min.y; + applyMatrix.elements[14] -= box.min.z; + return applyMatrix; } - app.m_Editor.UpdateScreen(); } diff --git a/src/Add-on/DrawBoard/DrawSpecialShapedBoard.ts b/src/Add-on/DrawBoard/DrawSpecialShapedBoard.ts index c9dcc1fb5..cfbf08f1d 100644 --- a/src/Add-on/DrawBoard/DrawSpecialShapedBoard.ts +++ b/src/Add-on/DrawBoard/DrawSpecialShapedBoard.ts @@ -1,102 +1,70 @@ -import { Matrix4, Vector3 } from "three"; import { app } from "../../ApplicationServices/Application"; import { FixedNotZero } from "../../Common/Utils"; -import { Arc } from "../../DatabaseServices/Arc"; -import { Board, BoardType } from "../../DatabaseServices/Board"; -import { Circle } from "../../DatabaseServices/Circle"; -import { Curve } from "../../DatabaseServices/Curve"; -import { Line } from "../../DatabaseServices/Line"; -import { Polyline } from "../../DatabaseServices/Polyline"; +import { BoardType, Board } from "../../DatabaseServices/Board"; +import { ExtureSolid } from "../../DatabaseServices/Extrude"; import { Command } from "../../Editor/CommandMachine"; -import { PromptStatus } from "../../Editor/PromptResult"; -import { MoveMatrix } from "../../Geometry/GeUtils"; import { SpecialShapeBoardModal } from "../../UI/Components/Board/SpecialBoardModal"; import { ModalPosition } from "../../UI/Components/Modal/ModalsManage"; import { SpecialShapeStore } from "../../UI/Store/BoardStore"; -import { getCulistShape } from "./DrawSpecialShapeBoardTool"; +import { ExtrudeApplyContour, SelectExtrudeContour } from "./DrawSpecialShapeBoardTool"; +import { Matrix4 } from "three"; export class DrawSpecialShapedBoard implements Command { + ext = new ExtureSolid(); async exec() { - let cuRes = await app.m_Editor.GetSelection({ - Msg: "选择对象", - Filter: { filterTypes: [Polyline, Line, Arc, Circle] } - }) - if (cuRes.Status === PromptStatus.Cancel) - return; - let culist = cuRes.SelectSet.SelectEntityList as Curve[]; + let { contour } = await SelectExtrudeContour(false); - let shape = getCulistShape(culist, true); - if (shape) + if (contour) { - shape = shape.Clone(); - const store = SpecialShapeStore.GetInstance(); + let applyMatrix4 = ExtrudeApplyContour(this.ext, contour); + let toCurve = new Matrix4().getInverse(applyMatrix4); - let cu = shape.Outline.Curve; - let cuOcs = cu.OCS; - - cu.ApplyMatrix(cu.OCSInv); - - let box = cu.BoundingBox; - let size = box.getSize(new Vector3()); - cu.ApplyMatrix(MoveMatrix(box.min.clone().negate())); - - store.m_Option.height = parseFloat(FixedNotZero(size.x, 2)); - store.m_Option.width = parseFloat(FixedNotZero(size.y, 2)); + const store = SpecialShapeStore.GetInstance() as SpecialShapeStore; + store.m_Option.height = parseFloat(FixedNotZero(this.ext.Height, 2)); + store.m_Option.width = parseFloat(FixedNotZero(this.ext.Width, 2)); app.m_Editor.m_ModalManage.RenderModeless(SpecialShapeBoardModal, ModalPosition.Center, { store }); app.m_Editor.m_ModalManage.Callback = async () => { - let thickness = store.m_Option.thickness; - let min = box.min.clone().setZ(-thickness); - min.applyMatrix4(cuOcs); - - let length: number; - let width: number; - - [length, width] = [size.y, size.x]; - + let br = new Board(); + br.BoardType = store.m_Option.type; + br.ApplyMatrix(br.OCSInv); + br.Thickness = store.m_Option.thickness; if (store.m_Option.type === BoardType.Layer) { - cu.ApplyMatrix(new Matrix4().makeRotationZ(-Math.PI / 2)); - cu.ApplyMatrix(MoveMatrix(new Vector3(0, box.getSize(new Vector3()).x))); - - [length, width] = [size.x, size.y]; - - let xv = new Vector3(); - let yv = new Vector3(); - let zv = new Vector3(); - - cuOcs.extractBasis(xv, yv, zv); - cuOcs.makeBasis(yv, xv.negate(), zv); + //基点修改 + toCurve.elements[12] += toCurve.elements[0] * this.ext.Width; + toCurve.elements[13] += toCurve.elements[1] * this.ext.Width; + toCurve.elements[14] += toCurve.elements[2] * this.ext.Width; + + //xy互换 + [ + toCurve.elements[0], + toCurve.elements[1], + toCurve.elements[2], + toCurve.elements[4], + toCurve.elements[5], + toCurve.elements[6] + ] + = + [ + toCurve.elements[4], + toCurve.elements[5], + toCurve.elements[6], + -toCurve.elements[0], + -toCurve.elements[1], + -toCurve.elements[2], + ]; } - - //创建板件 - let br = Board.CreateBoard(length, width, thickness, store.m_Option.type); - br.Name = store.m_Option.name; - br.BoardProcessOption = store.m_BoardProcessOption; - - br.ApplyMatrix(br.OCSInv); - br.ApplyMatrix(MoveMatrix(br.MinPoint.negate())); - cuOcs.setPosition(min); - br.ApplyMatrix(cuOcs); - - //应用轮廓 - br.Shape = shape; - - br.Length = store.m_Option.height; - br.Width = store.m_Option.width; - + br.ApplyMatrix(toCurve); + ExtrudeApplyContour(br, contour); app.m_Database.ModelSpace.Append(br); - - culist.forEach(cu => cu.Erase()); } } else - { app.m_Editor.Prompt('选择对象无效') - } } } diff --git a/src/Add-on/DrawBoard/DrawSpecialShapedBoardByContour.ts b/src/Add-on/DrawBoard/DrawSpecialShapedBoardByContour.ts index 8924abd2e..c8f635e3d 100644 --- a/src/Add-on/DrawBoard/DrawSpecialShapedBoardByContour.ts +++ b/src/Add-on/DrawBoard/DrawSpecialShapedBoardByContour.ts @@ -2,7 +2,7 @@ import { app } from "../../ApplicationServices/Application"; import { Board } from "../../DatabaseServices/Board"; import { Command } from "../../Editor/CommandMachine"; import { PromptStatus } from "../../Editor/PromptResult"; -import { aplicateContour, getEntShape } from "./DrawSpecialShapeBoardTool"; +import { SelectExtrudeContour, BoardApplyContour } from "./DrawSpecialShapeBoardTool"; export class DrawSpecialShapedBoardByContour implements Command { @@ -16,16 +16,16 @@ export class DrawSpecialShapedBoardByContour implements Command return; let targetBoards = brRes.SelectSet.SelectEntityList as Board[]; - let shape = await getEntShape(); - if (!shape) - return; + let { contour } = await SelectExtrudeContour(false); + let keyWord = await app.m_Editor.GetKeyWords({ Msg: "不改变板件大小:", KeyWordList: [{ key: "Y", msg: "是" }, { key: "N", msg: "否" }] }); + if (keyWord.Status !== PromptStatus.Keyword) return; - aplicateContour(shape, targetBoards, keyWord.StringResult === "Y") + BoardApplyContour(contour, targetBoards, keyWord.StringResult === "Y"); } } diff --git a/src/Add-on/DrawBoard/DrawTopBottomBoard.ts b/src/Add-on/DrawBoard/DrawTopBottomBoard.ts index 48d888087..e7aa9e301 100644 --- a/src/Add-on/DrawBoard/DrawTopBottomBoard.ts +++ b/src/Add-on/DrawBoard/DrawTopBottomBoard.ts @@ -75,7 +75,7 @@ export class DrawTopBottomBoard implements Command basePoint.set( max.x + spc.m_RightBoard.Thickness, min.y, - max.z + opt.thickness + max.z ) } else @@ -83,7 +83,7 @@ export class DrawTopBottomBoard implements Command basePoint.set( max.x, min.y, - max.z - opt.offset + max.z - (opt.thickness + opt.offset) ) } return basePoint; @@ -99,7 +99,7 @@ export class DrawTopBottomBoard implements Command basePoint.set( max.x + spc.m_RightBoard.Thickness, min.y, - min.z + min.z - opt.thickness ); } else @@ -107,7 +107,7 @@ export class DrawTopBottomBoard implements Command basePoint.set( max.x, min.y, - min.z + opt.thickness + opt.offset + min.z + opt.offset ); } return basePoint; @@ -155,7 +155,7 @@ export class DrawTopBottomBoard implements Command footBoard.BoardProcessOption = this.store.m_BoardProcessOption; footBoard.BoardProcessOption.composingFace = ComposingType.Reverse; footBoard.BoardProcessOption.bigHoleDir = FaceDirection.Back; - footBoard.ApplyMatrix(MoveMatrix(spaceParse.m_SpaceBox.min.add(new Vector3(0, opt.footBehindShrink)))); + footBoard.ApplyMatrix(MoveMatrix(spaceParse.m_SpaceBox.min.add(new Vector3(0, opt.footBehindShrink + opt.thickness)))); footBoard.ApplyMatrix(spaceParse.m_SpaceOCS); app.m_Database.ModelSpace.Append(footBoard); } diff --git a/src/Add-on/Entsel.ts b/src/Add-on/Entsel.ts index 3135122e7..74b0c21cf 100644 --- a/src/Add-on/Entsel.ts +++ b/src/Add-on/Entsel.ts @@ -39,7 +39,6 @@ export class Entsel implements Command dyn.Destroy(); - window["debugEn"] = en; - console.log('debugEn: ', en); + window["en"] = en.Entity; } } diff --git a/src/Add-on/FilletBoard.ts b/src/Add-on/FilletBoard.ts index ea257b097..f743126ed 100644 --- a/src/Add-on/FilletBoard.ts +++ b/src/Add-on/FilletBoard.ts @@ -86,9 +86,7 @@ export class CommandFilletBoard implements Command //-----5.应用轮廓 brContour.ApplyMatrix(brOCSInv); - let sp = br.Shape.Clone(); - sp.Outline = Contour.CreateContour([brContour]); - br.Shape = sp; + br.ContourCurve = brContour; brContour.Erase(); } UpdateFilletRadius(newRadius: number) diff --git a/src/Add-on/testEntity/test.ts b/src/Add-on/testEntity/test.ts index 58d5b7908..1ea3ae46c 100644 --- a/src/Add-on/testEntity/test.ts +++ b/src/Add-on/testEntity/test.ts @@ -1,33 +1,10 @@ -import { app } from "../../ApplicationServices/Application"; -import { Board } from "../../DatabaseServices/Board"; -import { PhysicalMaterialRecord } from "../../DatabaseServices/PhysicalMaterialRecord"; -import { TextureTableRecord } from "../../DatabaseServices/Texture"; -import { Command } from "../../Editor/CommandMachine"; import { HotCMD } from "../../Hot/HotCommand"; +import { Command } from "../../Editor/CommandMachine"; @HotCMD export class Test implements Command { async exec() { - - let texture = new TextureTableRecord(); - - texture.imageUrl = `https://cdn.jsdelivr.net/gh/FishOrBear/CDNResources/Default.jpg`; - texture.Name = app.m_Database.TextureTable.AllocateName(); - await texture.Update(); - app.m_Database.TextureTable.Add(texture); - let material = new PhysicalMaterialRecord(); - material.map = texture.Id; - material.Update(); - app.m_Database.MaterialTable.Add(material); - - - let br = new Board(); - br.InitBoard(600, 1200, 18); - - br.Material = material.Id; - - app.m_Database.ModelSpace.Append(br); } } diff --git a/src/Common/ArrayExt.ts b/src/Common/ArrayExt.ts index 98b6c4435..038aa13a1 100644 --- a/src/Common/ArrayExt.ts +++ b/src/Common/ArrayExt.ts @@ -157,3 +157,8 @@ export function equalArray(a: T[], b: T[], checkF = checkEqual) if (!checkF(a[i], b[i])) return false; return true; } + +export function arrayClone(arr: T[]): T[] +{ + return arr.slice(); +} diff --git a/src/Common/ColorPalette.ts b/src/Common/ColorPalette.ts index 6846c417d..326089ec5 100644 --- a/src/Common/ColorPalette.ts +++ b/src/Common/ColorPalette.ts @@ -1,4 +1,4 @@ -import { Color, DoubleSide, LineBasicMaterial, LineDashedMaterial, MeshBasicMaterial } from 'three'; +import { Color, DoubleSide, LineBasicMaterial, LineDashedMaterial, MeshBasicMaterial, Mesh } from 'three'; const ColorPalette = [ [255, 0, 0, 255], //----- 0 - lets make it red for an example @@ -290,6 +290,11 @@ export class ColorMaterial return mat; } + static SolidJigMaterial() + { + return new MeshBasicMaterial({ transparent: true, opacity: 0.1 }); + } + static GetColor(index: number) { let rgb = ColorPalette[index]; diff --git a/src/DatabaseServices/BlockTableRecord.ts b/src/DatabaseServices/BlockTableRecord.ts index 11104c222..19ede7585 100644 --- a/src/DatabaseServices/BlockTableRecord.ts +++ b/src/DatabaseServices/BlockTableRecord.ts @@ -31,6 +31,7 @@ export class BlockTableRecord extends SymbolTableRecord Append(entity: Entity, isCheckObjectCleanly = true) { this.EntityCol.Append(entity, isCheckObjectCleanly); + entity.Owner = this.objectId; } AppendEvent(entity: Entity) diff --git a/src/DatabaseServices/Board.ts b/src/DatabaseServices/Board.ts index 7589a5a36..80c621ff4 100644 --- a/src/DatabaseServices/Board.ts +++ b/src/DatabaseServices/Board.ts @@ -1,24 +1,16 @@ -import * as THREE from 'three'; -import { ExtrudeGeometry, Matrix3, Matrix4, Mesh, Object3D, Vector2, Vector3, MeshPhysicalMaterial } from 'three'; -import { arrayRemoveIf } from '../Common/ArrayExt'; +import { Matrix4, Mesh, Object3D, Vector3 } from 'three'; import { UpdateDraw } from '../Common/Status'; -import { ObjectSnapMode } from '../Editor/ObjectSnapMode'; import { Box3Ext } from '../Geometry/Box'; -import { cZeroVec, equaln, equalv3, isParallelTo, MoveMatrix, rotatePoint } from '../Geometry/GeUtils'; -import ThreeBSP from '../Geometry/ThreeCSG'; +import { equaln, MoveMatrix } from '../Geometry/GeUtils'; import { RenderType } from '../GraphicsSystem/RenderType'; -import { BoardProcessOption, ComposingType, DrillType, LinesType, FaceDirection } from '../UI/Store/BoardInterface'; +import { BoardProcessOption, ComposingType, DrillType, FaceDirection, LinesType } from '../UI/Store/BoardInterface'; import { Factory } from './CADFactory'; import { CADFiler } from './CADFiler'; import { Circle } from './Circle'; import { Contour } from './Contour'; -import { Curve } from './Curve'; -import { DefaultBoardMaterial } from './DefaultBoardMaterial'; -import { Entity } from './Entity'; -import { Line } from './Line'; -import { PhysicalMaterialRecord } from './PhysicalMaterialRecord'; +import { ExtureSolid } from './Extrude'; import { ObjectId } from './ObjectId'; -import { Polyline } from './Polyline'; +import { PhysicalMaterialRecord } from './PhysicalMaterialRecord'; import { Shape } from './Shape'; export enum BoardType @@ -47,7 +39,7 @@ export interface IModeling shape: Shape; thickness: number; dir: FaceDirection; - rad: number; + knifeRadius: number; addLen: number; } @@ -58,56 +50,28 @@ export interface IModeling * @extends {Entity} */ @Factory -export class Board extends Entity +export class Board extends ExtureSolid { - //板件厚度 - private m_Thickness: number; - private m_Length: number; - private m_Width: number; private m_Rotation = { x: 0, y: 0, z: 0 } - private m_Shape: Shape; - private m_BoardType: BoardType; private m_Name = ""; private m_SpecOCS: Matrix4 = new Matrix4(); //板件的标系 private m_BoardProcessOption: BoardProcessOption = {}; - private m_BoardModeling: IModeling[] = []; //板件排钻表,与之碰撞板件为key private m_DrillList: Map = new Map(); constructor(shape?: Shape, thickness?: number) { super(); - this.m_Shape = shape || new Shape(); - this.m_Thickness = thickness || 0; + this.InitBoardData(); } - //初始化板件 来自长宽高 - InitBoard(length: number, width: number, thickness: number, boardType: BoardType = BoardType.Layer) + private InitBoardData() { - this.m_BoardType = boardType; - this.m_Length = length; - this.m_Width = width; - this.m_Thickness = thickness; - - let pl = new Polyline([ - { pt: new Vector2(), bul: 0 }, - { pt: new Vector2(width, 0), bul: 0 }, - { pt: new Vector2(width, length), bul: 0 }, - { pt: new Vector2(0, length), bul: 0 }, - ]); - pl.CloseMark = true; - this.m_Shape = new Shape(Contour.CreateContour([pl])); - this.Update(UpdateDraw.Geometry); - } - static CreateBoard(length: number, width: number, thickness: number, boardType: BoardType = BoardType.Layer) - { - let board = new Board(); - board.InitBoard(length, width, thickness, boardType); - board.m_BoardProcessOption = { + this.m_BoardProcessOption = { roomName: "", cabinetName: "", boardName: "", @@ -129,7 +93,20 @@ export class Board extends Entity spliteHeight: "", spliteWidth: "", spliteThickness: "" - } + }; + } + + //初始化板件 来自长宽高 + InitBoard(length: number, width: number, thickness: number, boardType: BoardType = BoardType.Layer) + { + this.m_BoardType = boardType; + this.ConverToRectSolid(width, length, thickness); + this.Update(UpdateDraw.Geometry); + } + static CreateBoard(length: number, width: number, thickness: number, boardType: BoardType = BoardType.Layer) + { + let board = new Board(); + board.InitBoard(length, width, thickness, boardType); board.ApplyMatrix(board.RotateMat); board.m_SpecOCS.identity(); // board.ColorIndex = boardType + 1; @@ -151,18 +128,66 @@ export class Board extends Entity } get BoardModeling() { - return this.m_BoardModeling.slice(); + let models: IModeling[] = []; + for (let g of this.grooves) + { + let cu = g.ContourCurve.Clone().ApplyMatrix(this.OCSInv.multiply(g.OCS)); + + let outline = Contour.CreateContour(cu, false); + let holes: Contour[] = []; + for (let subG of g.Grooves) + { + let holeCu = subG.ContourCurve.Clone().ApplyMatrix(this.OCSInv.multiply(subG.OCS)); + holes.push(Contour.CreateContour(holeCu, false)); + } + + let s = new Shape(outline, holes); + + models.push({ + shape: s, + thickness: g.Thickness, + dir: equaln(g.Position.applyMatrix4(this.OCSInv).z, 0) ? FaceDirection.Back : FaceDirection.Front, + knifeRadius: g.KnifeRadius, + addLen: g.GroovesAddLength + }); + } + return models; } - set BoardModeling(items: IModeling[]) + set BoardModeling(models: IModeling[]) { this.WriteAllObjectRecord(); - this.m_BoardModeling = items; - this.Update(UpdateDraw.Geometry); + this.grooves.length = 0; + + for (let model of models) + { + let g = new ExtureSolid(); + g.OCS = this.OCS; + g.ContourCurve = model.shape.Outline.Curve; + g.Thickness = model.thickness; + g.GroovesAddLength = model.addLen; + g.KnifeRadius = model.knifeRadius; + + for (let hole of model.shape.Holes) + { + let subG = new ExtureSolid(); + subG.OCS = this.OCS; + subG.ContourCurve = hole.Curve; + subG.Thickness = model.thickness; + + g.AppendGroove(subG); + } + + if (model.dir === FaceDirection.Front) + g.ApplyMatrix(MoveMatrix(new Vector3(0, 0, this.thickness - g.Thickness))); + + this.grooves.push(g); + } + this.Update(); } ClearBoardModeling() { this.WriteAllObjectRecord(); - this.m_BoardModeling.length = 0; + this.grooves.length = 0; this.Update(UpdateDraw.Geometry); } AppendDrillList(k: ObjectId, drs: ObjectId[][]) @@ -244,61 +269,61 @@ export class Board extends Entity } get Thickness() { - return this.m_Thickness; + return this.thickness; } set Thickness(v: number) { - if (!equaln(v, this.m_Thickness, 1e-2)) + if (!equaln(v, this.thickness, 1e-2)) { - this.m_Thickness = v; + this.WriteAllObjectRecord(); + this.thickness = v; this.Update(); } } - get Length() + get Height() { - return this.m_Length + return this.height; } - set Length(v: number) + set Height(v: number) { - this.WriteAllObjectRecord(); - - if (this.m_Shape.Outline.Curve instanceof Circle) + if (this.ContourCurve instanceof Circle) return; - if (!equaln(v, this.m_Length, 1e-2)) + if (!equaln(v, this.height, 1e-2)) { - let refHeight = this.m_Length / 2; - let dist = v - this.m_Length; + this.WriteAllObjectRecord(); + let refHeight = this.height / 2; + let dist = v - this.height; - let isSuccess = this.m_Shape.Outline.UnEqualProportionScale(refHeight, dist, "y"); + let contour = Contour.CreateContour([this.contourCurve], false); + let isSuccess = contour.UnEqualProportionScale(refHeight, dist, "y"); if (isSuccess) { - this.m_Length = v; + this.height = v; this.Update(); } } } get Width() { - return this.m_Width; + return this.width; } set Width(v: number) { - this.WriteAllObjectRecord(); - - if (this.m_Shape.Outline.Curve instanceof Circle) + if (this.ContourCurve instanceof Circle) return; - if (!equaln(v, this.m_Width, 1e-2)) + if (!equaln(v, this.width, 1e-2)) { - let refDist = this.m_Width / 2; - let dist = v - this.m_Width; - let isSuccess = this.m_Shape.Outline.UnEqualProportionScale(refDist, dist, "x"); - + this.WriteAllObjectRecord(); + let refDist = this.width / 2; + let dist = v - this.width; + let contour = Contour.CreateContour([this.contourCurve], false); + let isSuccess = contour.UnEqualProportionScale(refDist, dist, "x"); if (isSuccess) { - this.m_Width = v; + this.width = v; this.Update(); } } @@ -328,25 +353,18 @@ export class Board extends Entity //最左下角的点 get MinPoint(): Vector3 { - let pt; switch (this.m_BoardType) { case BoardType.Layer: - pt = new Vector3(0, this.m_Length, -this.m_Thickness); - break; + return new Vector3(0, this.height).applyMatrix4(this.OCS); case BoardType.Vertical: - pt = new Vector3(0, 0, -this.m_Thickness); - break; case BoardType.Behind: - pt = new Vector3(0, 0, 0); + return this.Position; } - - pt.applyMatrix4(this.OCS) - return pt; } get MaxPoint(): Vector3 { - let pt = new Vector3(this.m_Width, this.m_Length, -this.m_Thickness); + let pt = new Vector3(this.width, this.height, -this.thickness); pt.applyMatrix4(this.OCS); return pt; } @@ -365,27 +383,31 @@ export class Board extends Entity } get BoundingBox() { - let box = new Box3Ext(new Vector3(0, 0, -this.m_Thickness), new Vector3(this.m_Width, this.m_Length)); + let box = new Box3Ext(new Vector3(0, 0, -this.thickness), new Vector3(this.width, this.height)); box.applyMatrix4(this.OCS); return box; } - get Shape() + // get Shape() + // { + // return this.ContourCurve; + // } + // set Shape(s: Shape) + // { + // this.WriteAllObjectRecord(); + // // this.m_Shape = s; + // this.UpdateBoardSize(); + // this.Update(); + // } + get IsSpecialShape() { - return this.m_Shape; + return !this.isRect; } - set Shape(s: Shape) - { - this.WriteAllObjectRecord(); - this.m_Shape = s; - this.UpdateBoardSize(); - this.Update(); - } - get IsSpecialShape() + + get HasGroove() { - let refArea = this.m_Length * this.m_Width; - let cuArea = this.m_Shape.Outline.Area; - return !equaln(refArea, cuArea, 1); + return this.grooves.length > 0; } + get Name() { return this.m_Name; @@ -397,40 +419,14 @@ export class Board extends Entity } GetBoardBoxInMat(mat) { - let min = new Vector3(0, 0, -this.m_Thickness).applyMatrix4(this.OCS).applyMatrix4(mat); - let max = new Vector3(this.m_Width, this.m_Length).applyMatrix4(this.OCS).applyMatrix4(mat); + let min = new Vector3(0, 0, 0).applyMatrix4(this.OCS).applyMatrix4(mat); + let max = new Vector3(this.width, this.height, this.thickness).applyMatrix4(this.OCS).applyMatrix4(mat); return new Box3Ext().setFromPoints([min, max]); } Explode() { - return this.m_Shape.Explode().map(cu => cu.ApplyMatrix(this.OCS)); - } - Join(target: this): boolean - { - if (equaln(this.m_Thickness, target.m_Thickness) - && isParallelTo(this.Normal, target.Normal) - && this.IsCoplaneTo(target)) - { - let cloneTar = target.Clone(); - let mat = this.OCSInv.multiply(target.OCS) - cloneTar.m_Shape.ApplyMatrix(mat); - - let shapes = this.m_Shape.UnionBoolOperation(cloneTar.m_Shape); - if (shapes.length === 1) - { - this.WriteAllObjectRecord(); - cloneTar.m_BoardModeling.forEach(m => - { - m.shape.ApplyMatrix(mat); - }); - - this.m_BoardModeling.push(...cloneTar.m_BoardModeling); - this.Shape = shapes[0]; - this.UpdateOutlineShape(); - return true; - } - } - return false; + return []; + // return this.m_Shape.Explode().map(cu => cu.ApplyMatrix(this.OCS)); } RotateBoard(rox: number, roy: number, roz: number) { @@ -466,10 +462,10 @@ export class Board extends Entity protected ApplyScaleMatrix(m: Matrix4): this { this.WriteAllObjectRecord(); - let cu = this.m_Shape.Outline.Curve; - cu.ApplyMatrix(this.OCS); - cu.ApplyMatrix(m); - cu.ApplyMatrix(this.OCSInv); + // let cu = this.m_Shape.Outline.Curve; + // cu.ApplyMatrix(this.OCS); + // cu.ApplyMatrix(m); + // cu.ApplyMatrix(this.OCSInv); this.Update(UpdateDraw.Geometry); return this; @@ -478,378 +474,6 @@ export class Board extends Entity { return this; } - GetObjectSnapPoints( - snapMode: ObjectSnapMode, - pickPoint: Vector3, - lastPoint: Vector3, - viewXform?: Matrix3 - ): Vector3[] - { - switch (snapMode) - { - case ObjectSnapMode.End: - return this.GetStretchPoints(); - case ObjectSnapMode.Mid: - case ObjectSnapMode.Cen: - case ObjectSnapMode.Nea: - case ObjectSnapMode.Ext: - case ObjectSnapMode.Per: - case ObjectSnapMode.Tan: - { - let cu = this.m_Shape.Outline.Curve.Clone().ApplyMatrix(this.OCS); - let zVec = new Vector3(0, 0, -this.m_Thickness).applyMatrix4(this.OCS.setPosition(cZeroVec)); - - let cu1 = cu.Clone().ApplyMatrix(MoveMatrix(zVec)); - let cuOrShapes: (Curve | Shape)[] = [cu, cu1]; - let cuPts = cu.GetStretchPoints(); - for (let p of cuPts) - cuOrShapes.push(new Line(p, p.clone().add(zVec))); - - //添加造型捕捉 - for (let m of this.m_BoardModeling) - { - let s1 = m.shape.Clone(); - if (m.dir == FaceDirection.Back) - s1.ApplyMatrix(MoveMatrix(new Vector3(0, 0, -this.m_Thickness + m.thickness))); - - let s2 = s1.Clone().ApplyMatrix(MoveMatrix(new Vector3(0, 0, -m.thickness))); - cuOrShapes.push(s1.ApplyMatrix(this.OCS), s2.ApplyMatrix(this.OCS)); - } - - let pts: Vector3[] = []; - for (let en of cuOrShapes) - pts.push(...en.GetObjectSnapPoints(snapMode, pickPoint, lastPoint, viewXform)); - return pts; - } - default: - break; - } - return []; - } - private GetGripOrStrechPts(isGrip: boolean) - { - let pts = isGrip ? this.m_Shape.GetGripPoints() : this.m_Shape.GetStretchPoints(); - let revPts: Vector3[] = []; - let vec = new Vector3(0, 0, -this.m_Thickness); - revPts.push(...pts.map(p => p.clone().add(vec))); - for (let m of this.m_BoardModeling) - { - let tmpPts = isGrip ? m.shape.GetGripPoints() : m.shape.GetStretchPoints(); - if (m.dir === FaceDirection.Back) - { - tmpPts = tmpPts.map(p => p.add(new Vector3(0, 0, -this.m_Thickness + m.thickness))); - } - pts.push(...tmpPts); - let v = new Vector3(0, 0, -m.thickness); - revPts.push(...tmpPts.map(p => p.clone().add(v))); - } - - pts = pts.concat(revPts); - - return pts.map(p => p.applyMatrix4(this.OCS)); - } - GetGripPoints() - { - return this.GetGripOrStrechPts(true); - } - MoveGripPoints(indexList: Array, vec: Vector3) - { - this.WriteAllObjectRecord(); - //修正移动向量 - let vl = vec.clone(); - vl.applyMatrix4(new Matrix4().extractRotation(this.OCSInv)).setZ(0); - //统一上下2层夹点 - let len = this.GetGripPoints().length; - let i = Math.min(...indexList); - if (i > len / 2 - 1) - { - i -= len / 2; - } - indexList = [i]; - - let cur = this.m_Shape.Outline.Curve; - let outlineIndex = cur.GetGripPoints().length; - - let gripShape: Shape = this.m_Shape; - - if (indexList[0] >= outlineIndex) - { - for (let m of this.m_BoardModeling) - { - let len = m.shape.GetGripPoints().length; - if (indexList[0] < outlineIndex + len) - { - indexList = [indexList[0] - outlineIndex] - gripShape = m.shape; - break; - } - outlineIndex += len; - } - } - else if (indexList[0] & 1) - { - let derv = cur.GetFistDeriv(indexList[0] / 2).normalize(); - rotatePoint(derv, Math.PI / 2); - - derv.multiplyScalar(derv.dot(vl)); - vl.copy(derv); - } - - gripShape.MoveGripPoints(indexList, vl); - this.UpdateBoardShape(); - this.UpdateBoardSize(); - this.Update(UpdateDraw.Geometry); - } - GetStretchPoints() - { - return this.GetGripOrStrechPts(false); - } - MoveStretchPoints(indexList: Array, vec: Vector3) - { - this.WriteAllObjectRecord(); - let vl = vec.clone() - .applyMatrix4(new Matrix4().extractRotation(this.OCSInv)); - - indexList.sort((a, b) => a - b); - - let totalCount = this.GetStretchPoints().length; - - //当前遍历形状之前索引数 - let outlen = 0; - //用于判断是否拉伸了板件厚度 - let oldThickness = this.m_Thickness; - - //遍历板件所有形状,包括造型形状,分配对应拉伸点索引 - for (let i = 0, ss = [this.m_Shape, ...this.m_BoardModeling.map(m => m.shape)]; i < ss.length; i++) - { - // 形状拉伸点数量 - let count = ss[i].GetStretchPoints().length; - //参考索引数 - let refIndex = outlen + count; - //属于当前形状的索引数组 - let curIndexs = []; - for (let i of indexList) - { - //用于比较的索引,下层索引需修正 - let compareIndex = i; - //下层索引需+fuzz - let fuzz = 0; - if (i > totalCount / 2 - 1) - { - fuzz = count; - compareIndex = i - totalCount / 2; - } - if (compareIndex < refIndex && compareIndex >= outlen) - curIndexs.push(compareIndex - outlen + fuzz); - } - - let minIndex = Math.min(...curIndexs); - let maxIndex = Math.max(...curIndexs); - - //是否全选了一层索引,是就改变厚度 - if (curIndexs.length === count - && ((minIndex === 0 && maxIndex === count - 1) - || (minIndex === count && maxIndex === 2 * count - 1))) - { - let dir = minIndex === 0 ? -1 : 1; - //修改板件厚度 - if (i === 0) - { - //如果是上层,则需要将板件移动修正板件位置 - if (minIndex === 0) - { - let v = vl.clone().setX(0).setY(0) - .applyMatrix4(new Matrix4().extractRotation(this.OCS)); - this.ApplyMatrix(MoveMatrix(v)); - } - this.m_Thickness -= vl.z * dir; - } - else - this.m_BoardModeling[i - 1].thickness -= vl.z * dir; - } - else if (curIndexs.length === count * 2) - { - //仅改变造型的位置 - if (oldThickness === this.m_Thickness) - ss[i].ApplyMatrix(MoveMatrix(vl)); - } - else //拉伸对应的形状 - { - //统一上下层拖拽点 - curIndexs = curIndexs.map(i => - { - if (i > count - 1) - { - return i - count; - } - return i; - }) - curIndexs = [...new Set(curIndexs)]; - ss[i].MoveStretchPoints(curIndexs, vl.clone().setZ(0)); - } - - outlen += count; - } - this.UpdateBoardShape(); - this.UpdateBoardSize(); - this.Update(UpdateDraw.Geometry); - } - private UpdateBoardSize() - { - let size = this.Shape.BoundingBox.getSize(new Vector3()); - this.m_Length = size.y; - this.m_Width = size.x; - } - /** - * 更新造型形状和外轮廓形状,用布尔运算 - */ - UpdateBoardShape() - { - let deleteModel: Set = new Set(); - for (let m of this.m_BoardModeling) - { - let shapeZ = m.shape.Outline.Curve.Position.z; - if (this.m_Thickness * m.thickness < 0) - deleteModel.add(m); - else if (m.dir === FaceDirection.Front) - { - if (shapeZ < 0 || shapeZ > m.thickness) - deleteModel.add(m); - } - else - { - if (shapeZ < - m.thickness || shapeZ > 0) - deleteModel.add(m); - } - if (!deleteModel.has(m) && m.thickness >= this.m_Thickness) - { - //TODO:有可能变成多块板,暂不处理这种情况 - //改变异型轮廓 - let specialShape = this.m_Shape.SubstactBoolOperation(m.shape)[0]; - if (specialShape) - { - if (specialShape.Holes.length > 0) - specialShape.Holes.length = 0; - else - deleteModel.add(m); - - this.Shape = specialShape; - } - } - - if (!deleteModel.has(m)) - { - //改变造型轮廓 - let modelShape = m.shape.IntersectionBoolOperation(this.m_Shape)[0]; - if (modelShape) - m.shape = modelShape; - } - - } - - arrayRemoveIf(this.m_BoardModeling, m => deleteModel.has(m)); - - this.UpdateOutlineShape(); - } - private UpdateOutlineShape() - { - //源形状min应在0点 - let min = this.m_Shape.BoundingBox.min; - if (!equalv3(min, new Vector3())) - { - let matVec = MoveMatrix(min.clone().negate()); - this.m_Shape.ApplyMatrix(matVec); - for (let m of this.BoardModeling) - m.shape.ApplyMatrix(matVec); - - this.ApplyMatrix( - MoveMatrix(min.applyMatrix4(new Matrix4().extractRotation(this.OCS)))); - this.Update(UpdateDraw.Geometry); - } - } - InitDrawObject(renderType: RenderType = RenderType.Wireframe): Object3D - { - let br = new THREE.Mesh(this.UpdateGeometry(), DefaultBoardMaterial.Material); - this.UpdateDrawObjectMaterial(renderType, br); - br.castShadow = true; - return br; - } - private UpdateGeometry() - { - if (!this.m_Shape) - { - //避免空的板件生成 - this.InitBoard(1e-5, 1e-5, 1e-5); - } - let extrudeSettings = { - steps: 1, - bevelEnabled: false, - depth: this.m_Thickness - }; - let geo = new ExtrudeGeometry(this.m_Shape.Shape, extrudeSettings); - geo.translate(0, 0, -this.m_Thickness); - geo.applyMatrix(this.m_Shape.Outline.Curve.OCS); - - this.Modeling(geo); - - return geo; - } - private Modeling(geo: ExtrudeGeometry) - { - let outlineCons: ExtrudeGeometry[] = []; - let holes: ExtrudeGeometry[] = []; - //形状孔洞分开计算,轮廓用来减,洞用来加 - for (let model of this.m_BoardModeling) - { - let outlineGeo = new ExtrudeGeometry(model.shape.Outline.Shape, { - steps: 1, - bevelEnabled: false, - depth: model.thickness - }); - outlineGeo.translate(0, 0, model.dir === FaceDirection.Back ? -this.m_Thickness : - model.thickness); - outlineGeo.applyMatrix(model.shape.Outline.Curve.OCS); - outlineCons.push(outlineGeo); - - holes.push(...model.shape.Holes.map(h => - { - let geo = new ExtrudeGeometry(h.Shape, { - steps: 1, - bevelEnabled: false, - depth: model.thickness - }); - geo.translate(0, 0, model.dir === FaceDirection.Back ? -this.m_Thickness : - model.thickness); - geo.applyMatrix(h.Curve.OCS); - return geo; - })) - - } - - let bsg = new ThreeBSP(geo); - - for (let outgeo of outlineCons) - { - let bsg2 = new ThreeBSP(outgeo); - bsg = bsg.subtract(bsg2); - } - for (let hgeo of holes) - { - let bsg2 = new ThreeBSP(hgeo); - bsg = bsg.union(bsg2); - } - geo.copy(bsg.toGeometry() as ExtrudeGeometry); - } - UpdateDrawObject(type: RenderType, obj: Object3D) - { - let mesh = obj as Mesh; - mesh.geometry.dispose(); - mesh.geometry = this.UpdateGeometry(); - - if (this.materialId) - { - let material = this.materialId.Object as PhysicalMaterialRecord; - mesh.material = material.Material; - } - } /** * 当实体需要被更新时,更新实体材质 @@ -873,11 +497,6 @@ export class Board extends Entity { super.ReadFile(file); let ver = file.Read(); - this.m_Shape = new Shape(); - this.m_Shape.ReadFile(file); - this.m_Length = file.Read(); - this.m_Width = file.Read(); - this.m_Thickness = file.Read(); this.m_SpecOCS.fromArray(file.Read()); this.m_BoardType = file.Read(); this.m_Name = file.Read(); @@ -903,32 +522,12 @@ export class Board extends Entity } this.m_DrillList.set(id, drIdList); } - //读取造型数据 - let modelCount = file.Read(); - this.m_BoardModeling.length = 0; - for (let i = 0; i < modelCount; i++) - { - let shape = new Shape(); - shape.ReadFile(file); - let thickness = file.Read(); - let dir = file.Read(); - let rad = file.Read(); - let addLen = file.Read(); - this.m_BoardModeling.push({ - shape, thickness, dir, rad, addLen - }) - } - this.Update(); } WriteFile(file: CADFiler) { super.WriteFile(file); file.Write(1); - this.m_Shape.WriteFile(file); - file.Write(this.m_Length); - file.Write(this.m_Width); - file.Write(this.m_Thickness); file.Write(this.m_SpecOCS.toArray()) file.Write(this.m_BoardType); file.Write(this.m_Name); @@ -950,17 +549,5 @@ export class Board extends Entity } } } - - //写入造型数据 - file.Write(this.m_BoardModeling.length); - for (let data of this.m_BoardModeling) - { - data.shape.WriteFile(file); - file.Write(data.thickness); - file.Write(data.dir); - file.Write(data.rad); - file.Write(data.addLen); - } - } } diff --git a/src/DatabaseServices/Contour.ts b/src/DatabaseServices/Contour.ts index bcd642153..7083a5f61 100644 --- a/src/DatabaseServices/Contour.ts +++ b/src/DatabaseServices/Contour.ts @@ -18,8 +18,19 @@ let cache = new WeakMap(); export class Contour { private m_Curve: Polyline | Circle; - static CreateContour(cus: Curve[], needLink = true) + static CreateContour(cus: Curve[] | Polyline | Circle, needLink = true) { + if (cus instanceof Curve) + { + if (cus.IsClose) + { + let c = new Contour(); + c.m_Curve = cus; + return c; + } + return; + } + let closeCurve = Contour.Combine(cus, needLink) as Polyline | Circle; if (closeCurve && closeCurve.IsClose) { @@ -47,7 +58,7 @@ export class Contour return this.m_Curve.BoundingBox; } /** - *不等比例缩放 + * 不等比例缩放 * @param {number} ref 缩放参考值,大于该值的点缩放 * @param {number} dist 缩放距离 * @param {string} dir x y z diff --git a/src/DatabaseServices/Entity.ts b/src/DatabaseServices/Entity.ts index 4772c45fd..49c68ded3 100644 --- a/src/DatabaseServices/Entity.ts +++ b/src/DatabaseServices/Entity.ts @@ -1,16 +1,16 @@ -import { Box3, Geometry, Matrix4, Object3D, Vector3, Material, Matrix3 } from 'three'; +import { Box3, Geometry, Material, Matrix3, Matrix4, Object3D, Vector3 } from 'three'; +import { iaop } from 'xaop'; import { DisposeThreeObj } from '../Common/Dispose'; import { matrixIsCoplane } from '../Common/Matrix4Utils'; +import { UpdateDraw } from '../Common/Status'; +import { ObjectSnapMode } from '../Editor/ObjectSnapMode'; import { equaln, equalv3 } from '../Geometry/GeUtils'; -import { RenderType } from '../GraphicsSystem/RenderType'; import { IntersectOption } from '../GraphicsSystem/IntersectWith'; +import { RenderType } from '../GraphicsSystem/RenderType'; import { Factory } from './CADFactory'; import { CADFiler } from './CADFiler'; import { CADObject } from './CADObject'; import { ObjectId } from './ObjectId'; -import { ObjectSnapMode } from '../Editor/ObjectSnapMode'; -import { UpdateDraw } from '../Common/Status'; -import { iaop } from 'xaop'; /** * Entity 是所有图元的基类,绘制的实体都集成该类. @@ -30,6 +30,13 @@ export class Entity extends CADObject //自身坐标系 protected m_Matrix = new Matrix4(); + protected m_Owner: ObjectId;//BlockTableRecord + + set Owner(owner: ObjectId) + { + this.m_Owner = owner; + } + /** * 当AutoUpdate为false时,记录需要更新的标志. * 以便延迟更新时找到相应的更新标志. @@ -405,15 +412,20 @@ export class Entity extends CADObject this.m_Color = file.Read(); this.materialId = file.ReadObjectId(); this.m_Matrix.fromArray(file.Read()); + + if (ver > 1) + this.m_Owner = file.ReadObjectId(); } //对象将自身数据写入到文件. WriteFile(file: CADFiler) { - file.Write(1); + file.Write(2); super.WriteFile(file); file.Write(this.m_Color); file.WriteObjectId(this.materialId); file.Write(this.m_Matrix.toArray()); + + file.WriteObjectId(this.m_Owner); } //局部撤销 ApplyPartialUndo(undoData: CADObject) diff --git a/src/DatabaseServices/Extrude.ts b/src/DatabaseServices/Extrude.ts new file mode 100644 index 000000000..cf76df199 --- /dev/null +++ b/src/DatabaseServices/Extrude.ts @@ -0,0 +1,1001 @@ +import { Box3, ExtrudeGeometry, ExtrudeGeometryOptions, Geometry, Matrix3, Matrix4, Mesh, Object3D, Vector3 } from "three"; +import { arrayClone, arrayRemoveIf, arraySortByNumber } from "../Common/ArrayExt"; +import { Status, UpdateDraw } from "../Common/Status"; +import { ObjectSnapMode } from "../Editor/ObjectSnapMode"; +import { BSPGroupParse } from "../Geometry/BSPGroupParse"; +import { cZeroVec, equaln, equalv3, isParallelTo, MoveMatrix } from "../Geometry/GeUtils"; +import ThreeBSP from "../Geometry/ThreeCSG"; +import { RenderType } from "../GraphicsSystem/RenderType"; +import { BlockTableRecord } from "./BlockTableRecord"; +import { Factory } from "./CADFactory"; +import { CADFiler } from "./CADFiler"; +import { Circle } from "./Circle"; +import { Contour } from "./Contour"; +import { DefaultBoardMaterial } from "./DefaultBoardMaterial"; +import { Entity } from "./Entity"; +import { PhysicalMaterialRecord } from "./PhysicalMaterialRecord"; +import { Polyline } from "./Polyline"; +import { Region } from "./Region"; +import { Shape } from "./Shape"; +import { ShapeManager } from "./ShapeManager"; + +export type ExtureContourCurve = Polyline | Circle; +export type ExtureContour = Polyline | Circle | ExtureSolid | Region; + +enum DragPointType +{ + Grip = 0, + Stretch = 1, +} + +@Factory +export class ExtureSolid extends Entity +{ + /* + ------------ + | | + | | + | | height + | | + | | + ----width--- + */ + + protected height: number = 1;//y + protected width: number = 1;//x + + /** + * 拉伸实体的厚度 + * 我们允许它的一个负数,但是这个时候这个实体已经是一个无效的拉伸实体了. + * 允许负数,用来校验凹槽的合理性. + */ + protected thickness: number = 1; + + protected isRect = true; + + /** + * 拉伸形状 + * 出于优化考虑,可能未初始化 + * 形状位于WCS 0点位置,不随OCS变化而变化 + */ + protected contourCurve: ExtureContourCurve; + + /** + * 正面和反面的凹槽造型 + */ + protected grooves: ExtureSolid[] = []; + + protected knifeRadius: number; + protected groovesAddLength: number; + + constructor() + { + super(); + } + + get KnifeRadius() + { + return this.knifeRadius; + } + set KnifeRadius(v) + { + if (!equaln(v, this.knifeRadius)) + { + this.WriteAllObjectRecord(); + this.knifeRadius = v; + } + } + + get GroovesAddLength() + { + return this.groovesAddLength; + } + + set GroovesAddLength(v) + { + if (!equaln(v, this.groovesAddLength)) + { + this.WriteAllObjectRecord(); + this.groovesAddLength = v; + } + } + + Clone() + { + let en = super.Clone(); + en.strectchPointCountList = this.strectchPointCountList; + return en; + } + + ApplyMatrix(m: Matrix4) + { + super.ApplyMatrix(m); + for (let g of this.grooves) + g.ApplyMatrix(m); + + //由于修改矩阵会导致矩阵错误 + this.bsp = undefined; + return this; + } + + get Position(): Vector3 + { + return super.Position; + } + set Position(p: Vector3) + { + let v = p.clone().sub(this.Position); + super.Position = p; + + let m = MoveMatrix(v); + for (let g of this.grooves) + g.ApplyMatrix(m); + + //由于修改矩阵会导致bsp错误 + this.bsp = undefined; + } + + get Width() + { + return this.width; + } + get Height() + { + return this.height; + } + + get Thickness() + { + return this.thickness; + } + set Thickness(thickness: number) + { + this.thickness = thickness; + } + + get Grooves() + { + return this.grooves; + } + + /** + * 返回未拷贝的轮廓曲线 + */ + get ContourCurve() + { + if (!this.contourCurve) + this.GeneralRectContour(); + return this.contourCurve; + } + + set ContourCurve(cu: ExtureContourCurve) + { + this.SetContourCurve(cu); + } + + /** + * 生成矩形轮廓(强制) + */ + GeneralRectContour() + { + if (!this.contourCurve || !(this.contourCurve instanceof Polyline)) + this.contourCurve = new Polyline(); + + this.contourCurve.Create2Pt(new Vector3(), new Vector3(this.width, this.height)); + } + + /** + * 转换成矩形拉伸实体 + */ + ConverToRectSolid(width = this.width, height = this.height, thickness = this.thickness) + { + this.height = height; + this.width = width; + this.thickness = thickness; + + this.isRect = true; + + this.GeneralRectContour(); + + return this; + } + + /** + * 更新拉伸实体的轮廓 + * @param curve 曲线已经存在WCS坐标系 + */ + SetContourCurve(curve: ExtureContourCurve) + { + this.WriteAllObjectRecord(); + this.contourCurve = curve; + this.CheckContourCurve(); + this.Update(); + } + + /** + * 检验轮廓曲线,通常当轮廓曲线被修改时,都需要检验轮廓曲线,并更新实体大小和轮廓位置. + * >计算轮廓大小 + * >判断是否矩形 + * >修正轮廓基点 + */ + CheckContourCurve() + { + let box = this.contourCurve.BoundingBox; + let size = box.getSize(new Vector3()); + this.width = size.x; + this.height = size.y; + + this.isRect = equaln(this.width * this.height, this.ContourCurve.Area, 1); + + //修正轮廓基点 + if (!equalv3(box.min, cZeroVec)) + { + this.contourCurve.Position = + this.contourCurve.Position.sub(box.min); + + let v = box.min.applyMatrix4(this.OCS.setPosition(cZeroVec)); + this.m_Matrix.setPosition(this.Position.add(v)); + } + } + + /** + * 这个拉伸实体的面域形状 + */ + get Shape() + { + let contour = Contour.CreateContour(this.ContourCurve.Clone(), false); + + let holes: Contour[] = []; + + for (let g of this.grooves) + { + if (equaln(g.thickness, this.thickness)) + holes.push(Contour.CreateContour(g.ContourCurve.Clone().ApplyMatrix(this.OCSInv.multiply(g.OCS)), false)); + } + return new Shape(contour, holes); + } + + /** + * 实体合并(不会删除target) + */ + Join(target: this): Status + { + this.WriteAllObjectRecord(); + if (equaln(this.thickness, target.thickness) + && isParallelTo(this.Normal, target.Normal) + && this.IsCoplaneTo(target)) + { + let matrixToLocal = this.OCSInv.multiply(target.OCS); + let thisShape = this.Shape; + let targetShape = target.Shape.ApplyMatrix(matrixToLocal); + + let unionShapes = thisShape.UnionBoolOperation(targetShape); + if (unionShapes.length === 1) + { + for (let hole of unionShapes[0].Holes) + { + let g = new ExtureSolid(); + g.thickness = this.thickness; + g.ContourCurve = hole.Curve; + g.ApplyMatrix(this.OCS); + + this.AppendGroove(g); + } + + this.ContourCurve = unionShapes[0].Outline.Curve; + + this.grooves.push(...target.grooves.map(g => g.Clone())); + + this.GrooveCheckMerge(); + this.Update(); + + return Status.True; + } + } + return Status.False; + } + + AppendGroove(groove: ExtureSolid) + { + if (this.GrooveCheckPosition(groove) === Status.True) + { + this.grooves.push(groove); + } + } + + GetObjectSnapPoints( + snapMode: ObjectSnapMode, + pickPoint: Vector3, + lastPoint: Vector3, + viewXform?: Matrix3 + ): Vector3[] + { + switch (snapMode) + { + case ObjectSnapMode.End: + return this.GetStretchPoints(); + case ObjectSnapMode.Mid: + case ObjectSnapMode.Cen: + case ObjectSnapMode.Nea: + case ObjectSnapMode.Ext: + case ObjectSnapMode.Per: + case ObjectSnapMode.Tan: + { + let contour = this.ContourCurve.Clone(); + contour.ApplyMatrix(this.OCS); + let pts = contour.GetObjectSnapPoints(snapMode, pickPoint, lastPoint, viewXform); + + contour.Position = contour.Position.add(this.Normal.multiplyScalar(this.thickness)); + pts.push( + ...contour.GetObjectSnapPoints(snapMode, pickPoint, lastPoint, viewXform) + ); + + for (let g of this.grooves) + pts.push(...g.GetObjectSnapPoints(snapMode, pickPoint, lastPoint, viewXform)); + + return pts; + } + default: + break; + } + return []; + } + + //#region Stretch + + /** + * 用于缓存子对象的点拉伸点表个数,可能为空 + */ + private strectchPointCountList: number[]; + private GetStrectchPointCountList(dragType: DragPointType) + { + if (!this.strectchPointCountList) + this.GetGripOrStretchPoints(dragType); + + return this.strectchPointCountList; + } + GetGripOrStretchPoints(dragType: DragPointType) + { + let isGrip = dragType === DragPointType.Grip; + + let pts = isGrip ? this.ContourCurve.GetGripPoints() : this.ContourCurve.GetStretchPoints(); + let v = new Vector3(0, 0, this.thickness); + pts.push(...pts.map(p => p.clone().add(v))); + pts.forEach(p => { p.applyMatrix4(this.OCS) }); + + this.strectchPointCountList = [pts.length]; + + for (let g of this.grooves) + { + let gpts = g.GetGripOrStretchPoints(dragType); + this.strectchPointCountList.push(gpts.length); + pts.push(...gpts); + } + return pts; + } + MoveGripOrStretchPoints(indexList: number[], vec: Vector3, dragType: DragPointType) + { + this.WriteAllObjectRecord(); + + arraySortByNumber(indexList); + + if (this.grooves.length === 0) + { + this.MoveGripOrStretchPointsOnly(indexList, vec, dragType); + } + else + { + let i = 0; + let icount = indexList.length; + let offset = 0; + + let grooveIndex = -1; + for (let count of this.GetStrectchPointCountList(dragType)) + { + offset += count; + let ilist = []; + for (; i < icount; i++) + { + if (indexList[i] < offset) + ilist.push(indexList[i] - offset + count); + else + break; + } + + if (ilist.length > 0) + { + if (grooveIndex === -1) + this.MoveGripOrStretchPointsOnly(ilist, vec, dragType); + else + this.grooves[grooveIndex].MoveGripOrStretchPoints(ilist, vec, dragType); + } + grooveIndex++; + } + } + + this.CheckContourCurve(); + if (this.objectId) + { + let splitEntitys: this[] = []; + this.GrooveCheckAll(splitEntitys); + + let ms = this.m_Owner.Object as BlockTableRecord; + for (let e of splitEntitys) + { + ms.Append(e); + } + } + this.Update(); + } + + GetGripPoints(): Array + { + return this.GetGripOrStretchPoints(DragPointType.Grip); + } + + MoveGripPoints(indexList: number[], vec: Vector3) + { + this.MoveGripOrStretchPoints(indexList, vec, DragPointType.Grip) + } + + + GetStretchPoints() + { + return this.GetGripOrStretchPoints(DragPointType.Stretch); + } + MoveStretchPoints(indexList: Array, vec: Vector3) + { + this.MoveGripOrStretchPoints(indexList, vec, DragPointType.Stretch); + } + + /** + * 只对自身的轮廓和厚度进行拉伸,忽略子实体 + */ + MoveGripOrStretchPointsOnly(indexList: Array, vec: Vector3, dragType: DragPointType) + { + let stretchCount = + this.strectchPointCountList + ? this.strectchPointCountList[0] / 2 + : ( + dragType === DragPointType.Grip + ? this.ContourCurve.GetGripPoints() + : this.ContourCurve.GetStretchPoints() + ).length; + + if (dragType === DragPointType.Stretch) + { + //Move + if (indexList.length === stretchCount * 2) + { + this.Position = this.Position.add(vec); + return; + } + + //判断是否拉伸厚度 + if (indexList.length === stretchCount) + { + let isFront = indexList[0] < stretchCount; + + if (indexList.every(v => v < stretchCount === isFront)) + { + //Change thickness + let lvec = vec.clone().applyMatrix4(this.OCSInv.setPosition(cZeroVec)); + if (isFront) + { + // if (lvec.z >= this.thickness) return; + this.thickness -= lvec.z; + this.Position = this.Position.add(this.Normal.multiplyScalar(lvec.z)); + } + else + { + // if (-lvec.z > this.thickness) return; + this.thickness += lvec.z; + } + this.Update(); + return; + } + } + + indexList = arrayClone(indexList); + } + + //修正点的索引 + for (let i = 0; i < indexList.length; i++) + { + let index = indexList[i]; + if (index >= stretchCount) + { + index -= stretchCount; + indexList[i] = index; + } + } + + indexList = [...new Set(indexList)]; + + let localVec = vec.clone().applyMatrix4(this.OCSInv.setPosition(cZeroVec)); + + dragType === DragPointType.Grip ? + this.ContourCurve.MoveGripPoints(indexList, localVec) : + this.ContourCurve.MoveStretchPoints(indexList, localVec); + } + + //#endregion + + //#region groove(凹槽(造型))操作 + + /* + + 添加凹槽一般会经过以下几个步骤 + + 1.凹槽转换成和本实体法线平行的凹槽实体 + ->调用第二步 + + 2.校验凹槽的Z轴位置是否存在交集 + ->{不存在Z轴交集} 或 {交集异常(凹槽被本实体包含不见光)} 的凹槽被移除 + ->凹槽的Z轴位置和厚度被更新 + + 3.凹槽合并 + + 4.修正轮廓. + ->{本实体}轮廓被修正(当实体被凹槽破坏形状时) + -->修正成功后,凹槽被移除 + -->本实体可能分裂 + + ->{凹槽}轮廓被修正({凹槽的轮廓}被约束在{实体轮廓}内部) + -->凹槽可能分裂 + + */ + + + /** + * 当调用Draw时,可以生成bsp信息 + */ + private bsp: ThreeBSP; + private get BSP() + { + if (this.bsp) + return this.bsp; + + this.Draw(); + if (!this.bsp) + this.Update(UpdateDraw.Geometry); + return this.bsp; + } + + /** + * (步骤1.2.) + * 将目标拉伸实体转换成在板件内部可用的凹槽实体 + * @param target 该对象可能被修改(内部不拷贝该实体) + * @param useClone 转换后的实体是目标实体拷贝后修改的 + */ + ConverToLocalGroove(target: this, useClone = false): ExtureSolid[] + { + if (isParallelTo(this.Normal, target.Normal)) + { + if (this.GrooveCheckPosition(target) !== Status.True) + return; + + return this.GrooveCheckContour(target); + } + else + { + let yv = target.Normal; + let zv = this.Normal; + let xv = yv.clone().cross(zv); + let m = new Matrix4().makeBasis(xv, yv, zv).copyPosition(this.OCS); + let mi = new Matrix4().getInverse(m); + + let interBSP = this.BSP.intersect(target.BSP); + let topology = new BSPGroupParse(interBSP); + let grooves: ExtureSolid[] = []; + for (let pts of topology.Parse()) + { + for (let p of pts) + p.applyMatrix4(mi); + let box = new Box3().setFromPoints(pts); + let size = box.getSize(new Vector3()); + m.setPosition(box.min.applyMatrix4(m)); + + let ext = useClone ? target.Clone() : new ExtureSolid(); + if (!useClone) + ext.grooves.length = 0; + ext.ConverToRectSolid(size.x, size.y, size.z); + ext.OCS = m; + + grooves.push(ext); + } + + return grooves; + } + } + + /** + * (步骤2) + * 更新凹槽位置和厚度(校验凹槽的Z轴位置是否存在交集) + */ + GrooveCheckPosition(target: ExtureSolid): Status + { + if (target.thickness <= 1e-3) + return Status.False; + + let tp = target.Position.applyMatrix4(this.OCSInv); + + let minZ = tp.z; + let maxZ = tp.z + target.thickness; + if (minZ <= 1e-2)//背面 + { + target.Thickness = maxZ; + if (minZ < -1e-4) + target.ApplyMatrix( + MoveMatrix(this.Normal.multiplyScalar(-minZ)) + ); + } + else if (maxZ >= (this.thickness - 1e-3) && minZ > 0)//正面 + { + target.Thickness = this.thickness - minZ; + } + else return Status.False; + + return Status.True; + } + + /** + * (步骤3) + * 计算凹槽合并 + */ + GrooveCheckMerge() + { + let thicknessMap = new Map>(); + + for (let groove of this.grooves) + { + let thicknessStr = groove.thickness.toFixed(2); + if (!thicknessMap.has(thicknessStr)) + thicknessMap.set(thicknessStr, [groove]); + else + thicknessMap.get(thicknessStr).push(groove); + } + + let gs: ExtureSolid[] = []; + for (let [, grooves] of thicknessMap) + { + while (grooves.length > 0) + { + let g = grooves.pop(); + while (grooves.length > 0) + { + //剩余的 无法合并的板件 + let remGs = grooves.filter(gn => + { + return g.Join(gn) === Status.False; + }); + + if (remGs.length === grooves.length) + break; + + grooves = remGs; + } + + gs.push(g); + } + } + + this.grooves = gs; + + for (let g of this.grooves) + g.CheckContourCurve(); + + return thicknessMap; + } + + /** + * (步骤4.1) + * 计算凹槽轮廓(可能分裂) + * @param target 不拷贝修改 + * @returns this[] 凹槽在本实体中正确的约束状态.(可能分裂成为多个) + */ + GrooveCheckContour(target: ExtureSolid): ExtureSolid[] + { + if (equaln(target.thickness, this.thickness)) + return [target]; + + let matrixToTarget = target.OCSInv.multiply(this.OCS); + + let thisShape = this.Shape.ApplyMatrix(matrixToTarget); + let targetShape = new Shape(Contour.CreateContour([target.ContourCurve.Clone()], false)); + + let inters = thisShape.IntersectionBoolOperation(targetShape); + + if (inters.length === 1) + { + target.ContourCurve = inters[0].Outline.Curve; + let grooves = [target]; + target.GrooveCheckAll(grooves); + return grooves; + } + else + { + let grooves: ExtureSolid[] = []; + for (let contour of inters) + { + let ext = target.Clone(); + ext.ContourCurve = contour.Outline.Curve; + ext.GrooveCheckAll(grooves); + grooves.push(ext); + } + return grooves; + } + } + /** + * (步骤4.2) + * 计算本实体被全身度的凹槽差集后正确的实体轮廓,和有可能的分裂实体 + * @param splitEntitys 分裂出来的实体 + * @returns [Status] Status FIXME: 消失不见 + */ + ContourCheckSubtract(splitEntitys: this[]) + { + let shapeManager = new ShapeManager(); + shapeManager.AppendShapeList( + new Shape(Contour.CreateContour(this.ContourCurve.Clone(), false)) + ); + let subtractShape = new ShapeManager(); + + let grooves: ExtureSolid[] = []; + arrayRemoveIf(this.grooves, groove => + { + if (equaln(groove.thickness, this.thickness)) + { + let grooveCurve = groove.ContourCurve.Clone(); + let matrixToLocal = this.OCSInv.multiply(groove.OCS); + grooveCurve.ApplyMatrix(matrixToLocal); + + subtractShape.AppendShapeList( + new Shape(Contour.CreateContour([grooveCurve], false)) + ); + + grooves.push(groove); + return true; + } + return false; + }); + + shapeManager.SubstactBoolOperation(subtractShape); + let shapes = shapeManager.ShapeList; + + //不做任何改变 + if (shapeManager.ShapeCount === 1 && shapes[0].Holes.length === grooves.length) + { + this.grooves.push(...grooves); + return; + } + + //分裂 + for (let i = 1; i < shapeManager.ShapeCount; i++) + { + let ext = this.Clone(); + let shape = shapes[i]; + ext.ContourCurve = shape.Outline.Curve; + + for (let hole of shape.Holes) + { + let groove = new ExtureSolid(); + groove.ContourCurve = hole.Curve; + groove.thickness = this.thickness; + groove.OCS = this.OCS; + ext.grooves.push(groove); + } + + ext.GrooveCheckAll(splitEntitys); + ext.Update(); + splitEntitys.push(ext); + } + + if (shapes.length > 0) + { + let shape = shapes[0]; + this.ContourCurve = shape.Outline.Curve; + for (let hole of shape.Holes) + { + let groove = new ExtureSolid(); + groove.OCS = this.OCS; + groove.ContourCurve = hole.Curve; + groove.thickness = this.thickness; + this.grooves.push(groove); + } + + return true; + } + else + return false; + } + + + /** + * 无法知道修改了轮廓是否为更新到内部凹槽. + * 无法知道修改了内部凹槽之后是否会更新到轮廓. + * 所以默认全部校验内部的凹槽 + */ + GrooveCheckAll(splitEntitys: this[]) + { + //校验Z轴位置 + arrayRemoveIf(this.grooves, g => + { + return this.GrooveCheckPosition(g) === Status.False; + }); + + //清除全深洞的子槽 + for (let g of this.grooves) + { + if (equaln(g.thickness, this.thickness)) + { + /* + 此刻我们直接将它的子槽清空,虽然子槽可能将这个槽分裂成2个, + 但是这样的情况只能在造型应用中才会产生 + */ + g.grooves.length = 0; + } + } + + //合并 + let map = this.GrooveCheckMerge(); + //修改本实体轮廓 + if (map.has(this.thickness.toFixed(2))) + this.ContourCheckSubtract(splitEntitys); + + //修正凹槽轮廓 + let splitGrooves = []; + for (let g of this.grooves) + splitGrooves.push(...this.GrooveCheckContour(g)); + + this.grooves = splitGrooves; + + this.Update(); + } + + //#endregion + + //#region Draw + InitDrawObject(renderType: RenderType = RenderType.Wireframe) + { + let br = new Mesh(this.GeneralGeometry(), DefaultBoardMaterial.Material); + br.castShadow = true; + return br; + } + GeneralGeometry() + { + let extrudeSettings: ExtrudeGeometryOptions = { + steps: 1, + bevelEnabled: false, + depth: this.thickness + }; + let geo = new ExtrudeGeometry(this.ContourCurve.Shape, extrudeSettings); + geo.applyMatrix(this.contourCurve.OCS); + + let mesh = new Mesh(geo); + mesh.matrix = this.m_Matrix; + this.bsp = new ThreeBSP(mesh); + + this.ChangeUV(geo); + if (this.grooves.length === 0) + return geo; + + for (let g of this.grooves) + { + if (g.thickness > 0) + this.bsp = this.bsp.subtract(g.BSP); + } + + let bgeo = this.bsp.toGeometry(); + this.ChangeUV(bgeo); + return bgeo; + } + private ChangeUV(geo: Geometry) + { + for (let uvsg of geo.faceVertexUvs) + { + for (let uvs of uvsg) + { + for (let uv of uvs) + { + uv.multiplyScalar(0.001); + } + } + } + } + + UpdateDrawObject(type: RenderType, obj: Object3D) + { + let mesh = obj as Mesh; + mesh.geometry.dispose(); + mesh.geometry = this.GeneralGeometry(); + + if (this.materialId) + { + let material = this.materialId.Object as PhysicalMaterialRecord; + mesh.material = material.Material; + } + } + + UpdateJigMaterial(color = 8) + { + // for (let [type, obj] of this.m_DrawEntity) + // { + // let m = obj as Mesh; + // m.material = ColorMaterial.SolidJigMaterial(); + // } + } + //#endregion + + //#region -------------------------File------------------------- + + /** + * 简化的文件读取和写入,只写入必要的数据,没有id,没有其他版本号 + */ + ReadFileLite(file: CADFiler) + { + this.ReadFileOnly(file); + this.m_Matrix.fromArray(file.Read()); + } + WriteFileLite(file: CADFiler) + { + this.WriteFileOnly(file); + file.Write(this.m_Matrix.toArray()); + } + + private ReadFileOnly(file: CADFiler) + { + file.Read(); + this.height = file.Read(); + this.width = file.Read(); + this.thickness = file.Read(); + this.isRect = file.Read(); + this.contourCurve = file.ReadObject() as ExtureContourCurve; + + let grooveCount = file.Read(); + this.grooves.length = 0; + for (let i = 0; i < grooveCount; i++) + { + if (this.grooves[i] === undefined) + this.grooves[i] = new ExtureSolid(); + + this.grooves[i].ReadFileLite(file); + } + + this.knifeRadius = file.Read(); + this.groovesAddLength = file.Read(); + } + private WriteFileOnly(file: CADFiler) + { + file.Write(1); + file.Write(this.height); + file.Write(this.width); + file.Write(this.thickness); + file.Write(this.isRect); + file.WriteObject(this.ContourCurve); + + file.Write(this.grooves.length); + for (let groove of this.grooves) + groove.WriteFileLite(file); + + file.Write(this.knifeRadius); + file.Write(this.groovesAddLength); + } + + //对象从文件中读取数据,初始化自身 + ReadFile(file: CADFiler) + { + super.ReadFile(file); + this.ReadFileOnly(file); + + if (this.isRect) + this.GeneralRectContour(); + this.Update(); + } + //对象将自身数据写入到文件. + WriteFile(file: CADFiler) + { + super.WriteFile(file); + this.WriteFileOnly(file); + } + //#endregion +} diff --git a/src/DatabaseServices/Polyline.ts b/src/DatabaseServices/Polyline.ts index 16714098c..41d1c0fdd 100644 --- a/src/DatabaseServices/Polyline.ts +++ b/src/DatabaseServices/Polyline.ts @@ -241,8 +241,9 @@ export class Polyline extends Curve { pt: px1, bul: 0 }, { pt: px2, bul: 0 }, { pt: px3, bul: 0 }, - { pt: px4, bul: 0 }, - { pt: px1, bul: 0 }]; + { pt: px4, bul: 0 }]; + + this.CloseMark = true; return this; } //多段线起点 diff --git a/src/DatabaseServices/Region.ts b/src/DatabaseServices/Region.ts index 74b4c7069..a0b173637 100644 --- a/src/DatabaseServices/Region.ts +++ b/src/DatabaseServices/Region.ts @@ -58,13 +58,7 @@ export class Region extends Entity let shapeList = this.m_ShapeManager.ShapeList; if (shapeList.length <= 1) { - let cus = shapeList[0].Explode(); - cus.forEach(c => - { - if (!(c instanceof Circle) && !(c instanceof Arc)) - c.ApplyMatrix(c.OCSInv).ApplyMatrix(this.OCS) - }); - return cus; + return shapeList[0].Explode(); } else { @@ -186,12 +180,19 @@ export class Region extends Entity { let regionGroup = en as Group; DisposeThreeObj(en); - this.m_ShapeManager.ShapeList.forEach(shape => + let shapeList = this.m_ShapeManager.ShapeList; + + for (let i = 0; i < shapeList.length; i++) { + let shape = shapeList[i]; + + //多形状面域,需把geo移动到相对 let geometry = new ShapeBufferGeometry(shape.Shape, 60);//60 可以优化. + let diffMat = this.OCSInv.clone().multiply(shape.Outline.Curve.OCS); + geometry.applyMatrix(diffMat); let mesh = new THREE.Mesh(geometry, mat); regionGroup.add(mesh); - }) + } } ReadFile(file: CADFiler) { diff --git a/src/DatabaseServices/Shape.ts b/src/DatabaseServices/Shape.ts index a4c08ea35..e2b24af86 100644 --- a/src/DatabaseServices/Shape.ts +++ b/src/DatabaseServices/Shape.ts @@ -76,11 +76,13 @@ export class Shape { let cus: Curve[] = []; let contours: Contour[] = [this.m_Outline, ...this.m_Holes]; - contours.forEach(h => + for (let con of contours) { - h.Curve instanceof Polyline - ? cus.push(...h.Curve.Explode()) : cus.push(h.Curve.Clone()) - }); + if (con.Curve instanceof Polyline) + cus.push(...con.Curve.Explode()); + else + cus.push(con.Curve.Clone()); + } return cus; } Clone() diff --git a/src/Editor/CommandMachine.ts b/src/Editor/CommandMachine.ts index dd0660769..4f88e236b 100644 --- a/src/Editor/CommandMachine.ts +++ b/src/Editor/CommandMachine.ts @@ -97,3 +97,6 @@ class CommandMachine } export const commandMachine = new CommandMachine(); + + +window["end"] = commandMachine.CommandEnd; diff --git a/src/Geometry/BSPGroupParse.ts b/src/Geometry/BSPGroupParse.ts new file mode 100644 index 000000000..90e8742d3 --- /dev/null +++ b/src/Geometry/BSPGroupParse.ts @@ -0,0 +1,96 @@ +import { Vector3 } from "three"; +import { ToFixed } from "../Common/Utils"; +import ThreeBSP, { Polygon } from "./ThreeCSG"; +interface Vec3 +{ + x: number; + y: number; + z: number; +} + + +/** + * 解决 THREEBSP(CSG) 产生的结果没有办法得到分裂的个数. + * 本类分析了THREEBSP的组合情况. + * + * Example: + * + * let topology = new BSPGroupParse(csg); + * topology.parse(); + */ +export class BSPGroupParse +{ + constructor(bsp?: ThreeBSP, public fractionDigits = 1) + { + if (bsp) + for (let poly of bsp.tree.allPolygons()) + this.Add(poly); + } + Add(poly: Polygon) + { + 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++) + { + let stri = strs[i]; + s0.add(stri); + this.Get(stri).add(str0); + } + } + + /** + * 返回组合点 + */ + Parse(): Vector3[][] + { + let set = new Set([...this.map.keys()]); + let res: Vector3[][] = []; + while (set.size > 0) + { + let fp = set[Symbol.iterator]().next().value; + set.delete(fp); + let cset = new Set(); + cset.add(fp); + this.GetPts(fp, cset, set); + let pts = [...cset].map(str => + { + let v3 = this.vecMap.get(str); + return new Vector3(v3.x, v3.y, v3.z); + }); + res.push(pts); + } + return res; + } + private map = new Map>(); + private Get(vstr: string): Set + { + if (!this.map.has(vstr)) + { + let s = new Set(); + this.map.set(vstr, s); + return s; + } + return this.map.get(vstr); + } + private GetPts(p: string, cset: Set, oset: Set) + { + let strs = this.map.get(p); + for (let str of strs) + { + if (!cset.has(str)) + { + cset.add(str); + oset.delete(str); + this.GetPts(str, cset, oset); + } + } + } + private vecMap = new Map(); + private GenerateP(v: Vec3) + { + let str = [v.x, v.y, v.z].map(n => ToFixed(n, this.fractionDigits)).join(","); + this.vecMap.set(str, v); + return str; + } +} diff --git a/src/Geometry/DrillParse/BoardGetFace.ts b/src/Geometry/DrillParse/BoardGetFace.ts index 2b0ffb2aa..a4b620fd4 100644 --- a/src/Geometry/DrillParse/BoardGetFace.ts +++ b/src/Geometry/DrillParse/BoardGetFace.ts @@ -45,7 +45,7 @@ export class BoardGetFace } GetTopAndBottomFace() { - let curve = this.m_Board.Shape.Outline.Curve; + let curve = this.m_Board.ContourCurve; let box = curve.BoundingBox; let size = box.getSize(new Vector3()); @@ -84,9 +84,9 @@ export class BoardGetFace GetSideFaces() { // 判断板件构建曲线方向 - let cus = this.m_Board.Shape.Outline.Curve.Explode() as Curve[]; + let cus = this.m_Board.ContourCurve.Explode() as Curve[]; //板构建曲线方向 - let dir = Math.sign(this.m_Board.Shape.Outline.Curve.Area2) + let dir = Math.sign(this.m_Board.ContourCurve.Area2) cus.forEach(cu => { diff --git a/src/Geometry/SpaceParse/ClampSpaceParse.ts b/src/Geometry/SpaceParse/ClampSpaceParse.ts index d6efbefec..6b3866c60 100644 --- a/src/Geometry/SpaceParse/ClampSpaceParse.ts +++ b/src/Geometry/SpaceParse/ClampSpaceParse.ts @@ -71,9 +71,9 @@ export class ClampSpaceParse extends ISpaceParse let mat = br.RotateMat; let p1 = new Vector3(0, 0, -br.Thickness).applyMatrix4(mat); - let p2 = new Vector3(br.Width, br.Length, -dist).applyMatrix4(mat); + let p2 = new Vector3(br.Width, br.Height, -dist).applyMatrix4(mat); let p3 = new Vector3(0, 0, 0).applyMatrix4(mat); - let p4 = new Vector3(br.Width, br.Length, br.Thickness + dist).applyMatrix4(mat); + let p4 = new Vector3(br.Width, br.Height, br.Thickness + dist).applyMatrix4(mat); let boxs = [new Box3Ext().setFromPoints([p1, p2]), new Box3Ext().setFromPoints([p3, p4])]; diff --git a/src/Geometry/ThreeCSG.ts b/src/Geometry/ThreeCSG.ts index cf053f0e8..19e68227c 100644 --- a/src/Geometry/ThreeCSG.ts +++ b/src/Geometry/ThreeCSG.ts @@ -1,4 +1,4 @@ -import { Face3, Face4, Geometry, Material, Matrix4, Mesh, Vector2, Vector3 } from "three"; +import { Face3, Face4, Geometry, Material, Matrix4, Mesh, Vector2, Vector3, BufferGeometry } from "three"; const EPSILON = 1e-5, COPLANAR = 0, //共面 @@ -33,7 +33,12 @@ export default class ThreeBSP { // #todo: add hierarchy support this.matrix = obj.matrix.clone(); - geometry = obj.geometry as Geometry; + let geo = obj.geometry; + if (geo instanceof BufferGeometry) + geometry = new Geometry().fromBufferGeometry(geo); + else + geometry = geo; + } else if (obj instanceof Node) { diff --git a/src/GraphicsSystem/ToolPath/FeedingToolPath.ts b/src/GraphicsSystem/ToolPath/FeedingToolPath.ts index dc8a33f49..b6f733e33 100644 --- a/src/GraphicsSystem/ToolPath/FeedingToolPath.ts +++ b/src/GraphicsSystem/ToolPath/FeedingToolPath.ts @@ -112,10 +112,11 @@ export class FeedingToolPath extends Singleton */ CalcPath(br: Board): Curve[] { - let cus: Curve[] = [br.Shape.Outline.Curve.Clone()]; + let cus: Curve[] = [br.ContourCurve.Clone()]; let modelings = br.BoardModeling; - for (let { shape, thickness, rad } of modelings) + for (let { shape, thickness, knifeRadius } of modelings) { + if (!knifeRadius) knifeRadius = 3; if (thickness >= br.Thickness) { //通孔只切一刀 @@ -123,19 +124,19 @@ export class FeedingToolPath extends Singleton let dir = this.GetCurveToInDir(outline); let paths: Curve[]; if (outline instanceof Circle) - paths = outline.GetOffsetCurves(dir * rad); + paths = outline.GetOffsetCurves(dir * knifeRadius); else - paths = outline.GetFeedingToolPath(dir * rad); + paths = outline.GetFeedingToolPath(dir * knifeRadius); paths.forEach(p => p.ColorIndex = outline.ColorIndex); outline.ColorIndex++; cus.push(outline, ...paths); } else { - let offsetCus = this.HandleShape(shape, rad); + let offsetCus = this.HandleShape(shape, knifeRadius); if (offsetCus.length > 1) cus.push( - ...OptimizeToolPath(offsetCus, shape, rad) + ...OptimizeToolPath(offsetCus, shape, knifeRadius) ); } } diff --git a/src/Reactor/BoardDefaultMaterialReactor.ts b/src/Reactor/BoardDefaultMaterialReactor.ts index 60bf84dba..30557610e 100644 --- a/src/Reactor/BoardDefaultMaterialReactor.ts +++ b/src/Reactor/BoardDefaultMaterialReactor.ts @@ -12,7 +12,7 @@ textureLoader.load(`https://cdn.jsdelivr.net/gh/FishOrBear/CDNResources/Default. map.wrapS = MirroredRepeatWrapping; map.wrapT = MirroredRepeatWrapping; map.anisotropy = 4; - map.repeat.set(0.0005, 0.0005); + map.repeat.set(1, 1); brMat.map = map; brMat.needsUpdate = true; }) diff --git a/src/UI/Components/Board/BoardConfigModal.tsx b/src/UI/Components/Board/BoardConfigModal.tsx index 3ec04f145..08e37e94d 100644 --- a/src/UI/Components/Board/BoardConfigModal.tsx +++ b/src/UI/Components/Board/BoardConfigModal.tsx @@ -1,27 +1,24 @@ import { Button, Checkbox, Intent } from "@blueprintjs/core"; import { IObservableValue, observable } from "mobx"; +import { observer } from "mobx-react"; import * as React from 'react'; import { Matrix4 } from "three"; -import { aplicateContour, changeShapeUCS, getEntShape, selectOutlinePosition } from "../../../Add-on/DrawBoard/DrawSpecialShapeBoardTool"; +import { ExtrudeApplyContour, SelectExtrudeContour, selectOutlinePosition } from "../../../Add-on/DrawBoard/DrawSpecialShapeBoardTool"; import { app } from "../../../ApplicationServices/Application"; import { CheckObjectType } from "../../../Common/CheckoutVaildValue"; import { Vec3DTo2D } from "../../../Common/CurveUtils"; import { DataAdapter } from "../../../Common/DataAdapter"; -import { Singleton } from "../../../Common/Singleton"; -import { Board, IModeling } from "../../../DatabaseServices/Board"; -import { Circle } from "../../../DatabaseServices/Circle"; +import { Board } from "../../../DatabaseServices/Board"; import { Contour } from "../../../DatabaseServices/Contour"; -import { Curve } from "../../../DatabaseServices/Curve"; -import { Polyline } from "../../../DatabaseServices/Polyline"; +import { ExtureSolid } from "../../../DatabaseServices/Extrude"; import { Shape } from "../../../DatabaseServices/Shape"; import { commandMachine } from "../../../Editor/CommandMachine"; import { JigUtils } from "../../../Editor/JigUtils"; import { SelectBox, SelectType } from "../../../Editor/SelectBox"; -import { equalv3, MoveMatrix } from "../../../Geometry/GeUtils"; -import { BoardConfigOption, BoardProcessOption } from '../../Store/BoardInterface'; +import { MoveMatrix } from "../../../Geometry/GeUtils"; +import { BoardConfigOption, BoardProcessOption, FaceDirection } from '../../Store/BoardInterface'; import { RightPanelStore } from "../../Store/RightPanelStore"; import { BoardTypeComponent, ItemName, SetBoardDataBlock } from "./BoardCommon"; -import { observer } from "mobx-react"; interface BoardConfigProps { @@ -55,104 +52,101 @@ export class BoardConfigModal extends React.Component{ await app.m_Editor.m_ModalManage.EndExecingCmd(); if (!commandMachine.CommandStart("zx")) return; - app.m_Editor.m_ModalManage.ToggleShow(); - - //储存选择的外轮廓实体 - let originEns = []; - let shape = await getEntShape("请选择外轮廓", true, originEns); - let br = this.props.br; - aplicateContour(shape, [br], false); + app.m_Editor.m_ModalManage.ToggleShow(); - if (shape) + let exec = async () => { - let box = shape.BoundingBox; - let min = box.min.clone(); - let max = box.max.clone(); - - app.m_Viewer.WorldToScreen(min); - app.m_Viewer.WorldToScreen(max); - //用包围盒构建选择框 - let selectBox = new SelectBox(app.m_Viewer, Vec3DTo2D(min), Vec3DTo2D(max), SelectType.C); - selectBox.Select(app.m_Viewer.Scene.children, { filterTypes: [Polyline, Circle] }); - - let cus = selectBox.SelectEntityList.filter((cu: Polyline | Circle) => cu.IsClose) as Curve[]; + let { contour, gourp: cuGourp } = await SelectExtrudeContour(true); + if (!contour) return; - const rightStore = RightPanelStore.GetInstance(); + let br = this.props.br; + let applyMatrix = ExtrudeApplyContour(br, contour); + br.ClearBoardModeling(); - //曲线按颜色分类 - let cuMap: Map = new Map(); - for (let cu of cus) + if (cuGourp) { - if (originEns.length > 0 && (cu === originEns[0] || !equalv3(cu.Normal, originEns[0].Normal))) - continue; + let box = contour.BoundingBox; + app.m_Viewer.WorldToScreen(box.min); + app.m_Viewer.WorldToScreen(box.max); + let selectBox = new SelectBox(app.m_Viewer, Vec3DTo2D(box.min), Vec3DTo2D(box.max), SelectType.C); - let colorIndex = cu.ColorIndex; - let modelData = rightStore.modelingItems[colorIndex - 1]; - if (modelData.height > 0) - { - if (cuMap.has(colorIndex)) - cuMap.get(colorIndex).push(Contour.CreateContour([cu])); - else - cuMap.set(colorIndex, [Contour.CreateContour([cu])]); - cu.Erase(); - } - } - - // 将外轮廓转移到板件坐标系或者是二维平面 - let oldOcsInv = shape.Outline.Curve.OCSInv; + const rightStore = RightPanelStore.GetInstance() as RightPanelStore; - changeShapeUCS(shape, br); + let contourMap = new Map(); - box = shape.BoundingBox; - - let modelings: IModeling[] = []; - for (let [i, cons] of cuMap) - { - let oldOcs = cons[0].Curve.OCS; - let ocsInv = cons[0].Curve.OCSInv; - //将轮廓转移到二维屏幕构建形状 - cons.forEach(c => c.Curve.ApplyMatrix(ocsInv)); - let shapes = Shape.pairHoleAndOutline(cons); + for (let g of cuGourp) + { + for (let c of g) + { + let cd = rightStore.modelingItems[c.ColorIndex - 1]; + if (cd.height <= 0) + break; - let modelData = rightStore.modelingItems[i - 1]; + if (selectBox.CheckSelect(c.Draw())) + { + let con = Contour.CreateContour(g, false); + if (!contourMap.has(c.ColorIndex)) + contourMap.set(c.ColorIndex, [con]); + else + contourMap.get(c.ColorIndex).push(con); + + break; + } + } + } - for (let s of shapes) + if (contourMap.size > 0) { - if (modelData.height >= br.Thickness) + for (let [color, contours] of contourMap) { - modelData.height = br.Thickness; - s.Holes.length = 0; - } - //还原构建形状到原来的坐标系,在转换到外轮廓所在位置 - s.ApplyMatrix(oldOcs); + for (let con of contours) + con.Curve.ApplyMatrix(applyMatrix); - changeShapeUCS(s, br, oldOcsInv); + let cd = rightStore.modelingItems[color - 1]; + let shapes = Shape.pairHoleAndOutline(contours); + for (let shape of shapes) + { + let groove = new ExtureSolid(); + groove.Thickness = cd.height; + groove.ContourCurve = shape.Outline.Curve; + + for (let hole of shape.Holes) + { + let holeSolid = new ExtureSolid(); + holeSolid.Thickness = cd.height; + holeSolid.ContourCurve = hole.Curve; + groove.AppendGroove(holeSolid); + } + + groove.ApplyMatrix(br.OCS); + if (cd.dir === FaceDirection.Front) + groove.ApplyMatrix(MoveMatrix(br.Normal.multiplyScalar(br.Thickness - groove.Thickness))); + br.AppendGroove(groove); + } + } - s.ApplyMatrix(MoveMatrix(box.min.clone().negate())); + let splits: Board[] = []; + br.GrooveCheckAll(splits); + for (let br of splits) + app.m_Database.ModelSpace.Append(br); - let ss = s.IntersectionBoolOperation(br.Shape); - for (let s1 of ss) - { - s1.SetColor(i); - modelings.push({ - shape: s1, - thickness: modelData.height, - dir: modelData.dir, - rad: modelData.rad, - addLen: modelData.length - }); - } + br.Update(); } } - br.BoardModeling = modelings; - this.props.canDrawSpeical.set(br.IsSpecialShape); - this.props.canModeling.set(modelings.length > 0); - } + + }; + + await exec(); app.m_Editor.m_ModalManage.ToggleShow(); commandMachine.CommandEnd(); + return; } + + /** + * 提取 + */ private PickUpModelingOutline = async () => { app.m_Editor.m_ModalManage.ToggleShow(); @@ -161,7 +155,7 @@ export class BoardConfigModal extends React.Component{ app.m_Viewer.m_CameraCtrl.LookAt(br.Normal.negate()); app.m_Editor.UCSMatrix = new Matrix4().extractRotation(br.OCS); - let cu = JigUtils.Draw(br.Shape.Outline.Curve.Clone().ApplyMatrix(br.OCS)); + let cu = JigUtils.Draw(br.ContourCurve.Clone().ApplyMatrix(br.OCS)); let moveCus = [cu]; let store = RightPanelStore.GetInstance(); @@ -253,4 +247,3 @@ export class BoardConfigModal extends React.Component{ ) } } - diff --git a/src/UI/Components/Board/BoardOptionModal.tsx b/src/UI/Components/Board/BoardOptionModal.tsx index d4768087b..f8a52accb 100644 --- a/src/UI/Components/Board/BoardOptionModal.tsx +++ b/src/UI/Components/Board/BoardOptionModal.tsx @@ -41,7 +41,7 @@ export class BoardOptionModal extends React.Component<{ board: Board }, {}> let newConfig = { name: this.m_CurrentBoard.Name, type: this.m_CurrentBoard.BoardType, - height: parseFloat(FixedNotZero(this.m_CurrentBoard.Length, 2)), + height: parseFloat(FixedNotZero(this.m_CurrentBoard.Height, 2)), width: parseFloat(FixedNotZero(this.m_CurrentBoard.Width, 2)), thickness: parseFloat(FixedNotZero(this.m_CurrentBoard.Thickness, 2)), rotateX: parseFloat(FixedNotZero(Math.radToDeg(ro.x), 2)), @@ -72,7 +72,7 @@ export class BoardOptionModal extends React.Component<{ board: Board }, {}> board.BoardProcessOption = this.m_ProcessOption; board.Name = this.m_ConfigOption.name; - board.Length = this.m_ConfigOption.height; + board.Height = this.m_ConfigOption.height; board.Width = this.m_ConfigOption.width; board.Thickness = this.m_ConfigOption.thickness; board.BoardType = this.m_ConfigOption.type; @@ -91,12 +91,12 @@ export class BoardOptionModal extends React.Component<{ board: Board }, {}> } //取消勾选造型,清除造型 - if (!this.canModeling.get() && board.BoardModeling.length > 0) + if (!this.canModeling.get() && board.HasGroove) board.ClearBoardModeling(); //取消勾选异型,板件回复正常形状 if (!this.canDrawSpecial.get()) - board.InitBoard(board.Length, board.Width, board.Thickness, board.BoardType); + board.InitBoard(board.Height, board.Width, board.Thickness, board.BoardType); app.m_Editor.m_ModalManage.Clear(); @@ -117,7 +117,7 @@ export class BoardOptionModal extends React.Component<{ board: Board }, {}> app.m_Viewer.Scene.children.forEach(obj => CheckFilter(obj, f)); this.canDrawSpecial.set(this.m_CurrentBoard.IsSpecialShape); - this.canModeling.set(this.m_CurrentBoard.BoardModeling.length > 0); + this.canModeling.set(this.m_CurrentBoard.HasGroove); } render() { diff --git a/src/UI/Components/Board/BoardProcessModal.tsx b/src/UI/Components/Board/BoardProcessModal.tsx index 6ddbe4e99..674210726 100644 --- a/src/UI/Components/Board/BoardProcessModal.tsx +++ b/src/UI/Components/Board/BoardProcessModal.tsx @@ -23,7 +23,7 @@ export class BoardProcessModal extends React.Component{ render() { let isShowHighEditor = this.props.br - && !(this.props.br.Shape.Outline.Curve instanceof Circle) + && !(this.props.br.ContourCurve instanceof Circle) && this.props.isSpecial.get(); return ( diff --git a/src/UI/Components/Board/EdgeSealingComponent.tsx b/src/UI/Components/Board/EdgeSealingComponent.tsx index 4474c36ea..e51b3936b 100644 --- a/src/UI/Components/Board/EdgeSealingComponent.tsx +++ b/src/UI/Components/Board/EdgeSealingComponent.tsx @@ -22,7 +22,7 @@ export class EdgeSealingComponent extends React.Component<{ br: Board }, {}> private EditorEdgeSealing = () => { let br = this.props.br; - let cus = br.Shape.Outline.Curve.Explode() as Curve[]; + let cus = br.ContourCurve.Explode() as Curve[]; //曲线分段 paragraphCulist(cus); @@ -48,7 +48,7 @@ export class EdgeSealingComponent extends React.Component<{ br: Board }, {}> private CalcEdgeSealing = () => { - let originCurve = this.props.br.Shape.Outline.Curve; + let originCurve = this.props.br.ContourCurve; let dir = Math.sign(originCurve.Area2) * -1; let infoEls = this.ulList.querySelectorAll('li input'); let edgeSealingNum: number[] = [];