From 85deff2a8ab59cbed3ed8ac3f77606d9ae0225db Mon Sep 17 00:00:00 2001 From: ZoeLeeFZ Date: Wed, 5 Aug 2020 17:56:59 +0800 Subject: [PATCH] =?UTF-8?q?!1149=20=E4=BC=98=E5=8C=96:=E8=B5=B0=E5=88=80?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FeedingToolPath/FeedingToolPath.test.ts | 29 +++ .../FeedingToolPath.test.ts.snap | 166 ++++++++++++------ src/Add-on/CheckModeling.ts | 36 +++- src/DatabaseServices/3DSolid/ExtrudeHole.ts | 4 + src/DatabaseServices/Shape.ts | 18 +- src/GraphicsSystem/CalcEdgeSealing.ts | 5 + .../ToolPath/FeedingToolPath.ts | 124 +++++++++---- .../ToolPath/OptimizeToolPath.ts | 16 +- src/Production/Product.ts | 2 +- src/UI/Components/Board/BoardConfigModal.tsx | 2 +- 10 files changed, 296 insertions(+), 106 deletions(-) diff --git a/__test__/FeedingToolPath/FeedingToolPath.test.ts b/__test__/FeedingToolPath/FeedingToolPath.test.ts index 50beec60e..6d14461c6 100644 --- a/__test__/FeedingToolPath/FeedingToolPath.test.ts +++ b/__test__/FeedingToolPath/FeedingToolPath.test.ts @@ -158,3 +158,32 @@ test("#I1MUQD", () => let brs = LoadBoardsFromFileData(data); testPathCount(brs[0], 8); }); + +test("日字加工", () => +{ + let data = + { "file": [1, "Board", 8, 2, 686, false, 1, 11, 0, [-0.999997439714021, -0.0022628666339358583, 0, 0, 0, 0, 1, 0, -0.0022628666339358583, 0.999997439714021, 0, 0, 431.23731244072155, 1126.9116927510254, 0, 1], 0, 0, true, [-0.0022628666339358583, 0.999997439714021, 0, 0, -0.999997439714021, -0.0022628666339358583, 0, 0, 0, 0, 1, 0, 442.24629054531874, 1126.9366046640337, 0, 1], 0, 3, 432.00000000000006, 206.21628154156102, 18, true, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -11.009006290800926, 432, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -11.009006290800926, 2.2737367544323206e-13, 0, 1], 0, 2, 4, [217.22528783236191, -432], 0, [217.22528783236191, 5.684341886080802e-14], 0, [11.009006290800892, 0], 0, [11.009006290800892, -432], 0, true, 1, 3, 21.459983999999963, 40.381175249996886, 1.8, false, "Polyline", 8, 2, 0, false, 0, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -245.01875510359605, 301.84343598133, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -245.0187551035961, 301.84343598133, 32.40000000000006, 1], 0, 2, 44, [285.0646181035918, -284.11978848133003], 0, [282.83718672859686, -282.58693248133], 0, [280.60975535359466, -281.05407648133007], 0, [279.6756712285933, -282.27557110633006], 0, [278.7415871035919, -283.49706573132994], 0, [263.96389722859385, -283.49706573132994], 0, [249.18620735359218, -283.49706573132994], 0, [247.10248122859048, -281.94025885633005], 0, [245.01875510359605, -280.38345198133004], 0, [245.16246035358927, -283.59286923133004], 0, [245.2103621035858, -287.08969698132995], 0, [245.2103621035858, -291.28110010633], 0, [245.2103621035858, -295.47250323132994], 0, [245.138509478591, -298.13105035633], 0, [245.06665685359258, -300.78959748133], 0, [245.17443579109022, -301.57997635633], 0, [245.49777260359042, -301.84343598133], 0, [246.10851991609525, -301.69973073133], 0, [247.07853035359585, -301.26861498133], 0, [247.97668816609075, -300.53811329383], 0, [248.27607410358905, -299.59205373133005], 0, [248.27607410358905, -299.30464323133003], 0, [248.27607410358905, -299.01723273133], 0, [263.96389722859385, -299.01723273133], 0, [279.65172035359865, -299.01723273133], 0, [279.65172035359865, -299.73575898133004], 0, [279.65172035359865, -300.45428523133], 0, [279.7714747285936, -301.49614829383], 0, [280.1307378535894, -301.84343598133], 0, [280.7893869160944, -301.71170616883006], 0, [281.80729910359514, -301.31651673133], 0, [282.74138322859653, -300.63391679383005], 0, [283.05274460359215, -299.73575898133004], 0, [282.9808919785937, -298.4663626063301], 0, [282.90903935359165, -297.19696623133], 0, [282.801260416094, -295.66411023133], 0, [282.7653341035875, -294.13125423133], 0, [282.7653341035875, -290.27516335633004], 0, [282.7653341035875, -286.41907248133003], 0, [283.86707435359494, -285.70054623133], 0, [284.9688146035951, -284.98201998133004], 0, [285.29215141609166, -284.73053579383003], 0, [285.39993035359294, -284.55090423133004], 0, [285.31610229109356, -284.34732179383], 0, true, 2, 3, 5.84401349999996, 31.375646250009595, 1.8, true, "Polyline", 8, 2, 0, false, 1, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -248.27607410358905, 290.5386229813299, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -248.2760741035891, 290.5386229813299, 32.40000000000007, 1], 0, 2, 4, [279.65172035359865, -290.5386229813299], 0, [279.65172035359865, -284.69460948132996], 0, [248.27607410358905, -284.69460948132996], 0, [248.27607410358905, -290.5386229813299], 0, true, 0, 3, 0, 0, 0, 0, 0, [-0.999997439714021, -0.0022628666339358583, 0, 0, 0, 0, 1, 0, -0.0022628666339358583, 0.999997439714021, 0, 0, 346.4066151822023, 1142.9197731819293, 191.98120133753412, 1], 3, 6.083522250000101, 31.375646250009595, 1.8, true, "Polyline", 8, 2, 0, false, 1, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -248.27607410358905, 297.81968898133005, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -248.2760741035891, 297.81968898133005, 32.40000000000007, 1], 0, 2, 4, [279.65172035359865, -297.81968898133005], 0, [279.65172035359865, -291.73616673132994], 0, [248.27607410358905, -291.73616673132994], 0, [248.27607410358905, -297.81968898133005], 0, true, 0, 3, 0, 0, 0, 0, 0, [-0.999997439714021, -0.0022628666339358583, 0, 0, 0, 0, 1, 0, -0.0022628666339358583, 0.999997439714021, 0, 0, 346.4066151822023, 1142.9197731819293, 184.700135337534, 1], 1, 0, 0, 0, 0, 0, [-0.999997439714021, -0.0022628666339358583, 0, 0, 0, 0, 1, 0, -0.0022628666339358583, 0.999997439714021, 0, 0, 349.66392584252543, 1142.9271440604105, 180.67638833753404, 1], 3, 0, 0, 0, 0, 0, 9, 1, "右侧板", "主卧", "下柜", "", "", "", 0, 0, "拉米诺", 2, 0, "1", "1", "1", "1", "", "", "", 4, "拉米诺", "拉米诺", "拉米诺", "拉米诺", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true], "basePt": { "x": 224.98082727240399, "y": 1126.4450528081506, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + let brs = LoadBoardsFromFileData(data); + testPathCount(brs[0], 7); +}); +test("孔轮廓比外轮廓大", () => +{ + let data = + { "file": [1, "Board", 8, 2, 100, false, 1, 3, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, -480.60225895268377, -185.23833994346205, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -480.60225895268377, -185.23833994346205, 0, 1], 0, 3, 800, 600, 18, true, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 4, [0, 0], 0, [600, 0], 0, [600, 800], 0, [0, 800], 0, true, 1, 3, 680, 480, 5, false, "Polyline", 8, 2, 0, false, 0, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -60, -60, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -60, -60, 13, 1], 0, 2, 8, [66, 60], 0, [534, 60], 0.41421356237309503, [540, 66], 0, [540, 734], 0.41421356237309503, [534, 740], 0, [66, 740], 0.41421356237309503, [60, 734], 0, [60, 66], 0.41421356237309503, true, 1, 3, 668, 468, 5, true, "Polyline", 8, 2, 0, false, 0, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -66, -66, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -66, -66, 13, 1], 0, 2, 4, [66, 66], 0, [534, 66], 0, [534, 734], 0, [66, 734], 0, true, 0, 3, 0, 0, 0, 0, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, -414.60225895268377, -198.23833994346205, 66, 1], 3, 0, 0, 0, 0, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, -420.60225895268377, -198.23833994346205, 60, 1], 3, 0, 0, 0, 0, 0, 9, 2, "背板", "", "", "", "", "", 0, 0, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 4, "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true], "basePt": { "x": -480.60225895268377, "y": -203.23833994346205, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + let brs = LoadBoardsFromFileData(data); + testPathCount(brs[0]); +}); +test("门字部分", () => +{ + let data = + { "file": [1, "Board", 8, 2, 2223, false, 1, 2, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 8426.318707426251, 2299.282791618, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 8426.318707426251, 2299.282791618, 0, 1], 0, 3, 1200, 600, 18, true, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 4, [0, 0], 0, [600, 0], 0, [600, 1200], 0, [0, 1200], 0, true, 1, 3, 57.21600000000001, 31.968000000000757, 2, false, "Polyline", 8, 2, 0, false, 0, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -209.6453198822055, 283.06701259445845, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -209.6453198822055, 283.06701259445845, 64.20000000000219, 1], 0, 2, 44, [241.0853198822042, -230.31501259445847], 0, [241.48131988220484, -229.99101259445843], 0, [241.61331988220627, -229.6910125944584], 0, [241.48131988220484, -229.36701259445846], 0, [241.0853198822042, -228.97101259445847], 0, [238.94931988220924, -227.41101259445844], 0, [236.81331988220336, -225.85101259445844], 0, [235.85331988220423, -227.24301259445846], 0, [234.89331988220147, -228.63501259445843], 0, [224.69331988220438, -228.63501259445843], 0, [214.49331988221093, -228.63501259445843], 0, [211.9613198822044, -228.57501259445843], 0, [209.6453198822055, -228.39501259445845], 0, [210.5813198822034, -229.6190125944584], 0, [211.51731988219763, -230.84301259445846], 0, [213.56931988220822, -230.3030125944585], 0, [215.9813198822012, -230.12301259445843], 0, [226.03731988220534, -230.12301259445843], 0, [236.09331988220583, -230.12301259445843], 0, [236.09331988220583, -252.68301259445846], 0, [236.09331988220583, -275.2430125944585], 0, [235.90131988219946, -276.5390125944584], 0, [235.3253198822058, -277.25901259445845], 0, [234.28131988219684, -277.54701259445847], 0, [232.6853198822064, -277.64301259445847], 0, [229.78131988220775, -277.37901259445846], 0, [224.81331988219972, -276.5870125944585], 0, [224.7893198822021, -277.09101259445845], 0, [224.7653198822045, -277.5950125944585], 0, [227.42931988220516, -278.41101259445844], 0, [229.9493198822056, -279.4190125944585], 0, [231.95331988220642, -280.7270125944585], 0, [232.97331988219958, -282.4430125944585], 0, [233.1653198822023, -282.91101259445844], 0, [233.45331988220642, -283.06701259445845], 0, [234.6653198822096, -282.76701259445844], 0, [236.3813198822063, -281.86701259445846], 0, [237.98931988220284, -280.5950125944585], 0, [238.8773198821982, -279.1790125944584], 0, [239.23731988220243, -277.3070125944585], 0, [239.3573198822014, -274.57101259445847], 0, [239.3573198822014, -253.01901259445842], 0, [239.3573198822014, -231.46701259445845], 0, [240.22131988220644, -230.89101259445843], 0, true, 0, 2, 0, 0, 0, 0, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 7822.589893866929, 2546.062452634949, 16, 1], 3, 0, 0, 0, 0, 0, 9, 0, "层板", "", "", "", "", "", 0, 0, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 4, "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true], "basePt": { "x": 7226.318707426251, "y": 2299.282791618, "z": 0 }, "ucs": [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + let brs = LoadBoardsFromFileData(data); + testPathCount(brs[0], 4); +}); +test("通槽加长错误", () => +{ + let data = + { "file": [1, "Board", 8, 2, 100, false, 1, 2, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 339.80952861870173, 249.3538870831253, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 339.80952861870173, 229.3538870831253, 0, 1], 0, 3, 918.0000000000002, 324.5928486066955, 18, true, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 4, [0, 0], 0, [324.5928486066955, 0], 0, [324.5928486066955, 918.0000000000002], 0, [0, 918.0000000000002], 0, true, 1, 3, 6, 712.0896318545867, 8.99999999999909, false, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [-0.20303412411504598, -0.9791716623988034, 0, 0, 0.9791716623988034, -0.20303412411504598, 0, 0, 0, 0, 1, 0, -150.85291425915239, 365.69871018220056, 0, 1], 0, 2, 5, [712.0896318545867, 5.999999999999886], 0, [0, 5.999999999999943], 0, [-5.684341886080802e-14, 2.921526605141594], 0, [14.089631854583672, -5.684341886080802e-14], 0, [710.8455142075273, 0], 0, true, 0, 3, 6, 0, 0, 0, 0, [-0.9791716623988034, -0.20303412411504598, 0, 0, 0.20303412411504598, -0.9791716623988034, 0, 0, 0, 0, 1, 0, 117.849312474018, 576.8074117525202, 0, 1], 3, 0, 0, 0, 0, 0, 9, 0, "层板", "5-主卧", "阳台柜", "", "E0级儿童板", "书香桐", 0, 1, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 8, "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true], "basePt": { "x": -578.1904713812985, "y": 249.3538870831253, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + let brs = LoadBoardsFromFileData(data); + testPathCount(brs[0], 3); +}); diff --git a/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap b/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap index 2d5b53a9e..1d97eb495 100644 --- a/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap +++ b/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap @@ -66,9 +66,9 @@ exports[`复杂极限刀半径 1`] = `"4356.84083"`; exports[`复杂极限刀半径 2`] = `"1073.24693"`; -exports[`复杂极限刀半径 3`] = `"34218.23967"`; +exports[`复杂极限刀半径 3`] = `"36199.20990"`; -exports[`复杂极限刀半径 4`] = `"4434.59178"`; +exports[`复杂极限刀半径 4`] = `"2928.44167"`; exports[`复杂极限刀半径 5`] = `"951.54022"`; @@ -190,6 +190,16 @@ exports[`复杂造型测试: 走刀数量 1`] = `12`; exports[`复杂造型测试: 走刀数量 2`] = `2`; +exports[`孔轮廓比外轮廓大 1`] = `"2800.00000"`; + +exports[`孔轮廓比外轮廓大 2`] = `"2290.84956"`; + +exports[`孔轮廓比外轮廓大 3`] = `"2309.69911"`; + +exports[`孔轮廓比外轮廓大 4`] = `"2272.00000"`; + +exports[`孔轮廓比外轮廓大: 走刀数量 1`] = `1`; + exports[`带孔造型板件 1`] = `"3600.00000"`; exports[`带孔造型板件 2`] = `"31857.87785"`; @@ -214,6 +224,22 @@ exports[`带孔造型板件: 走刀数量 1`] = `2`; exports[`带孔造型板件: 走刀数量 2`] = `2`; +exports[`日字加工 1`] = `"1276.43256"`; + +exports[`日字加工 2`] = `"41.15725"`; + +exports[`日字加工 3`] = `"1.56220"`; + +exports[`日字加工 4`] = `"38.29334"`; + +exports[`日字加工 5`] = `"124.64721"`; + +exports[`日字加工 6`] = `"74.43932"`; + +exports[`日字加工 7`] = `"74.91834"`; + +exports[`日字加工: 走刀数量 1`] = `3`; + exports[`极限刀半径 1`] = `"3600.00000"`; exports[`极限刀半径 2`] = `"1000.00000"`; @@ -276,111 +302,123 @@ exports[`超级复杂造型01 4`] = `"9.89484"`; exports[`超级复杂造型01 5`] = `"34.11041"`; -exports[`超级复杂造型01 6`] = `"93.09682"`; +exports[`超级复杂造型01 6`] = `"36.73893"`; + +exports[`超级复杂造型01 7`] = `"93.09682"`; -exports[`超级复杂造型01 7`] = `"3.00516"`; +exports[`超级复杂造型01 8`] = `"3.00516"`; -exports[`超级复杂造型01 8`] = `"15.55863"`; +exports[`超级复杂造型01 9`] = `"15.55863"`; -exports[`超级复杂造型01 9`] = `"1.50234"`; +exports[`超级复杂造型01 10`] = `"1.50234"`; -exports[`超级复杂造型01 10`] = `"34.11041"`; +exports[`超级复杂造型01 11`] = `"34.11041"`; -exports[`超级复杂造型01 11`] = `"23.17925"`; +exports[`超级复杂造型01 12`] = `"36.73893"`; -exports[`超级复杂造型01 12`] = `"3.00516"`; +exports[`超级复杂造型01 13`] = `"23.17925"`; -exports[`超级复杂造型01 13`] = `"3.00516"`; +exports[`超级复杂造型01 14`] = `"3.00516"`; -exports[`超级复杂造型01 14`] = `"15.55863"`; +exports[`超级复杂造型01 15`] = `"3.00516"`; -exports[`超级复杂造型01 15`] = `"1.50234"`; +exports[`超级复杂造型01 16`] = `"15.55863"`; -exports[`超级复杂造型01 16`] = `"9.89484"`; +exports[`超级复杂造型01 17`] = `"1.50234"`; -exports[`超级复杂造型01 17`] = `"2.27264"`; +exports[`超级复杂造型01 18`] = `"9.89484"`; -exports[`超级复杂造型01 18`] = `"23.17925"`; +exports[`超级复杂造型01 19`] = `"2.27264"`; -exports[`超级复杂造型01 19`] = `"34.11041"`; +exports[`超级复杂造型01 20`] = `"23.17925"`; -exports[`超级复杂造型01 20`] = `"3.00516"`; +exports[`超级复杂造型01 21`] = `"36.73893"`; -exports[`超级复杂造型01 21`] = `"3.00516"`; +exports[`超级复杂造型01 22`] = `"34.11041"`; -exports[`超级复杂造型01 22`] = `"15.55863"`; +exports[`超级复杂造型01 23`] = `"3.00516"`; -exports[`超级复杂造型01 23`] = `"1.50234"`; +exports[`超级复杂造型01 24`] = `"3.00516"`; -exports[`超级复杂造型01 24`] = `"9.89484"`; +exports[`超级复杂造型01 25`] = `"15.55863"`; -exports[`超级复杂造型01 25`] = `"2.27264"`; +exports[`超级复杂造型01 26`] = `"1.50234"`; -exports[`超级复杂造型01 26`] = `"23.17925"`; +exports[`超级复杂造型01 27`] = `"9.89484"`; -exports[`超级复杂造型01 27`] = `"34.11041"`; +exports[`超级复杂造型01 28`] = `"2.27264"`; -exports[`超级复杂造型01 28`] = `"3.00516"`; +exports[`超级复杂造型01 29`] = `"23.17925"`; -exports[`超级复杂造型01 29`] = `"3.00516"`; +exports[`超级复杂造型01 30`] = `"36.73893"`; -exports[`超级复杂造型01 30`] = `"15.55863"`; +exports[`超级复杂造型01 31`] = `"34.11041"`; -exports[`超级复杂造型01 31`] = `"1.50234"`; +exports[`超级复杂造型01 32`] = `"3.00516"`; -exports[`超级复杂造型01 32`] = `"9.89484"`; +exports[`超级复杂造型01 33`] = `"3.00516"`; -exports[`超级复杂造型01 33`] = `"2.27264"`; +exports[`超级复杂造型01 34`] = `"15.55863"`; -exports[`超级复杂造型01 34`] = `"23.17925"`; +exports[`超级复杂造型01 35`] = `"1.50234"`; -exports[`超级复杂造型01 35`] = `"34.11041"`; +exports[`超级复杂造型01 36`] = `"9.89484"`; -exports[`超级复杂造型01 36`] = `"3.00516"`; +exports[`超级复杂造型01 37`] = `"2.27264"`; -exports[`超级复杂造型01 37`] = `"3.00516"`; +exports[`超级复杂造型01 38`] = `"23.17925"`; -exports[`超级复杂造型01 38`] = `"15.55863"`; +exports[`超级复杂造型01 39`] = `"36.73893"`; -exports[`超级复杂造型01 39`] = `"1.50234"`; +exports[`超级复杂造型01 40`] = `"34.11041"`; -exports[`超级复杂造型01 40`] = `"9.89484"`; +exports[`超级复杂造型01 41`] = `"3.00516"`; -exports[`超级复杂造型01 41`] = `"2.27264"`; +exports[`超级复杂造型01 42`] = `"3.00516"`; -exports[`超级复杂造型01 42`] = `"23.17925"`; +exports[`超级复杂造型01 43`] = `"15.55863"`; -exports[`超级复杂造型01 43`] = `"34.11041"`; +exports[`超级复杂造型01 44`] = `"1.50234"`; -exports[`超级复杂造型01 44`] = `"3.00516"`; +exports[`超级复杂造型01 45`] = `"9.89484"`; -exports[`超级复杂造型01 45`] = `"3.00516"`; +exports[`超级复杂造型01 46`] = `"2.27264"`; -exports[`超级复杂造型01 46`] = `"15.55863"`; +exports[`超级复杂造型01 47`] = `"23.17925"`; -exports[`超级复杂造型01 47`] = `"1.50234"`; +exports[`超级复杂造型01 48`] = `"34.11041"`; -exports[`超级复杂造型01 48`] = `"9.89484"`; +exports[`超级复杂造型01 49`] = `"36.73893"`; -exports[`超级复杂造型01 49`] = `"2.27264"`; +exports[`超级复杂造型01 50`] = `"3.00516"`; -exports[`超级复杂造型01 50`] = `"11906.41153"`; +exports[`超级复杂造型01 51`] = `"3.00516"`; -exports[`超级复杂造型01 51`] = `"464.88810"`; +exports[`超级复杂造型01 52`] = `"9.89484"`; -exports[`超级复杂造型01 52`] = `"464.88810"`; +exports[`超级复杂造型01 53`] = `"2.27264"`; -exports[`超级复杂造型01 53`] = `"464.88810"`; +exports[`超级复杂造型01 54`] = `"15.55863"`; -exports[`超级复杂造型01 54`] = `"464.88810"`; +exports[`超级复杂造型01 55`] = `"1.50234"`; -exports[`超级复杂造型01 55`] = `"464.88810"`; +exports[`超级复杂造型01 56`] = `"11906.41153"`; -exports[`超级复杂造型01 56`] = `"464.88810"`; +exports[`超级复杂造型01 57`] = `"464.88810"`; -exports[`超级复杂造型01 57`] = `"9277.91064"`; +exports[`超级复杂造型01 58`] = `"464.88810"`; -exports[`超级复杂造型01: 走刀数量 1`] = `48`; +exports[`超级复杂造型01 59`] = `"464.88810"`; + +exports[`超级复杂造型01 60`] = `"464.88810"`; + +exports[`超级复杂造型01 61`] = `"464.88810"`; + +exports[`超级复杂造型01 62`] = `"464.88810"`; + +exports[`超级复杂造型01 63`] = `"9277.91064"`; + +exports[`超级复杂造型01: 走刀数量 1`] = `54`; exports[`通孔造型测试 1`] = `"3600.00000"`; @@ -390,6 +428,14 @@ exports[`通孔造型测试 3`] = `"1896.61683"`; exports[`通孔造型测试: 走刀数量 1`] = `1`; +exports[`通槽加长错误 1`] = `"2485.18570"`; + +exports[`通槽加长错误 2`] = `"719.93538"`; + +exports[`通槽加长错误 3`] = `"1432.44095"`; + +exports[`通槽加长错误: 走刀数量 1`] = `1`; + exports[`造型的外框和内框厚度小于刀半径厚度 1`] = `"3600.00000"`; exports[`造型的外框和内框厚度小于刀半径厚度: 走刀数量 1`] = `0`; @@ -403,3 +449,13 @@ exports[`造型的外框和内框厚度等于刀直径 3`] = `"1483.45340"`; exports[`造型的外框和内框厚度等于刀直径 4`] = `"1435.45340"`; exports[`造型的外框和内框厚度等于刀直径: 走刀数量 1`] = `1`; + +exports[`门字部分 1`] = `"3600.00000"`; + +exports[`门字部分 2`] = `"1.76759"`; + +exports[`门字部分 3`] = `"8.75659"`; + +exports[`门字部分 4`] = `"189.85784"`; + +exports[`门字部分: 走刀数量 1`] = `2`; diff --git a/src/Add-on/CheckModeling.ts b/src/Add-on/CheckModeling.ts index 33092ad88..4b11a2f70 100644 --- a/src/Add-on/CheckModeling.ts +++ b/src/Add-on/CheckModeling.ts @@ -5,9 +5,13 @@ import { Command } from "../Editor/CommandMachine"; import { JigUtils } from "../Editor/JigUtils"; import { PromptStatus } from "../Editor/PromptResult"; import { FeedingToolPath } from "../GraphicsSystem/ToolPath/FeedingToolPath"; +import { ExtrudeHole } from "../DatabaseServices/3DSolid/ExtrudeHole"; +import { AppToaster } from "../UI/Components/Toaster"; +import { Intent } from "@blueprintjs/core"; export class CheckModeling implements Command { + res: Function; async exec() { let brRes = await app.Editor.GetSelection({ @@ -22,6 +26,8 @@ export class CheckModeling implements Command let feedingTool = FeedingToolPath.GetInstance() as FeedingToolPath; let errGrooves: ExtrudeSolid[] = []; + let errHoles: ExtrudeHole[] = []; + for (let br of brs) { let errorIndexs = feedingTool.CheckModeling(br); @@ -30,18 +36,36 @@ export class CheckModeling implements Command { errGrooves.push(grooves[index]); } + errHoles.push(...feedingTool.CheckCustomHole(br)); } - if (errGrooves.length > 0) - app.Editor.Prompt(`检测到${errGrooves.length}个无法加工的造型!旋转视图可以隐藏板件查看造型位置!`); + if (errGrooves.length > 0 || errHoles.length > 0) + app.Editor.Prompt(`检测到${errGrooves.length}个无法加工的造型和${errHoles.length}个无法加共的自定义排钻!旋转视图可以隐藏板件查看造型位置!`); else app.Editor.Prompt(`未检测到无法加工的造型!`); - setTimeout(() => + if (errGrooves.length > 0 || errHoles.length > 0) { - //亮显它 - app.Viewer.OutlinePass.selectedObjects = errGrooves.map(g => JigUtils.Draw(g).DrawObject); + app.Viewer.OutlinePass.selectedObjects = [...errHoles.map(h => h.DrawObject), + ...errGrooves.map(g => JigUtils.Draw(g.Clone()).DrawObject)]; + app.Editor.UpdateScreen(); - }, 0); + AppToaster.show({ + message: "正在检查无法加工的造型,关闭以继续,否则无法执行其他操作!!", + timeout: 0, + intent: Intent.SUCCESS, + onDismiss: () => + { + JigUtils.Destroy(); + app.Viewer.OutlinePass.selectedObjects = []; + this.res(); + } + }, "checkModeling"); + await this.Wait(); + } + } + Wait() + { + return new Promise(res => this.res = res); } } diff --git a/src/DatabaseServices/3DSolid/ExtrudeHole.ts b/src/DatabaseServices/3DSolid/ExtrudeHole.ts index a7ab40498..72a0167a1 100644 --- a/src/DatabaseServices/3DSolid/ExtrudeHole.ts +++ b/src/DatabaseServices/3DSolid/ExtrudeHole.ts @@ -42,6 +42,10 @@ export class ExtrudeHole extends Hole this._knifeRadius = v; } } + Explode() + { + return [this.ContourCurve.Clone().ApplyMatrix(this.OCS)]; + } get ContourCurve() { return this._contourCurve; diff --git a/src/DatabaseServices/Shape.ts b/src/DatabaseServices/Shape.ts index b3b1b52d0..43f786568 100644 --- a/src/DatabaseServices/Shape.ts +++ b/src/DatabaseServices/Shape.ts @@ -273,7 +273,10 @@ export class Shape return shapes; } - //如果完全被减掉,就返回0个.其他的返回1个或者n个 + /** + * 如果完全被减掉,就返回0个.其他的返回1个或者n个 + * @param targetShapes 已经是合并后的形状数组 + */ SubstactBoolOperation(targetShapes: Shape[]) { let originOutline = this.Outline; @@ -410,13 +413,9 @@ export class Shape } /** * 合并洞,本质是使用(并集算法)将可以并集的洞合并在一起,减少洞的数量. - * - * @private - * @param {Contour[]} holes - * @returns - * @memberof Shape + * canSidewipe 用于走刀,擦边的是否合并 */ - static mergeContours(holes: Contour[]): Contour[] + static mergeContours(holes: Contour[], canSidewipe = true): Contour[] { if (holes.length <= 1) return holes; let rets: Contour[] = [];//返回的合并轮廓 @@ -454,6 +453,11 @@ export class Shape if (unions.contours.length === 1)//并集成功 { + if (!canSidewipe) + { + if (equaln(c.Area + ic.Area, unions.contours[0].Area, 0.1)) + return true; + } c = unions.contours[0]; //更新c b1 = c.BoundingBox; cache.set(c, b1); diff --git a/src/GraphicsSystem/CalcEdgeSealing.ts b/src/GraphicsSystem/CalcEdgeSealing.ts index 517ded9ef..677c2c1f4 100644 --- a/src/GraphicsSystem/CalcEdgeSealing.ts +++ b/src/GraphicsSystem/CalcEdgeSealing.ts @@ -129,6 +129,11 @@ export function CalcEdgeSealing(cus: Curve[]) let frontLine = cus[i]; let laterIndex = FixIndex(i + 1, cus); let laterLine = cus[laterIndex]; + if (!frontLine || !laterLine) + { + alert("获取封边错误,请提供图纸给相关人员"); + return; + } if (equalv3(frontLine.EndPoint, laterLine.StartPoint, 1e-2)) continue; let refLine = oldLine ?? frontLine; diff --git a/src/GraphicsSystem/ToolPath/FeedingToolPath.ts b/src/GraphicsSystem/ToolPath/FeedingToolPath.ts index 7a60ab51a..46e9d78ec 100644 --- a/src/GraphicsSystem/ToolPath/FeedingToolPath.ts +++ b/src/GraphicsSystem/ToolPath/FeedingToolPath.ts @@ -1,5 +1,5 @@ import { Matrix4, Vector3 } from "three"; -import { equalCurve, IsRect } from "../../Common/CurveUtils"; +import { equalCurve, IsRect, MergeCurvelist } from "../../Common/CurveUtils"; import { LogEnable } from "../../Common/Log"; import { Singleton } from "../../Common/Singleton"; import { ExtrudeHole } from "../../DatabaseServices/3DSolid/ExtrudeHole"; @@ -21,6 +21,7 @@ import { BoolOpeartionType, isTargetCurInOrOnSourceCur } from "../BoolOperateUti import { GetSealedBoardContour } from "../CalcEdgeSealing"; import { GetCurveToInDir, GetOffsetCurves, OptimizeToolPath } from "./OptimizeToolPath"; import { userConfig } from "../../Editor/UserConfig"; +import { Box3Ext } from "../../Geometry/Box"; /** *计算走刀工具类 @@ -39,6 +40,7 @@ export class FeedingToolPath extends Singleton if (isOut) outline = outline.Clone(); + let dir = GetCurveToInDir(outline); let offsetCus: Curve[] = [outline]; @@ -99,13 +101,16 @@ export class FeedingToolPath extends Singleton isInt = holes.some(h => h.Curve.IntersectWith(c, 0).length > 0 || h.CuInOutline(c)); if (isInt) break; } - c.ColorIndex = outline.ColorIndex; + if (isOut && offsetDist === knifRadius) + c.TempData = { isOut: true }; offsetCus.push(c); } if (isInt) { //洞形状管理器 let holesMg = new ShapeManager(); + if (isOut) + holes = Shape.mergeContours(holes, false); //#I1MUQD 正好擦边的孔不合并 holesMg.AppendShapeList(holes.map(h => new Shape(h))); let shapeMg = new ShapeManager(); let cons = this.GetContours(retCus as Polyline[], offsetCus); @@ -115,7 +120,6 @@ export class FeedingToolPath extends Singleton { if (isOut && tempOffsetCus.length > 1) s.Outline.Curve.TempData = { isOut: true }; - s.Outline.Curve.ColorIndex = outline.ColorIndex; offsetCus.push(...this.HandleShape(s, knifRadius, false)); } break; @@ -147,6 +151,12 @@ export class FeedingToolPath extends Singleton isVail = false; break; } + else if (isTargetCurInOrOnSourceCur(h.Curve, c as Polyline)) + { + offsetCus.push(c); + isVail = false; + break; + } } else if (ho.Area > maxArea) { @@ -158,16 +168,6 @@ export class FeedingToolPath extends Singleton if (isVail) vailHoles.push(h); } - if (isOut) - { - //#I1MUQD 走好擦边的孔不合并 - let oldHoles = vailHoles.map(c => c.Clone()); - let oldArea = vailHoles.reduce((area, c) => area += c.Area, 0); - vailHoles = Shape.mergeContours(vailHoles); - let newArea = vailHoles.reduce((area, c) => area += c.Area, 0); - if (equaln(oldArea, newArea, 0.1)) - vailHoles = oldHoles; - } offsetCus.push(...vailHoles.map(h => h.Curve)); return offsetCus; @@ -181,7 +181,8 @@ export class FeedingToolPath extends Singleton if (isCd && userConfig.chaidanOption.useDefaultRad) modelings.forEach(m => m.knifeRadius = userConfig.chaidanOption.radius); let cus = this.CalcPath(modelings, br); - + //不同走刀路径区分颜色 + cus.forEach((c, i) => c.ColorIndex = (i + 1 === 8 || i + 1 === 18 || i + 1 === 19) ? i + 2 : i + 1); let outline = br.ContourCurve as Polyline; let dir = Math.sign(outline.Area2); let sideOutlines: Polyline[] = []; @@ -212,7 +213,7 @@ export class FeedingToolPath extends Singleton { let outline = shape.Outline.Curve.Clone(); outline.Position = outline.Position.setZ(0); - outline.ColorIndex++; + outline.ColorIndex = 8; cus.push(outline); if (thickness < br.Thickness) { @@ -220,7 +221,7 @@ export class FeedingToolPath extends Singleton { let c = h.Curve.Clone(); c.Position = c.Position.setZ(0); - c.ColorIndex += 1; + c.ColorIndex = 8; return c; })); } @@ -230,7 +231,6 @@ export class FeedingToolPath extends Singleton } /** * 计算走刀路径 - * TODO:圆孔半径===刀半径时推送ys 显示点 */ CalcPath(modelings: IModeling[], br: Board): Curve[] { @@ -247,7 +247,8 @@ export class FeedingToolPath extends Singleton let cus: Curve[] = []; let { shape, thickness, knifeRadius, addLen, addWidth, addDepth } = m; if (!knifeRadius) knifeRadius = 3; - thickness += addDepth; + if (addDepth) + thickness += addDepth; shape = shape.Clone(); shape.Z0(); this.GrooveAddSize(shape, addLen, addWidth); @@ -263,8 +264,6 @@ export class FeedingToolPath extends Singleton paths = outline.GetOffsetCurves(dir * knifeRadius); else paths = outline.GetFeedingToolPath(dir * knifeRadius); - paths.forEach(p => p.ColorIndex = outline.ColorIndex); - outline.ColorIndex++; cus.push(...paths); } else @@ -297,7 +296,6 @@ export class FeedingToolPath extends Singleton box.min.add(new Vector3(-addWidth / 2, -addLen / 2)); } let pl = new Polyline().RectangleFrom2Pt(box.min, box.max).ApplyMatrix(curveData.OCS); - pl.ColorIndex = shape.Outline.Curve.ColorIndex; shape.Outline = Contour.CreateContour(pl); } } @@ -347,12 +345,31 @@ export class FeedingToolPath extends Singleton let modelings = br.BoardModeling; for (let i = 0; i < modelings.length; i++) { + if (userConfig.chaidanOption.useDefaultRad) + modelings[i].knifeRadius = userConfig.chaidanOption.radius; let cus = this.GetModelFeedPath(br, modelings[i]); if (cus.length === 0) errorIndexs.push(i); } return errorIndexs; } + CheckCustomHole(br: Board) + { + let { modeling, sideModeling } = GetModelingFromCustomDrill(br); + + let errHoles: ExtrudeHole[] = []; + + for (let m of [...modeling, ...sideModeling]) + { + if (userConfig.chaidanOption.useDefaultRad) + m.knifeRadius = userConfig.chaidanOption.radius; + let cus = this.GetModelFeedPath(br, m); + if (cus.length === 0) + errHoles.push(m.originEn); + } + + return errHoles; + } HandleThoughGroove(br: Board, shape: Shape, knifeRadius: number) { let brCon = br.ContourCurve; @@ -360,6 +377,7 @@ export class FeedingToolPath extends Singleton if (outline instanceof Circle) return; let cus = outline.Explode(); + MergeCurvelist(cus); let hasChange = false; for (let i = 0; i < cus.length; i++) { @@ -373,19 +391,34 @@ export class FeedingToolPath extends Singleton let cs = c.GetOffsetCurves(knifeRadius); cus[i] = cs[0]; let fline = cus[FixIndex(i - 1, cus.length)]; + + let isAddLine = false; + if (fline instanceof Line) { - let intPts = fline.IntersectWith(cs[0], 3); + let intPts = fline.IntersectWith2(cs[0], 3); if (intPts.length === 0) { console.error("未知错误情况"); return; } - fline.EndPoint = intPts[0]; - cs[0].StartPoint = intPts[0]; + if (intPts[0].thisParam >= 0 && intPts[0].argParam <= 1) + { + fline.EndPoint = intPts[0].pt; + cs[0].StartPoint = intPts[0].pt; + } + else + { + isAddLine = true; + } } else + { + isAddLine = true; + } + + if (isAddLine) { let newLine = new Line(fline.EndPoint, cs[0].StartPoint); if (i === 0) @@ -401,9 +434,11 @@ export class FeedingToolPath extends Singleton let backLine = cus[FixIndex(i + 1, cus.length)]; + isAddLine = false; + if (backLine instanceof Line) { - let intPts = backLine.IntersectWith(cs[0], 3); + let intPts = backLine.IntersectWith2(cs[0], 3); if (intPts.length === 0) { if (LogEnable.Display) @@ -411,10 +446,21 @@ export class FeedingToolPath extends Singleton return; } - backLine.StartPoint = intPts[0]; - cs[0].EndPoint = intPts[0]; + if (intPts[0].thisParam <= 1 && intPts[0].argParam >= 0) + { + backLine.StartPoint = intPts[0].pt; + cs[0].EndPoint = intPts[0].pt; + } + else + { + isAddLine = true; + } } else + { + isAddLine = true; + } + if (isAddLine) { let newLine = new Line(cs[0].EndPoint, backLine.StartPoint); if (i + 1 === cus.length) @@ -445,10 +491,13 @@ export function GetModelingFromCustomDrill(br: Board) let normal = br.Normal; let outline = GetSealedBoardContour(br, true) as Polyline; - let modeling: IModeling[] = []; - let sideModeling: IModeling[] = []; + let modeling: (IModeling & { originEn: ExtrudeHole; })[] = []; + let sideModeling: (IModeling & { originEn: ExtrudeHole; })[] = []; const holes: ExtrudeHole[] = []; + let bbox = br.BoundingBoxInOCS; + + let holeBoxMap = new WeakMap(); for (let [, idss] of br.DrillList) { @@ -459,7 +508,13 @@ export function GetModelingFromCustomDrill(br: Board) if (id?.Object && !id.Object.IsErase && id.Object instanceof ExtrudeHole && id.Object.isHole) { if (!(id.Object.ContourCurve instanceof Circle)) - holes.push(id.Object); + { + let en = id.Object as ExtrudeHole; + let enBox = en.GetBoundingBoxInMtx(br.OCSInv); + holeBoxMap.set(en, enBox); + if (enBox.clone().intersect(bbox).isSolid(0.1)) + holes.push(id.Object); + } } else break; } @@ -469,7 +524,7 @@ export function GetModelingFromCustomDrill(br: Board) for (let en of holes) { - let box = en.BoundingBox.applyMatrix4(br.OCSInv); + let box = holeBoxMap.get(en); let max = box.max; let min = box.min; let dir: FaceDirection; @@ -493,7 +548,7 @@ export function GetModelingFromCustomDrill(br: Board) thickness = max.z; } else continue; - if (thickness > +1e-6) + if (thickness > +1e-6 && isTargetCurInOrOnSourceCur(outline, shape.Outline.Curve.Clone().Z0())) { modeling.push({ shape, @@ -501,6 +556,7 @@ export function GetModelingFromCustomDrill(br: Board) dir, knifeRadius: en.KnifeRadius, addLen: 0, + originEn: en, }); } } @@ -524,13 +580,13 @@ export function GetModelingFromCustomDrill(br: Board) let cu = outline.GetCurveAtIndex(index); shape.ApplyMatrix(new Matrix4().getInverse(GetSideFaceMtx(cu))); - sideModeling.push({ shape, thickness, dir: index, knifeRadius: en.KnifeRadius, - addLen: 0 + addLen: 0, + originEn: en, }); } } diff --git a/src/GraphicsSystem/ToolPath/OptimizeToolPath.ts b/src/GraphicsSystem/ToolPath/OptimizeToolPath.ts index 2c3f1dc00..a89c0ceb8 100644 --- a/src/GraphicsSystem/ToolPath/OptimizeToolPath.ts +++ b/src/GraphicsSystem/ToolPath/OptimizeToolPath.ts @@ -32,13 +32,25 @@ export function OptimizeToolPath(offsetCus: Curve[], originShape: Shape, rad: nu if (cu instanceof Polyline) { //轮廓朝下的逆时针轮廓需要翻转 - if (cu.IsClose && cu.Normal.z * cu.Area2 < 0) - cu.Reverse(); + //如果走刀不止一条,第一刀为顺时针,其余为逆时针 + if (cu.IsClose) + { + if (offsetCus.length === 1) + { + if (cu.Normal.z * cu.Area2 < 0) + cu.Reverse(); + } + else + if ((cu.Normal.z * cu.Area2 < 0) === (cu !== offsetCus[0])) + cu.Reverse(); + } plList.push(cu); } else if (cu instanceof Circle) { let c = ConverCircleToPolyline(cu); + if (offsetCus.length > 1 && cu === offsetCus[0]) + c.Reverse(); c.ColorIndex = cu.ColorIndex; plList.push(c); } diff --git a/src/Production/Product.ts b/src/Production/Product.ts index 5d7f57d73..2e2b13eb6 100644 --- a/src/Production/Product.ts +++ b/src/Production/Product.ts @@ -412,7 +412,7 @@ export namespace Production else { AppToaster.show({ - message: "板件有造型无法加工,请运行造型检测命令确认", + message: "板件有造型或者自定义排钻无法加工,请运行造型检测命令确认", timeout: 5000, intent: Intent.DANGER, }, "造型加工错误"); diff --git a/src/UI/Components/Board/BoardConfigModal.tsx b/src/UI/Components/Board/BoardConfigModal.tsx index 200d1db19..0ca464ffa 100644 --- a/src/UI/Components/Board/BoardConfigModal.tsx +++ b/src/UI/Components/Board/BoardConfigModal.tsx @@ -293,7 +293,7 @@ export class BoardConfigModal extends React.Component{ for (let c of g) { let cd = rightStore.modelingStore.modelingItems[c.ColorIndex - 1]; - if (cd.height <= 0) + if (!cd || cd.height <= 0) break; if (selectBox.CheckSelectTraverse(c.GetDrawObjectFromRenderType()))