From 815d9cd777e50ac1b95744632504706c8616e46a Mon Sep 17 00:00:00 2001 From: ZoeLeeFZ Date: Thu, 13 Feb 2020 19:28:49 +0800 Subject: [PATCH] =?UTF-8?q?!734=20=E4=BC=98=E5=8C=96=E6=9D=BF=E4=BB=B6?= =?UTF-8?q?=E5=88=87=E5=89=B2=E6=9D=BF=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __test__/Booloperate/BoardCutting.test.ts | 99 ++++++++++ .../__snapshots__/BoardCutting.test.ts.snap | 68 +++++++ src/Add-on/testEntity/TestCurve.ts | 15 +- src/DatabaseServices/Entity/Extrude.ts | 173 ++++++++++++++---- 4 files changed, 314 insertions(+), 41 deletions(-) diff --git a/__test__/Booloperate/BoardCutting.test.ts b/__test__/Booloperate/BoardCutting.test.ts index 0e27bf62e..da780f64c 100644 --- a/__test__/Booloperate/BoardCutting.test.ts +++ b/__test__/Booloperate/BoardCutting.test.ts @@ -51,3 +51,102 @@ test('斜切割', () => } } }); + +test("板件切割测试2", () => +{ + let d = + { "file": [2, "Board", 7, 2, 101, false, 1, 11, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 58.11138014527837, -95.6416464891041, 0, 1], 100, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 58.11138014527837, -95.6416464891041, 0, 1], 2, 2000, 600, 18, false, "Polyline", 7, 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, -4826.750873683377, -162.89849415409662, 174.3341404358351, 1], 2, 8, [77.4818401937041, 2000], 0, [0, 2000], 0, [0, 0], 0, [600, 0], 0, [600, 2000], 0, [479.4188861985467, 2000], 0, [479.4188861985467, 518.1598062953994], 0, [77.4818401937041, 518.1598062953994], 0, true, 2, 2, 1043.0992736077485, 77.4818401937041, 5, true, "Polyline", 7, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -742.8571428571431, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -200.48426150121168, 0, 0, 1], 2, 4, [0, 1785.9564164648916], 0, [0, 742.8571428571431], 0, [77.4818401937041, 742.8571428571433], 0, [77.4818401937041, 1785.9564164648914], 0, true, 0, 3, 0, 0, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 58.11138014527837, -95.64164648910412, 742.8571428571431, 1], 2, 892.2196473551638, 120.58111380145328, 5, true, "Polyline", 7, 2, 0, false, 0, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -479.4188861985467, -851.4740554156175, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -601.4325065106937, -851.4740554156172, -13, 1], 2, 4, [600, 851.4740554156175], 0, [600, 1743.6937027707813], 0, [479.4188861985467, 1743.6937027707806], 0, [479.4188861985467, 851.4740554156178], 0, true, 0, 3, 0, 0, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 71.11138014527836, 383.7772397094426, 851.4740554156175, 1], 3, 0, 0, 0, 6, 1, "左侧板", "主卧", "下柜", "", "", "", 0, 0, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 8, "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, "Board", 7, 2, 104, false, 1, 2, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 976.5468710543694, -95.6416464891041, 991, 1], 103, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 976.5468710543694, -95.6416464891041, 991, 1], 2, 1164, 600, 18, true, "Polyline", 7, 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], 2, 4, [0, 0], 0, [600, 0], 0, [600, 1164], 0, [0, 1164], 0, true, 0, 3, 0, 0, 0, 6, 0, "层板", "主卧", "下柜", "", "", "", 0, 1, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 4, "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0], "basePt": { "x": -187.45312894563062, "y": -95.6416464891041, "z": 0 } }; + { + let [br0, br1] = LoadBoardsFromFileData(d) as Board[]; + let splitBrs = CuttingBoard(br0, [br1]); + + splitBrs.push(br0); + for (let b of splitBrs) + { + expect(b.ContourCurve.Area).toMatchNumberSnapshot(); + } + } + { + let [br1, br0] = LoadBoardsFromFileData(d) as Board[]; + let splitBrs = CuttingBoard(br0, [br1]); + splitBrs.push(br0); + for (let b of splitBrs) + { + expect(b.ContourCurve.Area).toMatchNumberSnapshot(); + } + } +}); +test("板件切割测试3", () => +{ + let d = + { "file": [2, "Board", 7, 2, 117, false, 1, 11, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -187.63269733656165, 859.2801162227601, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -187.63269733656165, 859.2801162227601, 0, 1], 2, 2000, 600, 18, false, "Polyline", 7, 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, -6845.879202981199, -24.883966309060042, 232.44552058111347, 1], 2, 8, [77.4818401937041, 2000], 0, [0, 2000], 0, [0, 0], 0, [600, 0], 0, [600, 2000], 0, [479.4188861985467, 2000], 0, [479.4188861985467, 518.1598062953994], 0, [77.4818401937041, 518.1598062953994], 0, true, 3, 2, 753.1234866828088, 59.27360774818362, 15, true, "Polyline", 7, 2, 0, false, 0, 3, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -2432.929782082325, -796.2227602905568, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -509.443099273607, -934.2372881355934, 0, 1], 2, 4, [2432.929782082325, 796.2227602905568], 0, [2492.2033898305085, 796.2227602905568], 0, [2492.2033898305085, 1549.3462469733656], 0, [2432.929782082325, 1549.3462469733656], 0, true, 0, 3, 0, 0, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -187.63269733656165, 1368.7232154963667, 934.2372881355934, 1], 2, 892.2196473551638, 120.58111380145328, 5, true, "Polyline", 7, 2, 0, false, 0, 2, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -479.4188861985467, -851.4740554156175, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1080.8513927092404, -1702.9481108312348, -25.999999999999993, 1], 2, 4, [600, 851.4740554156175], 0, [600, 1743.6937027707813], 0, [479.4188861985467, 1743.6937027707806], 0, [479.4188861985467, 851.4740554156178], 0, true, 0, 3, 0, 0, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -174.6326973365616, 1338.6990024213064, 851.4740554156175, 1], 2, 1043.0992736077485, 77.4818401937041, 5, true, "Polyline", 7, 2, 0, false, 0, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -742.8571428571431, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -200.48426150121168, -742.8571428571431, 0, 1], 2, 4, [0, 1785.9564164648916], 0, [0, 742.8571428571431], 0, [77.4818401937041, 742.8571428571433], 0, [77.4818401937041, 1785.9564164648914], 0, true, 0, 3, 0, 0, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -187.63269733656165, 859.2801162227601, 742.8571428571431, 1], 3, 0, 0, 0, 6, 1, "左侧板", "主卧", "下柜", "", "", "", 0, 0, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 8, "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, "Board", 7, 2, 118, false, 1, 2, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 730.8027935725294, 859.2801162227601, 991, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 730.8027935725294, 859.2801162227601, 991, 1], 2, 1164, 600, 18, true, "Polyline", 7, 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], 2, 4, [0, 0], 0, [600, 0], 0, [600, 1164], 0, [0, 1164], 0, true, 0, 3, 0, 0, 0, 6, 0, "层板", "主卧", "下柜", "", "", "", 0, 1, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 4, "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0], "basePt": { "x": -433.19720642747063, "y": 859.2801162227601, "z": 0 } }; + { + let [br0, br1] = LoadBoardsFromFileData(d) as Board[]; + let splitBrs = CuttingBoard(br0, [br1]); + + splitBrs.push(br0); + for (let b of splitBrs) + { + expect(b.Width).toMatchNumberSnapshot(); + expect(b.Height).toMatchNumberSnapshot(); + expect(b.Thickness).toMatchNumberSnapshot(); + } + } + { + let [br1, br0] = LoadBoardsFromFileData(d) as Board[]; + let splitBrs = CuttingBoard(br0, [br1]); + splitBrs.push(br0); + for (let b of splitBrs) + { + expect(b.Width).toMatchNumberSnapshot(); + expect(b.Height).toMatchNumberSnapshot(); + expect(b.Thickness).toMatchNumberSnapshot(); + } + } +}); + +test("切圆环", () => +{ + let d = + { "file": [4, "Board", 7, 2, 107, false, 1, 7, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 2545.8169491525423, -211.4460048426149, 1345.2784503631965, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2545.8169491525423, -211.4460048426149, 1345.2784503631965, 1], 2, 1977.2745762711866, 1977.2745762711866, 18, false, "Circle", 7, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 988.6372881355933, 988.6372881355933, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 434.9005129888785, 2508.6683465342476, 0, 1], 1, 988.6372881355933, 1, 2, 1393.2550112821252, 1393.2550112821252, 18, false, "Circle", 7, 2, 0, false, 1, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 696.6275056410626, 696.6275056410626, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -292.00978249453067, -292.00978249453067, 0, 1], 1, 696.6275056410626, 0, 3, 0, 0, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 2253.8071666580117, 80.56377765191576, 1345.2784503631965, 1], 3, 0, 0, 0, 6, 0, "", "", "", "", "", "", 0, 0, "3", 2, 0, "1", "1", "1", "1", "", "", "", 1, "3", true, true, 0, 0, 0, 0, 0, "Board", 7, 2, 114, false, 1, 11, 0, [-0.8065356455357975, 0.5911854636915175, 0, 0, 0, 0, 1, 0, 0.5911854636915175, 0.8065356455357975, 0, 0, 1172.829921560505, 1147.9956519058364, 0, 1], 0, 0, true, [0.5911854636915175, 0.8065356455357975, 0, 0, -0.8065356455357975, 0.5911854636915175, 0, 0, 0, 0, 1, 0, 1172.829921560505, 1147.9956519058364, 0, 1], 2, 2000, 600, 18, true, "Polyline", 7, 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], 2, 4, [0, 0], 0, [600, 0], 0, [600, 2000], 0, [0, 2000], 0, true, 0, 3, 0, 0, 0, 6, 1, "左侧板", "主卧", "下柜", "", "", "", 0, 0, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 6, "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, "Board", 7, 2, 115, false, 1, 11, 0, [-0.7071067811865476, -0.7071067811865475, 0, 0, 0, 0, 1, 0, -0.7071067811865475, 0.7071067811865476, 0, 0, 1132.9171192837023, 357.27673712009073, 0, 1], 0, 0, true, [-0.7071067811865475, 0.7071067811865476, 0, 0, -0.7071067811865476, -0.7071067811865475, 0, 0, 0, 0, 1, 0, 1132.9171192837023, 357.27673712009073, 0, 1], 2, 2000, 600, 18, true, "Polyline", 7, 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], 2, 4, [0, 0], 0, [600, 0], 0, [600, 2000], 0, [0, 2000], 0, true, 0, 3, 0, 0, 0, 6, 1, "左侧板", "主卧", "下柜", "", "", "", 0, 0, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 6, "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, "Board", 7, 2, 113, false, 1, 11, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1916.2025276390448, 1180.3425932283467, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1916.2025276390448, 1180.3425932283467, 0, 1], 2, 2000, 600, 18, true, "Polyline", 7, 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], 2, 4, [0, 0], 0, [600, 0], 0, [600, 2000], 0, [0, 2000], 0, true, 0, 3, 0, 0, 0, 6, 1, "左侧板", "主卧", "下柜", "", "", "", 0, 0, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 6, "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0], "basePt": { "x": 568.5423728813557, "y": -211.4460048426149, "z": 0 } }; + { + let [br0, ...brs] = LoadBoardsFromFileData(d) as Board[]; + let splitBrs = CuttingBoard(br0, brs); + + splitBrs.push(br0); + for (let b of splitBrs) + { + expect(b.Width).toMatchNumberSnapshot(); + expect(b.Height).toMatchNumberSnapshot(); + expect(b.Thickness).toMatchNumberSnapshot(); + } + } +}); +test("切割", () => +{ + let d = + { "file": [2, "Board", 7, 2, 100, false, 1, 11, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1624.6499120550416, 1030.3324374148244, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1624.6499120550416, 1030.3324374148244, 0, 1], 2, 2000, 600, 18, true, "Polyline", 7, 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], 2, 4, [0, 0], 0, [600, 0], 0, [600, 2000], 0, [0, 2000], 0, true, 0, 3, 0, 0, 0, 6, 1, "左侧板", "主卧", "下柜", "", "", "", 0, 0, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 4, "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, "Board", 7, 2, 101, false, 1, 2, 0, [0.3355187862897868, 0.9420335153520963, 0, 0, -0.9420335153520963, 0.3355187862897868, 0, 0, 0, 0, 1, 0, 2660.789609274726, 831.017630464863, 991, 1], 0, 0, true, [0.9420335153520963, -0.3355187862897868, 0, 0, 0.3355187862897868, 0.9420335153520963, 0, 0, 0, 0, 1, 0, 2660.789609274726, 831.017630464863, 991, 1], 2, 1164, 600, 18, true, "Polyline", 7, 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], 2, 4, [0, 0], 0, [600, 0], 0, [600, 1164], 0, [0, 1164], 0, true, 0, 3, 0, 0, 0, 6, 0, "层板", "主卧", "下柜", "", "", "", 0, 1, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 4, "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0], "basePt": { "x": 1564.2625974048858, "y": 831.017630464863, "z": 0 } }; + { + let [br0, br1] = LoadBoardsFromFileData(d) as Board[]; + let splitBrs = CuttingBoard(br0, [br1]); + + splitBrs.push(br0); + for (let b of splitBrs) + { + expect(b.Width).toMatchNumberSnapshot(); + expect(b.Height).toMatchNumberSnapshot(); + expect(b.Thickness).toMatchNumberSnapshot(); + } + } + { + let [br1, br0] = LoadBoardsFromFileData(d) as Board[]; + let splitBrs = CuttingBoard(br0, [br1]); + splitBrs.push(br0); + for (let b of splitBrs) + { + expect(b.Width).toMatchNumberSnapshot(); + expect(b.Height).toMatchNumberSnapshot(); + expect(b.Thickness).toMatchNumberSnapshot(); + } + } +}); diff --git a/__test__/Booloperate/__snapshots__/BoardCutting.test.ts.snap b/__test__/Booloperate/__snapshots__/BoardCutting.test.ts.snap index d97ba9764..646dbd25e 100644 --- a/__test__/Booloperate/__snapshots__/BoardCutting.test.ts.snap +++ b/__test__/Booloperate/__snapshots__/BoardCutting.test.ts.snap @@ -1,5 +1,41 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`切割 1`] = `"600.00000"`; + +exports[`切割 2`] = `"2000.00000"`; + +exports[`切割 3`] = `"18.00000"`; + +exports[`切割 4`] = `"179.98192"`; + +exports[`切割 5`] = `"64.10315"`; + +exports[`切割 6`] = `"18.00000"`; + +exports[`切割 7`] = `"600.00000"`; + +exports[`切割 8`] = `"1164.00000"`; + +exports[`切割 9`] = `"18.00000"`; + +exports[`切圆环 1`] = `"1324.87954"`; + +exports[`切圆环 2`] = `"481.37079"`; + +exports[`切圆环 3`] = `"18.00000"`; + +exports[`切圆环 4`] = `"507.77759"`; + +exports[`切圆环 5`] = `"1099.97958"`; + +exports[`切圆环 6`] = `"18.00000"`; + +exports[`切圆环 7`] = `"1902.56149"`; + +exports[`切圆环 8`] = `"1689.88004"`; + +exports[`切圆环 9`] = `"18.00000"`; + exports[`斜切割 1`] = `"600.00000"`; exports[`斜切割 2`] = `"481.36498"`; @@ -47,3 +83,35 @@ exports[`板件与板件切割_分裂成多个 10`] = `"600.00000"`; exports[`板件与板件切割_分裂成多个 11`] = `"746.09080"`; exports[`板件与板件切割_分裂成多个 12`] = `"18.00000"`; + +exports[`板件切割测试2 1`] = `"119495.88378"`; + +exports[`板件切割测试2 2`] = `"76784.50363"`; + +exports[`板件切割测试2 3`] = `"404548.00931"`; + +exports[`板件切割测试2 4`] = `"695825.18160"`; + +exports[`板件切割测试3 1`] = `"120.58111"`; + +exports[`板件切割测试3 2`] = `"991.00000"`; + +exports[`板件切割测试3 3`] = `"18.00000"`; + +exports[`板件切割测试3 4`] = `"77.48184"`; + +exports[`板件切割测试3 5`] = `"991.00000"`; + +exports[`板件切割测试3 6`] = `"18.00000"`; + +exports[`板件切割测试3 7`] = `"600.00000"`; + +exports[`板件切割测试3 8`] = `"991.00000"`; + +exports[`板件切割测试3 9`] = `"18.00000"`; + +exports[`板件切割测试3 10`] = `"600.00000"`; + +exports[`板件切割测试3 11`] = `"1164.00000"`; + +exports[`板件切割测试3 12`] = `"18.00000"`; diff --git a/src/Add-on/testEntity/TestCurve.ts b/src/Add-on/testEntity/TestCurve.ts index 84c2d4f20..0f70d273a 100644 --- a/src/Add-on/testEntity/TestCurve.ts +++ b/src/Add-on/testEntity/TestCurve.ts @@ -13,6 +13,7 @@ import { Line } from "../../DatabaseServices/Entity/Line"; import { Box3Ext } from "../../Geometry/Box"; import { Point } from "../../DatabaseServices/Entity/Point"; import { Entity } from "../../DatabaseServices/Entity/Entity"; +import { BoxSolid } from "../../DatabaseServices/Entity/BoxSolid"; export class TestTargeOnCurve implements Command { @@ -144,14 +145,8 @@ export function testBox(box3: Array, color: number = 2) export function testtBox3(box3: Box3, colorIndex = 1) { let min = box3.min; - let max = box3.max; - let l1 = new Line(min, min.clone().setX(max.x)); - let l2 = new Line(min, min.clone().setY(max.y)); - let l3 = new Line(max, max.clone().setX(min.x)); - let l4 = new Line(max, max.clone().setY(min.y)); - [l1, l2, l3, l4].forEach(l => - { - l.ColorIndex = colorIndex; - app.Database.ModelSpace.Append(l); - }); + let size = box3.getSize(new Vector3); + let box = new BoxSolid(size.x, size.y, size.z); + box.Position = min; + app.Database.ModelSpace.Append(box); } diff --git a/src/DatabaseServices/Entity/Extrude.ts b/src/DatabaseServices/Entity/Extrude.ts index 9771b2c0f..e2f0a2320 100644 --- a/src/DatabaseServices/Entity/Extrude.ts +++ b/src/DatabaseServices/Entity/Extrude.ts @@ -10,11 +10,10 @@ import { CSG2Geometry, Geometry2CSG } from "../../csg/core/Geometry2CSG"; import { ObjectSnapMode } from "../../Editor/ObjectSnapMode"; import { boardUVGenerator } from "../../Geometry/BoardUVGenerator"; import { Box3Ext } from "../../Geometry/Box"; -import { BSPGroupParse } from "../../Geometry/BSPGroupParse"; import { FastWireframe } from "../../Geometry/CreateWireframe"; import { EdgesGeometry } from "../../Geometry/EdgeGeometry"; import { GenerateExtrudeEdgeGeometry } from "../../Geometry/ExtrudeEdgeGeometry"; -import { AsVector3, equaln, equalv2, equalv3, IdentityMtx4, isIntersect, isParallelTo, MoveMatrix, ZeroVec } from "../../Geometry/GeUtils"; +import { AsVector2, AsVector3, equaln, equalv2, equalv3, IdentityMtx4, isIntersect, isParallelTo, isPerpendicularityTo, MoveMatrix, XAxis, YAxis, ZAxis, ZeroVec } from "../../Geometry/GeUtils"; import { OBB } from "../../Geometry/OBB/obb"; import { ScaleUV } from "../../Geometry/UVUtils"; import { RenderType } from "../../GraphicsSystem/RenderType"; @@ -29,6 +28,7 @@ import { DragPointType } from "./DragPointType"; import { Entity } from "./Entity"; import { Polyline } from "./Polyline"; import { Region } from "./Region"; +import { BSPGroupParse } from "../../Geometry/BSPGroupParse"; /** 最大的槽个数,当大于最大个数时,实体不会绘制槽,并且不会校验槽的正确性 */ const MaxGrooveCount = 15; @@ -779,40 +779,85 @@ export class ExtrudeSolid extends Entity if (this.GrooveCheckPosition(target) !== Status.True) return []; - return this.GrooveCheckContour(target); + return [target]; } else { - let yv = target.Normal; - let zv = this.Normal; - let xv = yv.clone().cross(zv); - yv.copy(zv).cross(xv); - let m = new Matrix4().makeBasis(xv, yv, zv).copyPosition(this.OCS); - let mi = new Matrix4().getInverse(m).multiply(this.OCS); - - let interBSP = this.CSG.intersect(target.CSG.transform1(this.OCSInv.multiply(target.OCS))); - let topology = new BSPGroupParse(interBSP); let grooves: ExtrudeSolid[] = []; - for (let pts of topology.Parse()) + let project = ProjectBoard(target, this); + if (!project) { - for (let p of pts) - p.applyMatrix4(mi); - let box = new Box3Ext().setFromPoints(pts); - if (!box.isSolid(0.1)) - continue; - let size = box.getSize(new Vector3()); - - let ext = new ExtrudeSolid(); - ext.groovesAddDepth = target.groovesAddDepth; - ext.groovesAddLength = target.groovesAddLength; - ext.groovesAddWidth = target.groovesAddWidth; - ext.knifeRadius = target.knifeRadius; - ext.ConverToRectSolid(size.x, size.y, size.z); - ext.OCS = m.clone().setPosition(box.min.applyMatrix4(m)); - - grooves.push(ext); + let yv = target.Normal; + let zv = this.Normal; + let xv = yv.clone().cross(zv); + yv.copy(zv).cross(xv); + let m = new Matrix4().makeBasis(xv, yv, zv).copyPosition(this.OCS); + let mi = new Matrix4().getInverse(m).multiply(this.OCS); + + let interBSP = this.CSG.intersect(target.CSG.transform1(this.OCSInv.multiply(target.OCS))); + let topology = new BSPGroupParse(interBSP); + let grooves: ExtrudeSolid[] = []; + for (let pts of topology.Parse()) + { + for (let p of pts) + p.applyMatrix4(mi); + let box = new Box3Ext().setFromPoints(pts); + if (!box.isSolid(0.1)) + continue; + let size = box.getSize(new Vector3()); + + let ext = new ExtrudeSolid(); + ext.groovesAddDepth = target.groovesAddDepth; + ext.groovesAddLength = target.groovesAddLength; + ext.groovesAddWidth = target.groovesAddWidth; + ext.knifeRadius = target.knifeRadius; + ext.ConverToRectSolid(size.x, size.y, size.z); + ext.OCS = m.clone().setPosition(box.min.applyMatrix4(m)); + + grooves.push(ext); + } + return grooves; } + project.ApplyMatrix(target.OCSInv); + project.Z0(); + let c1 = Contour.CreateContour(project); + let c2 = Contour.CreateContour(target.ContourCurve); + //投影轮廓列表 + let contours = c1.IntersectionBoolOperation(c2); + + let xv = this.Normal; + let zv = target.Normal; + let yv = zv.clone().cross(xv); + + //把<投影轮廓>对齐到肉的侧面坐标系上 + let projection2SideMatrix4 = new Matrix4().makeBasis(xv, yv, zv); + for (let c of contours) + { + let g = target.Clone(); + let gs = [g]; + g.ContourCurve = c.Curve; + g.GrooveCheckAll(gs); + for (let g1 of gs) + { + //按g1的位置设置 + projection2SideMatrix4.setPosition(g1.Position); + + //投影到肉的侧面坐标系,求槽在肉里面的长度(x)和厚度(z) + let alm = new Matrix4().getInverse(projection2SideMatrix4).multiply(g1.OCS); + g1.ContourCurve.ApplyMatrix(alm);//破坏它 + let box = g1.ContourCurve.BoundingBox; + let size = box.getSize(new Vector3); + + //构造新槽 + let g2 = new ExtrudeSolid().ConverToRectSolid(size.y, g1.Thickness, size.x); + g2.ApplyMatrix(OverturnMatrix);//翻转到和原先的投影曲线(肉侧面)一样的状态 + g2.ApplyMatrix(MoveMatrix(box.min));//和投影曲线重叠 + g2.ApplyMatrix(projection2SideMatrix4);//按照矩形还原回去 + + grooves.push(g2); + } + } return grooves; } } @@ -1055,12 +1100,42 @@ export class ExtrudeSolid extends Entity //修正凹槽轮廓 let splitGrooves: ExtrudeSolid[] = []; - for (let g of this.grooves) + let thisArea = this.contourCurve.Area; + for (let i = 0; i < this.grooves.length; i++) { + let g = this.grooves[i]; if (equaln(g.thickness, this.thickness)) splitGrooves.push(g); else - splitGrooves.push(...this.GrooveCheckContour(g)); + { + let gs = this.GrooveCheckContour(g); + if (gs.length === 1) + { + let gg = gs[0]; + if (gg.grooves.length === 0 && equaln(gg.contourCurve.Area, thisArea)) + { + //判断正反面 + let p = gg.Position.applyMatrix4(this.OCSInv); + if (equaln(p.z, 0)) + { + this.thickness -= gg.thickness; + let n = this.Normal; + n.multiplyScalar(gg.thickness); + this._Matrix.elements[12] += n.x; + this._Matrix.elements[13] += n.y; + this._Matrix.elements[14] += n.z; + } + else + { + this.thickness -= gg.thickness; + } + this.grooves.splice(i, 1); + this.GrooveCheckAll(splitEntitys); + return; + } + } + splitGrooves.push(...gs); + } } this.grooves = splitGrooves; @@ -1351,3 +1426,39 @@ export function FastMeshGeometry(width: number, height: number, thickness: numbe CADFactory.RegisterObjectAlias(ExtrudeSolid, "ExtureSolid"); + +function ProjectBoard(knifBoard: ExtrudeSolid, projectBoard: ExtrudeSolid) +{ + let n1 = knifBoard.Normal; + let n2 = projectBoard.Normal; + if (!isPerpendicularityTo(n1, n2)) return; + + let p1 = projectBoard.Position; + let p2 = n2.clone().multiplyScalar(projectBoard.Thickness).add(p1); + + let ocsInv = knifBoard.OCSInv; + p1.applyMatrix4(ocsInv).setZ(0); + p2.applyMatrix4(ocsInv).setZ(0); + + let dir = new Vector3().crossVectors(n1, n2).applyMatrix4(ocsInv.clone().setPosition(ZeroVec)); + + let lineLength = knifBoard.Width + knifBoard.Height;//两边之和大于第三边 + let pts = [ + dir.clone().multiplyScalar(lineLength).add(p1), + dir.clone().multiplyScalar(-lineLength).add(p1), + dir.clone().multiplyScalar(-lineLength).add(p2), + dir.clone().multiplyScalar(lineLength).add(p2), + ]; + + let pl = new Polyline(pts.map(p => + { + return { pt: AsVector2(p), bul: 0 }; + })); + pl.CloseMark = true; + + pl.ApplyMatrix(knifBoard.OCS); + return pl; +} + +//用于翻转绘制出来的槽 +const OverturnMatrix = new Matrix4().makeBasis(YAxis, ZAxis, XAxis);