From 78cf4ea3765b9db6c556f0adbbd2f91aa3386af4 Mon Sep 17 00:00:00 2001 From: ZoeLeeFZ Date: Wed, 4 Nov 2020 15:24:02 +0800 Subject: [PATCH] =?UTF-8?q?!1252=20=E4=BC=98=E5=8C=96:=E9=A1=B6=E7=BA=BF?= =?UTF-8?q?=E9=95=BF=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __test__/Sweep/SweepSegs.test.ts | 69 +++++++ .../__snapshots__/SweepSegs.test.ts.snap | 123 ++++++++++++ __test__/Utils/LoadEntity.util.ts | 2 + .../LookOverBoardInfosTool.ts | 3 +- src/Add-on/testEntity/TestSweepMaxLength.ts | 24 +++ src/Add-on/testEntity/test.ts | 12 ++ .../Hardware/HardwareTopline.ts | 188 ++++++++++++++++-- src/Editor/CommandRegister.ts | 2 + src/Production/Product.ts | 3 +- 9 files changed, 408 insertions(+), 18 deletions(-) create mode 100644 __test__/Sweep/SweepSegs.test.ts create mode 100644 __test__/Sweep/__snapshots__/SweepSegs.test.ts.snap create mode 100644 src/Add-on/testEntity/TestSweepMaxLength.ts diff --git a/__test__/Sweep/SweepSegs.test.ts b/__test__/Sweep/SweepSegs.test.ts new file mode 100644 index 000000000..463d7445f --- /dev/null +++ b/__test__/Sweep/SweepSegs.test.ts @@ -0,0 +1,69 @@ +import { HardwareTopline } from "../../src/DatabaseServices/Hardware/HardwareTopline"; +import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; + +describe("顶线分段测试", () => +{ + test("不闭合直线", () => + { + let data = { "file": [1, "HardwareTopline", 8, 2, 101, false, 1, 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, 1, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -287.8749030927833, -1610.1774753266122, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -259.0799031476998, 7.263922518159916, 0, 1], 0, 2, 12, [327.8749030927833, 1710.1774753266122], 0, [305.5142233177854, 1710.1774753266122], 0, [265.5142233177854, 1630.1774753266122], 0, [227.8749030927833, 1630.1774753266122], 0, [227.8749030927833, 1610.1774753266122], 0, [287.8749030927833, 1610.1774753266122], 0, [287.8749030927833, 1630.1774753266122], 0, [293.72274470531937, 1641.8731585516844], -0.4817330338808767, [307.8749030927833, 1670.1774753266122], 0, [315.06369878080005, 1684.5550667026457], -1.000000000000003, [322.30959178698555, 1699.0468527150167], 0, [327.8749030927833, 1710.1774753266122], 0, 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, 8, [665.0653753026636, 3.786924939467383], 0, [665.0653753026636, 1051.6513317191284], 0, [2248.2518159806295, 1051.6513317191284], 0, [2248.2518159806295, 274.2953995157385], 0, [3372.9975786924942, 274.2953995157385], 0, [3372.9975786924942, 934.9055690072639], 0, [4594.556900726393, 934.9055690072639], 0, [4594.556900726393, -132.89104116222757], 0, false, 1, 0, "0", "2", "", "", "", "", "", "", "", "", "", 0], "basePt": { "x": 605.0653753026636, "y": -132.89104116222757, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + + let en = LoadEntityFromFileData(data)[0] as HardwareTopline; + let sgs = en.Segmentations; + for (let sg of sgs) + expect(sg.Length).toMatchSnapshot(); + }); + test("闭合直线", () => + { + let data = { "file": [1, "HardwareTopline", 8, 2, 103, false, 1, 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, 1, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -287.8749030927833, -1610.1774753266122, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -259.0799031476998, 7.263922518159916, 0, 1], 0, 2, 12, [327.8749030927833, 1710.1774753266122], 0, [305.5142233177854, 1710.1774753266122], 0, [265.5142233177854, 1630.1774753266122], 0, [227.8749030927833, 1630.1774753266122], 0, [227.8749030927833, 1610.1774753266122], 0, [287.8749030927833, 1610.1774753266122], 0, [287.8749030927833, 1630.1774753266122], 0, [293.72274470531937, 1641.8731585516844], -0.4817330338808767, [307.8749030927833, 1670.1774753266122], 0, [315.06369878080005, 1684.5550667026457], -1.000000000000003, [322.30959178698555, 1699.0468527150167], 0, [327.8749030927833, 1710.1774753266122], 0, 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, 10, [6596.172000387409, 1362.5581683292971], 0, [8676.730470895884, 1362.5581683292971], 0, [9168.976165811138, 364.9402266343825], 0, [9359.311167845035, -639.2409909927355], 0, [8958.95133598063, -1512.156689975786], 0, [7199.993386150121, -1978.1492811622265], 0, [6569.918896658596, -1735.308071670701], 0, [5920.15457937046, -882.082200484261], 0, [5920.15457937046, 181.1685005326874], 0, [6596.172000387409, 1362.5581683292971], 0, false, 1, 0, "0", "2", "", "", "", "", "", "", "", "", "", 0], "basePt": { "x": 5860.15457937046, "y": -2041.1284915962528, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + + let en = LoadEntityFromFileData(data)[0] as HardwareTopline; + let sgs = en.Segmentations; + for (let sg of sgs) + expect(sg.Length).toMatchSnapshot(); + }); + test("闭合直线2", () => + { + let data = { "file": [1, "HardwareTopline", 8, 2, 125, false, 1, 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, 1, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -287.8749030927833, -1610.1774753266122, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -259.0799031476998, 7.263922518159916, 0, 1], 0, 2, 12, [327.8749030927833, 1710.1774753266122], 0, [305.5142233177854, 1710.1774753266122], 0, [265.5142233177854, 1630.1774753266122], 0, [227.8749030927833, 1630.1774753266122], 0, [227.8749030927833, 1610.1774753266122], 0, [287.8749030927833, 1610.1774753266122], 0, [287.8749030927833, 1630.1774753266122], 0, [293.72274470531937, 1641.8731585516844], -0.4817330338808767, [307.8749030927833, 1670.1774753266122], 0, [315.06369878080005, 1684.5550667026457], -1.000000000000003, [322.30959178698555, 1699.0468527150167], 0, [327.8749030927833, 1710.1774753266122], 0, 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, 13, [1015.8635290455081, -2009.9663326486714], 0, [1130.2226351130905, -3672.571797785067], 0, [-92.5401143787551, -3672.571797785067], 0, [-92.5401143787551, -5185.630739602315], 0, [1042.2540919841813, -5185.630739602315], 0, [1042.2540919841813, -6742.67395298402], 0, [2775.2343916237037, -6742.67395298402], 0, [2775.2343916237037, -5475.926931927717], 0, [4824.901446527302, -5475.926931927717], 0, [4824.901446527302, -3575.8064003432655], 0, [3311.8425047100536, -3575.8064003432655], 0, [3311.8425047100536, -2009.9663326486714], 0, [1015.8635290455081, -2009.9663326486714], 0, false, 1, 0, "0", "2", "", "", "", "", "", "", "", "", "", 0], "basePt": { "x": -132.5401143787559, "y": -6782.67395298402, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + + let en = LoadEntityFromFileData(data)[0] as HardwareTopline; + let sgs = en.Segmentations; + for (let sg of sgs) + expect(sg.Length).toMatchSnapshot(); + }); + test("不闭合直线圆弧", () => + { + let data = { "file": [1, "HardwareTopline", 8, 2, 138, false, 1, 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, 1, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -287.8749030927833, -1610.1774753266122, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -259.0799031476998, 7.263922518159916, 0, 1], 0, 2, 12, [327.8749030927833, 1710.1774753266122], 0, [305.5142233177854, 1710.1774753266122], 0, [265.5142233177854, 1630.1774753266122], 0, [227.8749030927833, 1630.1774753266122], 0, [227.8749030927833, 1610.1774753266122], 0, [287.8749030927833, 1610.1774753266122], 0, [287.8749030927833, 1630.1774753266122], 0, [293.72274470531937, 1641.8731585516844], -0.4817330338808767, [307.8749030927833, 1670.1774753266122], 0, [315.06369878080005, 1684.5550667026457], -1.000000000000003, [322.30959178698555, 1699.0468527150167], 0, [327.8749030927833, 1710.1774753266122], 0, 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, 7, [8161.170129063812, -4825.736011624398], 0, [10274.422826954877, -4535.8983420362665], -0.3209968703598907, [13631.804665466512, -3515.33299725931], 0.6961040990362499, [16433.95143649677, -4968.781221551193], 0, [18722.67479532548, -6256.188110892344], 0, [17900.164838246415, -8366.104957312566], 0, [13847.2172236539, -8938.285797019744], 0, false, 1, 0, "0", "2", "", "", "", "", "", "", "", "", "", 0], "basePt": { "x": 8153.017308542492, "y": -8997.696665063295, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + + let en = LoadEntityFromFileData(data)[0] as HardwareTopline; + let sgs = en.Segmentations; + for (let sg of sgs) + expect(sg.Length).toMatchSnapshot(); + }); + test("不闭合直线圆弧2", () => + { + let data = { "file": [1, "HardwareTopline", 8, 2, 176, false, 1, 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, 1, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -287.8749030927833, -1610.1774753266122, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -259.0799031476998, 7.263922518159916, 0, 1], 0, 2, 12, [327.8749030927833, 1710.1774753266122], 0, [305.5142233177854, 1710.1774753266122], 0, [265.5142233177854, 1630.1774753266122], 0, [227.8749030927833, 1630.1774753266122], 0, [227.8749030927833, 1610.1774753266122], 0, [287.8749030927833, 1610.1774753266122], 0, [287.8749030927833, 1630.1774753266122], 0, [293.72274470531937, 1641.8731585516844], -0.4817330338808767, [307.8749030927833, 1670.1774753266122], 0, [315.06369878080005, 1684.5550667026457], -1.000000000000003, [322.30959178698555, 1699.0468527150167], 0, [327.8749030927833, 1710.1774753266122], 0, 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, 6, [4897.356760796507, -13021.199375936494], 0, [9215.002456548624, -12210.606888994527], -1.5675361689042855, [8896.50860624945, -15932.715247401524], 0.6586041364016083, [13810.3273614602, -19298.493791077715], 0.5762572382754851, [19488.91928472054, -20035.357142623532], 1.0469568095664106, [24641.13993498401, -15563.349756617026], 0, false, 1, 0, "0", "2", "", "", "", "", "", "", "", "", "", 0], "basePt": { "x": 4886.285807460384, "y": -20100.459726764348, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + + let en = LoadEntityFromFileData(data)[0] as HardwareTopline; + let sgs = en.Segmentations; + for (let sg of sgs) + expect(sg.Length).toMatchSnapshot(); + }); + test("闭合圆弧", () => + { + let data = { "file": [1, "HardwareTopline", 8, 2, 212, false, 1, 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, 1, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -287.8749030927833, -1610.1774753266122, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -259.0799031476998, 7.263922518159916, 0, 1], 0, 2, 12, [327.8749030927833, 1710.1774753266122], 0, [305.5142233177854, 1710.1774753266122], 0, [265.5142233177854, 1630.1774753266122], 0, [227.8749030927833, 1630.1774753266122], 0, [227.8749030927833, 1610.1774753266122], 0, [287.8749030927833, 1610.1774753266122], 0, [287.8749030927833, 1630.1774753266122], 0, [293.72274470531937, 1641.8731585516844], -0.4817330338808767, [307.8749030927833, 1670.1774753266122], 0, [315.06369878080005, 1684.5550667026457], -1.000000000000003, [322.30959178698555, 1699.0468527150167], 0, [327.8749030927833, 1710.1774753266122], 0, 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, 9, [26918.40309536543, -6762.519351691368], 0, [30726.6994741038, -2358.141800628734], -0.5886269825401041, [35793.38943886006, -3417.8416625385407], 1.9631692691925628, [37945.904783364356, -536.7826629712545], -0.9869745189351885, [37945.904783364356, 2675.4325434428465], -0.15411492859354337, [45198.2257133096, 489.8015782538714], -0.7492501709688599, [41952.894886210815, -9511.115868519928], -0.13168435817007573, [31223.433784374025, -6298.900662105827], 0.3425423322181609, [26918.40309536543, -6762.519351691368], 0, false, 1, 0, "0", "2", "", "", "", "", "", "", "", "", "", 0], "basePt": { "x": 26006.740732473027, "y": -9571.090590925047, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + + let en = LoadEntityFromFileData(data)[0] as HardwareTopline; + let sgs = en.Segmentations; + for (let sg of sgs) + expect(sg.Length).toMatchSnapshot(); + }); + test("不闭合多补圆弧", () => + { + let data = { "file": [1, "HardwareTopline", 8, 2, 461, false, 1, 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, 1, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -287.8749030927833, -1610.1774753266122, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -259.0799031476998, 7.263922518159916, 0, 1], 0, 2, 12, [327.8749030927833, 1710.1774753266122], 0, [305.5142233177854, 1710.1774753266122], 0, [265.5142233177854, 1630.1774753266122], 0, [227.8749030927833, 1630.1774753266122], 0, [227.8749030927833, 1610.1774753266122], 0, [287.8749030927833, 1610.1774753266122], 0, [287.8749030927833, 1630.1774753266122], 0, [293.72274470531937, 1641.8731585516844], -0.4817330338808767, [307.8749030927833, 1670.1774753266122], 0, [315.06369878080005, 1684.5550667026457], -1.000000000000003, [322.30959178698555, 1699.0468527150167], 0, [327.8749030927833, 1710.1774753266122], 0, 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, 9, [45751.96592203299, 3086.036062563707], 0.22239155538431857, [52423.0828344913, 5938.5569393828955], 1.1461811427928006, [56463.47934476306, 3849.018445843789], 1.043480940008842, [62001.088374224215, 3387.691765452039], 0.8769933217842865, [68693.87601580269, 3758.4758746386747], 0.798237664392203, [75267.09679427171, 4091.702169937928], -0.8843311793277688, [80944.03676807143, 3824.3355122590892], -1.0886924073122075, [88681.92945847644, 2000.566713469759], -0.803057870546459, [94187.65216324253, -492.2642729771228], 0, false, 1, 0, "0", "2", "", "", "", "", "", "", "", "", "", 0], "basePt": { "x": 45750.62233582299, "y": -504.6289351196049, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + + let en = LoadEntityFromFileData(data)[0] as HardwareTopline; + let sgs = en.Segmentations; + for (let sg of sgs) + expect(sg.Length).toMatchSnapshot(); + }); +}); diff --git a/__test__/Sweep/__snapshots__/SweepSegs.test.ts.snap b/__test__/Sweep/__snapshots__/SweepSegs.test.ts.snap new file mode 100644 index 000000000..de30a3245 --- /dev/null +++ b/__test__/Sweep/__snapshots__/SweepSegs.test.ts.snap @@ -0,0 +1,123 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`顶线分段测试 不闭合多补圆弧 1`] = `7527.309534097056`; + +exports[`顶线分段测试 不闭合多补圆弧 2`] = `181.5491080422332`; + +exports[`顶线分段测试 不闭合多补圆弧 3`] = `7972.744263135363`; + +exports[`顶线分段测试 不闭合多补圆弧 4`] = `175.55938663598863`; + +exports[`顶线分段测试 不闭合多补圆弧 5`] = `9102.215223601412`; + +exports[`顶线分段测试 不闭合多补圆弧 6`] = `174.8880833875115`; + +exports[`顶线分段测试 不闭合多补圆弧 7`] = `9850.281806459632`; + +exports[`顶线分段测试 不闭合多补圆弧 8`] = `167.51636096659317`; + +exports[`顶线分段测试 不闭合多补圆弧 9`] = `9201.576517258296`; + +exports[`顶线分段测试 不闭合多补圆弧 10`] = `8466.391158009817`; + +exports[`顶线分段测试 不闭合多补圆弧 11`] = `13771.549281343938`; + +exports[`顶线分段测试 不闭合多补圆弧 12`] = `8903.394215503109`; + +exports[`顶线分段测试 不闭合直线 1`] = `1107.864406779661`; + +exports[`顶线分段测试 不闭合直线 2`] = `1703.186440677966`; + +exports[`顶线分段测试 不闭合直线 3`] = `877.3559322033899`; + +exports[`顶线分段测试 不闭合直线 4`] = `1204.7457627118647`; + +exports[`顶线分段测试 不闭合直线 5`] = `760.6101694915253`; + +exports[`顶线分段测试 不闭合直线 6`] = `1341.5593220338988`; + +exports[`顶线分段测试 不闭合直线 7`] = `1127.7966101694917`; + +exports[`顶线分段测试 不闭合直线圆弧 1`] = `2149.5428197912242`; + +exports[`顶线分段测试 不闭合直线圆弧 2`] = `3886.6189286714834`; + +exports[`顶线分段测试 不闭合直线圆弧 3`] = `4288.290679114739`; + +exports[`顶线分段测试 不闭合直线圆弧 4`] = `2721.960193789363`; + +exports[`顶线分段测试 不闭合直线圆弧 5`] = `2351.778679840207`; + +exports[`顶线分段测试 不闭合直线圆弧 6`] = `4128.24578371541`; + +exports[`顶线分段测试 不闭合直线圆弧2 1`] = `4393.076886867966`; + +exports[`顶线分段测试 不闭合直线圆弧2 2`] = `6.5660240646022485`; + +exports[`顶线分段测试 不闭合直线圆弧2 3`] = `8562.229412244691`; + +exports[`顶线分段测试 不闭合直线圆弧2 4`] = `7775.242286971556`; + +exports[`顶线分段测试 不闭合直线圆弧2 5`] = `7158.345287787591`; + +exports[`顶线分段测试 不闭合直线圆弧2 6`] = `11250.987271676091`; + +exports[`顶线分段测试 闭合圆弧 1`] = `183.06306067445354`; + +exports[`顶线分段测试 闭合圆弧 2`] = `5822.513453880229`; + +exports[`顶线分段测试 闭合圆弧 3`] = `6427.17494400804`; + +exports[`顶线分段测试 闭合圆弧 4`] = `9954.439545178488`; + +exports[`顶线分段测试 闭合圆弧 5`] = `5190.973862843558`; + +exports[`顶线分段测试 闭合圆弧 6`] = `7730.5776753028`; + +exports[`顶线分段测试 闭合圆弧 7`] = `14243.520190228804`; + +exports[`顶线分段测试 闭合圆弧 8`] = `11360.44019007804`; + +exports[`顶线分段测试 闭合圆弧 9`] = `4713.854133052737`; + +exports[`顶线分段测试 闭合直线 1`] = `2152.655017660556`; + +exports[`顶线分段测试 闭合直线 2`] = `1157.9339062625943`; + +exports[`顶线分段测试 闭合直线 3`] = `1049.373745402737`; + +exports[`顶线分段测试 闭合直线 4`] = `1007.7933435525692`; + +exports[`顶线分段测试 闭合直线 5`] = `1867.3971281882991`; + +exports[`顶线分段测试 闭合直线 6`] = `711.6950394345639`; + +exports[`顶线分段测试 闭合直线 7`] = `1109.7095976240196`; + +exports[`顶线分段测试 闭合直线 8`] = `1099.4488714706863`; + +exports[`顶线分段测试 闭合直线 9`] = `1411.8807330899142`; + +exports[`顶线分段测试 闭合直线2 1`] = `1773.6483926638098`; + +exports[`顶线分段测试 闭合直线2 2`] = `1327.0314994557618`; + +exports[`顶线分段测试 闭合直线2 3`] = `1593.058941817248`; + +exports[`顶线分段测试 闭合直线2 4`] = `1234.7942063629366`; + +exports[`顶线分段测试 闭合直线2 5`] = `1657.0432133817048`; + +exports[`顶线分段测试 闭合直线2 6`] = `1812.9802996395224`; + +exports[`顶线分段测试 闭合直线2 7`] = `1366.7470210563024`; + +exports[`顶线分段测试 闭合直线2 8`] = `2149.6670549035985`; + +exports[`顶线分段测试 闭合直线2 9`] = `1980.1205315844518`; + +exports[`顶线分段测试 闭合直线2 10`] = `1613.0589418172485`; + +exports[`顶线分段测试 闭合直线2 11`] = `1665.8400676945942`; + +exports[`顶线分段测试 闭合直线2 12`] = `2378.824808973823`; diff --git a/__test__/Utils/LoadEntity.util.ts b/__test__/Utils/LoadEntity.util.ts index a039b2b41..28592cda7 100644 --- a/__test__/Utils/LoadEntity.util.ts +++ b/__test__/Utils/LoadEntity.util.ts @@ -5,10 +5,12 @@ import { Factory } from "../../src/DatabaseServices/CADFactory"; import { Curve } from "../../src/DatabaseServices/Entity/Curve"; import { Board } from "../../src/DatabaseServices/Entity/Board"; import { Region } from "../../src/DatabaseServices/Entity/Region"; +import { HardwareTopline } from "../../src/DatabaseServices/Hardware/HardwareTopline"; Factory(Polyline); Factory(Region); Factory(Board); +Factory(HardwareTopline); export function LoadEntityFromFileData(data) { diff --git a/src/Add-on/LookOverBoardInfos/LookOverBoardInfosTool.ts b/src/Add-on/LookOverBoardInfos/LookOverBoardInfosTool.ts index 612eceb9c..adb8bf211 100644 --- a/src/Add-on/LookOverBoardInfos/LookOverBoardInfosTool.ts +++ b/src/Add-on/LookOverBoardInfos/LookOverBoardInfosTool.ts @@ -212,8 +212,7 @@ class LookOverBoardInfosTool for (let d of v) { let e = d as HardwareTopline; - let path = e.MaxPath; - let cus = path instanceof Polyline ? path.Explode() : [path]; + let cus = e.Segmentations; for (let cu of cus) { let len = parseFloat(FixedNotZero(cu.Length, 2)); diff --git a/src/Add-on/testEntity/TestSweepMaxLength.ts b/src/Add-on/testEntity/TestSweepMaxLength.ts new file mode 100644 index 000000000..1c680aaca --- /dev/null +++ b/src/Add-on/testEntity/TestSweepMaxLength.ts @@ -0,0 +1,24 @@ +import { app } from "../../ApplicationServices/Application"; +import { HardwareTopline } from "../../DatabaseServices/Hardware/HardwareTopline"; +import { Command } from "../../Editor/CommandMachine"; +import { PromptStatus } from "../../Editor/PromptResult"; +import { HotCMD } from "../../Hot/HotCommand"; +import { TestDraw } from "../test/TestUtil"; + +@HotCMD +export class Command_TestSweepMaxLength implements Command +{ + async exec() + { + let enRes = await app.Editor.GetEntity({ Filter: { filterTypes: [HardwareTopline] }, Msg: "选肉" }); + if (enRes.Status !== PromptStatus.OK) return; + let br = enRes.Entity as HardwareTopline; + let b = br.Path.Clone(); + b.Erase(false); + TestDraw(b, 1); + //@ts-ignore + TestDraw(br.Contours.map(c => c.ApplyMatrix(br.OCS)), 2); + TestDraw(br.Segmentations.map(c => c.ApplyMatrix(br.OCS)), 3); + br.Erase(); + } +} diff --git a/src/Add-on/testEntity/test.ts b/src/Add-on/testEntity/test.ts index f8d08baa2..8cbd759ec 100644 --- a/src/Add-on/testEntity/test.ts +++ b/src/Add-on/testEntity/test.ts @@ -2,12 +2,24 @@ import { app } from "../../ApplicationServices/Application"; import { Command } from "../../Editor/CommandMachine"; import { PromptStatus } from "../../Editor/PromptResult"; import { HotCMD } from "../../Hot/HotCommand"; +import { HardwareTopline } from "../../DatabaseServices/Hardware/HardwareTopline"; +import { TestDraw } from "../test/TestUtil"; @HotCMD export class Test implements Command { async exec() { + let enRes = await app.Editor.GetEntity({ Filter: { filterTypes: [HardwareTopline] }, Msg: "选肉" }); + if (enRes.Status !== PromptStatus.OK) return; + let br = enRes.Entity as HardwareTopline; + let b = br.Path.Clone(); + b.Erase(false); + TestDraw(b, 1); + //@ts-ignore + TestDraw(br.Contours.map(c => c.ApplyMatrix(br.OCS)), 2); + TestDraw(br.Segmentations.map(c => c.ApplyMatrix(br.OCS)), 3); + br.Erase(); } private async AllM0() { diff --git a/src/DatabaseServices/Hardware/HardwareTopline.ts b/src/DatabaseServices/Hardware/HardwareTopline.ts index 20ffb82c1..03f575a5b 100644 --- a/src/DatabaseServices/Hardware/HardwareTopline.ts +++ b/src/DatabaseServices/Hardware/HardwareTopline.ts @@ -5,7 +5,13 @@ import { DefaultToplineMetalsOption } from "../../Editor/DefaultConfig"; import { Matrix4 } from "three"; import { SweepSolid } from '../3DSolid/SweepSolid'; import { GetPointAtCurveDir } from "../../Common/CurveUtils"; -import { ZAxis } from "../../Geometry/GeUtils"; +import { ZAxis, isPerpendicularityTo, equalv3, rotatePoint, equaln } from "../../Geometry/GeUtils"; +import { Polyline } from "../Entity/Polyline"; +import { Curve } from "../Entity/Curve"; +import { FixIndex } from "../../Nest/Common/Util"; +import { IntersectOption } from "../../GraphicsSystem/IntersectWith"; +import { Line } from "../Entity/Line"; +import { arrayRemoveIf } from "../../Common/ArrayExt"; @Factory export class HardwareTopline extends SweepSolid @@ -17,6 +23,7 @@ export class HardwareTopline extends SweepSolid { return this._contourRotation; } + private _ContourWidth: number; private get Contours() { let c = this.Path; @@ -30,29 +37,182 @@ export class HardwareTopline extends SweepSolid mat.setPosition(c.StartPoint); [cMin, cMax].forEach(p => p.applyMatrix4(mat).setZ(0)); - let closePt = c.GetClosestPointTo(cMin, false); + let firstCurve: Curve; + if (c instanceof Polyline) + firstCurve = c.GetCurveAtParam(0); + else + firstCurve = c; + + let closePt = firstCurve.GetClosestPointTo(cMin, false); let offset = cMin.distanceTo(closePt); - let dir = GetPointAtCurveDir(this.Path, cMin); + let dir = GetPointAtCurveDir(firstCurve, cMin); let cus = this.Path.GetOffsetCurves(offset * dir); - let l1 = cus[0] ?? this.Path; + let l1 = cus[0] ?? this.Path.Clone(); - closePt = c.GetClosestPointTo(cMax, false); - offset = cMax.distanceTo(closePt); - dir = GetPointAtCurveDir(this.Path, cMax); - cus = this.Path.GetOffsetCurves(offset * dir); - let l2 = cus[0] ?? this.Path; + closePt = firstCurve.GetClosestPointTo(cMax, false); + let offset2 = cMax.distanceTo(closePt); + dir = GetPointAtCurveDir(firstCurve, cMax); + cus = this.Path.GetOffsetCurves(offset2 * dir); + let l2 = cus[0] ?? this.Path.Clone(); + this._ContourWidth = offset + offset2; return [l1, l2]; } - get MaxPath() + /** + *延伸取最大最小轮廓每段首尾到前面线段,取最长线段作为分段长 + * + */ + get Segmentations() { - let [l1, l2] = this.Contours; - return l1.Length > l2.Length ? l1 : l2; + const [l1, l2] = this.Contours; + if (!(l1 instanceof Polyline)) + return [l1]; + + let cus1 = l1.Explode() as Curve[]; + let cus2 = l2.Explode() as Curve[]; + + [cus1, cus2] = cus1.length < cus2.length ? [cus2, cus1] : [cus1, cus2]; + + let sgs: Curve[] = []; + + const AddSgs = (c1: Curve, c2: Curve) => + { + sgs.push(c1.Length > c2.Length ? c1 : c2); + }; + + const ExtendCurve = (c: Curve, refC: Curve, isPre) => + { + let pts = c.IntersectWith2(refC, IntersectOption.ExtendBoth).filter(r => + { + if (isPre) + return r.thisParam < 0; + else + return r.thisParam > 1; + }); + if (isPre) + { + pts.sort((r1, r2) => r2.thisParam - r1.thisParam); + if (pts.length > 0 && pts[0].thisParam < 0) + c.Extend(pts[0].thisParam); + } + else + { + pts.sort((r1, r2) => r1.thisParam - r2.thisParam); + if (pts.length > 0 && pts[0].thisParam > 1) + c.Extend(pts[0].thisParam); + } + }; + const IsNoRelativeCurve = (c1: Curve, c2: Curve) => + { + if ((c1 instanceof Line) !== (c2 instanceof Line)) + return true; + + let midPt = c1.GetPointAtParam(0.5); + let closePt = c2.GetClosestPointTo(midPt, false); + return !closePt || !equaln(midPt.distanceTo(closePt), this._ContourWidth, 1e-3); + }; + + const HasRelativeCurveAndChange = (target: Curve, cs: Curve[], isChange = false) => + { + let index = cs.findIndex(c => !IsNoRelativeCurve(c, target)); + if (index !== -1) + { + if (isChange && l1.IsClose) + cs.unshift(...cs.splice(index)); + return true; + } + return false; + }; + + + if (cus1.length !== cus2.length) + arrayRemoveIf(cus2, c => !HasRelativeCurveAndChange(c, cus1)); + + for (let i = 0; i < cus1.length; i++) + { + let c1 = cus1[i]; + let c2 = cus2[i]; + + if (cus1.length !== cus2.length) + { + if (IsNoRelativeCurve(c1, c2)) + { + sgs.push(c1); + cus1.splice(i, 1); + i--; + continue; + } + } + else + { + //第一段验证是否是关联段,不关联重置数组顺序 + if (i === 0) + { + if (IsNoRelativeCurve(c1, c2)) + { + if (!HasRelativeCurveAndChange(c1, cus2, true)) + { + console.error("错误"); + return cus1; + } + i--; + continue; + } + } + } + + let nextC1: Curve; + + if (l1.IsClose) + { + nextC1 = cus1[FixIndex(i + 1, cus1.length)]; + } + else + { + if (i < cus1.length - 1) + { + nextC1 = cus1[i + 1]; + } + } + + if (nextC1) + { + let derv = c1.GetFistDeriv(0).normalize(); + let derv2 = nextC1.GetFistDeriv(0).normalize(); + + if (isPerpendicularityTo(derv, derv2) && isPerpendicularityTo(derv, c1.StartPoint.sub(c2.StartPoint).normalize())) + { + AddSgs(c1, c2); + continue; + } + } + + let nextDerv1 = c1.GetFistDeriv(1).normalize(); + let nextDerv2 = c2.GetFistDeriv(1).normalize(); + let preDerv1 = c1.GetFistDeriv(0).normalize(); + let preDerv2 = c2.GetFistDeriv(0).normalize(); + [nextDerv1, nextDerv2, preDerv1, preDerv2].forEach(d => rotatePoint(d, Math.PI / 2)); + + let preRefLine1 = new Line(c1.StartPoint, c1.StartPoint.add(preDerv1)); + let preRefLine2 = new Line(c2.StartPoint, c2.StartPoint.add(preDerv2)); + + let nextRefLine1 = new Line(c1.EndPoint, c1.EndPoint.add(nextDerv1)); + let nextRefLine2 = new Line(c2.EndPoint, c2.EndPoint.add(nextDerv2)); + + ExtendCurve(c1, nextRefLine2, false); + ExtendCurve(c2, nextRefLine1, false); + + ExtendCurve(c1, preRefLine2, true); + ExtendCurve(c2, preRefLine1, true); + + AddSgs(c1, c2); + } + + return sgs; } get MaxLength() { - let [l1, l2] = this.Contours; - return Math.max(l1.Length, l2.Length); + return this.Segmentations.reduce((len, c) => len + c.Length, 0); } set ContourRotation(ro: number) { diff --git a/src/Editor/CommandRegister.ts b/src/Editor/CommandRegister.ts index dba4a8ab3..ab0213fdd 100644 --- a/src/Editor/CommandRegister.ts +++ b/src/Editor/CommandRegister.ts @@ -164,6 +164,7 @@ import { TestTargeOnCurve } from "../Add-on/testEntity/TestCurve"; import { Command_TestDrawEdgeGeometry } from "../Add-on/testEntity/TestDrawEdgeGeometry"; import { TestFillet } from "../Add-on/testEntity/TestFilletCode"; import { Command_TestRegionParse } from "../Add-on/testEntity/TestRegionParse"; +import { Command_TestSweepMaxLength } from "../Add-on/testEntity/TestSweepMaxLength"; import { Command_DeleteTemplate } from "../Add-on/testEntity/TestTemplateDelete"; import { Command_TestVPath } from "../Add-on/testEntity/TestVPath"; import { TestFb } from "../Add-on/TestFb"; @@ -219,6 +220,7 @@ export function registerCommand() commandMachine.RegisterCommand("testRegionParse", new Command_TestRegionParse()); commandMachine.RegisterCommand("TestBoundaryBox", new Command_TestBoundaryBox()); + commandMachine.RegisterCommand("TestSweepMaxLength", new Command_TestSweepMaxLength()); commandMachine.RegisterCommand(CommandNames.Insert, new Command_Insert()); diff --git a/src/Production/Product.ts b/src/Production/Product.ts index 751c2c573..36cbbb2a5 100644 --- a/src/Production/Product.ts +++ b/src/Production/Product.ts @@ -930,8 +930,7 @@ export namespace Production let datas: ISpliteHardwareData[] = []; let map = new Map(); let addLen = en.HardwareOption.addLen; - let path = en.MaxPath; - let cus = path instanceof Polyline ? path.Explode() : [path]; + let cus = en.Segmentations; let size = en.BoundingBoxInOCS.getSize(new Vector3); for (let cu of cus) {