From 6d3e1d52e5e08cca1b8ce84525477dbf41797447 Mon Sep 17 00:00:00 2001 From: ChenX Date: Wed, 18 Mar 2020 15:37:28 +0800 Subject: [PATCH] =?UTF-8?q?!817=20=E4=BF=AE=E5=A4=8D:join=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E7=BB=84=E5=90=88=E6=88=90=E5=A4=9A=E6=AE=B5=E7=BA=BF?= =?UTF-8?q?=E9=94=99=E8=AF=AF,=E9=9D=A2=E5=9F=9F=E5=88=86=E6=9E=90?= =?UTF-8?q?=E5=8D=A1=E6=AD=BB(=E6=AD=BB=E5=BE=AA=E7=8E=AF)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__snapshots__/EdgeSealing.test.ts.snap | 16 +- .../FeedingToolPath/FeedingToolPath.test.ts | 3 +- .../FeedingToolPath.test.ts.snap | 360 +++++++++--------- .../__snapshots__/offset.test.ts.snap | 26 +- .../__snapshots__/offsetbug.test.ts.snap | 16 +- src/Add-on/DrawRegion.ts | 14 + src/Add-on/Join.ts | 12 +- src/Common/CurveUtils.ts | 60 ++- src/DatabaseServices/Contour.ts | 16 +- src/DatabaseServices/Entity/Polyline.ts | 32 +- src/Geometry/CurveMap.ts | 17 +- src/Geometry/ExtrudeEdgeGeometry2.ts | 2 - src/Geometry/RegionParse.ts | 95 ++--- 13 files changed, 364 insertions(+), 305 deletions(-) diff --git a/__test__/EdgeSealing/__snapshots__/EdgeSealing.test.ts.snap b/__test__/EdgeSealing/__snapshots__/EdgeSealing.test.ts.snap index 670b093de..fea1e72f7 100644 --- a/__test__/EdgeSealing/__snapshots__/EdgeSealing.test.ts.snap +++ b/__test__/EdgeSealing/__snapshots__/EdgeSealing.test.ts.snap @@ -1,8 +1,8 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`丢失线段板件 1`] = `554052.5007766786`; +exports[`丢失线段板件 1`] = `554052.5007766776`; -exports[`丢失线段板件 2`] = `398758.87896958226`; +exports[`丢失线段板件 2`] = `398758.87896958215`; exports[`常规板件,常规坐标系 1`] = `716404`; @@ -10,21 +10,21 @@ exports[`常规板件,常规坐标系 2`] = `711624`; exports[`常规板件,常规坐标系 3`] = `712816`; -exports[`异型板件,常规坐标系 1`] = `2709777.7883832143`; +exports[`异型板件,常规坐标系 1`] = `2709777.7883832157`; -exports[`异型板件,常规坐标系 2`] = `2682243.4048994216`; +exports[`异型板件,常规坐标系 2`] = `2682243.404899421`; -exports[`异型板件,常规坐标系 3`] = `2660261.4833081043`; +exports[`异型板件,常规坐标系 3`] = `2660261.483308104`; -exports[`异型板件,常规坐标系 4`] = `2628158.6443366613`; +exports[`异型板件,常规坐标系 4`] = `2628158.6443366623`; -exports[`异型板件,常规坐标系 5`] = `2603082.551922608`; +exports[`异型板件,常规坐标系 5`] = `2603082.5519226086`; exports[`异型板件,非常规坐标系 1`] = `75939516.39226124`; exports[`异型板件,非常规坐标系 2`] = `75863286.03232269`; -exports[`异型板件,非常规坐标系 3`] = `75694680.60847881`; +exports[`异型板件,非常规坐标系 3`] = `75694680.60847883`; exports[`异型板件,非相切圆弧 1`] = `635612.2751433643`; diff --git a/__test__/FeedingToolPath/FeedingToolPath.test.ts b/__test__/FeedingToolPath/FeedingToolPath.test.ts index 24dad4373..fc6b8eb52 100644 --- a/__test__/FeedingToolPath/FeedingToolPath.test.ts +++ b/__test__/FeedingToolPath/FeedingToolPath.test.ts @@ -1,6 +1,7 @@ import { Board } from "../../src/DatabaseServices/Entity/Board"; import { FeedingToolPath } from "../../src/GraphicsSystem/ToolPath/FeedingToolPath"; import { LoadBoardsFromFileData } from "../Utils/LoadEntity.util"; +import "../Utils/jest.util"; function testPathCount(br: Board, count?: number) { @@ -18,7 +19,7 @@ function testPathCount(br: Board, count?: number) expect(pathCount < 0 ? 0 : pathCount).toMatchSnapshot("走刀数量"); for (let cu of cus) { - expect(cu.Length).toMatchSnapshot("曲线长度"); + expect(cu.Length).toMatchNumberSnapshot(); } } let feedUtil = FeedingToolPath.GetInstance() as FeedingToolPath; diff --git a/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap b/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap index 10be172b2..57dbe951a 100644 --- a/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap +++ b/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap @@ -1,240 +1,240 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`#IYX1P: 曲线长度 1`] = `3600`; +exports[`#IYX1P 1`] = `"3600.00000"`; -exports[`#IYX1P: 曲线长度 2`] = `1346.7694340038445`; +exports[`#IYX1P 2`] = `"1346.76943"`; -exports[`#IYX1P: 曲线长度 3`] = `8462.397070725754`; +exports[`#IYX1P 3`] = `"8462.39707"`; -exports[`#IYX1P: 曲线长度 4`] = `10.71238898038469`; +exports[`#IYX1P 4`] = `"10.71239"`; -exports[`#IYX1P: 曲线长度 5`] = `1483.4533999999999`; +exports[`#IYX1P 5`] = `"1483.45340"`; -exports[`#IYX1P: 曲线长度 6`] = `1324.9044565737036`; +exports[`#IYX1P 6`] = `"1324.90446"`; exports[`#IYX1P: 走刀数量 1`] = `3`; -exports[`刀切到外轮廓情况: 曲线长度 1`] = `3600`; +exports[`刀切到外轮廓情况 1`] = `"3600.00000"`; -exports[`刀切到外轮廓情况: 曲线长度 2`] = `22596.75011038598`; +exports[`刀切到外轮廓情况 2`] = `"22596.75011"`; -exports[`刀切到外轮廓情况: 曲线长度 3`] = `6355.243980782019`; +exports[`刀切到外轮廓情况 3`] = `"6355.24398"`; -exports[`刀切到外轮廓情况: 曲线长度 4`] = `1478.9393851461323`; +exports[`刀切到外轮廓情况 4`] = `"1478.93939"`; -exports[`刀切到外轮廓情况: 曲线长度 5`] = `729.5688477133849`; +exports[`刀切到外轮廓情况 5`] = `"729.56885"`; -exports[`刀切到外轮廓情况: 曲线长度 6`] = `3600`; +exports[`刀切到外轮廓情况 6`] = `"3600.00000"`; -exports[`刀切到外轮廓情况: 曲线长度 7`] = `14681.465974109033`; +exports[`刀切到外轮廓情况 7`] = `"14681.46597"`; -exports[`刀切到外轮廓情况: 曲线长度 8`] = `14658.277022001035`; +exports[`刀切到外轮廓情况 8`] = `"14658.27702"`; -exports[`刀切到外轮廓情况: 曲线长度 9`] = `14681.465974109033`; +exports[`刀切到外轮廓情况 9`] = `"14681.46597"`; -exports[`刀切到外轮廓情况: 曲线长度 10`] = `14658.277022000966`; +exports[`刀切到外轮廓情况 10`] = `"14658.27702"`; -exports[`刀切到外轮廓情况: 曲线长度 11`] = `2683.281572999748`; +exports[`刀切到外轮廓情况 11`] = `"2683.28157"`; -exports[`刀切到外轮廓情况: 曲线长度 12`] = `1800`; +exports[`刀切到外轮廓情况 12`] = `"1800.00000"`; exports[`刀切到外轮廓情况: 走刀数量 1`] = `2`; exports[`刀切到外轮廓情况: 走刀数量 2`] = `4`; -exports[`复杂极限刀半径: 曲线长度 1`] = `4356.840832388074`; +exports[`复杂极限刀半径 1`] = `"4356.84083"`; -exports[`复杂极限刀半径: 曲线长度 2`] = `1073.246931353379`; +exports[`复杂极限刀半径 2`] = `"1073.24693"`; -exports[`复杂极限刀半径: 曲线长度 3`] = `34218.239667713664`; +exports[`复杂极限刀半径 3`] = `"34218.23967"`; -exports[`复杂极限刀半径: 曲线长度 4`] = `4434.591784188829`; +exports[`复杂极限刀半径 4`] = `"4434.59178"`; -exports[`复杂极限刀半径: 曲线长度 5`] = `951.5402172137751`; +exports[`复杂极限刀半径 5`] = `"951.54022"`; -exports[`复杂极限刀半径: 曲线长度 6`] = `3278.9179349887763`; +exports[`复杂极限刀半径 6`] = `"3278.91793"`; exports[`复杂极限刀半径: 走刀数量 1`] = `3`; -exports[`复杂造型01: 曲线长度 1`] = `3600`; +exports[`复杂造型01 1`] = `"3600.00000"`; -exports[`复杂造型01: 曲线长度 2`] = `39413.775281964336`; +exports[`复杂造型01 2`] = `"39413.77528"`; -exports[`复杂造型01: 曲线长度 3`] = `15808.94716168059`; +exports[`复杂造型01 3`] = `"15808.94716"`; -exports[`复杂造型01: 曲线长度 4`] = `4413.317448318587`; +exports[`复杂造型01 4`] = `"4413.31745"`; -exports[`复杂造型01: 曲线长度 5`] = `1482.4552077856665`; +exports[`复杂造型01 5`] = `"1482.45521"`; -exports[`复杂造型01: 曲线长度 6`] = `838.7907023816642`; +exports[`复杂造型01 6`] = `"838.79070"`; -exports[`复杂造型01: 曲线长度 7`] = `25.328937185896002`; +exports[`复杂造型01 7`] = `"25.32894"`; -exports[`复杂造型01: 曲线长度 8`] = `25.328939247232213`; +exports[`复杂造型01 8`] = `"25.32894"`; -exports[`复杂造型01: 曲线长度 9`] = `676.6930479102881`; +exports[`复杂造型01 9`] = `"676.69305"`; -exports[`复杂造型01: 曲线长度 10`] = `227.60858174908054`; +exports[`复杂造型01 10`] = `"227.60858"`; -exports[`复杂造型01: 曲线长度 11`] = `80.89233579283737`; +exports[`复杂造型01 11`] = `"80.89234"`; -exports[`复杂造型01: 曲线长度 12`] = `10.104776221419284`; +exports[`复杂造型01 12`] = `"10.10478"`; -exports[`复杂造型01: 曲线长度 13`] = `3.2524680966497335`; +exports[`复杂造型01 13`] = `"3.25247"`; -exports[`复杂造型01: 曲线长度 14`] = `301.66992978702626`; +exports[`复杂造型01 14`] = `"301.66993"`; -exports[`复杂造型01: 曲线长度 15`] = `1749.8631881230117`; +exports[`复杂造型01 15`] = `"1749.86319"`; -exports[`复杂造型01: 曲线长度 16`] = `7.8285491298056655`; +exports[`复杂造型01 16`] = `"7.82855"`; -exports[`复杂造型01: 曲线长度 17`] = `2.5692483033658107`; +exports[`复杂造型01 17`] = `"2.56925"`; -exports[`复杂造型01: 曲线长度 18`] = `4316.136010511218`; +exports[`复杂造型01 18`] = `"4316.13601"`; -exports[`复杂造型01: 曲线长度 19`] = `60.75516885168303`; +exports[`复杂造型01 19`] = `"60.75517"`; -exports[`复杂造型01: 曲线长度 20`] = `270.97161059159566`; +exports[`复杂造型01 20`] = `"270.97161"`; -exports[`复杂造型01: 曲线长度 21`] = `282.82481905047365`; +exports[`复杂造型01 21`] = `"282.82482"`; -exports[`复杂造型01: 曲线长度 22`] = `819.9411466147131`; +exports[`复杂造型01 22`] = `"819.94115"`; -exports[`复杂造型01: 曲线长度 23`] = `1463.6056529693449`; +exports[`复杂造型01 23`] = `"1463.60565"`; exports[`复杂造型01: 走刀数量 1`] = `16`; -exports[`复杂造型测试: 曲线长度 1`] = `2402.511185283596`; +exports[`复杂造型测试 1`] = `"2402.51119"`; -exports[`复杂造型测试: 曲线长度 2`] = `24373.250750763476`; +exports[`复杂造型测试 2`] = `"24373.25075"`; -exports[`复杂造型测试: 曲线长度 3`] = `4285.071854430757`; +exports[`复杂造型测试 3`] = `"4285.07185"`; -exports[`复杂造型测试: 曲线长度 4`] = `2418.143451783811`; +exports[`复杂造型测试 4`] = `"2418.14345"`; -exports[`复杂造型测试: 曲线长度 5`] = `2293.076221853775`; +exports[`复杂造型测试 5`] = `"2293.07622"`; -exports[`复杂造型测试: 曲线长度 6`] = `4096.105045378747`; +exports[`复杂造型测试 6`] = `"4096.10505"`; -exports[`复杂造型测试: 曲线长度 7`] = `910.1341511193467`; +exports[`复杂造型测试 7`] = `"910.13415"`; -exports[`复杂造型测试: 曲线长度 8`] = `2841.1337227520216`; +exports[`复杂造型测试 8`] = `"2841.13372"`; -exports[`复杂造型测试: 曲线长度 9`] = `1079.2736477434978`; +exports[`复杂造型测试 9`] = `"1079.27365"`; -exports[`复杂造型测试: 曲线长度 10`] = `227.8342135021163`; +exports[`复杂造型测试 10`] = `"227.83421"`; -exports[`复杂造型测试: 曲线长度 11`] = `16.405200898113836`; +exports[`复杂造型测试 11`] = `"16.40520"`; -exports[`复杂造型测试: 曲线长度 12`] = `696.1986486992679`; +exports[`复杂造型测试 12`] = `"696.19865"`; -exports[`复杂造型测试: 曲线长度 13`] = `639.7910377879329`; +exports[`复杂造型测试 13`] = `"639.79104"`; -exports[`复杂造型测试: 曲线长度 14`] = `1715.2225461089636`; +exports[`复杂造型测试 14`] = `"1715.22255"`; -exports[`复杂造型测试: 曲线长度 15`] = `493.42887087968916`; +exports[`复杂造型测试 15`] = `"493.42887"`; -exports[`复杂造型测试: 曲线长度 16`] = `352.7973262382525`; +exports[`复杂造型测试 16`] = `"352.79733"`; -exports[`复杂造型测试: 曲线长度 17`] = `342.70973636046426`; +exports[`复杂造型测试 17`] = `"342.70974"`; -exports[`复杂造型测试: 曲线长度 18`] = `476.0989607667295`; +exports[`复杂造型测试 18`] = `"476.09896"`; -exports[`复杂造型测试: 曲线长度 19`] = `1167.5479341842502`; +exports[`复杂造型测试 19`] = `"1167.54793"`; -exports[`复杂造型测试: 曲线长度 20`] = `413.7195254587742`; +exports[`复杂造型测试 20`] = `"413.71953"`; -exports[`复杂造型测试: 曲线长度 21`] = `275.9275697576068`; +exports[`复杂造型测试 21`] = `"275.92757"`; -exports[`复杂造型测试: 曲线长度 22`] = `99.71551046503953`; +exports[`复杂造型测试 22`] = `"99.71551"`; -exports[`复杂造型测试: 曲线长度 23`] = `35.25475681965266`; +exports[`复杂造型测试 23`] = `"35.25476"`; -exports[`复杂造型测试: 曲线长度 24`] = `169.22283273433305`; +exports[`复杂造型测试 24`] = `"169.22283"`; -exports[`复杂造型测试: 曲线长度 25`] = `162.171881370416`; +exports[`复杂造型测试 25`] = `"162.17188"`; -exports[`复杂造型测试: 曲线长度 26`] = `3600`; +exports[`复杂造型测试 26`] = `"3600.00000"`; -exports[`复杂造型测试: 曲线长度 27`] = `106935.16317310504`; +exports[`复杂造型测试 27`] = `"106935.16317"`; -exports[`复杂造型测试: 曲线长度 28`] = `5545.665343214347`; +exports[`复杂造型测试 28`] = `"5545.66534"`; -exports[`复杂造型测试: 曲线长度 29`] = `2581.0848141151123`; +exports[`复杂造型测试 29`] = `"2581.08481"`; -exports[`复杂造型测试: 曲线长度 30`] = `463.19933816470575`; +exports[`复杂造型测试 30`] = `"463.19934"`; -exports[`复杂造型测试: 曲线长度 31`] = `713.891109728082`; +exports[`复杂造型测试 31`] = `"713.89111"`; exports[`复杂造型测试: 走刀数量 1`] = `12`; exports[`复杂造型测试: 走刀数量 2`] = `2`; -exports[`带孔造型板件: 曲线长度 1`] = `3600`; +exports[`带孔造型板件 1`] = `"3600.00000"`; -exports[`带孔造型板件: 曲线长度 2`] = `54665.25127222574`; +exports[`带孔造型板件 2`] = `"54665.25127"`; -exports[`带孔造型板件: 曲线长度 3`] = `4667.086663355046`; +exports[`带孔造型板件 3`] = `"4667.08666"`; -exports[`带孔造型板件: 曲线长度 4`] = `2195.9741153279983`; +exports[`带孔造型板件 4`] = `"2195.97412"`; -exports[`带孔造型板件: 曲线长度 5`] = `1209.6929369796912`; +exports[`带孔造型板件 5`] = `"1209.69294"`; -exports[`带孔造型板件: 曲线长度 6`] = `3600`; +exports[`带孔造型板件 6`] = `"3600.00000"`; -exports[`带孔造型板件: 曲线长度 7`] = `54665.25127222574`; +exports[`带孔造型板件 7`] = `"54665.25127"`; -exports[`带孔造型板件: 曲线长度 8`] = `4667.086663355046`; +exports[`带孔造型板件 8`] = `"4667.08666"`; -exports[`带孔造型板件: 曲线长度 9`] = `2195.9741153279983`; +exports[`带孔造型板件 9`] = `"2195.97412"`; -exports[`带孔造型板件: 曲线长度 10`] = `1209.6929369796912`; +exports[`带孔造型板件 10`] = `"1209.69294"`; exports[`带孔造型板件: 走刀数量 1`] = `2`; exports[`带孔造型板件: 走刀数量 2`] = `2`; -exports[`极限刀半径#I11UDE: 曲线长度 1`] = `4992.8497433755965`; +exports[`极限刀半径 1`] = `"3600.00000"`; -exports[`极限刀半径#I11UDE: 曲线长度 2`] = `2157.303908105796`; +exports[`极限刀半径 2`] = `"1000.00000"`; -exports[`极限刀半径#I11UDE: 曲线长度 3`] = `277.52909999999974`; +exports[`极限刀半径 3`] = `"1740.00000"`; -exports[`极限刀半径#I11UDE: 曲线长度 4`] = `2450.188718291298`; +exports[`极限刀半径 4`] = `"3600.00000"`; -exports[`极限刀半径#I11UDE: 曲线长度 5`] = `2419.4772979202935`; +exports[`极限刀半径 5`] = `"716.16750"`; -exports[`极限刀半径#I11UDE: 走刀数量 1`] = `2`; +exports[`极限刀半径 6`] = `"1552.33596"`; -exports[`极限刀半径: 曲线长度 1`] = `3600`; +exports[`极限刀半径 7`] = `"3600.00000"`; -exports[`极限刀半径: 曲线长度 2`] = `999.9999999999999`; +exports[`极限刀半径 8`] = `"1638.95917"`; -exports[`极限刀半径: 曲线长度 3`] = `1740`; +exports[`极限刀半径 9`] = `"3517.91835"`; -exports[`极限刀半径: 曲线长度 4`] = `3600`; +exports[`极限刀半径 10`] = `"3600.00000"`; -exports[`极限刀半径: 曲线长度 5`] = `716.1675009811012`; +exports[`极限刀半径 11`] = `"600.00000"`; -exports[`极限刀半径: 曲线长度 6`] = `1552.335957639782`; +exports[`极限刀半径 12`] = `"1040.00000"`; -exports[`极限刀半径: 曲线长度 7`] = `3600`; +exports[`极限刀半径 13`] = `"3600.00000"`; -exports[`极限刀半径: 曲线长度 8`] = `1638.9591725161226`; +exports[`极限刀半径 14`] = `"390.00000"`; -exports[`极限刀半径: 曲线长度 9`] = `3517.9183450322453`; +exports[`极限刀半径 15`] = `"900.00000"`; -exports[`极限刀半径: 曲线长度 10`] = `3600`; +exports[`极限刀半径#I11UDE 1`] = `"4992.84974"`; -exports[`极限刀半径: 曲线长度 11`] = `600`; +exports[`极限刀半径#I11UDE 2`] = `"2157.30391"`; -exports[`极限刀半径: 曲线长度 12`] = `1040`; +exports[`极限刀半径#I11UDE 3`] = `"277.52910"`; -exports[`极限刀半径: 曲线长度 13`] = `3600`; +exports[`极限刀半径#I11UDE 4`] = `"2450.18872"`; -exports[`极限刀半径: 曲线长度 14`] = `390`; +exports[`极限刀半径#I11UDE 5`] = `"2419.47730"`; -exports[`极限刀半径: 曲线长度 15`] = `900`; +exports[`极限刀半径#I11UDE: 走刀数量 1`] = `2`; exports[`极限刀半径: 走刀数量 1`] = `1`; @@ -246,152 +246,152 @@ exports[`极限刀半径: 走刀数量 4`] = `1`; exports[`极限刀半径: 走刀数量 5`] = `1`; -exports[`超级复杂造型01: 曲线长度 1`] = `5230.469840585598`; +exports[`超级复杂造型01 1`] = `"5230.46984"`; -exports[`超级复杂造型01: 曲线长度 2`] = `23338.03269164334`; +exports[`超级复杂造型01 2`] = `"23338.03268"`; -exports[`超级复杂造型01: 曲线长度 3`] = `11855.399792240174`; +exports[`超级复杂造型01 3`] = `"11855.39980"`; -exports[`超级复杂造型01: 曲线长度 4`] = `9.894843040787247`; +exports[`超级复杂造型01 4`] = `"9.89484"`; -exports[`超级复杂造型01: 曲线长度 5`] = `34.11040843800545`; +exports[`超级复杂造型01 5`] = `"34.11041"`; -exports[`超级复杂造型01: 曲线长度 6`] = `36.738926324214475`; +exports[`超级复杂造型01 6`] = `"36.73893"`; -exports[`超级复杂造型01: 曲线长度 7`] = `93.09682354812655`; +exports[`超级复杂造型01 7`] = `"93.09682"`; -exports[`超级复杂造型01: 曲线长度 8`] = `3.005160240466534`; +exports[`超级复杂造型01 8`] = `"3.00516"`; -exports[`超级复杂造型01: 曲线长度 9`] = `15.558634753572182`; +exports[`超级复杂造型01 9`] = `"15.55863"`; -exports[`超级复杂造型01: 曲线长度 10`] = `1.5023362215203946`; +exports[`超级复杂造型01 10`] = `"1.50234"`; -exports[`超级复杂造型01: 曲线长度 11`] = `34.11040843800589`; +exports[`超级复杂造型01 11`] = `"34.11041"`; -exports[`超级复杂造型01: 曲线长度 12`] = `36.73892632422102`; +exports[`超级复杂造型01 12`] = `"36.73893"`; -exports[`超级复杂造型01: 曲线长度 13`] = `23.17925136224735`; +exports[`超级复杂造型01 13`] = `"23.17925"`; -exports[`超级复杂造型01: 曲线长度 14`] = `3.0051602404694115`; +exports[`超级复杂造型01 14`] = `"3.00516"`; -exports[`超级复杂造型01: 曲线长度 15`] = `3.0051642696018828`; +exports[`超级复杂造型01 15`] = `"3.00516"`; -exports[`超级复杂造型01: 曲线长度 16`] = `15.558634753573735`; +exports[`超级复杂造型01 16`] = `"15.55863"`; -exports[`超级复杂造型01: 曲线长度 17`] = `1.5023362215224114`; +exports[`超级复杂造型01 17`] = `"1.50234"`; -exports[`超级复杂造型01: 曲线长度 18`] = `9.894843040789354`; +exports[`超级复杂造型01 18`] = `"9.89484"`; -exports[`超级复杂造型01: 曲线长度 19`] = `2.2726434483396147`; +exports[`超级复杂造型01 19`] = `"2.27264"`; -exports[`超级复杂造型01: 曲线长度 20`] = `23.17925136224733`; +exports[`超级复杂造型01 20`] = `"23.17925"`; -exports[`超级复杂造型01: 曲线长度 21`] = `36.73892632421867`; +exports[`超级复杂造型01 21`] = `"36.73893"`; -exports[`超级复杂造型01: 曲线长度 22`] = `34.110408438008804`; +exports[`超级复杂造型01 22`] = `"34.11041"`; -exports[`超级复杂造型01: 曲线长度 23`] = `3.005160240470314`; +exports[`超级复杂造型01 23`] = `"3.00516"`; -exports[`超级复杂造型01: 曲线长度 24`] = `3.0051602404691264`; +exports[`超级复杂造型01 24`] = `"3.00516"`; -exports[`超级复杂造型01: 曲线长度 25`] = `15.558634753574319`; +exports[`超级复杂造型01 25`] = `"15.55863"`; -exports[`超级复杂造型01: 曲线长度 26`] = `1.5023362215216194`; +exports[`超级复杂造型01 26`] = `"1.50234"`; -exports[`超级复杂造型01: 曲线长度 27`] = `9.894843040786107`; +exports[`超级复杂造型01 27`] = `"9.89484"`; -exports[`超级复杂造型01: 曲线长度 28`] = `2.272644014939738`; +exports[`超级复杂造型01 28`] = `"2.27264"`; -exports[`超级复杂造型01: 曲线长度 29`] = `23.179252903170394`; +exports[`超级复杂造型01 29`] = `"23.17925"`; -exports[`超级复杂造型01: 曲线长度 30`] = `36.73892632421504`; +exports[`超级复杂造型01 30`] = `"36.73893"`; -exports[`超级复杂造型01: 曲线长度 31`] = `34.11040843800676`; +exports[`超级复杂造型01 31`] = `"34.11041"`; -exports[`超级复杂造型01: 曲线长度 32`] = `3.0051602404685336`; +exports[`超级复杂造型01 32`] = `"3.00516"`; -exports[`超级复杂造型01: 曲线长度 33`] = `3.0051630894960395`; +exports[`超级复杂造型01 33`] = `"3.00516"`; -exports[`超级复杂造型01: 曲线长度 34`] = `15.558634753573429`; +exports[`超级复杂造型01 34`] = `"15.55863"`; -exports[`超级复杂造型01: 曲线长度 35`] = `1.5023362215210545`; +exports[`超级复杂造型01 35`] = `"1.50234"`; -exports[`超级复杂造型01: 曲线长度 36`] = `9.894843040790184`; +exports[`超级复杂造型01 36`] = `"9.89484"`; -exports[`超级复杂造型01: 曲线长度 37`] = `2.27264424963326`; +exports[`超级复杂造型01 37`] = `"2.27264"`; -exports[`超级复杂造型01: 曲线长度 38`] = `23.179252903170124`; +exports[`超级复杂造型01 38`] = `"23.17925"`; -exports[`超级复杂造型01: 曲线长度 39`] = `36.73892632421585`; +exports[`超级复杂造型01 39`] = `"36.73893"`; -exports[`超级复杂造型01: 曲线长度 40`] = `34.11040843800687`; +exports[`超级复杂造型01 40`] = `"34.11041"`; -exports[`超级复杂造型01: 曲线长度 41`] = `3.005160240469785`; +exports[`超级复杂造型01 41`] = `"3.00516"`; -exports[`超级复杂造型01: 曲线长度 42`] = `3.005164269599573`; +exports[`超级复杂造型01 42`] = `"3.00516"`; -exports[`超级复杂造型01: 曲线长度 43`] = `15.558634753572598`; +exports[`超级复杂造型01 43`] = `"15.55863"`; -exports[`超级复杂造型01: 曲线长度 44`] = `1.5023362215214884`; +exports[`超级复杂造型01 44`] = `"1.50234"`; -exports[`超级复杂造型01: 曲线长度 45`] = `9.894843040792889`; +exports[`超级复杂造型01 45`] = `"9.89484"`; -exports[`超级复杂造型01: 曲线长度 46`] = `2.272643448340335`; +exports[`超级复杂造型01 46`] = `"2.27264"`; -exports[`超级复杂造型01: 曲线长度 47`] = `23.17925136224723`; +exports[`超级复杂造型01 47`] = `"23.17925"`; -exports[`超级复杂造型01: 曲线长度 48`] = `34.11040843800603`; +exports[`超级复杂造型01 48`] = `"34.11041"`; -exports[`超级复杂造型01: 曲线长度 49`] = `36.73892632422722`; +exports[`超级复杂造型01 49`] = `"36.73893"`; -exports[`超级复杂造型01: 曲线长度 50`] = `3.0051602404670064`; +exports[`超级复杂造型01 50`] = `"3.00516"`; -exports[`超级复杂造型01: 曲线长度 51`] = `3.0051602404692153`; +exports[`超级复杂造型01 51`] = `"3.00516"`; -exports[`超级复杂造型01: 曲线长度 52`] = `9.894843040791566`; +exports[`超级复杂造型01 52`] = `"9.89484"`; -exports[`超级复杂造型01: 曲线长度 53`] = `2.2726440149400053`; +exports[`超级复杂造型01 53`] = `"2.27264"`; -exports[`超级复杂造型01: 曲线长度 54`] = `15.558634753570464`; +exports[`超级复杂造型01 54`] = `"15.55863"`; -exports[`超级复杂造型01: 曲线长度 55`] = `1.5023362215189802`; +exports[`超级复杂造型01 55`] = `"1.50234"`; -exports[`超级复杂造型01: 曲线长度 56`] = `11906.411531839705`; +exports[`超级复杂造型01 56`] = `"11906.41153"`; -exports[`超级复杂造型01: 曲线长度 57`] = `464.88809827474097`; +exports[`超级复杂造型01 57`] = `"464.88810"`; -exports[`超级复杂造型01: 曲线长度 58`] = `464.8880982747457`; +exports[`超级复杂造型01 58`] = `"464.88810"`; -exports[`超级复杂造型01: 曲线长度 59`] = `464.8880982747495`; +exports[`超级复杂造型01 59`] = `"464.88810"`; -exports[`超级复杂造型01: 曲线长度 60`] = `464.888098274753`; +exports[`超级复杂造型01 60`] = `"464.88810"`; -exports[`超级复杂造型01: 曲线长度 61`] = `464.88809827475325`; +exports[`超级复杂造型01 61`] = `"464.88810"`; -exports[`超级复杂造型01: 曲线长度 62`] = `464.8880982747512`; +exports[`超级复杂造型01 62`] = `"464.88810"`; -exports[`超级复杂造型01: 曲线长度 63`] = `9277.910642188759`; +exports[`超级复杂造型01 63`] = `"9277.91064"`; exports[`超级复杂造型01: 走刀数量 1`] = `54`; -exports[`通孔造型测试: 曲线长度 1`] = `3600`; +exports[`通孔造型测试 1`] = `"3600.00000"`; -exports[`通孔造型测试: 曲线长度 2`] = `1872.616834159402`; +exports[`通孔造型测试 2`] = `"1872.61683"`; -exports[`通孔造型测试: 曲线长度 3`] = `1896.616834159402`; +exports[`通孔造型测试 3`] = `"1896.61683"`; exports[`通孔造型测试: 走刀数量 1`] = `1`; -exports[`造型的外框和内框厚度小于刀半径厚度: 曲线长度 1`] = `3600`; +exports[`造型的外框和内框厚度小于刀半径厚度 1`] = `"3600.00000"`; exports[`造型的外框和内框厚度小于刀半径厚度: 走刀数量 1`] = `0`; -exports[`造型的外框和内框厚度等于刀直径: 曲线长度 1`] = `3600`; +exports[`造型的外框和内框厚度等于刀直径 1`] = `"3600.00000"`; -exports[`造型的外框和内框厚度等于刀直径: 曲线长度 2`] = `1459.4533999999999`; +exports[`造型的外框和内框厚度等于刀直径 2`] = `"1459.45340"`; -exports[`造型的外框和内框厚度等于刀直径: 曲线长度 3`] = `1483.4533999999999`; +exports[`造型的外框和内框厚度等于刀直径 3`] = `"1483.45340"`; -exports[`造型的外框和内框厚度等于刀直径: 曲线长度 4`] = `1435.4533999999999`; +exports[`造型的外框和内框厚度等于刀直径 4`] = `"1435.45340"`; exports[`造型的外框和内框厚度等于刀直径: 走刀数量 1`] = `1`; diff --git a/__test__/Polyline/__snapshots__/offset.test.ts.snap b/__test__/Polyline/__snapshots__/offset.test.ts.snap index f81300f05..7af8983c5 100644 --- a/__test__/Polyline/__snapshots__/offset.test.ts.snap +++ b/__test__/Polyline/__snapshots__/offset.test.ts.snap @@ -84,7 +84,7 @@ exports[`圆弧错误连接 1`] = `1`; exports[`圆弧错误连接 2`] = `"3624.05703"`; -exports[`圆求交错误导致的线丢失 1`] = `4148.655275462344`; +exports[`圆求交错误导致的线丢失 1`] = `4148.6552754623435`; exports[`圆求交错误导致的线丢失 2`] = `4425.280774659386`; @@ -92,11 +92,11 @@ exports[`圆求交错误导致的线丢失 3`] = `4021.90031602838`; exports[`圆求交错误导致的线丢失 4`] = `4581.224228650713`; -exports[`圆求交错误导致的线丢失 5`] = `3900.6078799293045`; +exports[`圆求交错误导致的线丢失 5`] = `3900.607880862771`; exports[`圆求交错误导致的线丢失 6`] = `4757.468532252452`; -exports[`圆求交错误导致的线丢失 7`] = `3783.7486269390533`; +exports[`圆求交错误导致的线丢失 7`] = `3783.748626939053`; exports[`圆求交错误导致的线丢失 8`] = `4972.0124797019525`; @@ -104,11 +104,11 @@ exports[`圆求交错误导致的线丢失 9`] = `1148.6626298786346`; exports[`圆求交错误导致的线丢失 10`] = `5979.881805331884`; -exports[`圆求交错误导致的线丢失 11`] = `1049.959063092095`; +exports[`圆求交错误导致的线丢失 11`] = `1049.9590630920934`; -exports[`圆求交错误导致的线丢失 12`] = `6051.226636287797`; +exports[`圆求交错误导致的线丢失 12`] = `6051.226636287796`; -exports[`圆求交错误导致的线丢失 13`] = `722.4732418587961`; +exports[`圆求交错误导致的线丢失 13`] = `722.4732418587959`; exports[`圆求交错误导致的线丢失 14`] = `6316.980880964775`; @@ -184,7 +184,7 @@ exports[`简单图形因为点在线内算法错误导致的丢失 3`] = `7.1494 exports[`简单图形因为点在线内算法错误导致的丢失 4`] = `6.693604273021889`; -exports[`精度过高导致无法连接 1`] = `"6723.54629"`; +exports[`精度过高导致无法连接 1`] = `"6723.54625"`; exports[`精度过高导致的曲线丢失 1`] = `1`; @@ -208,7 +208,7 @@ exports[`精度过高导致连接失败 2`] = `"75154.17850"`; exports[`精度过高导致连接失败 3`] = `1`; -exports[`精度过高导致连接失败 4`] = `"91209.36316"`; +exports[`精度过高导致连接失败 4`] = `"91209.36319"`; exports[`精度问题导致的连接错误 1`] = `2`; @@ -224,9 +224,9 @@ exports[`纯圆生成的多段线偏移 3`] = `1`; exports[`纯圆生成的多段线偏移 4`] = `"6328.57819"`; -exports[`补充bug测试 1`] = `7385.123391644346`; +exports[`补充bug测试 1`] = `7385.1233916443525`; -exports[`补充bug测试 2`] = `7455.861403941371`; +exports[`补充bug测试 2`] = `7455.861403941375`; exports[`补圆弧测试 补圆弧测试1 1`] = `1`; @@ -342,10 +342,10 @@ exports[`连续丢圆弧后无法连接 10`] = `"574.66475"`; exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 1`] = `54789.24964851236`; -exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 2`] = `54907.281737806166`; +exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 2`] = `54907.28173780604`; -exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 3`] = `55497.502122668986`; +exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 3`] = `55497.50212266886`; exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 4`] = `56678.24106604484`; -exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 5`] = `57859.37443960543`; +exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 5`] = `57859.37443960544`; diff --git a/__test__/Polyline/__snapshots__/offsetbug.test.ts.snap b/__test__/Polyline/__snapshots__/offsetbug.test.ts.snap index b826bb366..7b619331b 100644 --- a/__test__/Polyline/__snapshots__/offsetbug.test.ts.snap +++ b/__test__/Polyline/__snapshots__/offsetbug.test.ts.snap @@ -1,25 +1,25 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`补充bug测试#IKWGF 1`] = `0.44573953230750973`; +exports[`补充bug测试#IKWGF 1`] = `0.4457395323075094`; exports[`补充bug测试#IKWGF 2`] = `10.732981364094256`; -exports[`补充bug测试#IKWGF 3`] = `1.137640354477355`; +exports[`补充bug测试#IKWGF 3`] = `1.1376403544773555`; -exports[`补充bug测试#IKWGF 4`] = `12.786911814880934`; +exports[`补充bug测试#IKWGF 4`] = `12.786911814880929`; -exports[`补充bug测试#IKWGF 5`] = `10.586693841137812`; +exports[`补充bug测试#IKWGF 5`] = `10.58669384113781`; -exports[`补充bug测试#IKWGF 6`] = `0.624693344084014`; +exports[`补充bug测试#IKWGF 6`] = `0.6246933440840138`; -exports[`补充bug测试#IKWGF 7`] = `14.067113755971715`; +exports[`补充bug测试#IKWGF 7`] = `14.067113755971711`; exports[`补充bug测试#IKWGF 8`] = `11.891017922899252`; exports[`补充bug测试#IKWGF 9`] = `2.168984971098264`; -exports[`补充bug测试#IKWGF 10`] = `0.39474593983901435`; +exports[`补充bug测试#IKWGF 10`] = `0.39474593983901424`; exports[`补充bug测试#IKWGF 11`] = `10.69886845125427`; -exports[`补充bug测试#IKWGF 12`] = `1.0803374679586233`; +exports[`补充bug测试#IKWGF 12`] = `1.0803374679586235`; diff --git a/src/Add-on/DrawRegion.ts b/src/Add-on/DrawRegion.ts index 0943b29ea..5f7cf9739 100644 --- a/src/Add-on/DrawRegion.ts +++ b/src/Add-on/DrawRegion.ts @@ -1,4 +1,6 @@ +import { Matrix4 } from 'three'; import { app } from '../ApplicationServices/Application'; +import { ComputerCurvesNormalOCS } from '../Common/CurveUtils'; import { Curve } from '../DatabaseServices/Entity/Curve'; import { Region } from '../DatabaseServices/Entity/Region'; import { Command } from '../Editor/CommandMachine'; @@ -7,6 +9,7 @@ import { RegionParse, Route } from '../Geometry/RegionParse'; export class DrawRegion implements Command { + ocs: Matrix4; async exec() { let ssRes = await app.Editor.GetSelection({ UseSelect: true, Filter: { filterTypes: [Curve] } }); @@ -16,6 +19,9 @@ export class DrawRegion implements Command let cus = ssRes.SelectSet.SelectEntityList as Curve[]; + this.ocs = ComputerCurvesNormalOCS(cus); + let ocsInv = new Matrix4().getInverse(this.ocs); + let lines: Curve[] = []; for (let cu of cus) @@ -30,7 +36,10 @@ export class DrawRegion implements Command } } else + { + cu.ApplyMatrix(ocsInv); lines.push(cu); + } } if (lines.length > 0) { @@ -45,6 +54,8 @@ export class DrawRegion implements Command { if (reg.GetCueveUsed(cu)) cu.Erase(); + else + cu.ApplyMatrix(this.ocs); } for (let [, cus] of reg.ExpLineMap) @@ -62,6 +73,9 @@ export class DrawRegion implements Command cus.push(r.curve); let reg = Region.CreateFromCurves(cus); if (reg) + { + reg.ApplyMatrix(this.ocs); app.Database.ModelSpace.Append(reg); + } } } diff --git a/src/Add-on/Join.ts b/src/Add-on/Join.ts index 4a7b9fcd8..4fcb770ff 100644 --- a/src/Add-on/Join.ts +++ b/src/Add-on/Join.ts @@ -1,6 +1,6 @@ import { Line3, Vector3 } from "three"; import { app } from "../ApplicationServices/Application"; -import { curveLinkGroup } from "../Common/CurveUtils"; +import { ComputerCurvesNormalOCS, curveLinkGroup } from "../Common/CurveUtils"; import { Status } from "../Common/Status"; import { Arc } from "../DatabaseServices/Entity/Arc"; import { Board, BoardType } from "../DatabaseServices/Entity/Board"; @@ -77,12 +77,8 @@ export class Command_Join implements Command if (g.length === 1) continue; - let pl: Polyline; - if (g[0] instanceof Polyline) - pl = g.shift() as Polyline; - else - pl = new Polyline(); - + let pl = new Polyline(); + pl.OCS = ComputerCurvesNormalOCS(g); for (let cu of g) { pl.Join(cu); @@ -255,4 +251,4 @@ export class Command_Join implements Command brs = remBrs;//更新 } } -} +} diff --git a/src/Common/CurveUtils.ts b/src/Common/CurveUtils.ts index d97d6ffb6..5ef7be34a 100644 --- a/src/Common/CurveUtils.ts +++ b/src/Common/CurveUtils.ts @@ -4,18 +4,19 @@ import { Circle } from '../DatabaseServices/Entity/Circle'; import { Curve } from '../DatabaseServices/Entity/Curve'; import { Ellipse } from '../DatabaseServices/Entity/Ellipse'; import { Line } from '../DatabaseServices/Entity/Line'; -import { IsPointInBowArc } from '../DatabaseServices/PointInPolyline'; import { Polyline } from '../DatabaseServices/Entity/Polyline'; +import { IsPointInBowArc } from '../DatabaseServices/PointInPolyline'; import { Count } from '../Geometry/Count'; import { CurveMap } from '../Geometry/CurveMap'; -import { ZeroVec, equaln, equalv2, equalv3, isParallelTo, AsVector3, AsVector2 } from '../Geometry/GeUtils'; +import { AsVector2, AsVector3, equaln, equalv2, equalv3, isParallelTo, ZeroVec } from '../Geometry/GeUtils'; +import { Orbit } from '../Geometry/Orbit'; import { PlaneExt } from '../Geometry/Plane'; import { Stand } from '../Geometry/RegionParse'; import { IntersectOption, IntersectResult } from '../GraphicsSystem/IntersectWith'; -import { arrayLast, changeArrayStartIndex, equalArray } from './ArrayExt'; import { OffsetPolyline } from '../GraphicsSystem/OffsetPolyline'; -import { FixIndex } from './Utils'; +import { arrayLast, changeArrayStartIndex, equalArray } from './ArrayExt'; import { Status } from './Status'; +import { FixIndex } from './Utils'; //3点获取圆心 export function getCircleCenter(pt1: Vector3, pt2: Vector3, pt3: Vector3) @@ -597,3 +598,54 @@ export function SwapParam(res: IntersectResult[]) } return res; } + +export function ComputerCurvesNormalOCS(curves: Curve[], allowAutoCalc: boolean = true): Matrix4 | undefined +{ + //准备计算多段线的法向量 + let normal: Vector3; + let firstV: Vector3; + for (let c of curves) + { + if (c instanceof Arc) + { + normal = c.Normal; + break; + } + else if (firstV) + { + let v = c.GetFistDeriv(0); + v.cross(firstV); + if (!equalv3(v, ZeroVec)) + { + normal = v.normalize(); + break; + } + } + else + { + let cus = c.Explode() as Curve[]; + let ocs = ComputerCurvesNormalOCS(cus, false); + if (ocs) + return ocs; + firstV = c.GetFistDeriv(0); + } + } + + if (!normal && !allowAutoCalc) return; + + let x = new Vector3(); + let y = new Vector3(); + if (!normal) + { + normal = firstV; + Orbit.ComputUpDirection(normal, y, x); + [x, y, normal] = [normal, x, y]; + } + else + { + if (equalv3(normal, curves[0].Normal.negate())) + normal.negate(); + Orbit.ComputUpDirection(normal, y, x); + } + return new Matrix4().makeBasis(x, y, normal).setPosition(curves[0].StartPoint); +} diff --git a/src/DatabaseServices/Contour.ts b/src/DatabaseServices/Contour.ts index 38f590b8a..c5dec46da 100644 --- a/src/DatabaseServices/Contour.ts +++ b/src/DatabaseServices/Contour.ts @@ -1,9 +1,10 @@ -import { Vector3 } from "three"; +import { Matrix4, Vector3 } from "three"; import { arrayLast, arrayRemoveDuplicateBySort } from "../Common/ArrayExt"; import { curveLinkGroup, equalCurve } from "../Common/CurveUtils"; import { Status } from "../Common/Status"; import { FixIndex } from "../Common/Utils"; import { equaln, equalv2, equalv3 } from "../Geometry/GeUtils"; +import { Orbit } from "../Geometry/Orbit"; import { RegionParse, Route } from "../Geometry/RegionParse"; import { isTargetCurInOrOnSourceCur } from "../GraphicsSystem/BoolOperateUtils"; import { IntersectOption } from "../GraphicsSystem/IntersectWith"; @@ -375,8 +376,6 @@ export class Contour if (cache.has(g)) return cache.get(g); - let pl = new Polyline(); - let gclone = g.map(c => c.Clone()); arrayRemoveDuplicateBySort(gclone, (cu1: Curve, cu2: Curve) => cu1.Join(cu2) === Status.True); @@ -384,16 +383,7 @@ export class Contour if (gclone.length > 1 && gclone[0].Join(arrayLast(gclone))) gclone.pop(); - for (let cu of gclone) - pl.Join(cu, false, tolerance); - - let d = pl.LineData; - if (d.length > 1) - { - let ld = arrayLast(d).pt; - if (equalv2(d[0].pt, ld, tolerance)) - ld.copy(d[0].pt); - } + let pl = Polyline.Combine(gclone, tolerance); cache.set(g, pl); diff --git a/src/DatabaseServices/Entity/Polyline.ts b/src/DatabaseServices/Entity/Polyline.ts index d2d4f9489..b1c580957 100644 --- a/src/DatabaseServices/Entity/Polyline.ts +++ b/src/DatabaseServices/Entity/Polyline.ts @@ -2,7 +2,7 @@ import { Box3, BufferGeometry, Line as TLine, Matrix3, Matrix4, Object3D, Vector import { CreateBoardUtil } from '../../ApplicationServices/mesh/createBoard'; import { arrayLast, arrayRemoveDuplicateBySort, changeArrayStartIndex } from '../../Common/ArrayExt'; import { ColorMaterial } from '../../Common/ColorPalette'; -import { getDeterminantFor2V } from '../../Common/CurveUtils'; +import { ComputerCurvesNormalOCS, getDeterminantFor2V } from '../../Common/CurveUtils'; import { matrixAlignCoordSys, matrixIsCoplane, reviseMirrorMatrix } from '../../Common/Matrix4Utils'; import { Status } from '../../Common/Status'; import { FixIndex } from '../../Common/Utils'; @@ -827,8 +827,6 @@ export class Polyline extends Curve let [sp, ep, cuSp, cuEp] = [this.StartPoint, this.EndPoint, cu.StartPoint, cu.EndPoint]; - if (this._LineData.length === 0) - this.ApplyMatrix(cu.OCS); let ocsInv = this.OCSInv; let [cuSp2, cuEp2] = [cuSp, cuEp].map(p => AsVector2(p.clone().applyMatrix4(ocsInv))); @@ -960,7 +958,33 @@ export class Polyline extends Curve //在上面的其他分支已经返回了假 所以这里直接返回真. this.Update(); return Status.True; - }; + } + + /** + * 将曲线数组组合成多段线 + * @param curves 已经使用CurveLinked的数组,总是首尾相连 + * @returns + */ + static Combine(curves: Curve[], tolerance = 1e-5): Polyline | undefined + { + if (!curves || curves.length === 0) return; + + let pl = new Polyline; + pl.OCS = ComputerCurvesNormalOCS(curves); + + for (let cu of curves) + pl.Join(cu, false, tolerance); + + let d = pl.LineData; + if (d.length > 1) + { + let ld = arrayLast(d).pt; + if (equalv2(d[0].pt, ld, tolerance)) + ld.copy(d[0].pt); + } + + return pl; + } PtOnCurve(pt: Vector3): boolean { diff --git a/src/Geometry/CurveMap.ts b/src/Geometry/CurveMap.ts index ecddec5a1..419bb4dd2 100644 --- a/src/Geometry/CurveMap.ts +++ b/src/Geometry/CurveMap.ts @@ -1,7 +1,8 @@ import { Vector3 } from "three"; +import { ToFixed } from "../Common/Utils"; import { Curve } from "../DatabaseServices/Entity/Curve"; +import { angle, equalv3 } from "./GeUtils"; import { Route, Stand } from "./RegionParse"; -import { ToFixed } from "../Common/Utils"; /** * 曲线地图,使用站点连接. @@ -22,10 +23,7 @@ export class CurveMap /** * 得到节点图的所有站点列表 - * - * @readonly * @type {Stand[]} - * @memberof CurveMap */ get Stands(): Stand[] { @@ -36,12 +34,15 @@ export class CurveMap AddCurveToMap(cu: Curve) { + cu.TempData = 0; let sp = cu.StartPoint; let ep = cu.EndPoint; let startS = this.GetStand(sp); let endS = this.GetStand(ep); let routeS2E: Route = { curve: cu, to: endS, s: sp, e: ep }; + CalcRouteAngle(routeS2E, startS.position); let routeE2S: Route = { curve: cu, to: startS, s: ep, e: sp }; + CalcRouteAngle(routeE2S, endS.position); startS.routes.push(routeS2E); endS.routes.push(routeE2S); } @@ -83,3 +84,11 @@ export class CurveMap return v; } } + +function CalcRouteAngle(r: Route, standPoint: Vector3) +{ + if (equalv3(r.curve.StartPoint, standPoint)) + r.an = angle(r.curve.GetFistDeriv(0)); + else + r.an = angle(r.curve.GetFistDeriv(r.curve.EndParam).negate()); +} diff --git a/src/Geometry/ExtrudeEdgeGeometry2.ts b/src/Geometry/ExtrudeEdgeGeometry2.ts index 86dd5cc7f..4b6198a7d 100644 --- a/src/Geometry/ExtrudeEdgeGeometry2.ts +++ b/src/Geometry/ExtrudeEdgeGeometry2.ts @@ -1218,7 +1218,6 @@ export class ExtrudeGeometryBuilder let gContour = g.ContourCurve.Clone(); gContour.ApplyMatrix(this.alMatrix4); gContour.Z0(); - gContour.TempData = g.Thickness; if (gContour instanceof Polyline) gContour.UpdateMatrixTo(IdentityMtx4);//不可能改变这个 let contour = Contour.CreateContour(gContour); @@ -1229,7 +1228,6 @@ export class ExtrudeGeometryBuilder let c = gg.ContourCurve.Clone(); this.alMatrix4.multiplyMatrices(this.brOcsInv, gg.OCSNoClone); c.ApplyMatrix(this.alMatrix4).Z0(); - c.TempData = g.Thickness; if (c instanceof Polyline) c.UpdateMatrixTo(IdentityMtx4); let contour = Contour.CreateContour(c); holes.push(contour); diff --git a/src/Geometry/RegionParse.ts b/src/Geometry/RegionParse.ts index 1ccefbc2e..ad3dda849 100644 --- a/src/Geometry/RegionParse.ts +++ b/src/Geometry/RegionParse.ts @@ -3,9 +3,9 @@ import { arrayRemoveDuplicateBySort, arrayRemoveIf } from '../Common/ArrayExt'; import { Arc } from '../DatabaseServices/Entity/Arc'; import { Curve } from '../DatabaseServices/Entity/Curve'; import { Polyline } from '../DatabaseServices/Entity/Polyline'; -import { Count } from './Count'; +import { equaln } from '../Nest/Util'; import { CurveMap } from './CurveMap'; -import { angle, equalv3 } from './GeUtils'; +import { equalv3 } from './GeUtils'; //路线 export interface Route @@ -14,6 +14,7 @@ export interface Route to: Stand; //终点的点 s: Vector3; e: Vector3; + an?: number; } @@ -32,9 +33,6 @@ type RegionRouteS = Array>; //区域搜索算法 export class RegionParse { - //曲线使用计数器 - private _CountCu = new Count(); - //区域列表 通常是外轮廓 RegionsOutline: RegionRouteS = []; //区域列表 通常是内轮廓 @@ -44,9 +42,7 @@ export class RegionParse ExpLineMap: Map = new Map(); /** - * Creates an instance of RegionParse. * @param {Curve[]} cuList 请不要传递圆和椭圆. - * @memberof RegionParse */ constructor(cuList: Curve[], public fractionDigits = 3) { @@ -57,21 +53,21 @@ export class RegionParse while (needFinds.size > 0) { //找到最小的站. - let minStand = this.FindMinStand(needFinds); - needFinds.delete(minStand); + let lowerLeftStand = this.FindLowerLeftStand(needFinds); + needFinds.delete(lowerLeftStand); //逆时针+逆时针 - for (let i = minStand.routes.length; i--;) + for (let i = lowerLeftStand.routes.length; i--;) { let wayS = new Set(); let routeS = new Set(); - let isFind = this.FindRegion(minStand, minStand, undefined, wayS, routeS, 1); + let isFind = this.FindRegion(lowerLeftStand, lowerLeftStand, undefined, wayS, routeS, 1); if (isFind) { this.RegionsOutline.push(routeS); //计数增加 for (let route of routeS) - this._CountCu.AddCount(route.curve, 1); - this.FindMinRegion(wayS); + route.curve.TempData += 1; + this.FindInternalRegion(wayS); } } } @@ -79,30 +75,28 @@ export class RegionParse /** * 曲线是否已经被算法使用 - * @param cu - * @returns true if cueve used + * @param cu + * @returns true if cueve used */ GetCueveUsed(cu: Curve): boolean { if (this.ExpLineMap.has(cu)) { - let use = this.ExpLineMap.get(cu).some(c => this._CountCu.GetCount(c) > 0); + let use = this.ExpLineMap.get(cu).some(c => c.TempData > 0); if (!use) this.ExpLineMap.delete(cu); return use; } else - return this._CountCu.GetCount(cu) > 0; + return cu.TempData > 0; } /** * 使用类似涨潮的方式,从最低的地方,采用顺时针填充. * 算法允许搜索到的区域在外轮廓外. - * * @param {Set} standS 外轮廓站点 - * @memberof RegionAlg */ - private FindMinRegion(standS: Set) + FindInternalRegion(standS: Set) { //需要搜索的. let needFinds = new Set(); @@ -114,27 +108,30 @@ export class RegionParse while (needFinds.size > 0) { - //找到最小站 - let minStand = this.FindMinStand(needFinds); + //找到最下方最左边的站点yx + let lowerLeftStand = this.FindLowerLeftStand(needFinds); //添加为已经计算 - passingStands.add(minStand); - needFinds.delete(minStand); + passingStands.add(lowerLeftStand); + needFinds.delete(lowerLeftStand); //顺时针搜索 - for (let j = minStand.routes.length; j--;) + for (let j = lowerLeftStand.routes.length; j--;) { - let route = minStand.routes[j]; + let route = lowerLeftStand.routes[j]; if (!needFinds.has(route.to)) continue; + if (route.curve.TempData === 2) + continue; + let wayS = new Set(); let routeS = new Set(); routeS.add(route); wayS.add(route.to); - let isFindMin = this.FindRegion(minStand, route.to, route.curve, wayS, routeS, 2); + let isFindMin = this.FindRegion(lowerLeftStand, route.to, route.curve, wayS, routeS, 2); if (isFindMin) { regs.push(routeS); @@ -147,7 +144,7 @@ export class RegionParse }); for (let route of routeS) - this._CountCu.AddCount(route.curve, 1); + route.curve.TempData += 1; } } } @@ -157,14 +154,10 @@ export class RegionParse } /** - * 找到左下角的站. - * - * @private + * 找到最下方并且最左边的站 yx * @param {Set} standS - * @returns - * @memberof RegionAlg */ - private FindMinStand(standS: Set) + private FindLowerLeftStand(standS: Set): Stand { let minStand: Stand; for (let stand of standS) @@ -175,24 +168,17 @@ export class RegionParse continue; } if (minStand.position.y > stand.position.y) - { minStand = stand; - } else if (minStand.position.y === stand.position.y && minStand.position.x > stand.position.x) - { minStand = stand; - } } return minStand; } /** * 构造路线图. 每个节点对应下一个路口的路线表. 路口表使用逆时针排序,起始角度使用正x轴. - * - * @private - * @param {Curve[]} cuList + * @param {Curve[]} cuList * @returns {Set} 站点列表 - * @memberof RegionParse */ private GenerateNodeMap(cuList: Curve[]): Set { @@ -210,15 +196,15 @@ export class RegionParse let arcs: Arc[] = []; arrayRemoveIf(cus, c => { + if (c.Length < 1e-5) return true; + if (c instanceof Arc) { let arcBrs = this.BreakArc(c); - if (arcBrs.length > 1) - { - arcs.push(...arcBrs); - return true; - } + for (let arc of arcBrs) + arcs.push(arc); } + return false; }); //加入到计算 @@ -253,18 +239,7 @@ export class RegionParse { s.routes.sort((r1, r2) => { - let a1: number, a2: number; - if (equalv3(r1.curve.StartPoint, s.position)) - a1 = angle(r1.curve.GetFistDeriv(0)); - else - a1 = angle(r1.curve.GetFistDeriv(r1.curve.EndParam).negate()); - - if (equalv3(r2.curve.StartPoint, s.position)) - a2 = angle(r2.curve.GetFistDeriv(0)); - else - a2 = angle(r2.curve.GetFistDeriv(r1.curve.EndParam).negate()); - - return a1 - a2; + return r1.an - r2.an; }); //移除重复的线 @@ -322,7 +297,7 @@ export class RegionParse //下一站 let route = nowStand.routes[index]; - let usedCount = this._CountCu.GetCount(route.curve); + let usedCount = route.curve.TempData; if (usedCount >= cuMaximumCount) continue;