diff --git a/__test__/EdgeSealing/EdgeSealing.test.ts b/__test__/EdgeSealing/EdgeSealing.test.ts index eead1c149..e59ddf806 100644 --- a/__test__/EdgeSealing/EdgeSealing.test.ts +++ b/__test__/EdgeSealing/EdgeSealing.test.ts @@ -1,7 +1,8 @@ import { Board } from "../../src/DatabaseServices/Entity/Board"; import { Curve } from "../../src/DatabaseServices/Entity/Curve"; import { Polyline } from "../../src/DatabaseServices/Entity/Polyline"; -import { CalcEdgeSealing, GetSealedBoardContour, ParagraphCulist } from "../../src/GraphicsSystem/CalcEdgeSealing"; +import { CalcEdgeSealing, GetBoardSealingData, GetSealedBoardContour, ParagraphCulist } from "../../src/GraphicsSystem/CalcEdgeSealing"; +import { ConverToPtsBul } from "../../src/Production/Convert2PtsBul"; import "../Utils/jest.util"; import { LoadBoardsFromFileData } from "../Utils/LoadEntity.util"; @@ -138,7 +139,8 @@ test("封边错误板件", () => }); test("封边错误板件2", () => { - let data = { "file": [1, "Board", 8, 2, 321, false, 1, 3, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 8511.883548299666, -144.54126186296344, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 8536.883548299666, -144.54126186296344, 0, 1], 0, 3, 400.2476503569924, 2300, 25, false, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 406.2643066383516, 310.58952284495217, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, -9115.641761047009, -1933.6524071638414, 0, 1], 0, 2, 16, [-67.06912303135869, 78.84805159804773], 0, [0, 0], 0.2202439982667024, [22.874295099078154, -10.58952284995803], 0, [742.3473665786241, -10.589522844952171], 0.22024399852882928, [765.2216616957576, 5.275069270282984e-9], 0, [832.5014391616369, 79.0957019560442], -0.21993334211278368, [855.3527126344816, 89.6581275100466], 0, [1318.9838435386573, 89.65812751204021], -0.21993334237487636, [1341.8351170292226, 79.09570194591333], 0, [1409.1148944956167, 1.0472831490915269e-9], 0.18676524414106982, [1428.1424129374664, -10.341872493370829], 0, [1893.7356933616484, -10.34187248795979], 0, [1893.7356933616484, -310.58952284495217], 0, [-406.2643066383516, -310.58952284495217], 0, [-406.2643066383516, 89.41047715504783], 0, [-89.92039651338382, 89.41047715504783], -0.21993334237487636, true, 1, 3, 80.00000000199361, 243.63113088517912, 25, false, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 203.6311308697916, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, -10487.258780340819, -2173.90005751884, 0, 1], 0, 2, 4, [-163.63113088158752, 1.9936123862862587e-9], 0, [0, 0], 1.0000000002948966, [7.183189154602587e-9, 80], 0, [-163.63113088158752, 80.00000000199361], 0.9999999997051033, true, 0, 3, 0, 0, 0, 0, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 9883.500567593475, -144.54126186296344, 240.24765035499877, 1], 3, 0, 0, 0, 0, 0, 9, 2, "背板", "小孩房", "小孩房床", "25进口暖白无光麻LZ9202", "多层板", "进口暖白无光麻LZ9202", 1, 1, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 16, "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", false, true, 0, 0, 0, 0, 0, 0, 0, 0, true], "basePt": { "x": 8511.883548299666, "y": -169.54126186296344, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + let data = + { "file": [1, "Board", 8, 2, 321, false, 1, 3, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 8511.883548299666, -144.54126186296344, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 8536.883548299666, -144.54126186296344, 0, 1], 0, 3, 400.2476503569924, 2300, 25, false, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 406.2643066383516, 310.58952284495217, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, -9115.641761047009, -1933.6524071638414, 0, 1], 0, 2, 16, [-67.06912303135869, 78.84805159804773], 0, [0, 0], 0.2202439982667024, [22.874295099078154, -10.58952284995803], 0, [742.3473665786241, -10.589522844952171], 0.22024399852882928, [765.2216616957576, 5.275069270282984e-9], 0, [832.5014391616369, 79.0957019560442], -0.21993334211278368, [855.3527126344816, 89.6581275100466], 0, [1318.9838435386573, 89.65812751204021], -0.21993334237487636, [1341.8351170292226, 79.09570194591333], 0, [1409.1148944956167, 1.0472831490915269e-9], 0.18676524414106982, [1428.1424129374664, -10.341872493370829], 0, [1893.7356933616484, -10.34187248795979], 0, [1893.7356933616484, -310.58952284495217], 0, [-406.2643066383516, -310.58952284495217], 0, [-406.2643066383516, 89.41047715504783], 0, [-89.92039651338382, 89.41047715504783], -0.21993334237487636, true, 1, 3, 80.00000000199361, 243.63113088517912, 25, false, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 203.6311308697916, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, -10487.258780340819, -2173.90005751884, 0, 1], 0, 2, 4, [-163.63113088158752, 1.9936123862862587e-9], 0, [0, 0], 1.0000000002948966, [7.183189154602587e-9, 80], 0, [-163.63113088158752, 80.00000000199361], 0.9999999997051033, true, 0, 3, 0, 0, 0, 0, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 9883.500567593475, -144.54126186296344, 240.24765035499877, 1], 3, 0, 0, 0, 0, 0, 9, 2, "背板", "小孩房", "小孩房床", "25进口暖白无光麻LZ9202", "多层板", "进口暖白无光麻LZ9202", 1, 1, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 16, "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", false, true, 0, 0, 0, 0, 0, 0, 0, 0, true], "basePt": { "x": 8511.883548299666, "y": -169.54126186296344, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; let br = LoadBoardsFromFileData(data)[0]; let con = GetSealedBoardContour(br, false); @@ -148,7 +150,8 @@ test("封边错误板件2", () => }); test("封边错误板件3", () => { - let data = { "file": [1, "Board", 8, 2, 100, false, 1, 3, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 668.6547958775191, 360.34483792621177, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 668.6547958775191, 360.34483792621177, 0, 1], 0, 3, 430.00000000003945, 843.0000701800069, 18, true, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 429.99984841118567, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 6, [843, -429.99984841118567], 0, [843.0000701800067, 0.00015158885375399223], 0, [843.0000701800069, 0.00015158885375399223], 0, [843.0000000000002, 0.00015158881433308125], 0, [0, 0], 0, [0, -429.99984841118567], 0, true, 0, 3, 0, 0, 0, 0, 0, 9, 2, "背板", "", "父母房-衣柜", "兔宝宝洛萨暮影(杉木芯)", "兔宝宝洛萨暮影(杉木芯)", "兔宝宝洛萨暮影(杉木芯)", 0, 1, "三合一", 2, 5, 1, 1, 1, 1, 1, "1", "1", "1", "1", "", "", "", 6, "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", false, true, 0, 0, 0, 0, 0, 0, 0, 0, true], "basePt": { "x": 668.6547958775191, "y": 342.34483792621177, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + let data = + { "file": [1, "Board", 8, 2, 100, false, 1, 3, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 668.6547958775191, 360.34483792621177, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 668.6547958775191, 360.34483792621177, 0, 1], 0, 3, 430.00000000003945, 843.0000701800069, 18, true, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 429.99984841118567, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 6, [843, -429.99984841118567], 0, [843.0000701800067, 0.00015158885375399223], 0, [843.0000701800069, 0.00015158885375399223], 0, [843.0000000000002, 0.00015158881433308125], 0, [0, 0], 0, [0, -429.99984841118567], 0, true, 0, 3, 0, 0, 0, 0, 0, 9, 2, "背板", "", "父母房-衣柜", "兔宝宝洛萨暮影(杉木芯)", "兔宝宝洛萨暮影(杉木芯)", "兔宝宝洛萨暮影(杉木芯)", 0, 1, "三合一", 2, 5, 1, 1, 1, 1, 1, "1", "1", "1", "1", "", "", "", 6, "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", false, true, 0, 0, 0, 0, 0, 0, 0, 0, true], "basePt": { "x": 668.6547958775191, "y": 342.34483792621177, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; let br = LoadBoardsFromFileData(data)[0]; let con = GetSealedBoardContour(br, false); @@ -158,7 +161,8 @@ test("封边错误板件3", () => }); test("封边错误板件4", () => { - let data = { "file": [1, "Board", 8, 2, 104, false, 1, 4, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 1791.2350208071002, 332.28157054709305, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1791.221632944289, 332.28157054709305, -1220.5383064692724, 1], 0, 3, 608.4984929746847, 54, 18, 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, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 5, [0, 0], 0, [53.986612137188786, 0], 0, [54, 0.8772342627713384], 0, [53.99999999999998, 578.4441943321467], 0, [0, 608.4984929746847], 0, true, 0, 3, 0, 0, 0, 0, 0, 9, 2, "左收口条", "主卧", "下柜左收口", "多层板", "多层板", "无语枫木", 0, 0, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 5, "三合一", "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true], "basePt": { "x": 1791.2350208071002, "y": 314.28157054709305, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + let data = + { "file": [1, "Board", 8, 2, 104, false, 1, 4, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 1791.2350208071002, 332.28157054709305, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1791.221632944289, 332.28157054709305, -1220.5383064692724, 1], 0, 3, 608.4984929746847, 54, 18, 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, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 5, [0, 0], 0, [53.986612137188786, 0], 0, [54, 0.8772342627713384], 0, [53.99999999999998, 578.4441943321467], 0, [0, 608.4984929746847], 0, true, 0, 3, 0, 0, 0, 0, 0, 9, 2, "左收口条", "主卧", "下柜左收口", "多层板", "多层板", "无语枫木", 0, 0, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 5, "三合一", "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true], "basePt": { "x": 1791.2350208071002, "y": 314.28157054709305, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; let br = LoadBoardsFromFileData(data)[0]; let con = GetSealedBoardContour(br, false); @@ -185,7 +189,8 @@ test("切割残留一个封边厚度的凸角的板件封边", () => }); test("切割残留2个封边厚度的凸角的板件封边", () => { - let data = { "file": [1, "Board", 8, 2, 194, false, 1, 3, 0, [0, -1.8369701987210297e-16, -1, 0, 0, 1, -1.8369701987210297e-16, 0, 1, 0, 0, 0, -1942.5790708477725, -1015.708335469244, 53.500000000000114, 1], 0, 0, true, [1, 0, 0, 0, 0, -1.8369701987210297e-16, -1, 0, 0, 1, -1.8369701987210297e-16, 0, -1942.5790708477725, -1015.708335469244, 54.000000000000114, 1], 0, 3, 623, 53.5, 18, 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, 0, 1, 0, -1.8369701987210297e-16, 1, 0, 0, -1, -1.8369701987210297e-16, 0, 0, -653.1428571428573, 743.924437164159, 0, 1], 0, 2, 8, [53.5, 605], 0, [53.49999999999999, 18], 0, [1.4999999999996518, 18], 0, [1.499999999999659, 0], 0, [0, 0], 0, [0, 623], 0, [1.5, 623], 0, [1.5, 605], 0, true, 0, 3, 0, 0, 0, 0, 0, 9, 1, "右收口条", "1", "主卧飘窗柜", "", "流金岁月零度实木多层板", "", 0, 0, "不排", 2, 0, "1", "1", "1", "1", "", "", "", 8, "不排", "不排", "不排", "不排", "不排", "不排", "不排", "不排", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true], "basePt": { "x": -1942.5790708477725, "y": -1015.708335469244, "z": 0 }, "ucs": [0, -1.8369701987210297e-16, -1, 0, 0, 1, -1.8369701987210297e-16, 0, 1, 0, 0, 0, 0, 0, 0, 1] }; + let data = + { "file": [1, "Board", 8, 2, 194, false, 1, 3, 0, [0, -1.8369701987210297e-16, -1, 0, 0, 1, -1.8369701987210297e-16, 0, 1, 0, 0, 0, -1942.5790708477725, -1015.708335469244, 53.500000000000114, 1], 0, 0, true, [1, 0, 0, 0, 0, -1.8369701987210297e-16, -1, 0, 0, 1, -1.8369701987210297e-16, 0, -1942.5790708477725, -1015.708335469244, 54.000000000000114, 1], 0, 3, 623, 53.5, 18, 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, 0, 1, 0, -1.8369701987210297e-16, 1, 0, 0, -1, -1.8369701987210297e-16, 0, 0, -653.1428571428573, 743.924437164159, 0, 1], 0, 2, 8, [53.5, 605], 0, [53.49999999999999, 18], 0, [1.4999999999996518, 18], 0, [1.499999999999659, 0], 0, [0, 0], 0, [0, 623], 0, [1.5, 623], 0, [1.5, 605], 0, true, 0, 3, 0, 0, 0, 0, 0, 9, 1, "右收口条", "1", "主卧飘窗柜", "", "流金岁月零度实木多层板", "", 0, 0, "不排", 2, 0, "1", "1", "1", "1", "", "", "", 8, "不排", "不排", "不排", "不排", "不排", "不排", "不排", "不排", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true], "basePt": { "x": -1942.5790708477725, "y": -1015.708335469244, "z": 0 }, "ucs": [0, -1.8369701987210297e-16, -1, 0, 0, 1, -1.8369701987210297e-16, 0, 1, 0, 0, 0, 0, 0, 0, 1] }; let brs = LoadBoardsFromFileData(data); for (let b of brs) @@ -198,7 +203,8 @@ test("切割残留2个封边厚度的凸角的板件封边", () => }); test("切割残留一个小于封边厚度的凸角的板件封边", () => { - let data = { "file": [2, "Board", 8, 2, 194, false, 1, 3, 0, [0, -1.8369701987210297e-16, -1, 0, 0, 1, -1.8369701987210297e-16, 0, 1, 0, 0, 0, -1942.5790708477725, -1015.708335469244, 53.500000000000114, 1], 0, 0, true, [1, 0, 0, 0, 0, -1.8369701987210297e-16, -1, 0, 0, 1, -1.8369701987210297e-16, 0, -1942.5790708477725, -1015.708335469244, 54.000000000000114, 1], 0, 3, 605, 53.5, 18, 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, 0, 1, 0, -1.8369701987210297e-16, 1, 0, 0, -1, -1.8369701987210297e-16, 0, 0, -298.0228087167077, 1161.398383895394, 0, 1], 0, 2, 6, [53.5, 605], 0, [53.49999999999999, 18], 0, [1.4999999999996518, 18], 0, [1.499999999999659, 0], 0, [0, 0], 0, [0, 605], 0, true, 0, 3, 0, 0, 0, 0, 0, 9, 1, "右收口条", "1", "主卧飘窗柜", "", "流金岁月零度实木多层板", "", 0, 0, "不排", 2, 0, "1", "1", "1", "1", "", "", "", 6, "不排", "不排", "不排", "不排", "不排", "不排", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true, "Board", 8, 2, 187, false, 1, 3, 0, [0, -1.8369701987210297e-16, -1, 0, 0, 1, -1.8369701987210297e-16, 0, 1, 0, 0, 0, -2346.852039258465, -1029.4798626194247, 53.50000000000023, 1], 0, 0, true, [1, 0, 0, 0, 0, -1.8369701987210297e-16, -1, 0, 0, 1, -1.8369701987210297e-16, 0, -2346.852039258465, -1029.4798626194247, 54.00000000000023, 1], 0, 3, 605, 53.5, 18, false, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.5, 605, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.5, 1.3642420526593924e-12, 0, 1], 0, 2, 6, [1.999999999999659, -605], 0, [0.5, -605], 0, [0.5, 0], 0, [54, 0], 0, [54, -587], 0, [1.999999999999659, -587], 0, true, 0, 3, 0, 0, 0, 0, 0, 9, 1, "右收口条", "1", "主卧飘窗柜", "", "流金岁月零度实木多层板", "", 0, 0, "不排", 2, 0, "1", "1", "1", "1", "", "", "", 6, "不排", "不排", "不排", "不排", "不排", "不排", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true], "basePt": { "x": -2346.852039258465, "y": -1029.4798626194247, "z": 0 }, "ucs": [0, -1.8369701987210297e-16, -1, 0, 0, 1, -1.8369701987210297e-16, 0, 1, 0, 0, 0, 0, 0, 0, 1] }; + let data = + { "file": [2, "Board", 8, 2, 194, false, 1, 3, 0, [0, -1.8369701987210297e-16, -1, 0, 0, 1, -1.8369701987210297e-16, 0, 1, 0, 0, 0, -1942.5790708477725, -1015.708335469244, 53.500000000000114, 1], 0, 0, true, [1, 0, 0, 0, 0, -1.8369701987210297e-16, -1, 0, 0, 1, -1.8369701987210297e-16, 0, -1942.5790708477725, -1015.708335469244, 54.000000000000114, 1], 0, 3, 605, 53.5, 18, 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, 0, 1, 0, -1.8369701987210297e-16, 1, 0, 0, -1, -1.8369701987210297e-16, 0, 0, -298.0228087167077, 1161.398383895394, 0, 1], 0, 2, 6, [53.5, 605], 0, [53.49999999999999, 18], 0, [1.4999999999996518, 18], 0, [1.499999999999659, 0], 0, [0, 0], 0, [0, 605], 0, true, 0, 3, 0, 0, 0, 0, 0, 9, 1, "右收口条", "1", "主卧飘窗柜", "", "流金岁月零度实木多层板", "", 0, 0, "不排", 2, 0, "1", "1", "1", "1", "", "", "", 6, "不排", "不排", "不排", "不排", "不排", "不排", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true, "Board", 8, 2, 187, false, 1, 3, 0, [0, -1.8369701987210297e-16, -1, 0, 0, 1, -1.8369701987210297e-16, 0, 1, 0, 0, 0, -2346.852039258465, -1029.4798626194247, 53.50000000000023, 1], 0, 0, true, [1, 0, 0, 0, 0, -1.8369701987210297e-16, -1, 0, 0, 1, -1.8369701987210297e-16, 0, -2346.852039258465, -1029.4798626194247, 54.00000000000023, 1], 0, 3, 605, 53.5, 18, false, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.5, 605, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.5, 1.3642420526593924e-12, 0, 1], 0, 2, 6, [1.999999999999659, -605], 0, [0.5, -605], 0, [0.5, 0], 0, [54, 0], 0, [54, -587], 0, [1.999999999999659, -587], 0, true, 0, 3, 0, 0, 0, 0, 0, 9, 1, "右收口条", "1", "主卧飘窗柜", "", "流金岁月零度实木多层板", "", 0, 0, "不排", 2, 0, "1", "1", "1", "1", "", "", "", 6, "不排", "不排", "不排", "不排", "不排", "不排", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true], "basePt": { "x": -2346.852039258465, "y": -1029.4798626194247, "z": 0 }, "ucs": [0, -1.8369701987210297e-16, -1, 0, 0, 1, -1.8369701987210297e-16, 0, 1, 0, 0, 0, 0, 0, 0, 1] }; let brs = LoadBoardsFromFileData(data); for (let b of brs) @@ -211,7 +217,8 @@ test("切割残留一个小于封边厚度的凸角的板件封边", () => }); test("获取封边错误案例", () => { - let data = { "file": [3, "Board", 8, 2, 100, false, 1, 2, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 158.18450775789097, -88.04258177080192, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -20.81549224210903, 150.95741822919808, 0, 1], 0, 3, 426, 520, 18, false, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 426, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 8, [221, -426], 0, [221, -247], 0, [230, -247], 0, [230, -246], 0, [520, -162.60897861073317], 0, [520, 0], 0, [0, 0], 0, [0, -426], 0, true, 0, 3, 0, 0, 0, 0, 0, 9, 0, "底板", "厨房", "地柜3", "暖白", "18多层板", "暖白", 0, 1, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 8, "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true, "Board", 8, 2, 116, false, 1, 2, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -582.4375243070995, -82.23281127955624, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -761.4375243070995, 156.76718872044376, 0, 1], 0, 3, 426, 520, 18, false, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 426, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 8, [221, -426], 0, [221, -247], 0, [230, -247], 0, [230, -246], 0, [520, -246.00000000000003], 0, [520, 0], 0, [0, 0], 0, [0, -426], 0, true, 0, 3, 0, 0, 0, 0, 0, 9, 0, "底板", "厨房", "地柜3", "暖白", "18多层板", "暖白", 0, 1, "三合一", 2, 8, 2, 2, 2, 2, 2, 2, 2, 2, "1", "1", "1", "1", "", "", "", 8, "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true, "Board", 8, 2, 125, false, 1, 2, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -2044.8775109710668, -161.86694795795037, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -2223.877510971067, 77.13305204204963, 0, 1], 0, 3, 426, 520, 18, false, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 426, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -4.547473508864641e-13, 0, 1], 0, 2, 8, [221, -426], 0, [0, -426], 0, [0, 0], 0, [520, 0], 0, [520, -246.00000000000003], 0, [230, -246], 0, [230, -247], 0, [221, -247], 0, true, 0, 3, 0, 0, 0, 0, 0, 9, 0, "底板", "厨房", "地柜3", "暖白", "18多层板", "暖白", 0, 1, "三合一", 2, 8, 1, 1, 1, 1, 1, 1, 1, 1, "1", "1", "1", "1", "", "", "", 8, "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true], "basePt": { "x": -2470.877510971067, "y": -161.86694795795037, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + let data = + { "file": [3, "Board", 8, 2, 100, false, 1, 2, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 158.18450775789097, -88.04258177080192, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -20.81549224210903, 150.95741822919808, 0, 1], 0, 3, 426, 520, 18, false, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 426, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 8, [221, -426], 0, [221, -247], 0, [230, -247], 0, [230, -246], 0, [520, -162.60897861073317], 0, [520, 0], 0, [0, 0], 0, [0, -426], 0, true, 0, 3, 0, 0, 0, 0, 0, 9, 0, "底板", "厨房", "地柜3", "暖白", "18多层板", "暖白", 0, 1, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 8, "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true, "Board", 8, 2, 116, false, 1, 2, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -582.4375243070995, -82.23281127955624, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -761.4375243070995, 156.76718872044376, 0, 1], 0, 3, 426, 520, 18, false, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 426, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 8, [221, -426], 0, [221, -247], 0, [230, -247], 0, [230, -246], 0, [520, -246.00000000000003], 0, [520, 0], 0, [0, 0], 0, [0, -426], 0, true, 0, 3, 0, 0, 0, 0, 0, 9, 0, "底板", "厨房", "地柜3", "暖白", "18多层板", "暖白", 0, 1, "三合一", 2, 8, 2, 2, 2, 2, 2, 2, 2, 2, "1", "1", "1", "1", "", "", "", 8, "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true, "Board", 8, 2, 125, false, 1, 2, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, -2044.8775109710668, -161.86694795795037, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -2223.877510971067, 77.13305204204963, 0, 1], 0, 3, 426, 520, 18, false, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 426, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -4.547473508864641e-13, 0, 1], 0, 2, 8, [221, -426], 0, [0, -426], 0, [0, 0], 0, [520, 0], 0, [520, -246.00000000000003], 0, [230, -246], 0, [230, -247], 0, [221, -247], 0, true, 0, 3, 0, 0, 0, 0, 0, 9, 0, "底板", "厨房", "地柜3", "暖白", "18多层板", "暖白", 0, 1, "三合一", 2, 8, 1, 1, 1, 1, 1, 1, 1, 1, "1", "1", "1", "1", "", "", "", 8, "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true], "basePt": { "x": -2470.877510971067, "y": -161.86694795795037, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; let brs = LoadBoardsFromFileData(data); for (let b of brs) @@ -222,3 +229,42 @@ test("获取封边错误案例", () => expect(con.Length).toMatchNumberSnapshot(); } }); + +test('封边数据个数不匹配', () => +{ + let data = + { "file": [2, "Board", 8, 2, 101, false, 1, 2, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 1692.3844709212972, 43.15983892617464, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1832.3844709212972, 26.159838926174643, 0, 1], 0, 3, 718, 388, 16, false, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 718, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 10, [388, -718], 0, [388, -409], 0, [188, -409], -0.41421356237309503, [138, -359], 0, [138, -359], -0.41421356237309515, [188.00000000000003, -309], 0, [388, -309.0000000000001], 0, [388, 0], 0, [0, 0], 0, [0, -718], 0, true, 0, 3, 0, 0, 0, 0, 0, 10, 0, "层板2", "B20813", "主柜", "萨米色", "多层板", "萨米色", 0, 1, "三合一", 2, 6, 1, 0, 1, 0, 1, 0, "0", "0", "1", "1", "", "", "", 10, "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", true, true, 1, "1", "黄海玉", 0, 0, 0, 0, 0, 0, 0, true, 0, 0, "Board", 8, 2, 102, false, 1, 2, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 762.0444563758392, 43.15983892617464, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 902.0444563758392, 26.159838926174643, 0, 1], 0, 3, 718, 388, 16, false, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 718, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 10, [388, -718], 0, [388, -409], 0, [188, -409], -0.41421356237309503, [138, -359], 0, [138, -359], -0.41421356237309515, [188.00000000000003, -309], 0, [388, -309.0000000000001], 0, [388, 0], 0, [0, 0], 0, [0, -718], 0, true, 0, 3, 0, 0, 0, 0, 0, 10, 0, "层板1", "B20813", "主柜", "萨米色", "多层板", "萨米色", 0, 1, "三合一", 2, 6, 1, 1, 1, 0, 1, 0, "0", "0", "1", "1", "", "", "", 10, "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", true, true, 1, "1", "黄海玉", 0, 0, 0, 0, 0, 0, 0, true, 0, 0], "basePt": { "x": 44.04445637583922, "y": 43.15983892617464, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + + let brs = LoadBoardsFromFileData(data); + + for (let br of brs) + { + let orgContour = GetSealedBoardContour(br, true, true); + let orgPtsBul = ConverToPtsBul(orgContour); + orgPtsBul.pts.pop(); + orgPtsBul.buls.pop(); + + let sealData = GetBoardSealingData(orgContour); + expect(orgPtsBul.pts.length === sealData.length).toBeTruthy(); + } +}); + + +test('封边数据个数不匹配2', () => +{ + let data = + { "file": [1, "Board", 8, 2, 100, false, 1, 8, 0, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 847.9731543624166, 87.24832214765104, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 847.9731543624166, 127.24832214765104, 0, 1], 0, 3, 740, 420, 18, false, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 40, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 40, 0, 0, 1], 0, 2, 6, [-20, 0], 0, [380, 0], 0, [380, 740], 0, [-20, 740], 0.41421356237309503, [-40, 720], 0, [-40, 20.000000000000004], 0.41421356237309503, true, 2, 3, 9, 716, 6, 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, [716, 0], 0, [716, 9], 0, [0, 9], 0, true, 0, 3, 6, 1, 1, 0, 0, [-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 835.9731543624166, 459.24832214765104, 0, 1], 3, 9, 716, 6, 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, [716, 0], 0, [716, 9], 0, [0, 9], 0, true, 0, 3, 6, 1, 1, 0, 0, [-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 835.9731543624166, 489.24832214765104, 0, 1], 3, 0, 0, 0, 0, 0, 10, 0, "顶板", "大厅", "电视柜", "深咖布纹18厚", "多层板", "深咖布纹", 2, 1, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 6, "三合一", "三合一", "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true, 0, 0], "basePt": { "x": 107.97315436241661, "y": 87.24832214765104, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + + let brs = LoadBoardsFromFileData(data); + + for (let br of brs) + { + let orgContour = GetSealedBoardContour(br, true, true); + let orgPtsBul = ConverToPtsBul(orgContour); + orgPtsBul.pts.pop(); + orgPtsBul.buls.pop(); + + let sealData = GetBoardSealingData(orgContour); + expect(orgPtsBul.pts.length === sealData.length).toBeTruthy(); + } +}); diff --git a/src/Add-on/Erp/Models/ArrayHelper.ts b/src/Add-on/Erp/Models/ArrayHelper.ts new file mode 100644 index 000000000..4b98836d6 --- /dev/null +++ b/src/Add-on/Erp/Models/ArrayHelper.ts @@ -0,0 +1,75 @@ + +import { Vec2 } from "three"; +import { IContourData } from "../../../Production/Convert2PtsBul"; +import { IOriginModelingData } from "../../../Production/Product"; +import { BaseModel, CadBlockHoles, CadBlockInfo, CadBlockModel, CadBlockPoint } from "./CadBlockInfo"; +import { CadBlockBasePosition } from "./CadModel"; +export function GetOrgModelingArray(modeling: IOriginModelingData) +{ + if (modeling) + { + return [ + GetContourDataArray(modeling.outline), + GetOrgModelingHolesArray(modeling.holes), + modeling.thickness, + modeling.dir, modeling.knifeRadius, + modeling.addLen, + modeling.addWidth, + modeling.addDepth]; + } else + { + return undefined; + } +} +function GetOrgModelingHolesArray(contours: IContourData[]) +{ + return contours.map(t => GetContourDataArray(t)); +} +function GetContourDataArray(data: IContourData) +{ + return [GetContourPointsArray(data.pts), data.buls]; +} +function GetContourPointsArray(pts: Vec2[]) +{ + return pts.map(t => { return [t.x, t.y]; }); +} +export function GetArray(c: new () => T, arr: T[]) +{ + if (arr == null) return []; + let t = new c(); + return arr.map(p => + { + return t.ToArray.call(p); + }); +} +export function GetPointInfoArray(info: CadBlockInfo): [object, object, object, object, object, object] +{ + let orgPoints = GetArray(CadBlockPoint, info.OrgPointDetail); + if (orgPoints.length > 0) + { + orgPoints[0][5] = 1; + } + return [ + GetArray(CadBlockPoint, info.PointDetail), + GetArray(CadBlockHoles, info.HoleDetail), + GetArray(CadBlockModel, info.ModelDetail), + orgPoints, + GetArray(CadBlockModel, info.SideModelDetail), + GetArray(CadBlockHoles, info.SideHoleDetail)]; +} +export function GetVec2ListArray(pointList: Vec2[]): [number, number][] +{ + if (pointList == null) return []; + return pointList.map(p => + { + return GetVec2Array(p); + }); +} +export function GetVec2Array(point: Vec2): [number, number] +{ + return [point.x, point.y]; +} +export function GetBasePositionArray(basePosition: CadBlockBasePosition): [number, number, number] +{ + return [basePosition.x, basePosition.y, basePosition.z]; +} diff --git a/src/Add-on/Erp/Models/CadBlockInfo.ts b/src/Add-on/Erp/Models/CadBlockInfo.ts index 71918eb25..d29d53aae 100644 --- a/src/Add-on/Erp/Models/CadBlockInfo.ts +++ b/src/Add-on/Erp/Models/CadBlockInfo.ts @@ -1,14 +1,40 @@ -import { IOriginModelingData } from "../../../Production/Product"; +import { IOriginModelingData } from '../../../Production/Product'; +import { GetArray, GetOrgModelingArray } from './ArrayHelper'; -export class CadBlockPoint +export abstract class BaseModel +{ + protected get props() + { + return []; + } + ToArray() + { + let reuslt = []; + for (const key of this.props) + { + reuslt.push(this[key]); + } + return reuslt; + } +} +export class CadBlockPoint extends BaseModel { PointID: number; PointX: number; PointY: number; Curve: number; SealSize: number; + protected get props() + { + return ['PointID', 'PointX', 'PointY', 'Curve', 'SealSize']; + } + ToArray() + { + let result = super.ToArray(); + return result; + } } -export class CadBlockHoles +export class CadBlockHoles extends BaseModel { HoleID: number; HoleType: HoleType; @@ -22,12 +48,16 @@ export class CadBlockHoles PointX2: number; PointY2: number; Angle?: number; + protected get props() + { + return ['HoleID', 'HoleType', 'Face', 'PointX', 'PointY', 'PointZ', 'Radius', 'Depth', 'EndPoint', 'PointX2', 'PointY2', 'Angle']; + } } export enum HoleType { 大孔 = 0, 小孔 = 10, 木削 = 20, 木削大孔 = 21, 层板钉 = 30, 通孔 = 40, 连接杆 = 50, 造型孔 = -10 } export enum FaceType { 正面 = 0, 反面 = 1, 侧面 = 2 } -export class CadBlockModel +export class CadBlockModel extends BaseModel { ModelID: number; LineID: number; @@ -38,8 +68,19 @@ export class CadBlockModel PointList: CadBlockModelPoint[]; OffSetList: ModelOffSetData[]; OriginModeling: IOriginModelingData; + protected get props() + { + return ['ModelID', 'LineID', 'Face', 'KnifeName', 'KnifeRadius', 'Depth']; + } + ToArray() + { + return [this.ModelID, this.LineID, this.Face, this.KnifeName, this.KnifeRadius, this.Depth, + GetArray(CadBlockModelPoint, this.PointList), + GetArray(ModelOffSetData, this.OffSetList), + GetOrgModelingArray(this.OriginModeling)]; + } } -export class ModelOffSetData +export class ModelOffSetData extends BaseModel { Name: string; Face: FaceType; @@ -47,9 +88,13 @@ export class ModelOffSetData Radius: number; Deep: number; Angle: number; + ToArray() + { + return [this.Name, this.Face, this.Value, this.Radius, this.Deep, this.Angle.toString()]; + } } -export class CadBlockModelPoint +export class CadBlockModelPoint extends BaseModel { LineID: number; PointID: number; @@ -58,13 +103,22 @@ export class CadBlockModelPoint Radius: number; Depth: number; Curve: number; + protected get props() + { + return ['LineID', 'PointID', 'PointX', 'PointY', 'Radius', 'Depth', 'Curve']; + } + } -export class BasePosition +export class BasePosition extends BaseModel { BasePoint: string; XVec: string; YVec: string; ZVec: string; + protected get props() + { + return ['BasePoint', 'XVec', 'YVec', 'ZVec']; + } } export class CadBlockInfo { diff --git a/src/Add-on/Erp/Models/CadModel.ts b/src/Add-on/Erp/Models/CadModel.ts index 998df2791..0e86ad055 100644 --- a/src/Add-on/Erp/Models/CadModel.ts +++ b/src/Add-on/Erp/Models/CadModel.ts @@ -1,5 +1,8 @@ import { Vec2 } from "three"; -export class CADDbBoard +import { GetArray, GetBasePositionArray, GetVec2ListArray } from "./ArrayHelper"; +import { BaseModel } from "./CadBlockInfo"; + +export class CADDbBoard extends BaseModel { L: number = 0; W: number = 0; @@ -16,6 +19,11 @@ export class CADDbBoard SubBoardLocal: CADDbBoard[] = null; SubBoardAssoc: CADDbBoard[] = null; Drillings: CadBlockDrillings[] = null; + + ToArray() + { + return [this.L, this.W, this.H, this.CabName, this.BoardName, GetBasePositionArray(this.BasePoint), GetBasePositionArray(this.XVec), GetBasePositionArray(this.YVec), GetBasePositionArray(this.ZVec), this.Grain, GetVec2ListArray(this.Pts), this.Buls, GetArray(CADDbBoard, this.SubBoardLocal), GetArray(CADDbBoard, this.SubBoardAssoc), GetArray(CadBlockDrillings, this.Drillings)]; + } } export class CadBlockBasePosition { @@ -23,11 +31,15 @@ export class CadBlockBasePosition y: number; z: number; } -export class CadBlockDrillings +export class CadBlockDrillings extends BaseModel { x: number; y: number; r: number; h: number; f: number; + protected get props() + { + return ['x', 'y', 'r', 'h', 'f']; + } } diff --git a/src/Add-on/Erp/ParseData.ts b/src/Add-on/Erp/ParseData.ts index d01e1df4c..1ed48a17b 100644 --- a/src/Add-on/Erp/ParseData.ts +++ b/src/Add-on/Erp/ParseData.ts @@ -11,18 +11,20 @@ import { ObjectId } from "../../DatabaseServices/ObjectId"; import { TemplateRecord } from "../../DatabaseServices/Template/TemplateRecord"; import { CoordinateSystem } from "../../Geometry/CoordinateSystem"; import { AsVector2, equalv3, GetBoxArr, ZeroVec } from "../../Geometry/GeUtils"; -import { I2DModeling, I3DContourData, I3DModeling, IContourData, IDrillingOption, IHardwareType, IModelingData, IOriginModelingData, ISealingData, ISpliteHardwareData, ISpliteOrderData, Production } from '../../Production/Product'; +import { IContourData } from "../../Production/Convert2PtsBul"; +import { I2DModeling, I3DContourData, I3DModeling, IDrillingOption, IHardwareType, IModelingData, ISpliteHardwareData, ISpliteOrderData, Production } from '../../Production/Product'; import { EMetalsType } from "../../UI/Components/RightPanel/RightPanelInterface"; -import { BoardOpenDir, FaceDirection, LinesType } from "../../UI/Store/BoardInterface"; +import { BoardOpenDir, FaceDirection, ISealingData, LinesType } from "../../UI/Store/BoardInterface"; // import { DownPanelStore } from "../../UI/Store/DownPanelStore"; import { GetCountOption, ICountType, lookOverBoardInfosTool } from "../LookOverBoardInfos/LookOverBoardInfosTool"; import { HardwareCompositeEntity } from './../../DatabaseServices/Hardware/HardwareCompositeEntity'; import { ProcessingGroupRecord } from './../../DatabaseServices/ProcessingGroup/ProcessingGroupRecord'; import { TemplateLatticeRecord } from './../../DatabaseServices/Template/ProgramTempate/TemplateLatticeRecord'; import { TemplateWineRackRecord } from './../../DatabaseServices/Template/ProgramTempate/TemplateWineRackRecord'; +import { GetArray, GetPointInfoArray } from "./Models/ArrayHelper"; import { CadType, OrderDataBlock, WaveType } from "./Models/CadBlock"; import { BasePosition, CadBlockHoles, CadBlockInfo, CadBlockModel, CadBlockModelPoint, CadBlockPoint, FaceType, HoleType, ModelOffSetData } from "./Models/CadBlockInfo"; -import { CadBlockBasePosition, CadBlockDrillings, CADDbBoard } from "./Models/CadModel"; +import { CADDbBoard } from "./Models/CadModel"; import { OrderDataObject, ProcessGroupObject, ProcessGroupProjObject } from "./Models/CadObject"; import { parseParts } from "./ParseParts"; enum FrontOrSide @@ -161,9 +163,9 @@ export class ErpParseData let PointInfo = this.GetBlockPointInfo(boardData); let modelData = this.GetModelData(entity); // Cad板数据 - let pointInfoArray = this.GetPointInfoArray(PointInfo); - let basepositionArray = this.GetBasePointArray(baseposition); - let cadModelArray = this.GetCadModelArray([modelData]); + let pointInfoArray = GetPointInfoArray(PointInfo); + let basepositionArray = baseposition.ToArray(); + let cadModelArray = GetArray(CADDbBoard, [modelData]); block.CadDataType = CadType.WebCad; let offsetArray = [boardData.offsetTanslation.x, boardData.offsetTanslation.y, boardData.offsetTanslation.z]; block.KaiLiaoWidth = boardData.info.kaiLiaoWidth; @@ -354,10 +356,15 @@ export class ErpParseData { if (points == null || points.pts == null) return []; - if (points.pts.length !== seals.length) - { - console.error("轮廓数据和封边数据无法对应!"); - } + //现在程序认定为不可能不一致 所以移除弹窗 + // if (points.pts.length !== seals.length) + // { + // Toaster({ + // message: "封边数据异常!(封边个数不匹配) 该错误会导致便签显示封边可能错误!", + // timeout: 5000, + // intent: Intent.DANGER, + // }); + // } let pointList: CadBlockPoint[] = []; for (let i = 0; i < points.pts.length; i++) @@ -619,9 +626,10 @@ export class ErpParseData let orgPointDetail: CadBlockPoint[] = []; if (board.info.isRect === false) { - pointDetail = this.GetPointDetail(board.outline, board.sealing); - orgPointDetail = this.GetPointDetail(board.originOutlin, board.sealing); - } else + pointDetail = this.GetPointDetail(board.outline, board.sealing);//TODO: 现在这个不应该在写入封边信息了 + orgPointDetail = this.GetPointDetail(board.originOutlin, board.sealing);//保留这个 + } + else { add = this.GetFaceAdd(board.originOutlin.pts[0]); } @@ -865,134 +873,6 @@ export class ErpParseData } return objectList; } - GetPointsArray(points: CadBlockPoint[]) - { - return points.map(p => - { - return [p.PointID, p.PointX, p.PointY, p.Curve, p.SealSize]; - }); - } - GetHolesArray(holes: CadBlockHoles[]) - { - return holes.map(h => - { - return [h.HoleID, h.HoleType, h.Face, h.PointX, h.PointY, h.PointZ, h.Radius, h.Depth, h.EndPoint, h.PointX2, h.PointY2, h.Angle]; - }); - } - GetModelsArray(models: CadBlockModel[]) - { - return models.map(m => - { - return [m.ModelID, m.LineID, m.Face, m.KnifeName, m.KnifeRadius, m.Depth, - this.GetModelPointsArray(m.PointList), - this.GetModelOffSetsArray(m.OffSetList), - this.GetOrgModelingArray(m.OriginModeling)]; - }); - } - GetOrgModelingArray(modeling: IOriginModelingData) - { - if (modeling) - { - return [ - this.GetContourDataArray(modeling.outline), - this.GetOrgModelingHolesArray(modeling.holes), - modeling.thickness, - modeling.dir, modeling.knifeRadius, - modeling.addLen, - modeling.addWidth, - modeling.addDepth]; - } else - { - return undefined; - } - } - GetOrgModelingHolesArray(contours: IContourData[]) - { - return contours.map(t => this.GetContourDataArray(t)); - } - GetContourDataArray(data: IContourData) - { - return [this.GetContourPointsArray(data.pts), data.buls]; - } - GetContourPointsArray(pts: Vec2[]) - { - return pts.map(t => { return [t.x, t.y]; }); - } - GetModelPointsArray(points: CadBlockModelPoint[]): number[][] - { - if (points == null) return []; - return points.map(p => - { - return [p.LineID, p.PointID, p.PointX, p.PointY, p.Radius, p.Depth, p.Curve]; - }); - } - GetModelOffSetsArray(offsets: ModelOffSetData[]) - { - if (offsets == null) return []; - return offsets.map(p => - { - return [p.Name, p.Face, p.Value, p.Radius, p.Deep, p.Angle.toString()]; - }); - } - GetBasePointArray(info: BasePosition): [string, string, string, string] - { - return [info.BasePoint, info.XVec, info.YVec, info.ZVec]; - } - GetPointInfoArray(info: CadBlockInfo): [object, object, object, object, object, object] - { - return [ - this.GetPointsArray(info.PointDetail), - this.GetHolesArray(info.HoleDetail), - this.GetModelsArray(info.ModelDetail), - this.GetPointsArray(info.OrgPointDetail), - this.GetModelsArray(info.SideModelDetail), - this.GetHolesArray(info.SideHoleDetail)]; - } - GetBasePositionArray(basePosition: CadBlockBasePosition): [number, number, number] - { - return [basePosition.x, basePosition.y, basePosition.z]; - } - GetBasePositionListArray(basePositionList: CadBlockBasePosition[]): [number, number, number][] - { - if (basePositionList == null) return []; - return basePositionList.map(p => - { - return this.GetBasePositionArray(p); - }); - } - GetVec2ListArray(pointList: Vec2[]): [number, number][] - { - if (pointList == null) return []; - return pointList.map(p => - { - return this.GetVec2Array(p); - }); - } - GetVec2Array(point: Vec2): [number, number] - { - return [point.x, point.y]; - } - GetDrillingsArray(drillings: CadBlockDrillings): number[] - { - return [drillings.x, drillings.y, drillings.r, drillings.h, drillings.f]; - } - GetDrillingsListArray(drillingsList: CadBlockDrillings[]): number[][] - { - if (drillingsList == null) return []; - return drillingsList.map(d => - { - return this.GetDrillingsArray(d); - }); - } - GetCadModelArray(CADDbBoardList: CADDbBoard[]) - { - if (CADDbBoardList == null) return []; - return CADDbBoardList.map(b => - { - return [b.L, b.W, b.H, b.CabName, b.BoardName, this.GetBasePositionArray(b.BasePoint), this.GetBasePositionArray(b.XVec), this.GetBasePositionArray(b.YVec), this.GetBasePositionArray(b.ZVec), b.Grain, this.GetVec2ListArray(b.Pts), b.Buls, this.GetCadModelArray(b.SubBoardLocal), this.GetCadModelArray(b.SubBoardAssoc), this.GetDrillingsListArray(b.Drillings)]; - }); - } - groupBy(data: any[], fileds: string[]) { let groupList = {}; diff --git a/src/Add-on/LookOverBoardInfos/LookOverBoardInfosTool.ts b/src/Add-on/LookOverBoardInfos/LookOverBoardInfosTool.ts index a605a6937..478a67741 100644 --- a/src/Add-on/LookOverBoardInfos/LookOverBoardInfosTool.ts +++ b/src/Add-on/LookOverBoardInfos/LookOverBoardInfosTool.ts @@ -12,6 +12,7 @@ import { GroupRecord } from "../../DatabaseServices/GroupTableRecord"; import { HardwareCompositeEntity } from "../../DatabaseServices/Hardware/HardwareCompositeEntity"; import { HardwareTopline } from "../../DatabaseServices/Hardware/HardwareTopline"; import { equaln } from "../../Geometry/GeUtils"; +import { GetBoardSealingData, GetSealedBoardContour } from "../../GraphicsSystem/CalcEdgeSealing"; import { IHardwareType, Production } from "../../Production/Product"; import { HoleInBoard } from "../DrawDrilling/HoleUtils"; @@ -213,7 +214,7 @@ class LookOverBoardInfosTool } //封边 - let sealData = Production.GetBoardSealingData(b); + let sealData = GetBoardSealingData(GetSealedBoardContour(b, true, true)); let color = b.BoardProcessOption[EBoardKeyList.Color]; for (let data of sealData) diff --git a/src/Add-on/TestFb.ts b/src/Add-on/TestFb.ts index f09762d84..35b52eb23 100644 --- a/src/Add-on/TestFb.ts +++ b/src/Add-on/TestFb.ts @@ -1,11 +1,15 @@ import { Vector3 } from "three"; +import { Polyline } from "../api"; import { app } from "../ApplicationServices/Application"; +import { Intent } from "../Common/Toaster"; +import { FixedNotZero } from "../Common/Utils"; import { Board } from "../DatabaseServices/Entity/Board"; import { Curve } from "../DatabaseServices/Entity/Curve"; +import { Text, TextAligen } from "../DatabaseServices/Text/Text"; import { Command } from "../Editor/CommandMachine"; import { PromptStatus } from "../Editor/PromptResult"; -import { GetSealedBoardContour } from "../GraphicsSystem/CalcEdgeSealing"; -import { Production } from "../Production/Product"; +import { GetBoardSealingData, GetSealedBoardContour } from "../GraphicsSystem/CalcEdgeSealing"; +import { AppToaster } from "../UI/Components/Toaster"; export class TestFb implements Command { @@ -23,6 +27,7 @@ export class TestFb implements Command let brs: Board[] = []; for (let e of ens) brs.push(...e.SplitBoards); + let showCus: Curve[] = []; let errBrs: Board[] = []; @@ -33,13 +38,21 @@ export class TestFb implements Command if (pl) { pl.ColorIndex = 1; - showCus.push(Production.GetSpliteOutline(br, true), pl); + + let orgOutline = GetSealedBoardContour(br, true, true); + showCus.push(orgOutline, pl); } else - { errBrs.push(br); - app.Editor.Prompt("警告:该板件无法得到模拟封边结果!"); - } + } + + if (errBrs.length) + { + AppToaster.show({ + message: `${errBrs.length}个板计算封边错误,已经选中错误的板,请检查!`, + timeout: 5000, + intent: Intent.DANGER, + }); } app.Viewer.OutlinePass.selectedObjects = errBrs.map(b => b.DrawObject); @@ -58,14 +71,25 @@ export class TestFb implements Command for (let i = 0; i < showCus.length; i++) { let c = showCus[i]; - if (i % 2 === 0) + if (i % 2 === 0)//未扣封边 { let min = c.BoundingBox.min; vec = ptRes.Point.clone().sub(min).add(new Vector3(moveDist)); c.Position = c.Position.add(vec); moveDist += c.BoundingBox.getSize(new Vector3).x + 20; + + //写字 + let data = GetBoardSealingData(c as Polyline); + for (let i = 0; i < data.length; i++) + { + let p = c.GetPointAtParam(i + 0.5); + let t = new Text(p, FixedNotZero(data[i].size)); + t.Height = 40; + t.TextAligen = TextAligen.Mid; + app.Database.ModelSpace.Append(t); + } } - else + else//扣封边 { c.Position = c.Position.add(vec); } diff --git a/src/Common/CurveUtils.ts b/src/Common/CurveUtils.ts index 0d94fe472..fd8f15d25 100644 --- a/src/Common/CurveUtils.ts +++ b/src/Common/CurveUtils.ts @@ -326,7 +326,7 @@ export function ConverCircleToPolyline(cir: Circle): Polyline let arcs = cir.GetSplitCurves([0, 0.5]); let pl = new Polyline(); - pl.OCS = cir.OCS; + pl.OCS = cir.OCSNoClone; pl.Join(arcs[0]); pl.Join(arcs[1]); return pl; diff --git a/src/DatabaseServices/HistoricManage.ts b/src/DatabaseServices/HistoricManage.ts index 96f204700..5b65cb803 100644 --- a/src/DatabaseServices/HistoricManage.ts +++ b/src/DatabaseServices/HistoricManage.ts @@ -18,7 +18,7 @@ export class HistoricManage extends CADObject curIndex: number = -1; //当前执行位置,也就是当前的状态, undo时,撤销当前状态,redo时,应用下一个状态 lockIndex = -1; //锁定极限撤销索引(将无法在往前撤销) historyRecord: CommandHistoryRecord[] = []; //历史记录 - doing: boolean = false; + doing: boolean = false;//正在执行工作 例如: 文件读取中 撤销中 重做中 Enable: boolean = true; _SignalCommandHistory: HistoricManage; diff --git a/src/GraphicsSystem/CalcEdgeSealing.ts b/src/GraphicsSystem/CalcEdgeSealing.ts index 7f54b660d..69f8fcb7c 100644 --- a/src/GraphicsSystem/CalcEdgeSealing.ts +++ b/src/GraphicsSystem/CalcEdgeSealing.ts @@ -1,3 +1,4 @@ +import { arrayPushArray } from "../Common/ArrayExt"; import { EBoardKeyList } from "../Common/BoardKeyList"; import { safeEval } from "../Common/eval"; import { Intent, Toaster } from "../Common/Toaster"; @@ -11,7 +12,7 @@ import { Polyline } from "../DatabaseServices/Entity/Polyline"; import { CreateContour2 } from "../Geometry/CreateContour2"; import { angle, equaln, equalv3, isParallelTo, SelectNearP, XAxis } from "../Geometry/GeUtils"; import { Production } from "../Production/Product"; -import { IHighSealedItem } from "../UI/Store/BoardInterface"; +import { IHighSealedItem, ISealingData } from "../UI/Store/BoardInterface"; import { IntersectOption } from "./IntersectWith"; /** @@ -129,12 +130,12 @@ export function ParagraphCulist(cus: Curve[]) } /** - *计算封边 + * 计算封边(删除无效线,连接尖角) */ -export function CalcEdgeSealing(cus: Curve[]) +export function CalcEdgeSealing(cus: Curve[], highSeals?: IHighSealedItem[]) { - if (cus.length <= 1) - return; + if (cus.length <= 1) return; + let oldLine: Curve; let firstLine = cus[0].Clone(); let oldLen = cus.length; @@ -150,20 +151,24 @@ export function CalcEdgeSealing(cus: Curve[]) } let dist = frontLine.EndPoint.distanceToSquared(laterLine.StartPoint); - if (dist < LINK_FUZZ ** 2) + if (dist < LINK_FUZZ ** 2)//直连共线(只有共线才有可能起点等于终点) { if (frontLine instanceof Line && laterLine instanceof Line) { - if (frontLine.PtOnCurve(laterLine.EndPoint)) + if (frontLine.PtOnCurve(laterLine.EndPoint))//反向共线 later 在front内 { + //删除线 cus.splice(laterIndex, 1); + highSeals?.splice(laterIndex, 1); if (laterIndex === 0) firstLine = cus[0].Clone(); i -= 2; } - else if (laterLine.PtOnCurve(frontLine.StartPoint)) + else if (laterLine.PtOnCurve(frontLine.StartPoint))//反向共线 front 在 later内 { + //删除线 cus.splice(i, 1); + highSeals?.splice(i, 1); i -= 2; if (i < -1) i = -1; @@ -175,10 +180,7 @@ export function CalcEdgeSealing(cus: Curve[]) let refLine = oldLine ?? frontLine; let refLine2 = i === cus.length - 1 ? firstLine : laterLine; let iPts = refLine.IntersectWith(refLine2, IntersectOption.ExtendBoth); - let tPts = iPts.filter(p => - refLine.PtOnCurve(p) - && refLine2.PtOnCurve(p) - ); + let tPts = iPts.filter(p => refLine.PtOnCurve(p) && refLine2.PtOnCurve(p)); let iPt = SelectNearP(tPts.length > 0 ? tPts : iPts, refLine.EndPoint); if (!iPt) @@ -186,7 +188,9 @@ export function CalcEdgeSealing(cus: Curve[]) //没交点,如果删过线,则尝试继续连接 if (cus.length !== oldLen && cus.length > 2) { + //删除线 cus.splice(i, 1); + highSeals?.splice(i, 1); i -= 2; if (i < -1) i = -1; @@ -200,6 +204,7 @@ export function CalcEdgeSealing(cus: Curve[]) if (par < 1e-6) { cus.splice(i, 1); + highSeals?.splice(i, 1); i -= 2; if (i < -1) i = -1; @@ -216,7 +221,9 @@ export function CalcEdgeSealing(cus: Curve[]) { if (laterIndex === 0) { + //删除线 cus.shift(); + highSeals?.shift(); firstLine = cus[0].Clone(); i -= 2; continue; @@ -326,38 +333,62 @@ export function GetBoardSealingCurves(br: Board, isOffset = false): Curve[] } } + +const SEAL_VALUE_KEY = "__highSeals__"; + + /** * 获取板件轮廓 * 结果轮廓拆单用,统一逆时针数据 * hasSealing 轮廓是否包含封边 * 用户计算拆单侧孔面id - * TODO:如果封边一致,那么应该直接偏移!!! + * + * //返回的曲线中 如果 hasSealing isParseSeal 那么将可以取出封边信息 */ -export function GetSealedBoardContour(br: Board, hasSealing: boolean): Polyline | Circle | undefined +export function GetSealedBoardContour(br: Board, hasSealing: boolean, isParseSeal = false): Polyline | Circle | undefined { let area2 = br.ContourCurve.Area2; if (Math.abs(area2) < 10) return; let offsetCus: Curve[] = []; - let cus = GetBoardSealingCurves(br); + let curves = GetBoardSealingCurves(br); let dir = Math.sign(area2); + let highSealsExpd: ISealingData[];//展开后的封边信息(仅在未扣除封边的分支中计算) if (hasSealing) { - for (let c of cus) + let highSeals: IHighSealedItem[]; + if (isParseSeal) { - if (c instanceof Polyline) - offsetCus.push(...c.Explode()); - else + highSeals = GetBoardHighSeal(br, curves); + highSealsExpd = []; + } + + for (let i = 0; i < curves.length; i++) + { + let curve = curves[i]; + + const PushCurve = (c: Curve) => + { offsetCus.push(c); + highSealsExpd?.push({ size: highSeals[i].size, length: c.Length }); + }; + + if (curve instanceof Polyline) + for (let cu of curve.Explode()) + PushCurve(cu); + else + PushCurve(curve); } } else { - let highSeals = GetBoardHighSeal(br, cus); - if (cus[0] instanceof Circle) - dir = 1; + let highSeals = GetBoardHighSeal(br, curves); + + //圆的dir始终等于1 + // if (cus[0] instanceof Circle) + // dir = 1; //所有的封边都一样时 if (highSeals.every(s => equaln(s.size, highSeals[0].size), 1e-3)) @@ -401,33 +432,51 @@ export function GetSealedBoardContour(br: Board, hasSealing: boolean): Polyline if (retPl) return retPl; } - for (let i = 0; i < cus.length; i++) + for (let i = 0; i < curves.length; i++) { let cs: Curve[]; if (!highSeals[i].size) - cs = [cus[i].Clone()]; + cs = [curves[i].Clone()]; else - cs = cus[i].GetOffsetCurves(-highSeals[i].size * dir); + cs = curves[i].GetOffsetCurves(-highSeals[i].size * dir); for (let c of cs) { if (c instanceof Polyline) - offsetCus.push(...c.Explode()); + arrayPushArray(offsetCus, c.Explode()); else offsetCus.push(c); } } } + if (offsetCus.length === 1 && offsetCus[0] instanceof Circle) - return offsetCus[0] as Circle; + { + let cir = offsetCus[0]; + + if (highSealsExpd) cir[SEAL_VALUE_KEY] = highSealsExpd; - if (!CalcEdgeSealing(offsetCus)) return; + return cir; + } + + if (!CalcEdgeSealing(offsetCus, highSealsExpd)) return; let pl = Polyline.FastCombine(offsetCus, LINK_FUZZ); if (pl && dir < 0) + { pl.Reverse(); + highSealsExpd?.reverse(); + } + + if (highSealsExpd) pl[SEAL_VALUE_KEY] = highSealsExpd; + return pl; } +export function GetBoardSealingData(curve: Polyline | Circle) +{ + return curve[SEAL_VALUE_KEY] as ISealingData[]; +} + export function ParagraphSealinglist(hightSeal: IHighSealedItem[], cus: Curve[]) { diff --git a/src/Production/Convert2PtsBul.ts b/src/Production/Convert2PtsBul.ts new file mode 100644 index 000000000..8ca5a9e8d --- /dev/null +++ b/src/Production/Convert2PtsBul.ts @@ -0,0 +1,64 @@ +import { Vector2, Vector3 } from "three"; +import { ConverCircleToPolyline } from "../Common/CurveUtils"; +import { Vector2ApplyMatrix4 } from "../Common/Matrix4Utils"; +import { Arc } from "../DatabaseServices/Entity/Arc"; +import { Circle } from "../DatabaseServices/Entity/Circle"; +import { Polyline } from "../DatabaseServices/Entity/Polyline"; +import { equaln } from "../Geometry/GeUtils"; + + +/**轮廓(多段线Pts Bul)数据 */ +export interface IContourData +{ + pts: Vector2[]; + buls: number[]; +} + + +//转换成多段线点表(pts bul) +export function ConverToPtsBul(cu: Polyline | Circle, isOutline = true): IContourData +{ + let ptsBuls: IContourData; + if (cu instanceof Circle) + { + let pl = ConverCircleToPolyline(cu); + ptsBuls = pl.PtsBuls; + } + else + { + if (isOutline && cu.IsClose && cu.Normal.z * cu.Area2 < 0) + cu.Reverse(); + ptsBuls = cu.PtsBuls; + } + let ocs = cu.OCSNoClone; + if (!equaln(ocs.elements[0], 1) + || !equaln(ocs.elements[9], 0) + || !equaln(ocs.elements[10], 0) + ) + { + for (let i = 0; i < ptsBuls.pts.length; i++) + { + Vector2ApplyMatrix4(ocs, ptsBuls.pts[i]); + ptsBuls.buls[i] *= cu.Normal.z; + } + } + return ptsBuls; +} + +//转换成多段线点表(pts bul) +export function ConverArcToPtsBul(arc: Arc, hasEnd = false): { pts: Vector3[], buls: number[]; } +{ + let result: { pts: Vector3[], buls: number[]; } = { pts: [], buls: [] }; + let bul = arc.Bul; + + result.pts.push(arc.StartPoint); + result.buls.push(bul); + + if (hasEnd) + { + result.pts.push(arc.EndPoint); + result.buls.push(0); + } + + return result; +} diff --git a/src/Production/Product.ts b/src/Production/Product.ts index 37cfeec97..703f105bf 100644 --- a/src/Production/Product.ts +++ b/src/Production/Product.ts @@ -2,13 +2,11 @@ import { Box3, Matrix4, Vector2, Vector3 } from "three"; import { SCALAR } from "../Add-on/DrawDrilling/HoleUtils"; import { lookOverBoardInfosTool } from "../Add-on/LookOverBoardInfos/LookOverBoardInfosTool"; import { HostApplicationServices } from "../ApplicationServices/HostApplicationServices"; -import { arrayLast } from "../Common/ArrayExt"; import { EBoardKeyList } from "../Common/BoardKeyList"; import { MergeCurvelist } from "../Common/CurveUtils"; import { IsDev } from "../Common/Deving"; import { ParseExpr, safeEval } from "../Common/eval"; import { Log } from "../Common/Log"; -import { Vector2ApplyMatrix4 } from "../Common/Matrix4Utils"; import { SendReport } from "../Common/Report"; import { ShowSelectObjects } from "../Common/ShowSelectObjects"; import { Intent, Toaster } from "../Common/Toaster"; @@ -20,30 +18,23 @@ import { Contour } from "../DatabaseServices/Contour"; import { Arc } from "../DatabaseServices/Entity/Arc"; import { Board, I2DModeingItem, IKnifeInfo, IModeling } from "../DatabaseServices/Entity/Board"; import { Circle } from "../DatabaseServices/Entity/Circle"; -import { Curve } from "../DatabaseServices/Entity/Curve"; import { ExtrudeContourCurve } from "../DatabaseServices/Entity/Extrude"; import { Line } from "../DatabaseServices/Entity/Line"; import { Polyline } from "../DatabaseServices/Entity/Polyline"; import { HardwareCompositeEntity } from "../DatabaseServices/Hardware/HardwareCompositeEntity"; import { HardwareTopline } from "../DatabaseServices/Hardware/HardwareTopline"; import { Shape } from "../DatabaseServices/Shape"; -import { Vec2 } from "../Geometry/CheckIntersect"; import { CanDrawHoleFuzz } from "../Geometry/DrillParse/BoardGetFace"; -import { angleTo, AsVector2, equaln, equalv2, equalv3, IsBetweenA2B, isIntersect2, isParallelTo, MoveMatrix, XAxis } from "../Geometry/GeUtils"; -import { GetBoardHighSeal, GetBoardSealingCurves, GetSealedBoardContour } from "../GraphicsSystem/CalcEdgeSealing"; +import { angleTo, equaln, equalv3, IsBetweenA2B, isIntersect2, isParallelTo, MoveMatrix, XAxis } from "../Geometry/GeUtils"; +import { GetBoardSealingData, GetSealedBoardContour } from "../GraphicsSystem/CalcEdgeSealing"; import { FeedingToolPath, GetModelingFromCustomDrill } from "../GraphicsSystem/ToolPath/FeedingToolPath"; import { EMetalsType, IHardwareOption, IToplineOption } from "../UI/Components/RightPanel/RightPanelInterface"; -import { BoardOpenDir, FaceDirection, IHighSealedItem } from "../UI/Store/BoardInterface"; +import { BoardOpenDir, FaceDirection, ISealingData } from "../UI/Store/BoardInterface"; import { Entity } from './../DatabaseServices/Entity/Entity'; import { ICompHardwareOption } from './../UI/Components/RightPanel/RightPanelInterface'; +import { ConverArcToPtsBul, ConverToPtsBul, IContourData } from "./Convert2PtsBul"; -/**轮廓数据 */ -export interface IContourData -{ - pts: Vec2[]; - buls: number[]; -} export interface I3DContourData { pts: Vector3[]; @@ -51,12 +42,7 @@ export interface I3DContourData } export type IHardwareType = HardwareTopline | HardwareCompositeEntity; -export interface ISealingData extends IHighSealedItem -{ - length: number; - type?: string; - shop?: string; -} + export interface IModelingData { feeding: IContourData[]; @@ -173,8 +159,8 @@ export namespace Production /**获取板件拆单数据 */ export function GetBoardSplitOrderData(br: Board): ISpliteOrderData | undefined { - let sealedContour = GetSealedBoardContour(br, true); - if (!sealedContour || equaln(sealedContour.Area, 0)) + let orgContour = GetSealedBoardContour(br, true, true); + if (!orgContour || equaln(orgContour.Area, 0)) { Toaster({ message: br.Name + " 轮廓错误,可能存在轮廓自交,请检查后重新拆单!(错误的板已经选中,您可以按住鼠标中键查看该板!)(使用FISC命令可以修复自交轮廓!)", @@ -184,9 +170,9 @@ export namespace Production Report([br.__OriginalEnt__ ?? br], br.Name + " 轮廓错误"); return undefined; } - let outline = GetSealedBoardContour(br, false); + let sealedOutline = GetSealedBoardContour(br, false); - if (!outline || equaln(outline.Area, 0)) + if (!sealedOutline || equaln(sealedOutline.Area, 0)) { Toaster({ message: br.Name + "扣除封边轮廓有误,请检查后重新拆单!(错误的板已经选中,您可以按住鼠标中键查看该板!)", @@ -196,17 +182,16 @@ export namespace Production Report([br.__OriginalEnt__ ?? br], br.Name + "扣除封边轮廓有误"); return; } - - let offsetTanslation = outline.BoundingBox.min; - outline.Position = outline.Position.sub(offsetTanslation); - let outlinePtsBul = ConverToPolylineAndSplitArc(outline); + let offsetTanslation = sealedOutline.BoundingBox.min; + sealedOutline.Position = sealedOutline.Position.sub(offsetTanslation); + let sealedOutlinePtsBul = ConverToPtsBul(sealedOutline);//不分裂圆弧转点表 //外轮廓去掉最后的闭合点 - outlinePtsBul.pts.pop(); - outlinePtsBul.buls.pop(); - let size = outline.BoundingBox.getSize(new Vector3); + sealedOutlinePtsBul.pts.pop(); + sealedOutlinePtsBul.buls.pop(); + let size = sealedOutline.BoundingBox.getSize(new Vector3); //不扣除封边的轮廓信息 - let originOutlinePtsBul = ConverToPolylineAndSplitArc(sealedContour); + let originOutlinePtsBul = ConverToPtsBul(orgContour); originOutlinePtsBul.pts.pop(); originOutlinePtsBul.buls.pop(); @@ -214,15 +199,15 @@ export namespace Production let boardContour: IContourData; if (GetSpiteSize(br)) - boardContour = ConverToPolylineAndSplitArc(br.ContourCurve); + boardContour = ConverToPtsBul(br.ContourCurve);//不分裂圆弧转点表 return { info: GetBoardInfo(br, size), - originOutlin: originOutlinePtsBul, - outline: outlinePtsBul, - sealing: GetBoardSealingData(br), + originOutlin: originOutlinePtsBul,//拼错了 未扣封边的点表 + outline: sealedOutlinePtsBul, //扣完封边的点表 + sealing: GetBoardSealingData(orgContour), modeling, - holes: GetBoardHolesData(br, offsetTanslation, sealedContour), + holes: GetBoardHolesData(br, offsetTanslation, orgContour), sideModeling, offsetTanslation, metalsData: GetBoardMetals(br), @@ -259,203 +244,6 @@ export namespace Production }; } - /** - * 转换成多段线并且将圆弧打断(大于1/4的话) - */ - export function ConverToPolylineAndSplitArc(cu: Polyline | Circle, isOutline = true, isSplite = true): IContourData - { - let ptsBuls: { pts: Vector2[]; buls: number[]; }; - if (cu instanceof Circle) - { - let pl = ConverCircleToPolyline(cu); - ptsBuls = pl.PtsBuls; - } - else - { - if (isOutline && cu.IsClose && cu.Normal.z * cu.Area2 < 0) - cu.Reverse(); - if (isSplite) - ptsBuls = SplitePolylineAtArc(cu); - else - ptsBuls = cu.PtsBuls; - } - let ocs = cu.OCS; - if (!equaln(ocs.elements[0], 1) - || !equaln(ocs.elements[9], 0) - || !equaln(ocs.elements[10], 0) - ) - { - for (let i = 0; i < ptsBuls.pts.length; i++) - { - Vector2ApplyMatrix4(ocs, ptsBuls.pts[i]); - ptsBuls.buls[i] *= cu.Normal.z; - } - } - return ptsBuls; - } - - export function ConverCircleToPolyline(cir: Circle): Polyline - { - let arcs = cir.GetSplitCurves([0, 0.25, 0.5, 0.75]); - let pl = new Polyline(); - pl.OCS = cir.OCS; - for (let arc of arcs) - pl.Join(arc); - return pl; - } - - const SPLITBUL = Math.tan(Math.PI / 8); - function GetSpliteCount(allAngle: number) - { - return Math.ceil(Math.abs(allAngle) / Math.PI * 2); - } - - /** 打断多段线超过1/4圆的圆弧*/ - export function SplitePolylineAtArc(cu: Polyline, isSplite = true): { pts: Vector2[], buls: number[]; } - { - let ptsBuls = cu.PtsBuls; - let ocsInv = cu.OCSInv; - - let result: { pts: Vector2[], buls: number[]; } = { pts: [], buls: [] }; - - if (ptsBuls.pts.length === 0) - return result; - - for (let i = 0; i < ptsBuls.buls.length - 1; i++) - { - let bul = ptsBuls.buls[i]; - if (Math.abs(bul) > SPLITBUL + 1e-8 && isSplite) - { - let allAngle = Math.atan(bul) * 4; - let splitCount = GetSpliteCount(allAngle); - let arc = cu.GetCurveAtIndex(i) as Arc; - let paramDiv = 1 / splitCount; - let newBul = Math.tan((allAngle / splitCount) / 4); - for (let i = 0; i < splitCount; i++) - { - let param = i * paramDiv; - let p = arc.GetPointAtParam(param).applyMatrix4(ocsInv); - let p2 = AsVector2(p); - //暂时不处理0长度段 - if (true || result.pts.length === 0 || !equalv2(p2, arrayLast(result.pts), 1e-2)) - { - result.pts.push(p2); - result.buls.push(newBul); - } - } - } - else - { - //暂时不处理0长度段 - if (true || result.pts.length === 0 || !equalv2(ptsBuls.pts[i], arrayLast(result.pts), 1e-2)) - { - result.pts.push(ptsBuls.pts[i]); - result.buls.push(ptsBuls.buls[i]); - } - } - } - - result.pts.push(arrayLast(ptsBuls.pts)); - result.buls.push(arrayLast(ptsBuls.buls)); - - //测试是否存在无效的边(0长度边) - // for (let i = 1; i < result.pts.length; i++) - // { - // if (equalv2(result.pts[i], result.pts[i - 1], 0.01)) - // alert("存在无效的边"); - // } - - return result; - } - export function SplitetArc(arc: Arc, hasEnd = false): { pts: Vector3[], buls: number[]; } - { - let result: { pts: Vector3[], buls: number[]; } = { pts: [], buls: [] }; - let bul = arc.Bul; - - if (Math.abs(bul) > SPLITBUL + 1e-8) - { - let allAngle = Math.atan(bul) * 4; - let splitCount = GetSpliteCount(allAngle); - - let paramDiv = 1 / splitCount; - let newBul = Math.tan((allAngle / splitCount) / 4); - for (let i = 0; i < splitCount; i++) - { - let param = i * paramDiv; - let p = arc.GetPointAtParam(param); - - result.pts.push(p); - result.buls.push(newBul); - } - } - else - { - result.pts.push(arc.StartPoint); - result.buls.push(bul); - } - - if (hasEnd) - { - result.pts.push(arc.EndPoint); - result.buls.push(0); - } - - return result; - } - - /** - * 获取封边数据 - * 封边数据未统一逆时针顺序,用于拆单 - * */ - export function GetBoardSealingData(br: Board): ISealingData[] - { - let sealCus = GetBoardSealingCurves(br); - let highSeal = GetBoardHighSeal(br, sealCus); - - let sealData: ISealingData[] = []; - - for (let i = 0; i < sealCus.length; i++) - { - let sealCu = sealCus[i]; - let data = highSeal[i]; - let cus: Curve[] = []; - if (sealCu instanceof Polyline) - cus.push(...sealCu.Explode()); - else - cus.push(sealCu); - - for (let cu of cus) - { - if (cu instanceof Line) - { - sealData.push(Object.assign({}, data, { length: cu.Length })); - } - else if (cu instanceof Arc) - { - let splitCount = GetSpliteCount(cu.AllAngle); - let len = 2 * Math.PI * cu.Radius / 4; - for (let i = 0; i < splitCount; i++) - { - let arcLen = i !== splitCount - 1 ? len : cu.Length - (splitCount - 1) * len; - if (!equaln(arcLen, 0)) - sealData.push(Object.assign({}, data, { length: arcLen })); - } - } - else if (cu instanceof Circle) - { - let length = 2 * Math.PI * cu.Radius / 4; - sealData.push(...Array.from({ length: 4 }, () => - { - return { ...data, length }; - })); - } - } - } - if (br.ContourCurve instanceof Polyline && br.ContourCurve.Area2 < 0) - sealData.reverse(); - return sealData; - } - export function GetMetalTotalEntitys(md: HardwareCompositeEntity, isHole = false, filter?: (e: Entity) => boolean) { let holes: Entity[] = []; @@ -478,6 +266,7 @@ export namespace Production } return holes; } + export function GetOriginBoardModelingData(br: Board) { const getModelings = (ms: IModeling[]): IOriginModelingData[] => @@ -493,8 +282,8 @@ export namespace Production m.knifeRadius = HostApplicationServices.chaidanOption.radius; data.push({ - outline: ConverToPolylineAndSplitArc(cu.Clone(), false, false), - holes: m.shape.Holes.map(h => ConverToPolylineAndSplitArc(h.Curve.Clone(), false, false)), + outline: ConverToPtsBul(cu.Clone(), false), + holes: m.shape.Holes.map(h => ConverToPtsBul(h.Curve.Clone(), false)), thickness: m.thickness + (m.addDepth ?? 0), dir: m.dir, knifeRadius: m.knifeRadius, @@ -531,7 +320,7 @@ export namespace Production if (!isSide) paths.forEach(path => path.ApplyMatrix(tMtx)); - let feeding = paths.map((c: ExtrudeContourCurve) => ConverToPolylineAndSplitArc(c, false)); + let feeding = paths.map((c: ExtrudeContourCurve) => ConverToPtsBul(c, false)); if (feeding.length > 0) data.push({ feeding, @@ -539,8 +328,8 @@ export namespace Production dir: m.dir, knifeRadius: m.knifeRadius, origin: { - outline: ConverToPolylineAndSplitArc(cu.Clone(), false, false), - holes: m.shape.Holes.map(h => ConverToPolylineAndSplitArc(h.Curve.Clone(), false, false)), + outline: ConverToPtsBul(cu.Clone(), false), + holes: m.shape.Holes.map(h => ConverToPtsBul(h.Curve.Clone(), false)), addLen: m.addLen, addWidth: m.addWidth, addDepth: m.addDepth, @@ -1115,13 +904,14 @@ export namespace Production pl.CloseMark = true; return pl; } + export function Report(ens: Entity[], msg: string) { if (IsDev()) return; ShowSelectObjects(ens); SendReport(msg); - } + export function Get2DModeing(br: Board, offset: Vector3) { let res: I2DModeling[] = []; @@ -1130,13 +920,14 @@ export namespace Production { let path = m.path.Clone().ApplyMatrix(tmtx) as Polyline; res.push({ - path: ConverToPolylineAndSplitArc(path), + path: ConverToPtsBul(path), dir: m.dir, items: m.items.map(item => ({ ...item })) }); } return res; } + export function Get3DModeing(br: Board, offset: Vector3) { let res: I3DModeling[] = []; @@ -1162,7 +953,7 @@ export namespace Production else { let arc = new Arc().ParseFromBul(d1.pt.clone().sub(offset), d2.pt.clone().sub(offset), d1.bul); - let r = SplitetArc(arc, false); + let r = ConverArcToPtsBul(arc, false); r.pts.forEach(p => InvertPosition(p, br.Thickness)); d.path.pts.push(...r.pts); d.path.buls.push(...r.buls); @@ -1180,6 +971,7 @@ export namespace Production } return res; } + export function GetChaiDanFeedingPath(data: IChaiDanFeedingData) { const { thickness, boardContour, dir, addLen, addWidth, addDepth, knifeRadius, brThickness } = data; @@ -1195,6 +987,6 @@ export namespace Production dir, knifeRadius, addLen, addWidth, addDepth }); - return paths.map((c: ExtrudeContourCurve) => ConverToPolylineAndSplitArc(c, false)); + return paths.map((c: ExtrudeContourCurve) => ConverToPtsBul(c, false)); } } diff --git a/src/UI/Components/RightPanel/SealingComponent.tsx b/src/UI/Components/RightPanel/SealingComponent.tsx index 09a0d135c..c70ea4b76 100644 --- a/src/UI/Components/RightPanel/SealingComponent.tsx +++ b/src/UI/Components/RightPanel/SealingComponent.tsx @@ -70,6 +70,7 @@ export class SealingComponent extends React.Component<{ store?: RightPanelStore; } private ok = () => { + if (!this.props.store.sealingStore.Check()) return; this.props.store.sealingStore.IsApplyData = true; this.exit(); }; diff --git a/src/UI/Store/BoardInterface.ts b/src/UI/Store/BoardInterface.ts index 99c2f361a..38b280ad8 100644 --- a/src/UI/Store/BoardInterface.ts +++ b/src/UI/Store/BoardInterface.ts @@ -91,6 +91,13 @@ export interface IHighSealedItem size: number; } +export interface ISealingData extends IHighSealedItem +{ + length: number; + type?: string; + shop?: string; +} + export interface BoardProcessOption extends IBaseOption { [EBoardKeyList.RoomName]?: string; diff --git a/src/UI/Store/RightPanelStore/SealingStore.ts b/src/UI/Store/RightPanelStore/SealingStore.ts index e0b209685..09e26cca7 100644 --- a/src/UI/Store/RightPanelStore/SealingStore.ts +++ b/src/UI/Store/RightPanelStore/SealingStore.ts @@ -1,12 +1,14 @@ import { Intent } from "@blueprintjs/core"; import { observable } from "mobx"; +import { app } from "../../../ApplicationServices/Application"; import { CommandNames } from "../../../Common/CommandNames"; import { safeEval } from "../../../Common/eval"; import { Log } from "../../../Common/Log"; import { Board } from "../../../DatabaseServices/Entity/Board"; +import { Entity } from "../../../DatabaseServices/Entity/Entity"; import { CommandWrap } from "../../../Editor/CommandMachine"; -import { GetBoardHighSeal, GetBoardSealingCurves, HandleRectBoardSealingData } from "../../../GraphicsSystem/CalcEdgeSealing"; -import { ShowLinesToaster } from "../../Components/Toaster"; +import { GetBoardHighSeal, GetBoardSealingCurves, GetSealedBoardContour, HandleRectBoardSealingData } from "../../../GraphicsSystem/CalcEdgeSealing"; +import { AppToaster, ShowLinesToaster } from "../../Components/Toaster"; import { IHighSealedItem } from "../BoardInterface"; import { BoardEdgesEditor, Board_Editor_Key } from "./BoardEdgesEditor"; @@ -98,4 +100,31 @@ export class SealingStore extends BoardEdgesEditor }, CommandNames.封边属性编辑); } + Check() + { + this.ParseData(); + let ens: Entity[] = []; + for (let [b, cus] of this._brMap) + { + let data = this._dataMap.get(b); + let cboard = b.Clone(); + cboard.BoardProcessOption.highSealed = data; + let pl = GetSealedBoardContour(cboard, false); + if (!pl) + for (let en of cus) + ens.push(en); + + } + if (ens.length > 0) + { + AppToaster.show({ + message: `封边值计算错误,请检查选中封边!`, + timeout: 5000, + intent: Intent.DANGER, + }); + app.Editor.SetSelection(ens); + return false; + } + return true; + } }