!514 重构偏移算法,优化走刀结果

pull/514/MERGE
ChenX 5 years ago
parent 9a4b8205b2
commit 60f2491d04

@ -18,7 +18,7 @@ exports[`异型板件,常规坐标系 3`] = `2660261.483308105`;
exports[`异型板件,常规坐标系 4`] = `2628158.6443366623`;
exports[`异型板件,常规坐标系 5`] = `2603082.551922608`;
exports[`异型板件,常规坐标系 5`] = `2603082.551922609`;
exports[`异型板件,非常规坐标系 1`] = `75939516.39226122`;

File diff suppressed because one or more lines are too long

@ -1,20 +1,24 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`#IYX1P: 曲线长度 1`] = `1334.7992356906177`;
exports[`#IYX1P: 曲线长度 1`] = `1346.3292345344717`;
exports[`#IYX1P: 曲线长度 2`] = `7092.317327216775`;
exports[`#IYX1P: 曲线长度 2`] = `8468.604267178238`;
exports[`#IYX1P: 曲线长度 3`] = `3600`;
exports[`#IYX1P: 曲线长度 3`] = `10.71238898038469`;
exports[`#IYX1P: 曲线长度 4`] = `1483.4533999999999`;
exports[`#IYX1P: 曲线长度 4`] = `10.71238898038469`;
exports[`#IYX1P: 曲线长度 5`] = `1324.9044565737036`;
exports[`#IYX1P: 曲线长度 5`] = `3600`;
exports[`#IYX1P: 走刀数量 1`] = `2`;
exports[`#IYX1P: 曲线长度 6`] = `1483.4533999999999`;
exports[`刀切到外轮廓情况: 曲线长度 1`] = `22596.75011038597`;
exports[`#IYX1P: 曲线长度 7`] = `1324.9044565737036`;
exports[`刀切到外轮廓情况: 曲线长度 2`] = `6355.243980781998`;
exports[`#IYX1P: 走刀数量 1`] = `4`;
exports[`刀切到外轮廓情况: 曲线长度 1`] = `22596.75011038598`;
exports[`刀切到外轮廓情况: 曲线长度 2`] = `6355.243980782019`;
exports[`刀切到外轮廓情况: 曲线长度 3`] = `3600`;
@ -22,115 +26,155 @@ exports[`刀切到外轮廓情况: 曲线长度 4`] = `1478.9393851461323`;
exports[`刀切到外轮廓情况: 曲线长度 5`] = `729.5688477133849`;
exports[`刀切到外轮廓情况: 曲线长度 6`] = `939.4039853849376`;
exports[`刀切到外轮廓情况: 曲线长度 6`] = `14681.465974109033`;
exports[`刀切到外轮廓情况: 曲线长度 7`] = `13736.355649626326`;
exports[`刀切到外轮廓情况: 曲线长度 7`] = `14658.277022001026`;
exports[`刀切到外轮廓情况: 曲线长度 8`] = `1216.987577519942`;
exports[`刀切到外轮廓情况: 曲线长度 8`] = `14681.465974109033`;
exports[`刀切到外轮廓情况: 曲线长度 9`] = `13428.231939084195`;
exports[`刀切到外轮廓情况: 曲线长度 9`] = `14658.277022000973`;
exports[`刀切到外轮廓情况: 曲线长度 10`] = `939.4039853849374`;
exports[`刀切到外轮廓情况: 曲线长度 10`] = `3600`;
exports[`刀切到外轮廓情况: 曲线长度 11`] = `13736.355649626326`;
exports[`刀切到外轮廓情况: 曲线长度 11`] = `2683.281572999748`;
exports[`刀切到外轮廓情况: 曲线长度 12`] = `13428.23193908413`;
exports[`刀切到外轮廓情况: 曲线长度 12`] = `1800`;
exports[`刀切到外轮廓情况: 曲线长度 13`] = `1216.9875775199384`;
exports[`刀切到外轮廓情况: 走刀数量 1`] = `2`;
exports[`刀切到外轮廓情况: 曲线长度 14`] = `3600`;
exports[`刀切到外轮廓情况: 走刀数量 2`] = `4`;
exports[`刀切到外轮廓情况: 曲线长度 15`] = `2683.281572999748`;
exports[`复杂极限刀半径: 曲线长度 1`] = `232.80420650475034`;
exports[`刀切到外轮廓情况: 曲线长度 16`] = `1800`;
exports[`复杂极限刀半径: 曲线长度 2`] = `806.2513545258738`;
exports[`刀切到外轮廓情况: 走刀数量 1`] = `2`;
exports[`复杂极限刀半径: 曲线长度 3`] = `31170.805670163638`;
exports[`复杂极限刀半径: 曲线长度 4`] = `2917.48021978714`;
exports[`复杂极限刀半径: 曲线长度 5`] = `4434.591784188829`;
exports[`复杂极限刀半径: 曲线长度 6`] = `4356.840832388074`;
exports[`复杂极限刀半径: 曲线长度 7`] = `951.5402172137751`;
exports[`复杂极限刀半径: 曲线长度 8`] = `3278.9179349887763`;
exports[`复杂极限刀半径: 走刀数量 1`] = `5`;
exports[`复杂造型01: 曲线长度 1`] = `59609.750635032455`;
exports[`复杂造型01: 曲线长度 2`] = `1482.4552077856665`;
exports[`复杂造型01: 曲线长度 3`] = `838.7907023816642`;
exports[`复杂造型01: 曲线长度 4`] = `119.2450237058813`;
exports[`复杂造型01: 曲线长度 5`] = `920.6205527518313`;
exports[`刀切到外轮廓情况: 走刀数量 2`] = `8`;
exports[`复杂造型01: 曲线长度 6`] = `136.38881122495832`;
exports[`复杂极限刀半径: 曲线长度 1`] = `1068.3190582501113`;
exports[`复杂造型01: 曲线长度 7`] = `40.76338989846492`;
exports[`复杂极限刀半径: 曲线长度 2`] = `35730.26757931215`;
exports[`复杂造型01: 曲线长度 8`] = `3.2524680966497335`;
exports[`复杂极限刀半径: 曲线长度 3`] = `2927.3167299028455`;
exports[`复杂造型01: 曲线长度 9`] = `301.66992978702626`;
exports[`复杂极限刀半径: 曲线长度 4`] = `4356.840832388074`;
exports[`复杂造型01: 曲线长度 10`] = `1749.8631881230112`;
exports[`复杂极限刀半径: 曲线长度 5`] = `951.5402172137751`;
exports[`复杂造型01: 曲线长度 11`] = `7.8285491298056655`;
exports[`复杂极限刀半径: 曲线长度 6`] = `3278.9179349887763`;
exports[`复杂造型01: 曲线长度 12`] = `2.5692483033658107`;
exports[`复杂极限刀半径: 走刀数量 1`] = `3`;
exports[`复杂造型01: 曲线长度 13`] = `3600`;
exports[`复杂造型01: 曲线长度 14`] = `4316.136010511218`;
exports[`复杂造型01: 曲线长度 15`] = `60.75516885168303`;
exports[`复杂造型01: 曲线长度 16`] = `270.97161059159566`;
exports[`复杂造型01: 曲线长度 17`] = `282.82481905047365`;
exports[`复杂造型01: 曲线长度 18`] = `819.9411466147131`;
exports[`复杂造型01: 曲线长度 19`] = `1463.6056529693449`;
exports[`复杂造型01: 走刀数量 1`] = `12`;
exports[`复杂造型测试: 曲线长度 1`] = `24373.250750763476`;
exports[`复杂造型测试: 曲线长度 2`] = `4285.071854430757`;
exports[`复杂造型测试: 曲线长度 2`] = `4285.071854430756`;
exports[`复杂造型测试: 曲线长度 3`] = `2418.1434517838106`;
exports[`复杂造型测试: 曲线长度 3`] = `2418.1434517838115`;
exports[`复杂造型测试: 曲线长度 4`] = `2293.0762218537734`;
exports[`复杂造型测试: 曲线长度 5`] = `4096.105045378747`;
exports[`复杂造型测试: 曲线长度 5`] = `4096.105045378748`;
exports[`复杂造型测试: 曲线长度 6`] = `910.1341511193466`;
exports[`复杂造型测试: 曲线长度 6`] = `8.0486334855557`;
exports[`复杂造型测试: 曲线长度 7`] = `2841.1337227520216`;
exports[`复杂造型测试: 曲线长度 7`] = `875.5142132396979`;
exports[`复杂造型测试: 曲线长度 8`] = `1079.2736477434973`;
exports[`复杂造型测试: 曲线长度 8`] = `2841.1337227520225`;
exports[`复杂造型测试: 曲线长度 9`] = `227.8342135021163`;
exports[`复杂造型测试: 曲线长度 9`] = `1079.273647743498`;
exports[`复杂造型测试: 曲线长度 10`] = `16.405200898113836`;
exports[`复杂造型测试: 曲线长度 10`] = `227.8342135021163`;
exports[`复杂造型测试: 曲线长度 11`] = `696.1986486992679`;
exports[`复杂造型测试: 曲线长度 11`] = `16.405200898113836`;
exports[`复杂造型测试: 曲线长度 12`] = `639.7910377879329`;
exports[`复杂造型测试: 曲线长度 12`] = `696.1986486992679`;
exports[`复杂造型测试: 曲线长度 13`] = `2402.511185283596`;
exports[`复杂造型测试: 曲线长度 13`] = `639.7910377879329`;
exports[`复杂造型测试: 曲线长度 14`] = `1715.2225461089636`;
exports[`复杂造型测试: 曲线长度 14`] = `2402.511185283596`;
exports[`复杂造型测试: 曲线长度 15`] = `493.42887087968916`;
exports[`复杂造型测试: 曲线长度 15`] = `1715.2225461089636`;
exports[`复杂造型测试: 曲线长度 16`] = `352.7973262382525`;
exports[`复杂造型测试: 曲线长度 16`] = `493.42887087968916`;
exports[`复杂造型测试: 曲线长度 17`] = `342.70973636046426`;
exports[`复杂造型测试: 曲线长度 17`] = `352.7973262382525`;
exports[`复杂造型测试: 曲线长度 18`] = `476.0989607667295`;
exports[`复杂造型测试: 曲线长度 18`] = `342.70973636046426`;
exports[`复杂造型测试: 曲线长度 19`] = `1167.5479341842504`;
exports[`复杂造型测试: 曲线长度 19`] = `476.0989607667295`;
exports[`复杂造型测试: 曲线长度 20`] = `413.7195254587742`;
exports[`复杂造型测试: 曲线长度 20`] = `1167.5479341842504`;
exports[`复杂造型测试: 曲线长度 21`] = `275.9275697576068`;
exports[`复杂造型测试: 曲线长度 21`] = `413.7195254587742`;
exports[`复杂造型测试: 曲线长度 22`] = `99.71551046503953`;
exports[`复杂造型测试: 曲线长度 22`] = `275.9275697576068`;
exports[`复杂造型测试: 曲线长度 23`] = `35.25475681965266`;
exports[`复杂造型测试: 曲线长度 23`] = `99.71551046503953`;
exports[`复杂造型测试: 曲线长度 24`] = `169.22283273433305`;
exports[`复杂造型测试: 曲线长度 24`] = `35.25475681965266`;
exports[`复杂造型测试: 曲线长度 25`] = `162.171881370416`;
exports[`复杂造型测试: 曲线长度 25`] = `169.22283273433305`;
exports[`复杂造型测试: 曲线长度 26`] = `106446.82051696385`;
exports[`复杂造型测试: 曲线长度 26`] = `162.171881370416`;
exports[`复杂造型测试: 曲线长度 27`] = `5545.665343214347`;
exports[`复杂造型测试: 曲线长度 27`] = `104483.03471871806`;
exports[`复杂造型测试: 曲线长度 28`] = `3600`;
exports[`复杂造型测试: 曲线长度 28`] = `2279.1571138841996`;
exports[`复杂造型测试: 曲线长度 29`] = `2581.0848141151123`;
exports[`复杂造型测试: 曲线长度 29`] = `5545.665343214347`;
exports[`复杂造型测试: 曲线长度 30`] = `463.19933816470575`;
exports[`复杂造型测试: 曲线长度 30`] = `3600`;
exports[`复杂造型测试: 曲线长度 31`] = `713.891109728082`;
exports[`复杂造型测试: 曲线长度 31`] = `2581.0848141151123`;
exports[`复杂造型测试: 走刀数量 1`] = `12`;
exports[`复杂造型测试: 曲线长度 32`] = `463.19933816470575`;
exports[`复杂造型测试: 走刀数量 2`] = `2`;
exports[`复杂造型测试: 曲线长度 33`] = `713.891109728082`;
exports[`带孔造型板件: 曲线长度 1`] = `53389.1518227565`;
exports[`复杂造型测试: 走刀数量 1`] = `13`;
exports[`带孔造型板件: 曲线长度 2`] = `4667.086663355046`;
exports[`复杂造型测试: 走刀数量 2`] = `3`;
exports[`带孔造型板件: 曲线长度 1`] = `54662.04598627183`;
exports[`带孔造型板件: 曲线长度 2`] = `4678.35714568232`;
exports[`带孔造型板件: 曲线长度 3`] = `3600`;
@ -138,9 +182,9 @@ exports[`带孔造型板件: 曲线长度 4`] = `2195.9741153279983`;
exports[`带孔造型板件: 曲线长度 5`] = `1209.6929369796912`;
exports[`带孔造型板件: 曲线长度 6`] = `53389.1518227565`;
exports[`带孔造型板件: 曲线长度 6`] = `54662.04598627183`;
exports[`带孔造型板件: 曲线长度 7`] = `4667.086663355046`;
exports[`带孔造型板件: 曲线长度 7`] = `4678.35714568232`;
exports[`带孔造型板件: 曲线长度 8`] = `3600`;
@ -152,17 +196,33 @@ exports[`带孔造型板件: 走刀数量 1`] = `2`;
exports[`带孔造型板件: 走刀数量 2`] = `2`;
exports[`极限刀半径#I11UDE: 曲线长度 1`] = `2434.8330081057957`;
exports[`极限刀半径#I11UDE: 曲线长度 1`] = `2589.4683707776608`;
exports[`极限刀半径#I11UDE: 曲线长度 2`] = `10.71238898038469`;
exports[`极限刀半径#I11UDE: 曲线长度 3`] = `10.71238898038469`;
exports[`极限刀半径#I11UDE: 曲线长度 4`] = `10.71238898038521`;
exports[`极限刀半径#I11UDE: 曲线长度 5`] = `10.712388980384734`;
exports[`极限刀半径#I11UDE: 曲线长度 6`] = `10.71238898038408`;
exports[`极限刀半径#I11UDE: 曲线长度 2`] = `4992.8497433755965`;
exports[`极限刀半径#I11UDE: 曲线长度 7`] = `10.7123889803843`;
exports[`极限刀半径#I11UDE: 曲线长度 3`] = `2450.188718291298`;
exports[`极限刀半径#I11UDE: 曲线长度 8`] = `10.712388980384993`;
exports[`极限刀半径#I11UDE: 曲线长度 4`] = `2419.4772979202935`;
exports[`极限刀半径#I11UDE: 曲线长度 9`] = `10.71238898038469`;
exports[`极限刀半径#I11UDE: 走刀数量 1`] = `1`;
exports[`极限刀半径#I11UDE: 曲线长度 10`] = `4992.8497433755965`;
exports[`极限刀半径: 曲线长度 1`] = `999.9999999999999`;
exports[`极限刀半径#I11UDE: 曲线长度 11`] = `2450.188718291298`;
exports[`极限刀半径#I11UDE: 曲线长度 12`] = `2419.4772979202935`;
exports[`极限刀半径#I11UDE: 走刀数量 1`] = `9`;
exports[`极限刀半径: 曲线长度 1`] = `1314.2477796076937`;
exports[`极限刀半径: 曲线长度 2`] = `3600`;
@ -174,33 +234,193 @@ exports[`极限刀半径: 曲线长度 5`] = `3600`;
exports[`极限刀半径: 曲线长度 6`] = `1552.3359576397822`;
exports[`极限刀半径: 曲线长度 7`] = `1638.9591725161226`;
exports[`极限刀半径: 曲线长度 7`] = `1638.9591725161224`;
exports[`极限刀半径: 曲线长度 8`] = `47.12388980384689`;
exports[`极限刀半径: 曲线长度 8`] = `3600`;
exports[`极限刀半径: 曲线长度 9`] = `47.12388980384689`;
exports[`极限刀半径: 曲线长度 9`] = `3517.9183450322453`;
exports[`极限刀半径: 曲线长度 10`] = `3600`;
exports[`极限刀半径: 曲线长度 10`] = `600`;
exports[`极限刀半径: 曲线长度 11`] = `3517.9183450322453`;
exports[`极限刀半径: 曲线长度 11`] = `3600`;
exports[`极限刀半径: 曲线长度 12`] = `617.1238898038469`;
exports[`极限刀半径: 曲线长度 12`] = `1040`;
exports[`极限刀半径: 曲线长度 13`] = `3600`;
exports[`极限刀半径: 曲线长度 13`] = `390`;
exports[`极限刀半径: 曲线长度 14`] = `1040`;
exports[`极限刀半径: 曲线长度 14`] = `3600`;
exports[`极限刀半径: 曲线长度 15`] = `390`;
exports[`极限刀半径: 曲线长度 15`] = `900`;
exports[`极限刀半径: 曲线长度 16`] = `23.56194490192345`;
exports[`极限刀半径: 曲线长度 17`] = `3600`;
exports[`极限刀半径: 曲线长度 18`] = `900`;
exports[`极限刀半径: 走刀数量 1`] = `1`;
exports[`极限刀半径: 走刀数量 2`] = `1`;
exports[`极限刀半径: 走刀数量 3`] = `1`;
exports[`极限刀半径: 走刀数量 3`] = `3`;
exports[`极限刀半径: 走刀数量 4`] = `1`;
exports[`极限刀半径: 走刀数量 5`] = `1`;
exports[`极限刀半径: 走刀数量 5`] = `2`;
exports[`超级复杂造型01: 曲线长度 1`] = `23310.391778382174`;
exports[`超级复杂造型01: 曲线长度 2`] = `11849.91310995222`;
exports[`超级复杂造型01: 曲线长度 3`] = `9.894843040787247`;
exports[`超级复杂造型01: 曲线长度 4`] = `2.686492242389678`;
exports[`超级复杂造型01: 曲线长度 5`] = `15.558634753572182`;
exports[`超级复杂造型01: 曲线长度 6`] = `1.5023362215203946`;
exports[`超级复杂造型01: 曲线长度 7`] = `36.738926324214475`;
exports[`超级复杂造型01: 曲线长度 8`] = `2.345373451530522`;
exports[`超级复杂造型01: 曲线长度 9`] = `23.179252903171008`;
exports[`超级复杂造型01: 曲线长度 10`] = `34.11040843800545`;
exports[`超级复杂造型01: 曲线长度 11`] = `3.00516024046907`;
exports[`超级复杂造型01: 曲线长度 12`] = `3.005160240466534`;
exports[`超级复杂造型01: 曲线长度 13`] = `3.0051602404694115`;
exports[`超级复杂造型01: 曲线长度 14`] = `3.0051642696018828`;
exports[`超级复杂造型01: 曲线长度 15`] = `23.17925136224735`;
exports[`超级复杂造型01: 曲线长度 16`] = `2.3453734515378883`;
exports[`超级复杂造型01: 曲线长度 17`] = `36.73892632422056`;
exports[`超级复杂造型01: 曲线长度 18`] = `34.11040843800589`;
exports[`超级复杂造型01: 曲线长度 19`] = `9.894843040789354`;
exports[`超级复杂造型01: 曲线长度 20`] = `2.2726434483396147`;
exports[`超级复杂造型01: 曲线长度 21`] = `2.6864922423941437`;
exports[`超级复杂造型01: 曲线长度 22`] = `15.558634753573351`;
exports[`超级复杂造型01: 曲线长度 23`] = `1.5023362215224114`;
exports[`超级复杂造型01: 曲线长度 24`] = `23.17925136224733`;
exports[`超级复杂造型01: 曲线长度 25`] = `2.345373451535995`;
exports[`超级复杂造型01: 曲线长度 26`] = `36.73892632421837`;
exports[`超级复杂造型01: 曲线长度 27`] = `34.110408438008804`;
exports[`超级复杂造型01: 曲线长度 28`] = `3.005160240470314`;
exports[`超级复杂造型01: 曲线长度 29`] = `3.0051602404691264`;
exports[`超级复杂造型01: 曲线长度 30`] = `2.686492242389917`;
exports[`超级复杂造型01: 曲线长度 31`] = `15.558634753574319`;
exports[`超级复杂造型01: 曲线长度 32`] = `1.5023362215216194`;
exports[`超级复杂造型01: 曲线长度 33`] = `9.894843040786107`;
exports[`超级复杂造型01: 曲线长度 34`] = `2.272644014939738`;
exports[`超级复杂造型01: 曲线长度 35`] = `23.179252903170394`;
exports[`超级复杂造型01: 曲线长度 36`] = `2.3453734515314206`;
exports[`超级复杂造型01: 曲线长度 37`] = `36.73892632421504`;
exports[`超级复杂造型01: 曲线长度 38`] = `34.11040843800676`;
exports[`超级复杂造型01: 曲线长度 39`] = `3.0051602404685336`;
exports[`超级复杂造型01: 曲线长度 40`] = `3.0051630894960395`;
exports[`超级复杂造型01: 曲线长度 41`] = `2.6864922423866937`;
exports[`超级复杂造型01: 曲线长度 42`] = `15.558634753573163`;
exports[`超级复杂造型01: 曲线长度 43`] = `1.5023362215210545`;
exports[`超级复杂造型01: 曲线长度 44`] = `9.894843040790184`;
exports[`超级复杂造型01: 曲线长度 45`] = `2.27264424963326`;
exports[`超级复杂造型01: 曲线长度 46`] = `23.179252903170124`;
exports[`超级复杂造型01: 曲线长度 47`] = `2.345373451550585`;
exports[`超级复杂造型01: 曲线长度 48`] = `36.738926324216564`;
exports[`超级复杂造型01: 曲线长度 49`] = `34.11040843800687`;
exports[`超级复杂造型01: 曲线长度 50`] = `3.005160240469785`;
exports[`超级复杂造型01: 曲线长度 51`] = `3.005164269599573`;
exports[`超级复杂造型01: 曲线长度 52`] = `2.686492242390355`;
exports[`超级复杂造型01: 曲线长度 53`] = `15.558634753572672`;
exports[`超级复杂造型01: 曲线长度 54`] = `1.5023362215214884`;
exports[`超级复杂造型01: 曲线长度 55`] = `9.894843040792889`;
exports[`超级复杂造型01: 曲线长度 56`] = `2.272643448340335`;
exports[`超级复杂造型01: 曲线长度 57`] = `23.17925136224723`;
exports[`超级复杂造型01: 曲线长度 58`] = `2.345373451548128`;
exports[`超级复杂造型01: 曲线长度 59`] = `36.73892632422722`;
exports[`超级复杂造型01: 曲线长度 60`] = `34.11040843800603`;
exports[`超级复杂造型01: 曲线长度 61`] = `3.0051602404692153`;
exports[`超级复杂造型01: 曲线长度 62`] = `3.0051602404670064`;
exports[`超级复杂造型01: 曲线长度 63`] = `2.686492242390764`;
exports[`超级复杂造型01: 曲线长度 64`] = `15.558634753570397`;
exports[`超级复杂造型01: 曲线长度 65`] = `1.5023362215189802`;
exports[`超级复杂造型01: 曲线长度 66`] = `9.894843040791566`;
exports[`超级复杂造型01: 曲线长度 67`] = `2.2726440149400053`;
exports[`超级复杂造型01: 曲线长度 68`] = `5230.469840585598`;
exports[`超级复杂造型01: 曲线长度 69`] = `11906.411531839705`;
exports[`超级复杂造型01: 曲线长度 70`] = `464.88809827474097`;
exports[`超级复杂造型01: 曲线长度 71`] = `464.8880982747457`;
exports[`超级复杂造型01: 曲线长度 72`] = `464.8880982747495`;
exports[`超级复杂造型01: 曲线长度 73`] = `464.888098274753`;
exports[`超级复杂造型01: 曲线长度 74`] = `464.88809827475325`;
exports[`超级复杂造型01: 曲线长度 75`] = `464.8880982747512`;
exports[`超级复杂造型01: 曲线长度 76`] = `9277.910642188759`;
exports[`超级复杂造型01: 走刀数量 1`] = `67`;
exports[`通孔造型测试: 曲线长度 1`] = `1872.616834159402`;
@ -214,12 +434,18 @@ exports[`造型的外框和内框厚度小于刀半径厚度: 曲线长度 1`] =
exports[`造型的外框和内框厚度小于刀半径厚度: 走刀数量 1`] = `0`;
exports[`造型的外框和内框厚度等于刀直径: 曲线长度 1`] = `1459.4533999999999`;
exports[`造型的外框和内框厚度等于刀直径: 曲线长度 1`] = `1468.0153449019233`;
exports[`造型的外框和内框厚度等于刀直径: 曲线长度 2`] = `10.71238898038469`;
exports[`造型的外框和内框厚度等于刀直径: 曲线长度 3`] = `10.712388980384869`;
exports[`造型的外框和内框厚度等于刀直径: 曲线长度 4`] = `10.71238898038469`;
exports[`造型的外框和内框厚度等于刀直径: 曲线长度 2`] = `3600`;
exports[`造型的外框和内框厚度等于刀直径: 曲线长度 5`] = `3600`;
exports[`造型的外框和内框厚度等于刀直径: 曲线长度 3`] = `1483.4533999999999`;
exports[`造型的外框和内框厚度等于刀直径: 曲线长度 6`] = `1483.4533999999999`;
exports[`造型的外框和内框厚度等于刀直径: 曲线长度 4`] = `1435.4533999999999`;
exports[`造型的外框和内框厚度等于刀直径: 曲线长度 7`] = `1435.4533999999999`;
exports[`造型的外框和内框厚度等于刀直径: 走刀数量 1`] = `1`;
exports[`造型的外框和内框厚度等于刀直径: 走刀数量 1`] = `4`;

@ -15,13 +15,13 @@ test('2个大圆中间', () =>
let isR = GetPointAtCurveDir(pl, new Vector3(110.19, 17.4));
expect(isR).toBeFalsy();
expect(isR).toBe(-1);
let p = new Vector3().fromArray([84.89024786541306, 11.031154321671167, 0]);
isR = GetPointAtCurveDir(pl, p);
expect(isR).toBeTruthy();
expect(isR).toBe(1);
});
test('点在端点且端点平行', () =>
@ -64,7 +64,7 @@ test('点在端点上且点在圆心上', () =>
let p = new Vector3(19.48, 8.1097);
let isR = GetPointAtCurveDir(pl, p);
expect(isR).toBeFalsy();
expect(isR).toBe(-1);
});
@ -95,7 +95,7 @@ test('存在精度误差,并且点在圆内', () =>
let isR = GetPointAtCurveDir(pl, p);
expect(isR).toBeFalsy();
expect(isR).toBe(-1);
}
});
@ -112,7 +112,7 @@ test('大于1凸度的圆', () =>
let isR = GetPointAtCurveDir(pl, pt);
expect(isR).toBeFalsy();
expect(isR).toBe(-1);
});
test('盲区计算', () =>
@ -127,7 +127,7 @@ test('盲区计算', () =>
let isR = GetPointAtCurveDir(pl, pt);
expect(isR).toBeFalsy();
expect(isR).toBe(-1);
pl.Reverse();
isR = GetPointAtCurveDir(pl, pt);
@ -146,7 +146,7 @@ test('参数点在终点上', () =>
let pl = f.ReadObject() as Polyline;
let pt = new Vector3().fromArray([24.40481807693597, 4.679455426066854, 0]);
let isR = GetPointAtCurveDir(pl, pt);
expect(isR).toBeFalsy();
expect(isR).toBe(-1);
pt = new Vector3().fromArray([30.314368267468268, 10.71117601112483, 0]);
isR = GetPointAtCurveDir(pl, pt);
@ -154,7 +154,7 @@ test('参数点在终点上', () =>
pl.Reverse();
isR = GetPointAtCurveDir(pl, pt);
expect(isR).toBeFalsy();
expect(isR).toBe(-1);
pt = new Vector3().fromArray([24.40481807693597, 4.679455426066854, 0]);
isR = GetPointAtCurveDir(pl, pt);
@ -173,7 +173,7 @@ test('点在小角内', () =>
let pt = new Vector3().fromArray([-45.25245903106504, 20.057300217471017, 0]);
let isR = GetPointAtCurveDir(pl, pt);
expect(isR).toBeFalsy();
expect(isR).toBe(-1);
pl.Reverse();
isR = GetPointAtCurveDir(pl, pt);
@ -195,7 +195,7 @@ test('首尾点相等', () =>
pl.Reverse();
isR = GetPointAtCurveDir(pl, pt);
expect(isR).toBeFalsy();
expect(isR).toBe(-1);
});
@ -209,7 +209,7 @@ test('点在圆弧的弦中心上', () =>
let pt = new Vector3().fromArray([4.999999999999999, 2.5, 0]);
let isR = GetPointAtCurveDir(pl, pt);
expect(isR).toBeFalsy();
expect(isR).toBe(-1);
pt = new Vector3().fromArray([5, 9.5, 0]);
isR = GetPointAtCurveDir(pl, pt);
@ -233,11 +233,11 @@ test('圆弧过大导致直线小角错误', () =>
let pt = new Vector3().fromArray([-2246.7733894227954, -220.1844621837422, 0]);
let isR = GetPointAtCurveDir(pl, pt);
expect(isR).toBeFalsy();
expect(isR).toBe(-1);
pt = new Vector3().fromArray([-2184.668414731696, -221.35723534211996, 0]);
//[1,["Circle",1,1,4,false,7,-1,[1,0,0,0,0,1,0,0,0,0,1,0,-2184,-221.357,0,1],1,1]]
isR = GetPointAtCurveDir(pl, pt);
expect(isR).toBeFalsy();
expect(isR).toBe(-1);
});

@ -16,33 +16,101 @@ exports[`中间区域需要圆裁剪 1`] = `1`;
exports[`中间区域需要圆裁剪 2`] = `"24.71130"`;
exports[`圆求交错误导致的线丢失 1`] = `4148.6552839918695`;
exports[`假圆弧交点选点直连 1`] = `1`;
exports[`圆求交错误导致的线丢失 2`] = `4425.280774659357`;
exports[`假圆弧交点选点直连 2`] = `"903.79892"`;
exports[`圆求交错误导致的线丢失 3`] = `4021.9003332433485`;
exports[`判断点在线上错误导致的偏移错误 1`] = `1`;
exports[`圆求交错误导致的线丢失 4`] = `4581.2242286506635`;
exports[`判断点在线上错误导致的偏移错误 2`] = `"119778.26631"`;
exports[`圆求交错误导致的线丢失 5`] = `3900.607906945287`;
exports[`双圆偏移导致求延伸点错误 1`] = `1`;
exports[`圆求交错误导致的线丢失 6`] = `4757.46853225238`;
exports[`双圆偏移导致求延伸点错误 2`] = `"787.87800"`;
exports[`圆求交错误导致的线丢失 7`] = `3783.7486621001212`;
exports[`双圆偏移导致求延伸点错误 3`] = `1`;
exports[`圆求交错误导致的线丢失 8`] = `4972.012479701851`;
exports[`双圆偏移导致求延伸点错误 4`] = `"168.83973"`;
exports[`圆求交错误导致的线丢失 9`] = `1148.663268759687`;
exports[`双圆可能只有一个交点的问题 1`] = `1`;
exports[`圆求交错误导致的线丢失 10`] = `5979.881810920418`;
exports[`双圆可能只有一个交点的问题 2`] = `"6744.69470"`;
exports[`圆求交错误导致的线丢失 11`] = `1049.9599133172633`;
exports[`圆弧全丢时需要扇形切割 1`] = `1`;
exports[`圆求交错误导致的线丢失 12`] = `6051.226641876329`;
exports[`圆弧全丢时需要扇形切割 2`] = `"4844.93527"`;
exports[`圆求交错误导致的线丢失 13`] = `722.4732418587954`;
exports[`圆弧全部丢失 1`] = `1`;
exports[`圆求交错误导致的线丢失 14`] = `6316.980887212943`;
exports[`圆弧全部丢失 2`] = `"1623.41712"`;
exports[`圆弧如果连接就自交,需要补圆弧才能解决 1`] = `1`;
exports[`圆弧如果连接就自交,需要补圆弧才能解决 2`] = `"948.21488"`;
exports[`圆弧连接后逆向 1`] = `1`;
exports[`圆弧连接后逆向 2`] = `"4159.59625"`;
exports[`圆弧连接成圆 1`] = `7`;
exports[`圆弧连接成圆 2`] = `"139.57806"`;
exports[`圆弧连接成圆 3`] = `"359.72091"`;
exports[`圆弧连接成圆 4`] = `"486.59311"`;
exports[`圆弧连接成圆 5`] = `"359.72091"`;
exports[`圆弧连接成圆 6`] = `"423.15701"`;
exports[`圆弧连接成圆 7`] = `"423.15701"`;
exports[`圆弧连接成圆 8`] = `"486.59311"`;
exports[`圆弧选点实例 1`] = `1`;
exports[`圆弧选点实例 2`] = `"1.33642"`;
exports[`圆弧错误的直连(需要验证是否可以连接,避免反向连接) 1`] = `1`;
exports[`圆弧错误的直连(需要验证是否可以连接,避免反向连接) 2`] = `"3880.28257"`;
exports[`圆弧错误的直连(需要验证是否可以连接,避免反向连接) 3`] = `1`;
exports[`圆弧错误的直连(需要验证是否可以连接,避免反向连接) 4`] = `"3791.62583"`;
exports[`圆弧错误连接 1`] = `1`;
exports[`圆弧错误连接 2`] = `"3624.05703"`;
exports[`圆求交错误导致的线丢失 1`] = `4148.655275462344`;
exports[`圆求交错误导致的线丢失 2`] = `4425.280774659386`;
exports[`圆求交错误导致的线丢失 3`] = `4021.90031602838`;
exports[`圆求交错误导致的线丢失 4`] = `4581.224228650713`;
exports[`圆求交错误导致的线丢失 5`] = `3900.6078799293045`;
exports[`圆求交错误导致的线丢失 6`] = `4757.468532252452`;
exports[`圆求交错误导致的线丢失 7`] = `3783.7486269390533`;
exports[`圆求交错误导致的线丢失 8`] = `4972.0124797019525`;
exports[`圆求交错误导致的线丢失 9`] = `1148.6626298786346`;
exports[`圆求交错误导致的线丢失 10`] = `5979.881805331884`;
exports[`圆求交错误导致的线丢失 11`] = `1049.959063092095`;
exports[`圆求交错误导致的线丢失 12`] = `6051.226636287797`;
exports[`圆求交错误导致的线丢失 13`] = `722.4732418587961`;
exports[`圆求交错误导致的线丢失 14`] = `6316.980880964775`;
exports[`复杂圆盘选点 1`] = `1`;
@ -84,6 +152,18 @@ exports[`拱门偏移 3`] = `1`;
exports[`拱门偏移 4`] = `"6.82743"`;
exports[`极限刀半径偏移 1`] = `2`;
exports[`极限刀半径偏移 2`] = `"500.00000"`;
exports[`极限刀半径偏移 3`] = `"250.00000"`;
exports[`正确的裁剪多段线 1`] = `2`;
exports[`正确的裁剪多段线 2`] = `"1.81330"`;
exports[`正确的裁剪多段线 3`] = `"4.43077"`;
exports[`海豚圆选点导致的错误 1`] = `1`;
exports[`海豚圆选点导致的错误 2`] = `"1591.19822"`;
@ -92,13 +172,49 @@ exports[`海豚圆选点导致的错误 3`] = `1`;
exports[`海豚圆选点导致的错误 4`] = `"1827.63524"`;
exports[`点在多段线内 1`] = `1`;
exports[`点在多段线内 2`] = `"1589.94630"`;
exports[`简单图形因为点在线内算法错误导致的丢失 1`] = `8.675189454805244`;
exports[`简单图形因为点在线内算法错误导致的丢失 2`] = `8.252841733482935`;
exports[`简单图形因为点在线内算法错误导致的丢失 3`] = `6.802689012735881`;
exports[`简单图形因为点在线内算法错误导致的丢失 3`] = `7.1494048498542835`;
exports[`简单图形因为点在线内算法错误导致的丢失 4`] = `6.693604273021889`;
exports[`精度过高导致无法连接 1`] = `"6721.53910"`;
exports[`精度过高导致的曲线丢失 1`] = `1`;
exports[`精度过高导致的曲线丢失 2`] = `"86945.68009"`;
exports[`精度过高导致的曲线丢失 3`] = `1`;
exports[`精度过高导致的曲线丢失 4`] = `"97661.61008"`;
exports[`精度过高导致直连失败 1`] = `1`;
exports[`精度过高导致直连失败 2`] = `"32040.01360"`;
exports[`精度过高导致直连失败 3`] = `1`;
exports[`精度过高导致直连失败 4`] = `"32045.24858"`;
exports[`精度过高导致连接失败 1`] = `1`;
exports[`简单图形因为点在线内算法错误导致的丢失 4`] = `6.045609380056393`;
exports[`精度过高导致连接失败 2`] = `"75154.17850"`;
exports[`精度过高导致连接失败 3`] = `1`;
exports[`精度过高导致连接失败 4`] = `"91209.36327"`;
exports[`精度问题导致的连接错误 1`] = `2`;
exports[`精度问题导致的连接错误 2`] = `"19.40228"`;
exports[`精度问题导致的连接错误 3`] = `"19.40228"`;
exports[`纯圆生成的多段线偏移 1`] = `1`;
@ -108,9 +224,9 @@ exports[`纯圆生成的多段线偏移 3`] = `1`;
exports[`纯圆生成的多段线偏移 4`] = `"6328.57819"`;
exports[`补充bug测试 1`] = `7385.123391644449`;
exports[`补充bug测试 1`] = `7385.123391644346`;
exports[`补充bug测试 2`] = `7455.861403941378`;
exports[`补充bug测试 2`] = `7455.861403941371`;
exports[`补圆弧测试 补圆弧测试1 1`] = `1`;
@ -200,12 +316,36 @@ exports[`补圆弧测试 补圆弧测试1 43`] = `1`;
exports[`补圆弧测试 补圆弧测试1 44`] = `"192.58327"`;
exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 1`] = `54789.24964851234`;
exports[`被补圆弧的裁剪圆所裁剪导致的曲线丢失(和CAD一样) 1`] = `1`;
exports[`被补圆弧的裁剪圆所裁剪导致的曲线丢失(和CAD一样) 2`] = `"1771.95957"`;
exports[`连续丢圆弧后无法连接 1`] = `1`;
exports[`连续丢圆弧后无法连接 2`] = `"1310.80545"`;
exports[`连续丢圆弧后无法连接 3`] = `7`;
exports[`连续丢圆弧后无法连接 4`] = `"574.66475"`;
exports[`连续丢圆弧后无法连接 5`] = `"1182.81794"`;
exports[`连续丢圆弧后无法连接 6`] = `"574.66475"`;
exports[`连续丢圆弧后无法连接 7`] = `"574.66475"`;
exports[`连续丢圆弧后无法连接 8`] = `"574.66475"`;
exports[`连续丢圆弧后无法连接 9`] = `"574.66475"`;
exports[`连续丢圆弧后无法连接 10`] = `"574.66475"`;
exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 1`] = `54789.24964851236`;
exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 2`] = `54907.281737806145`;
exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 2`] = `54907.281737806166`;
exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 3`] = `55497.50212266897`;
exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 3`] = `55497.502122668986`;
exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 4`] = `56678.24106604482`;
exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 4`] = `56678.24106604484`;
exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 5`] = `57859.374439605526`;
exports[`闭合多段线判断精度和重复交点参数导致偏移丢失 5`] = `57859.37443960543`;

@ -1,25 +1,25 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`补充bug测试#IKWGF 1`] = `1.1376403544773552`;
exports[`补充bug测试#IKWGF 1`] = `0.44573953230750973`;
exports[`补充bug测试#IKWGF 2`] = `0.44573953236152686`;
exports[`补充bug测试#IKWGF 2`] = `10.732981364094256`;
exports[`补充bug测试#IKWGF 3`] = `10.732981364094256`;
exports[`补充bug测试#IKWGF 3`] = `1.137640354477355`;
exports[`补充bug测试#IKWGF 4`] = `12.78691181488093`;
exports[`补充bug测试#IKWGF 4`] = `12.786911814880934`;
exports[`补充bug测试#IKWGF 5`] = `0.6246933440840137`;
exports[`补充bug测试#IKWGF 5`] = `10.586693841137812`;
exports[`补充bug测试#IKWGF 6`] = `10.586693752451833`;
exports[`补充bug测试#IKWGF 6`] = `0.624693344084014`;
exports[`补充bug测试#IKWGF 7`] = `14.067113755971711`;
exports[`补充bug测试#IKWGF 7`] = `14.067113755971715`;
exports[`补充bug测试#IKWGF 8`] = `2.168984971098264`;
exports[`补充bug测试#IKWGF 8`] = `11.891017922899252`;
exports[`补充bug测试#IKWGF 9`] = `11.89101792289927`;
exports[`补充bug测试#IKWGF 9`] = `2.168984971098264`;
exports[`补充bug测试#IKWGF 10`] = `1.0803374679586235`;
exports[`补充bug测试#IKWGF 10`] = `0.39474593983901435`;
exports[`补充bug测试#IKWGF 11`] = `0.39474593983890793`;
exports[`补充bug测试#IKWGF 11`] = `10.69886845125427`;
exports[`补充bug测试#IKWGF 12`] = `10.69886845125427`;
exports[`补充bug测试#IKWGF 12`] = `1.0803374679586233`;

File diff suppressed because one or more lines are too long

@ -6,6 +6,7 @@ import { GangDrill } from "../DatabaseServices/3DSolid/GangDrill";
import { CADFiler } from "../DatabaseServices/CADFiler";
import { Board } from "../DatabaseServices/Entity/Board";
import { PromptStatus } from "../Editor/PromptResult";
import { deflate } from "../Common/SerializeMaterial";
export class CopyClip
{
@ -43,9 +44,10 @@ export class CopyClip
for (let e of ens)
f.WriteObject(e);
copyTextToClipboard(JSON.stringify({
let str = JSON.stringify({
file: f.Data,
basePt,
}));
});
copyTextToClipboard(str);
}
}

@ -724,7 +724,7 @@ export class FilletUtils
let line = lineRes.Entity as Line;
let arc = arcRes.Entity as Arc;
let dir = GetPointAtCurveDir(line, arc.Center) ? 1 : -1;
let dir = GetPointAtCurveDir(line, arc.Center);
let lineO = line.GetOffsetCurves(this.FilletRadius * dir)[0];
let arcO = arc.GetOffsetCurves(this.FilletRadius * (arc.IsClockWise ? -1 : 1))[0];// tip面积逆时针为正, 顺时针为负.

@ -2,10 +2,13 @@ import { Vector3 } from 'three';
import { app } from '../ApplicationServices/Application';
import { GetPointAtCurveDir } from '../Common/CurveUtils';
import { Curve } from '../DatabaseServices/Entity/Curve';
import { Polyline } from '../DatabaseServices/Entity/Polyline';
import { Command } from '../Editor/CommandMachine';
import { JigUtils } from '../Editor/JigUtils';
import { PromptStatus } from '../Editor/PromptResult';
const OffsetKey = "offset";
//获取偏移距离的返回状态.
type GetOffsetStatus = { Status: PromptStatus, offsetDist?: number };
@ -13,22 +16,35 @@ type GetOffsetStatus = { Status: PromptStatus, offsetDist?: number };
export class Command_Offset implements Command
{
offsetDis: number = 1;
isDyn = false;
constructor()
{
let o = window.localStorage.getItem(OffsetKey);
if (o)
this.offsetDis = parseFloat(o) || this.offsetDis;
}
async exec()
{
this.isDyn = false;
let disRes = await app.Editor.GetDistance({
Msg: "指定偏移距离:",
KeyWordList: [{ msg: "通过:", key: "T" }],
Default: this.offsetDis
});
let isDyn = false;//动态偏移.
if (disRes.StringResult === "T")
isDyn = true;
this.isDyn = true;
else if (disRes.Status === PromptStatus.OK)
this.offsetDis = disRes.Distance;
this.UpdateDistance(disRes.Distance);
else
return;
await this.Run();
app.Viewer.OutlinePass.selectedObjects = [];
}//end exec
async Run()
{
let oldUCS = app.Editor.UCSMatrix;
while (true)
{
@ -49,7 +65,7 @@ export class Command_Offset implements Command
{
app.Viewer.OutlinePass.selectedObjects = [cu.DrawObject];
let state: GetOffsetStatus;
if (isDyn)
if (this.isDyn)
state = await this.GetDynOffsetDist(cu);
else
state = await this.GetOffsetDir(cu);
@ -65,15 +81,19 @@ export class Command_Offset implements Command
}
app.Editor.UCSMatrix = oldUCS;
}//end exec
}
UpdateDistance(offsetDist: number)
{
this.offsetDis = offsetDist || this.offsetDis;
window.localStorage.setItem(OffsetKey, this.offsetDis.toString());
}
//绘制偏移的对象
DrawOffset(cu: Curve, offsetDist: number)
{
cu.GetOffsetCurves(offsetDist).forEach(c =>
{
for (let c of cu.GetOffsetCurves(offsetDist))
app.Database.ModelSpace.Append(c);
});
}
//单一对象,已经确定偏移距离的时候,用户选择偏移方向.
@ -87,7 +107,7 @@ export class Command_Offset implements Command
Msg: "指定要偏移的那一侧的点",
Callback: (p: Vector3) =>
{
let dir = GetPointAtCurveDir(cu, p) ? 1 : -1;
let dir = GetPointAtCurveDir(cu, p);
if (dir !== oldDir)
{
JigUtils.Destroy();
@ -101,7 +121,7 @@ export class Command_Offset implements Command
let status = { Status: ptRes.Status, offsetDist: 0 };
if (ptRes.Status === PromptStatus.OK)
{
let dir = GetPointAtCurveDir(cu, ptRes.Point) ? 1 : -1;
let dir = GetPointAtCurveDir(cu, ptRes.Point);
status.offsetDist = this.offsetDis * dir;
}
return status;
@ -113,6 +133,9 @@ export class Command_Offset implements Command
let basePoint: Vector3 = new Vector3();
let isMulti = false;
let cuOcsInv = cu.OCSInv;
let cuOCs = cu.OCS;
while (true)
{
let dir: number = 0;
@ -123,8 +146,9 @@ export class Command_Offset implements Command
BasePoint: basePoint,
CalcDistance: (baseP, p: Vector3) =>
{
p.applyMatrix4(cuOcsInv).setZ(0).applyMatrix4(cuOCs);
basePoint.copy(cu.GetClosestPointTo(p, false));
dir = GetPointAtCurveDir(cu, p) ? 1 : -1;
dir = GetPointAtCurveDir(cu, p);
return p.distanceTo(basePoint) * dir;
},
Callback: (dis: number) =>
@ -133,7 +157,6 @@ export class Command_Offset implements Command
cu.GetOffsetCurves(dis).forEach(c => JigUtils.Draw(c));
}
});
if (distRes.Status === PromptStatus.OK)
{
let offsetDist = distRes.Distance;
@ -156,3 +179,54 @@ export class Command_Offset implements Command
}
}
}
export class Command_DynOffset extends Command_Offset
{
async exec()
{
this.isDyn = true;
await this.Run();
app.Viewer.OutlinePass.selectedObjects = [];
}
}
export class Command_DynOffsetToolPath
{
async exec()
{
let enRes = await app.Editor.GetEntity({ Filter: { filterTypes: [Polyline] } });
if (enRes.Status !== PromptStatus.OK) return;
let pl = enRes.Entity as Polyline;
let basePoint: Vector3 = new Vector3();
let dir: number = 0;
let distRes = await app.Editor.GetDistance(
{
Msg: "指定通过点或输入偏移距离:",
BasePoint: basePoint,
CalcDistance: (baseP, p: Vector3) =>
{
basePoint.copy(pl.GetClosestPointTo(p, false));
dir = GetPointAtCurveDir(pl, p);
return p.distanceTo(basePoint) * dir;
},
Callback: (dis: number) =>
{
JigUtils.Destroy();
pl.GetFeedingToolPath(dis).forEach(c => JigUtils.Draw(c));
}
});
if (distRes.Status === PromptStatus.OK)
{
let offsetDist = distRes.Distance;
if (dir !== Math.sign(offsetDist))
offsetDist = -offsetDist;
let pls = pl.GetFeedingToolPath(offsetDist);
for (let pl of pls)
app.Database.ModelSpace.Append(pl);
}
}
}

@ -1,82 +1,47 @@
import { app } from "../ApplicationServices/Application";
import { Curve } from "../DatabaseServices/Entity/Curve";
import { Polyline } from "../DatabaseServices/Entity/Polyline";
import { Command } from "../Editor/CommandMachine";
import { PromptStatus } from "../Editor/PromptResult";
import { Vector3 } from "three";
import { HotCMD } from "../Hot/HotCommand";
import { TestDraw } from "./test/TestUtil";
//无限内偏移
@HotCMD
export class OffsetX implements Command
{
offsetDis: number = 1;
async exec()
{
let ssRes = await app.Editor.GetEntity();
let ssRes = await app.Editor.GetEntity({ Msg: "选择多段线进行偏移测试:", Filter: { filterTypes: [Polyline] } });
if (ssRes.Status != PromptStatus.OK) return;
let pl = ssRes.Entity as Polyline;
if (!pl) return;
let dis: number, step: number;
if (window["autoDis"])
{
this.offsetDis = 1.2 * Math.max(...pl.BoundingBox.getSize(new Vector3()).toArray());
dis = -this.offsetDis;
step = this.offsetDis / 20;
}
else
{
let disRes = await app.Editor.GetDistance({
Msg: "指定偏移距离:",
KeyWordList: [{ msg: "通过", key: "T" }],
Default: this.offsetDis
});
if (disRes.Status != PromptStatus.OK) return;
this.offsetDis = disRes.Distance;
dis = -this.offsetDis;
if (pl.IsClockWise) dis = -dis;
let disRes1 = await app.Editor.GetDistance({
Msg: "步长:",
KeyWordList: [{ msg: "通过", key: "T" }],
Default: 1
});
if (disRes1.Status != PromptStatus.OK) return;
step = disRes1.Distance;
}
// let step = 0.5;
let offRes: Polyline[] = [];
// offRes.push(...pl.GetOffsetCurves(dis) as Polyline[]);
let offsetDis = Math.abs(disRes.Distance);
TestDraw(pl.GetFeedingToolPath(offsetDis * Math.sign(pl.Area2)), 3);//外偏移
// for (let i = 0; i < offRes.length; i++)
// {
// let offpl = offRes[i];
// if (offpl.IsClose)
// {
// offRes.push(...offpl.GetOffsetCurves(dis) as Polyline[]);
// }
// }
let offsetQueue: Curve[] = [pl];
if (step === 0)
while (offsetQueue.length > 0)
{
app.Editor.Prompt("步长不能为0,已经帮你转换成" + dis / 10);
step = dis / 10;
}
let count = dis / step;
for (let i = 0; i < count; i++)
let pl = offsetQueue.pop() as Polyline;
let offsets = pl.GetFeedingToolPath(offsetDis * -Math.sign(pl.Area2));
for (let c of offsets)
{
offRes.push(...pl.GetOffsetCurves(i * step) as Polyline[]);
offRes.push(...pl.GetOffsetCurves(-i * step) as Polyline[]);
if (i > 50)
if (c.IsClose)
{
alert("执行次数太多,怕你卡死,帮你停止了!");
break;
TestDraw(c, 4);
offsetQueue.push(c);
}
else
TestDraw(c, 5);
}
}
offRes.forEach(c => app.Database.ModelSpace.Append(c));
}
}

@ -1,5 +1,6 @@
import { Vector3 } from "three";
import { app } from "../ApplicationServices/Application";
import { inflate } from "../Common/SerializeMaterial";
import { readClipboardText } from "../Common/Utils";
import { CADFiler } from "../DatabaseServices/CADFiler";
import { Entity } from "../DatabaseServices/Entity/Entity";
@ -14,6 +15,8 @@ export class PasteClip
try
{
let str = await readClipboardText();
if (str.startsWith("zip:"))
str = inflate(str.slice(4));
data = JSON.parse(str);
}
catch (error)

@ -9,6 +9,7 @@ import { RightPanelStore } from '../UI/Store/RightPanelStore/RightPanelStore';
export class Save implements Command
{
NoHistory = true;
async exec()
{
let fileServer = FileServer.GetInstance() as FileServer;

@ -3,6 +3,7 @@ import { Command } from '../Editor/CommandMachine';
export class Undo implements Command
{
NoHistory = true;
async exec()
{
app.Database.hm.Undo();
@ -12,6 +13,7 @@ export class Undo implements Command
export class Redo implements Command
{
NoHistory = true;
async exec()
{
app.Database.hm.Redo();

@ -5,6 +5,7 @@ import { Orbit } from "../Geometry/Orbit";
export class ViewChange implements Command
{
NoHistory = true;
constructor(private viewDir: Vector3, private useWCS = false)
{
viewDir.normalize();

@ -62,7 +62,7 @@ export class Command_ClosePt implements Command
dyn.UpdatePrompt("点在线内外?:" + IsPointInPolyLine(cu, p));
closeCir.Center = p;
closeCir.ColorIndex = GetPointAtCurveDir(cu, p) ? 1 : 2;
closeCir.ColorIndex = GetPointAtCurveDir(cu, p) + 3;
}
}
})

@ -0,0 +1,115 @@
import { app } from "../../../ApplicationServices/Application";
import { Arc } from "../../../DatabaseServices/Entity/Arc";
import { Entity } from "../../../DatabaseServices/Entity/Entity";
import { Point } from "../../../DatabaseServices/Entity/Point";
import { Polyline } from "../../../DatabaseServices/Entity/Polyline";
import { Region } from "../../../DatabaseServices/Entity/Region";
import { OffsetPolyline } from "../../../GraphicsSystem/OffsetPolyline";
import { TestDraw } from "../TestUtil";
export class OffsetTestUtil extends OffsetPolyline
{
constructor(_Polyline: Polyline, _OffsetDist: number, _ToolPath = false)
{
super(_Polyline, _OffsetDist, _ToolPath)
}
//----TEST
TestDrawPolyline()
{
this.OffsetSubCurves();
app.Editor.Prompt("开始绘制多段线")
for (let i = 0; i < this._SubCurves.length; i++)
{
let c = this._SubCurves[i].Clone().ApplyMatrix(this._CacheOCS);
c.ColorIndex = i + 1;
TestDraw(c);
for (let d of this._SubOffsetedCurves)
{
if (d.index === i)
{
let c2 = d.curve.Clone().ApplyMatrix(this._CacheOCS);
c2.ColorIndex = i + 1;
TestDraw(c2);
}
}
}
}
TestDrawLinkSubCurve()
{
app.Editor.Prompt("开始显示曲线连接");
for (let i = 0; i < this._SubOffsetedCurves.length; i++)
{
let d = this._SubOffsetedCurves[i];
let c = d.curve.Clone();
if (d.sp || d.ep)
{
if (d.sp) c.StartPoint = d.sp;
if (d.ep) c.EndPoint = d.ep;
}
c.ColorIndex = d.index + 1;
c.ApplyMatrix(this._CacheOCS);
TestDraw(c);
if (d.paddingCurve)
{
for (let c of d.paddingCurve)
{
let arc = c.Clone().ApplyMatrix(this._CacheOCS) as Arc;
let p = new Point(arc.Center);
TestDraw(p);
p.Erase();
arc.ColorIndex = d.index + 1;
TestDraw(arc);
}
}
}
}
TestDrawTrimCircle()
{
app.Editor.Prompt("开始显示裁剪圆弧");
for (let i = 0; i < this._TrimCircleContours.length; i++)
{
let c = this._TrimCircleContours[i].Clone().ApplyMatrix(this._CacheOCS);
let region = Region.CreateFromCurves([c]);
region.ColorIndex = i + 1;
TestDraw(region);
}
}
TestDrawTriContours()
{
app.Editor.Prompt("开始显示裁剪轮廓");
for (let i = 0; i < this._TrimPolylineContours.length; i++)
{
let c = this._TrimPolylineContours[i].Curve.Clone().ApplyMatrix(this._CacheOCS);
let region = Region.CreateFromCurves([c]);
region.ColorIndex = i + 1;
TestDraw(region);
}
}
TestDrawRetCurves()
{
app.Editor.Prompt("开始绘制最终结果");
for (let i = 0; i < this._RetCurves.length; i++)
{
let c = this._RetCurves[i];
TestDraw(c);
}
}
TestTrimedCurve()
{
let i = 1;
for (let c of this._CurveTrimedTreeNodes)
{
TestDraw(c.curve.ApplyMatrix(this._CacheOCS), i);
i++
}
}
}

@ -0,0 +1,85 @@
import { Box3 } from "three";
import { begin } from "xaop";
import { app } from "../../../ApplicationServices/Application";
import { JigMoveEntity } from "../../../Common/JigMove";
import { CADFiler } from "../../../DatabaseServices/CADFiler";
import { Entity } from "../../../DatabaseServices/Entity/Entity";
import { Polyline } from "../../../DatabaseServices/Entity/Polyline";
import { ObjectSnapMode } from "../../../Editor/ObjectSnapMode";
import { TestDraw } from "../TestUtil";
import { OffsetTestUtil } from "./OffsetTestUtil";
export function LoadEntityFromFileData(data)
{
if (!Array.isArray(data))
data = data.file;
let file = new CADFiler();
file.Data = data;
let ens: Entity[] = [];
let count = file.Read();
if (typeof count !== "number")
{
count = file.Data.length;
file.Reset();
}
for (let i = 0; i < count; i++)
{
ens.push(file.ReadObject() as Entity);
}
return ens;
}
async function TestOffset(cud: Object, offsetDist: number | number[], count?: number)
{
let ds = (typeof offsetDist === "number") ? [offsetDist] : offsetDist;
let ents: Entity[] = [];
let rm = begin(app.Database.ModelSpace, app.Database.ModelSpace.AppendEvent, (e: Entity) =>
{
ents.push(e);
});
app.Editor.GetPointServices.snapServices.SnapModeEnable = ObjectSnapMode.Node;
for (let d of ds)
{
let pl = LoadEntityFromFileData(cud)[0] as Polyline;
app.Editor.UpdateScreen();
let u = new OffsetTestUtil(pl, d, true);
u.Do();
for (let step = 1; step < 6; step++)
{
u.Do();
ents.length = 0;
TestDraw(pl.Clone());
if (step === 1)
{
u.TestDrawPolyline();
}
else if (step === 2)
{
u.TestDrawLinkSubCurve();
}
else if (step === 3)
u.TestDrawTriContours();
else if (step === 4)
u.TestTrimedCurve();
else if (step === 5)
{
let i = 1;
for (let c of u._RetCurves)
{
TestDraw(c, i);
i++;
}
}
let b = new Box3();
for (let e of ents)
b.union(e.BoundingBox);
await JigMoveEntity(ents, b.min)
}
}
rm();
}

@ -0,0 +1,22 @@
import { Object3D } from "three";
import { app } from "../../ApplicationServices/Application";
import { Entity } from "../../DatabaseServices/Entity/Entity";
export function TestDraw(en: Entity | Entity[] | Object3D, colorIndex = 0)
{
if (en instanceof Object3D)
app.Viewer.Scene.add(en);
else if (en instanceof Entity)
{
if (colorIndex > 0)
en.ColorIndex = colorIndex;
app.Database.ModelSpace.Append(en);
}
else
for (let e of en)
{
if (colorIndex > 0)
e.ColorIndex = colorIndex;
app.Database.ModelSpace.Append(e);
}
}

@ -4,19 +4,24 @@ import { app } from "../../ApplicationServices/Application";
import { PromptStatus } from "../../Editor/PromptResult";
import { Board } from "../../DatabaseServices/Entity/Board";
import { Production } from "../../Production/Product";
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
import { Matrix4 } from "three";
@HotCMD
export class Test implements Command
{
async exec()
{
let enRes = await app.Editor.GetEntity();
let enRes = await app.Editor.GetSelection({});
if (enRes.Status === PromptStatus.OK)
{
let en = enRes.Entity as Board;
let en = enRes.SelectSet.SelectEntityList as Polyline[];
console.log(Production.GetBoardSplitOrderData(en));
for (let e of en)
{
if (e.IsClockWise) e.ColorIndex = 1;
}
}
}
}

@ -13,7 +13,7 @@ import { PlaneExt } from '../Geometry/Plane';
import { Stand } from '../Geometry/RegionParse';
import { IntersectOption } from '../GraphicsSystem/IntersectWith';
import { arrayLast, changeArrayStartIndex, equalArray } from './ArrayExt';
import { FixIndex } from './Utils';
import { OffsetPolyline } from '../GraphicsSystem/OffsetPolyline';
//3点获取圆心
export function getCircleCenter(pt1: Vector3, pt2: Vector3, pt3: Vector3)
@ -102,7 +102,7 @@ export function curveLinkGroup(cus: Curve[]): Array<Array<Curve>>
if (cus.length === 0) return groupCus;
//曲线节点图
let cuMap = new CurveMap();
cus.forEach(c => cuMap.addCurveToMap(c));
cus.forEach(c => cuMap.AddCurveToMap(c));
//曲线站点表
let stands = cuMap.Stands;
@ -266,121 +266,26 @@ export function equalCurve(cu1: Curve, cu2: Curve, tolerance = 1e-4)
*
* @param {Curve} cu
* @param {Vector3} pt
* @returns {boolean} false,true
* @returns {boolean} -1,1
*/
export function GetPointAtCurveDir(cu: Curve, pt: Vector3): boolean
export function GetPointAtCurveDir(cu: Curve, pt: Vector3): number
{
if (cu instanceof Circle)
return !cu.PtInCurve(pt);
//TODO: 当T字形多段线时,最近点将重叠,导致方向结果出错
return cu.PtInCurve(pt) ? -1 : 1;
else if (cu instanceof Polyline)
{
let u = new OffsetPolyline(cu, 1);
u.InitSubCurves();
return u.GetPointAtCurveDir(pt.clone().applyMatrix4(cu.OCSInv).setZ(0));
}
//最近点
let cp = cu.GetClosestPointTo(pt, false);
if (equalv3(cp, pt, 1e-6)) return 0;
//最近点参数
let cparam = cu.GetParamAtPoint(cp);
//归一化最近点参数
let floorParam = Math.round(cparam);
//当最近点在参数上时,可能产生退化,在这里重新计算合适的最近点和切线.
if (
cu instanceof Polyline
&& equaln(floorParam, cparam, 1e-2)
&&
(cu.IsClose || (floorParam !== 0 && floorParam !== cu.EndParam))
)
{
let plVerCount = cu.NumberOfVertices;
if (equalv2(cu.GetPoint2dAt(0), cu.GetPoint2dAt(plVerCount - 1)))
plVerCount--;
//分三点,本点,前一个点,后一个点
if (floorParam === cu.EndParam) floorParam = 0;
let fIndex = FixIndex(floorParam - 1, plVerCount);
let p = cu.GetPointAtParam(floorParam);
let cu1 = cu.GetCurveAtIndex(fIndex);
let cu2 = cu.GetCurveAtIndex(floorParam);
let cu1Length = cu1.Length;
let cu2Length = cu2.Length;
let minLength = Math.min(cu1Length, cu2Length);
let fDer: Vector3;
let nDer: Vector3;
if (equaln(cu.GetBuilgeAt(fIndex), 0))
fDer = cu.GetFistDeriv(fIndex).normalize();
else
{
let tp = cu1.GetPointAtDistance(cu1Length - minLength * 0.25);
fDer = tp.negate().add(p).normalize();
}
if (equaln(cu.GetBuilgeAt(floorParam), 0))
nDer = cu.GetFistDeriv(floorParam).normalize();
else
{
let tp = cu2.GetPointAtDistance(minLength * 0.25);
nDer = tp.sub(p).normalize();
}
let l1 = new Line(p.clone().sub(fDer.clone().multiplyScalar(300)), p);
l1.ColorIndex = 1;
let l2 = new Line(p, p.clone().add(nDer.clone().multiplyScalar(200)));
l2.ColorIndex = 2;
let cp1 = l1.GetClosestPointTo(pt, true);
let cp2 = l2.GetClosestPointTo(pt, true);
// T 型曲线
let nDerN = nDer.clone().negate();
if (equalv3(fDer, nDerN))
{
let frontParam = floorParam;
while (frontParam > 1)
{
let fp = cu.GetPointAtParam(frontParam - 1.2);
fDer.copy(p).sub(fp).normalize();
if (!equalv3(fDer, nDerN))
break;
frontParam--;
}
if (frontParam <= 1)
{
let nextParam = floorParam;
let endParam = cu.EndParam - 1;
while (nextParam < endParam)
{
let np = cu.GetPointAtParam(nextParam + 1.2);
nDer = np.sub(p).normalize();
if (!equalv3(fDer, nDerN))
break;
nextParam++;
}
}
}
if (equalv3(fDer, nDer))
return fDer.cross(pt.clone().sub(cp1)).applyMatrix4(cu.OCSInv).z < 0;
let adir = Math.sign(fDer.clone().cross(nDer).applyMatrix4(cu.OCSInv).z);
//判断点是否在小角内.
if (
Math.sign(fDer.cross(pt.clone().sub(cp1)).applyMatrix4(cu.OCSInv).z) === adir
&& Math.sign(nDer.cross(pt.clone().sub(cp2)).applyMatrix4(cu.OCSInv).z) === adir
)
return adir < 0;
else
return adir > 0;
}
let dri = cu.GetFistDeriv(cparam);
let cross = dri.cross(pt.clone().sub(cp)).applyMatrix4(cu.OCSInv);
return cross.z < 0;
return -Math.sign(cross.z);
}
/**

@ -0,0 +1,45 @@
/**
* Decimal adjustment of a number.
*
* @param {String} type The type of adjustment.
* @param {Number} value The number.
* @param {Integer} exp The exponent (the 10 logarithm of the adjustment base).
* @returns {Number} The adjusted value.
*/
function decimalAdjust(type: string, value: number | (string | number)[], exp: number): number
{
// If the exp is undefined or zero...
if (typeof exp === 'undefined' || +exp === 0)
{
return Math[type](value);
}
value = +value;
exp = +exp;
// If the value is not a number or the exp is not an integer...
if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
{
return NaN;
}
// Shift
value = value.toString().split('e');
value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
// Shift back
value = value.toString().split('e');
return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
}
// Decimal round
export function round10(value: number, exp: number): number
{
return decimalAdjust('round', value, exp);
};
// Decimal floor
function floor10(value: number, exp: number): number
{
return decimalAdjust('floor', value, exp);
};
// Decimal ceil
function ceil10(value: number, exp: number): number
{
return decimalAdjust('ceil', value, exp);
};

@ -184,6 +184,18 @@ export class Arc extends Curve
{
return this.AllAngle * this.m_Radius;
}
GetParamAtPoint2(pt: Vector3): number
{
return this.GetParamAtAngle(this.GetAngleAtPoint(pt));
}
//点在曲线上,已经确定点在曲线的延伸线上
PtOnCurve3(p: Vector3, fuzz = 1e-6): boolean
{
let param = this.GetParamAtPoint2(p);
return this.ParamOnCurve(param, fuzz);
}
protected ApplyScaleMatrix(m: Matrix4): this
{
this.WriteAllObjectRecord();
@ -232,7 +244,7 @@ export class Arc extends Curve
{
if (this.m_Radius == 0 ||
this.AllAngle == 0 ||
!equaln(pt.distanceTo(this.Center), this.m_Radius, 1e-8))
!equaln(pt.distanceTo(this.Center), this.m_Radius, 1e-6))
return NaN;
return this.GetParamAtAngle(this.GetAngleAtPoint(pt));

@ -35,14 +35,14 @@ export class Circle extends Curve
{
super();
center && this._Matrix.setPosition(center);
this.m_Radius = radius;
this._Radius = radius;
}
private m_Radius: number;
private _Radius: number;
get Shape()
{
let sp = new Shape();
sp.ellipse(0, 0, this.m_Radius, this.m_Radius, 0, 2 * Math.PI, false, 0);
sp.ellipse(0, 0, this._Radius, this._Radius, 0, 2 * Math.PI, false, 0);
return sp;
}
@ -58,12 +58,12 @@ export class Circle extends Curve
}
get Radius()
{
return this.m_Radius;
return this._Radius;
}
set Radius(v: number)
{
this.WriteAllObjectRecord();
this.m_Radius = clamp(v, 1e-9, 1e19);
this._Radius = clamp(v, 1e-9, 1e19);
this.Update();
}
@ -107,11 +107,15 @@ export class Circle extends Curve
}
get Area()
{
return Math.PI * Math.pow(this.m_Radius, 2);
return Math.PI * this._Radius ** 2;
}
get Area2()
{
return Math.PI * this._Radius ** 2;
}
get Length()
{
return Math.PI * 2 * this.m_Radius;
return Math.PI * 2 * this._Radius;
}
get IsClose(): boolean
@ -119,20 +123,23 @@ export class Circle extends Curve
return true;
}
//曲线为顺时针
get IsClockWise(): boolean { return false; }
GetPointAtParam(param: number)
{
return (polar(new Vector3(), param * 2 * Math.PI, this.m_Radius) as Vector3).applyMatrix4(this._Matrix);
return (polar(new Vector3(), param * 2 * Math.PI, this._Radius) as Vector3).applyMatrix4(this._Matrix);
}
GetPointAtDistance(distance: number)
{
let param = distance / (Math.PI * 2 * this.m_Radius);
let param = distance / (Math.PI * 2 * this._Radius);
return this.GetPointAtParam(param);
}
GetDistAtParam(param: number)
{
return Math.PI * 2 * this.m_Radius * param;
return Math.PI * 2 * this._Radius * param;
}
GetDistAtPoint(pt: Vector3)
@ -143,7 +150,7 @@ export class Circle extends Curve
GetParamAtDist(d: number)
{
return d / (Math.PI * 2 * this.m_Radius);
return d / (Math.PI * 2 * this._Radius);
}
GetSplitCurves(param: number[] | number)
@ -171,7 +178,7 @@ export class Circle extends Curve
let ea = anglelist[i + 1];
if (!equaln(sa, ea, 1e-6))
{
let arc = new Arc(new Vector3(), this.m_Radius, sa, ea);
let arc = new Arc(new Vector3(), this._Radius, sa, ea);
arc.ApplyMatrix(this.OCS);
curvelist.push(arc);
}
@ -190,14 +197,14 @@ export class Circle extends Curve
PtOnCurve(pt: Vector3)
{
return equaln(pt.distanceToSquared(this.Center), this.m_Radius * this.m_Radius, 1e-5);
return equaln(pt.distanceToSquared(this.Center), this._Radius * this._Radius, 1e-5);
}
GetOffsetCurves(offsetDist: number)
{
if ((offsetDist + this.m_Radius) > 0)
if ((offsetDist + this._Radius) > 0)
{
let circle = this.Clone();
circle.Radius = this.m_Radius + offsetDist;
circle.Radius = this._Radius + offsetDist;
return [circle];
}
return []
@ -241,7 +248,7 @@ export class Circle extends Curve
}
UpdateDrawObject(type: RenderType, obj: Object3D)
{
obj.children[0].scale.set(this.m_Radius, this.m_Radius, this.m_Radius);
obj.children[0].scale.set(this._Radius, this._Radius, this._Radius);
obj.children[0].updateMatrix();
}
UpdateDrawObjectMaterial(type: RenderType, obj: Object3D, material: Material)
@ -262,10 +269,10 @@ export class Circle extends Curve
{
let pts = [
new Vector3(),
new Vector3(0, this.m_Radius),
new Vector3(0, -this.m_Radius),
new Vector3(-this.m_Radius, 0),
new Vector3(this.m_Radius, 0),
new Vector3(0, this._Radius),
new Vector3(0, -this._Radius),
new Vector3(-this._Radius, 0),
new Vector3(this._Radius, 0),
];
let ocs = this.OCS;
@ -382,14 +389,14 @@ export class Circle extends Curve
{
super._ReadFile(file);
let ver = file.Read();
this.m_Radius = file.Read();
this._Radius = file.Read();
}
//对象将自身数据写入到文件.
WriteFile(file: CADFiler)
{
super.WriteFile(file);
file.Write(1);
file.Write(this.m_Radius);
file.Write(this._Radius);
}
//#endregion
}

@ -69,6 +69,8 @@ export abstract class Curve extends Entity
GetDistAtParam(param: number): number { return; }
GetDistAtPoint(pt: Vector3): number { return; }
GetParamAtPoint(pt: Vector3): number { return; }
GetParamAtPoint2(pt: Vector3): number { return this.GetParamAtPoint(pt); }
GetParamAtDist(d: number): number { return; }
/**
@ -140,6 +142,12 @@ export abstract class Curve extends Entity
return !(equalv3(this.StartPoint, pt, 1e-6) || equalv3(this.EndPoint, pt, 1e-6)) && this.ParamOnCurve(this.GetParamAtPoint(pt), 0);
}
//点在曲线上,已经确定点在曲线的延伸线上
PtOnCurve3(p: Vector3, fuzz = 1e-6): boolean
{
return this.PtOnCurve(p, fuzz);
}
//参数在曲线上 容差,1e-6
ParamOnCurve(param: number, fuzz = 1e-6): boolean { return !isNaN(param) && param >= -fuzz && param <= this.EndParam + fuzz; }
GetOffsetCurves(offsetDist: number): Array<Curve> { return; }

@ -210,7 +210,7 @@ export class Entity extends CADObject
}
UpdateRenderType(type: RenderType)
{
if (this.OnlyRenderType || !this.Visible) return;
if ((this.OnlyRenderType && this.DrawObject.children.length > 0) || !this.Visible) return;
Object3DRemoveAll(this.DrawObject);
let obj = this.GetDrawObjectFromRenderType(type);
if (obj) this.DrawObject.add(obj);

@ -73,7 +73,7 @@ export class ExtrudeSolid extends Entity
protected grooves: ExtrudeSolid[] = [];
protected knifeRadius: number = 3;
protected groovesAddLength: number = 3;
protected groovesAddLength: number = 0;
protected groovesAddWidth: number = 0;
protected groovesAddDepth: number = 0;

@ -227,6 +227,19 @@ export class Line extends Curve
return ret;
}
GetParamAtPoint2(pt: Vector3): number
{
let { param } = this.GetClosestAtPoint(pt, true);
return param;
}
//点在曲线上,已经确定点在曲线的延伸线上
PtOnCurve3(p: Vector3, fuzz = 1e-6): boolean
{
let { param } = this.GetClosestAtPoint(p, true);
return this.ParamOnCurve(param, fuzz);
}
GetClosestAtPoint(pt: Vector3, extend: boolean): { closestPt: Vector3, param: number }
{
let sp = this.StartPoint;

@ -10,7 +10,7 @@ import { ObjectSnapMode } from '../../Editor/ObjectSnapMode';
import { BufferGeometryUtils } from '../../Geometry/BufferGeometryUtils';
import { AsVector2, AsVector3, equaln, equalv2, equalv3, updateGeometry } from '../../Geometry/GeUtils';
import { IntersectOption, IntersectPolylineAndCurve } from '../../GraphicsSystem/IntersectWith';
import { PolyOffsetUtil } from '../../GraphicsSystem/OffsetPolyline';
import { OffsetPolyline } from '../../GraphicsSystem/OffsetPolyline';
import { RenderType } from '../../GraphicsSystem/RenderType';
import { Factory } from '../CADFactory';
import { CADFiler } from '../CADFiler';
@ -877,9 +877,27 @@ export class Polyline extends Curve
PtOnCurve(pt: Vector3): boolean
{
let param = this.GetParamAtPoint(pt);
return this.ParamOnCurve(param);
for (let i = 0; i < this.EndParam; i++)
{
let c = this.GetCurveAtIndex(i);
if (c.PtOnCurve(pt))
return true;
}
return false;
}
//点在曲线上,已经确定点在曲线的延伸线上
PtOnCurve3(p: Vector3, fuzz = 1e-6): boolean
{
for (let i = 0; i < this.EndParam; i++)
{
let c = this.GetCurveAtIndex(i);
if (c.PtOnCurve3(p, fuzz))
return true;
}
return false;
}
PtInCurve(pt: Vector3)
{
return this.IsClose && IsPointInPolyLine(this, pt);
@ -946,13 +964,15 @@ export class Polyline extends Curve
//偏移
GetOffsetCurves(offsetDist: number): Array<Curve>
{
let polyOffestUtil = new PolyOffsetUtil(this, offsetDist);
return polyOffestUtil.GetOffsetCurves();
if (equaln(offsetDist, 0)) return [];
let polyOffestUtil = new OffsetPolyline(this, offsetDist);
return polyOffestUtil.Do();
}
GetFeedingToolPath(offsetDist: number): Array<Curve>
{
let polyOffestUtil = new PolyOffsetUtil(this, offsetDist);
return polyOffestUtil.GetOffsetCurves(true);
if (equaln(offsetDist, 0)) return [];
let polyOffestUtil = new OffsetPolyline(this, offsetDist, true);
return polyOffestUtil.Do();
}
/**
*
@ -1280,7 +1300,7 @@ export class Polyline extends Curve
arc.MoveGripPoints([2], moveVec);
this.m_LineData[frontIndex].bul = arc.Bul;
}
if (this.GetBuilgeAt(cuIndex))
if ((cuIndex !== ptCout - 1) && this.GetBuilgeAt(cuIndex))
{
let arc = this.GetCurveAtIndex(cuIndex) as Arc;
arc.MoveGripPoints([0], moveVec);

@ -67,6 +67,7 @@ export class ObjectCollection<T extends CADObject> extends CADObject
undoRec.WriteObjectHistoryPath(this, hisRec);
}
if (obj)
obj.GoodBye();
}

@ -126,7 +126,6 @@ export function IsPointInPolyLine(pl: Polyline, pt: Vector3): boolean
}
continue;
}
if (equaln(sp.x, pt.x) && sp.y > pt.y)
{
let der = arc.GetFistDeriv(0);
@ -142,7 +141,7 @@ export function IsPointInPolyLine(pl: Polyline, pt: Vector3): boolean
for (let pti of arc.IntersectWith(insLine, IntersectOption.ExtendArg))
{
if (pti.y < pt.y || equalv3(sp, pti) || equalv3(ep, pti))
if (pti.y < pt.y || equalv3(sp, pti, 1e-5) || equalv3(ep, pti, 1e-5))
continue;
let der = arc.GetFistDeriv(pti);

@ -5,6 +5,7 @@ import { CommandState } from './CommandState';
import { JigUtils } from './JigUtils';
export interface Command
{
NoHistory?: boolean;
exec: Function;//函数可以返回true,实现放弃命令的任何操作.
}
@ -24,9 +25,10 @@ class CommandMachine
arrayRemoveOnce(app.Editor.CommandStore.historyCmdList, cmdName)
app.Editor.CommandStore.historyCmdList.push(cmdName);
if (cmdName === "U" || cmdName === "REDO")
let cmd = this.CommandMap.get(cmdName);
if (cmd.NoHistory)
{
await this.CommandMap.get(cmdName).exec();
await cmd.exec();
app.Editor.UpdateScreen();
return;
}
@ -36,7 +38,7 @@ class CommandMachine
let abort: boolean = true;
try
{
abort = await this.CommandMap.get(cmdName).exec();
abort = await cmd.exec();
}
catch (error)
{

@ -92,12 +92,13 @@ import { Fbx } from "../Add-on/loadfbx";
import { LookOverBoardInfos } from "../Add-on/LookOverBoardInfos";
import { MirrorCommand } from "../Add-on/Mirror";
import { Command_Move } from "../Add-on/Move";
import { Command_Offset } from "../Add-on/Offset";
import { Command_DynOffset, Command_DynOffsetToolPath, Command_Offset } from "../Add-on/Offset";
import { OffsetX } from "../Add-on/OffsetX";
import { Open } from "../Add-on/Open";
import { PasteClip } from "../Add-on/PasteClip";
import { Pedit } from "../Add-on/Pedit";
import { Command_PLTest } from "../Add-on/polytest";
import { Command_Purge } from "../Add-on/Purge";
import { Command_RestoreColor } from "../Add-on/RestoreColor";
import { Command_Reverse } from "../Add-on/Reverse";
import { Command_Rotate } from "../Add-on/Rotate";
@ -134,7 +135,6 @@ import { CommandServer } from '../DatabaseServices/CommandServer';
import { AutoTempateSizeAction } from '../DatabaseServices/Template/TemplateTest';
import { ICommand } from '../UI/Components/CommandPanel/CommandList';
import { commandMachine } from './CommandMachine';
import { Command_Purge } from "../Add-on/Purge";
export function registerCommand()
{
@ -236,6 +236,9 @@ export function registerCommand()
commandMachine.RegisterCommand("testFilletCode", new TestFillet());
commandMachine.RegisterCommand("O", new Command_Offset());
commandMachine.RegisterCommand("OT", new Command_DynOffset());
commandMachine.RegisterCommand("TO", new Command_DynOffsetToolPath());
commandMachine.RegisterCommand("Length", new Command_Length());
//绘制灯

@ -52,11 +52,15 @@ export class Box3Ext extends Box3
interBox.max.setComponent(splitType, Math.max(this.min.getComponent(splitType), b2.min.getComponent(splitType)));
return interBox;
}
intersectsBox(box: this, fuzz = 1e-8)
intersectsBox(box: this, fuzz = 1e-8): boolean
{
// 重载three.js的相交判断,加入误差
return box.max.x < this.min.x - fuzz || box.min.x > this.max.x + fuzz ||
box.max.y < this.min.y - fuzz || box.min.y > this.max.y + fuzz ||
box.max.z < this.min.z - fuzz || box.min.z > this.max.z + fuzz ? false : true;
return IntersectsBox(this, box, fuzz);
}
}
export function IntersectsBox(box1: Box3, box2: Box3, fuzz = 1e-6): boolean
{
return box2.max.x < box1.min.x - fuzz || box2.min.x > box1.max.x + fuzz ||
box2.max.y < box1.min.y - fuzz || box2.min.y > box1.max.y + fuzz ||
box2.max.z < box1.min.z - fuzz || box2.min.z > box1.max.z + fuzz ? false : true;
}

@ -34,12 +34,14 @@ export class CurveMap
return stands;
}
addCurveToMap(cu: Curve)
AddCurveToMap(cu: Curve)
{
let startS = this.GetStand(cu.StartPoint);
let endS = this.GetStand(cu.EndPoint);
let routeS2E: Route = { curve: cu, to: endS };
let routeE2S: Route = { curve: cu, to: startS };
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 };
let routeE2S: Route = { curve: cu, to: startS, s: ep, e: sp };
startS.routes.push(routeS2E);
endS.routes.push(routeE2S);
}

@ -1,6 +1,7 @@
import { Box3, BufferGeometry, Geometry, Line, Matrix4, Mesh, Object3D, Vector, Vector2, Vector3 } from 'three';
import { ToFixed } from '../Common/Utils';
export const IdentityMtx4 = new Matrix4();
export const ZeroVec = new Vector3();
export const XAxis = new Vector3(1, 0, 0);
export const YAxis = new Vector3(0, 1, 0);
@ -374,3 +375,14 @@ export function SnapPoint(sqCenter: Vector3, snapPt: Vector3, size: number)
return Math.abs(sqCenter.x - snapPt.x) < size
&& Math.abs(sqCenter.y - snapPt.y) < size;
}
export function SelectNearP(pts: Vector3[], refPt: Vector3): Vector3
{
if (pts.length > 1)
{
let dist1 = refPt.distanceToSquared(pts[0]);
let dist2 = refPt.distanceToSquared(pts[1]);
return dist1 <= dist2 ? pts[0] : pts[1];
}
return pts[0];
}

@ -12,6 +12,8 @@ export interface Route
{
curve: Curve; //路线的曲线
to: Stand; //终点的点
s: Vector3;
e: Vector3;
}
@ -238,12 +240,12 @@ export class RegionParse
let arcs = this.BreakArc(cu);
if (arcs.length > 1)
{
arcs.forEach(a => curveMap.addCurveToMap(a));
arcs.forEach(a => curveMap.AddCurveToMap(a));
this.ExpLineMap.set(cu, arcs);
continue;
}
}
curveMap.addCurveToMap(cu);
curveMap.AddCurveToMap(cu);
}
//排序,根据角度逆时针排序.

@ -6,9 +6,8 @@ import { Circle } from "../DatabaseServices/Entity/Circle";
import { Curve } from "../DatabaseServices/Entity/Curve";
import { Line } from "../DatabaseServices/Entity/Line";
import { Polyline } from "../DatabaseServices/Entity/Polyline";
import { angle, equaln, equalv3, isParallelTo } from "../Geometry/GeUtils";
import { angle, equaln, equalv3, isParallelTo, SelectNearP } from "../Geometry/GeUtils";
import { IntersectOption } from "./IntersectWith";
import { PolyOffsetUtil } from "./OffsetPolyline";
/**
*线
@ -132,7 +131,7 @@ export function CalcEdgeSealing(cus: Curve[])
&& laterLine.PtOnCurve(p)
);
let iPt = PolyOffsetUtil.SelectFitInterPt(tPts.length > 0 ? tPts : iPts, frontLine.EndPoint);
let iPt = SelectNearP(tPts.length > 0 ? tPts : iPts, frontLine.EndPoint);
frontLine.EndPoint = iPt;
laterLine.StartPoint = iPt;

@ -56,7 +56,14 @@ function CheckPointOnCurve(intPts: Vector3[], c1: Curve, c2: Curve, extType: Int
{
return intPts.filter(p =>
{
return (extType & IntersectOption.ExtendThis || c1.PtOnCurve(p, tolerance)) && (extType & IntersectOption.ExtendArg || c2.PtOnCurve(p, tolerance))
if (!(extType & IntersectOption.ExtendThis))
if (!c1.PtOnCurve3(p, tolerance))
return false;
if (!(extType & IntersectOption.ExtendArg))
if (!c2.PtOnCurve3(p, tolerance))
return false;
return true;
});
}

@ -11,7 +11,7 @@ export class LinkSelf
private curveIndexData: WeakMap<Curve, number> = new WeakMap();
sealCus: Set<Curve>[] = [];
noSealCus: Curve[][] = [];
private m_Count;
private m_Count: number;
private cuMap: CurveMap;
constructor(cus: Curve[])
{
@ -279,7 +279,7 @@ export class LinkSelf
GenerateCurveMap(breakCus: Curve[])
{
let cuMap = new CurveMap();
breakCus.forEach(c => cuMap.addCurveToMap(c));
breakCus.forEach(c => cuMap.AddCurveToMap(c));
//所有的站点 逆序排序.
for (let [, stand] of cuMap.m_NodeMap)
{

File diff suppressed because it is too large Load Diff

@ -1,16 +1,16 @@
import { Vector3 } from "three";
import { IsRect, equalCurve } from "../../Common/CurveUtils";
import { Singleton } from "../../Common/Singleton";
import { Contour } from "../../DatabaseServices/Contour";
import { Board, IModeling } from "../../DatabaseServices/Entity/Board";
import { Circle } from "../../DatabaseServices/Entity/Circle";
import { Contour } from "../../DatabaseServices/Contour";
import { Curve } from "../../DatabaseServices/Entity/Curve";
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
import { Shape } from "../../DatabaseServices/Shape";
import { ShapeManager } from "../../DatabaseServices/ShapeManager";
import { BoolOpeartionType } from "../BoolOperateUtils";
import { OptimizeToolPath } from "./OptimizeToolPath";
import { equalCurve, IsRect } from "../../Common/CurveUtils";
import { Vector3 } from "three";
import { RegionParse } from "../../Geometry/RegionParse";
import { RegionParse, Route } from "../../Geometry/RegionParse";
import { BoolOpeartionType, isTargetCurInOrOnSourceCur } from "../BoolOperateUtils";
import { GetCurveToInDir, OptimizeToolPath, GetOffsetCurves } from "./OptimizeToolPath";
/**
*
@ -27,40 +27,30 @@ export class FeedingToolPath extends Singleton
{
let outline = shape.Outline.Curve.Clone();
let dir = this.GetCurveToInDir(outline);
let dir = GetCurveToInDir(outline);
let offsetCus: Curve[] = [outline];
//偏移后不闭合的走刀路径
let uncloseCurves: Curve[] = [];
//获得形状外孔轮廓
let holes: Contour[] = [];
/**用于判断孤岛是否与外轮廓相交 */
let holeOffsetCus: Curve[] = [];
for (let h of shape.Holes)
{
if (!isOut)
holes.push(h.Clone());
else
{
let dir = -this.GetCurveToInDir(h.Curve);
let tmpCus: Curve[];
if (h.Curve instanceof Polyline)
{
tmpCus = h.Curve.GetFeedingToolPath(knifRadius * dir);
if (tmpCus[0] instanceof Polyline && !tmpCus[0].IsClose)
{
uncloseCurves.push(tmpCus[0]);
let reg = new RegionParse(tmpCus[0].Explode() as Curve[], 3);
tmpCus.length = 0;
for (let routes of reg.RegionsOutline)
for (let r of routes)
tmpCus.push(r.curve);
}
}
let dir = -GetCurveToInDir(h.Curve);
let cus: Curve[];
if (h.Curve instanceof Circle)
cus = h.Curve.GetOffsetCurves(knifRadius * dir);
else
tmpCus = h.Curve.GetOffsetCurves(knifRadius * dir);
cus = h.Curve.GetFeedingToolPath(knifRadius * dir);
let con = Contour.CreateContour(tmpCus);
if (con)
holes.push(con);
holeOffsetCus.push(...h.Curve.GetOffsetCurves(knifRadius * dir).filter(c => c.IsClose));
holes.push(...this.GetContours(cus as Polyline[], offsetCus));
}
}
@ -71,7 +61,7 @@ export class FeedingToolPath extends Singleton
offsetDist += knifRadius;
let retCus: Curve[] = [];
if (outline instanceof Polyline && isOut && offsetDist === knifRadius)
if (outline instanceof Polyline)
retCus.push(...outline.GetFeedingToolPath(offsetDist * dir));
else
retCus.push(...outline.GetOffsetCurves(offsetDist * dir));
@ -82,12 +72,11 @@ export class FeedingToolPath extends Singleton
let isInt = false;
for (let c of retCus)
{
if (holes.length > 0 && c.IsClose)
if (holes.length > 0)
{
isInt = holes.some(h => h.Curve.IntersectWith(c, 0).length > 0 || h.CuInOutline(c));
if (isInt) break;
}
c.ColorIndex = outline.ColorIndex;
offsetCus.push(c);
}
@ -97,7 +86,8 @@ export class FeedingToolPath extends Singleton
let holesMg = new ShapeManager();
holesMg.AppendShapeList(holes.map(h => new Shape(h)));
let shapeMg = new ShapeManager();
shapeMg.AppendShapeList(retCus.map(c => new Shape(Contour.CreateContour([c]))));
let cons = this.GetContours(retCus as Polyline[], offsetCus);
shapeMg.AppendShapeList(cons.map(c => new Shape(c)));
shapeMg.BoolOper(holesMg, BoolOpeartionType.Subtract);
for (let s of shapeMg.ShapeList)
{
@ -107,54 +97,48 @@ export class FeedingToolPath extends Singleton
break;
}
}
let vailHoles: Contour[] = [];
for (let h of holes)
for (let i = 0; i < holes.length; i++)
{
let h = holes[i]
//如果加工洞外圈和最外轮廓相交,则去掉
if (h.Curve.IntersectWith(outline, 0).length > 0)
continue;
let isVail = true;
//若最外轮廓内偏移一个刀半径的曲线 和最内轮廓相交或者被包含,则去掉.且不与洞曲线相等
if (isOut)
{
let tmpCus = outline.GetOffsetCurves(dir * offsetDist);
for (let c of tmpCus)
let outlineOffsetCus = outline.GetOffsetCurves(dir * knifRadius).filter(c => c.IsClose);
let outlineCus = GetOffsetCurves(outline, dir * knifRadius);
for (let j = 0; j < outlineOffsetCus.length; j++)
{
if (h.Curve.IntersectWith(c, 0).length > 0)
let c = outlineOffsetCus[j];
let ho = holeOffsetCus[i];
if (h.Curve.IntersectWith(outlineCus[j], 0).length > 0)
{
if (!(offsetDist === knifRadius && equalCurve(h.Curve, c)))
if (!(equalCurve(ho, c) || isTargetCurInOrOnSourceCur(c as Polyline, h.Curve)))
{
isVail = false;
break;
}
}
else if (h.Area > c.Area)
else if (ho.Area > c.Area)
{
isVail = false;
break;
}
}
}
if (isVail)
offsetCus.push(h.Curve);
vailHoles.push(h);
}
if (isOut)
vailHoles = Shape.mergeContours(vailHoles);
offsetCus.push(...uncloseCurves);
offsetCus.push(...vailHoles.map(h => h.Curve));
return offsetCus;
}
/**
* 线
*/
private GetCurveToInDir(cu: Curve): number
{
let dir = -Math.sign(cu.Area2);
if (cu instanceof Circle)
dir = -1;
return dir;
}
/**用于测试走刀路径 */
TestCalcPath(br: Board)
{
@ -211,7 +195,7 @@ export class FeedingToolPath extends Singleton
{
//通孔只切一刀
let outline = shape.Outline.Curve;
let dir = this.GetCurveToInDir(outline);
let dir = GetCurveToInDir(outline);
let paths: Curve[];
if (outline instanceof Circle)
paths = outline.GetOffsetCurves(dir * knifeRadius);
@ -256,4 +240,45 @@ export class FeedingToolPath extends Singleton
}
}
}
private GetContours(cus: (Polyline | Circle)[], retCus: Curve[])
{
let cons: Contour[] = [];
for (let c of cus)
{
if (c.IsClose)
{
cons.push(Contour.CreateContour(c));
}
else
{
let expCus = c.Explode() as Curve[];
let regParse = new RegionParse(expCus);
//分析封闭包围区域
const parseRoute = (routeSet: Set<Route>[]) =>
{
for (let routes of routeSet)
{
let cs: Curve[] = [];
for (let r of routes)
cs.push(r.curve);
let c = Contour.CreateContour(cs, false);
if (c && c.Area > 1e-3)
cons.push(c);
}
}
parseRoute(regParse.RegionsOutline);
parseRoute(regParse.RegionsInternal);
for (let c of expCus)
{
if (!regParse.GetCueveUsed(c))
{
retCus.push(c);
}
}
}
}
return cons;
}
}

@ -1,12 +1,12 @@
import { Curve } from "../../DatabaseServices/Entity/Curve";
import { Shape } from "../../DatabaseServices/Shape";
import { arrayRemoveIf } from "../../Common/ArrayExt";
import { ConverCircleToPolyline, curveLinkGroup, equalCurve } from "../../Common/CurveUtils";
import { matrixAlignCoordSys } from "../../Common/Matrix4Utils";
import { curveLinkGroup, ConverCircleToPolyline, equalCurve } from "../../Common/CurveUtils";
import { Line } from "../../DatabaseServices/Entity/Line";
import { Circle } from "../../DatabaseServices/Entity/Circle";
import { Curve } from "../../DatabaseServices/Entity/Curve";
import { Line } from "../../DatabaseServices/Entity/Line";
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
import { comparePoint, AsVector3, AsVector2 } from "../../Geometry/GeUtils";
import { arrayLast, arrayRemoveIf } from "../../Common/ArrayExt";
import { Shape } from "../../DatabaseServices/Shape";
import { AsVector2, AsVector3, comparePoint } from "../../Geometry/GeUtils";
/**
* ,线
@ -15,7 +15,7 @@ import { arrayLast, arrayRemoveIf } from "../../Common/ArrayExt";
* @param rad
* @returns tool path
*/
export function OptimizeToolPath(offsetCus: Curve[], originShape: Shape, rad: number, isTest = false): Curve[]
export function OptimizeToolPath(offsetCus: Curve[], originShape: Shape, rad: number): Curve[]
{
// 去掉最外轮廓
let outline = offsetCus.shift();
@ -46,7 +46,13 @@ export function OptimizeToolPath(offsetCus: Curve[], originShape: Shape, rad: nu
if (noCloseCus.length > 0)
{
let culist: Curve[] = [];
noCloseCus.forEach(c => culist.push(...c.Explode() as Curve[]));
noCloseCus.forEach(c =>
{
if (c instanceof Polyline)
culist.push(...c.Explode() as Curve[]);
else
culist.push(c);
});
//移除相等的曲线避免重复走刀
RempveEqualCurves(culist);
let groups = curveLinkGroup(culist);
@ -61,8 +67,10 @@ export function OptimizeToolPath(offsetCus: Curve[], originShape: Shape, rad: nu
plList.push(pl);
}
}
let dir = GetCurveToInDir(outline);
let cantIntCur: Curve[] = [];
cantIntCur.push(...GetOffsetCurves(outline, rad * dir));
let cantIntCur: Curve[] = [outline];
if (originShape.Holes.length > 0)
{
for (let h of originShape.Holes)
@ -70,7 +78,7 @@ export function OptimizeToolPath(offsetCus: Curve[], originShape: Shape, rad: nu
let dir = Math.sign(h.Curve.Area2);
if (h.Curve instanceof Circle)
dir = 1;
cantIntCur.push(...h.Curve.GetOffsetCurves(rad * dir));
cantIntCur.push(...GetOffsetCurves(h.Curve, rad * dir));
}
}
@ -91,7 +99,7 @@ export function OptimizeToolPath(offsetCus: Curve[], originShape: Shape, rad: nu
let isDisVail = false;
isDisVail = cantIntCur.some(c => c.IntersectWith(refLine, 0).length > 0);
isDisVail = cantIntCur.some(c => c.IntersectWith(refLine, 0).length > 1);
if (isDisVail)
{
@ -170,43 +178,42 @@ function ChangePlListStartPt(plList: Polyline[])
}
}
}
/**
* 线,
* @param plList
*/
function SortPlByStartPt(plList: Polyline[])
function SortPlByStartPt(pls: Polyline[]): Polyline[]
{
if (plList.length <= 1) return plList;
if (pls.length <= 1) return pls;
let result = [plList[0]];
let usedPl = new WeakSet([plList[0]]);
let result = [pls[0]];
let usedPl = new WeakSet([pls[0]]);
let p = pls[0].StartPoint;
while (true)
{
if (plList.length === result.length)
if (pls.length === result.length)
break;
let refPt = arrayLast(result).StartPoint;
let vaildPl: Polyline;
let refDist: number;
for (let pl of plList)
let minDist: number = Infinity;
for (let pl of pls)
{
if (usedPl.has(pl))
continue;
let sPt = pl.StartPoint;
if (!refDist || sPt.distanceToSquared(refPt) < refDist)
let dist = pl.StartPoint.distanceToSquared(p);
if (dist < minDist)
{
refDist = sPt.distanceToSquared(refPt);
minDist = dist;
vaildPl = pl;
}
}
p = vaildPl.StartPoint;
result.push(vaildPl);
usedPl.add(vaildPl);
}
plList.length = 0;
plList.push(...result);
pls.length = 0;
pls.push(...result);
}
function RempveEqualCurves(cus: Curve[])
@ -228,3 +235,17 @@ function RempveEqualCurves(cus: Curve[])
}
arrayRemoveIf(cus, (c) => needRemoveCurve.has(c));
}
export function GetOffsetCurves(cu: Curve, dist: number): Curve[]
{
if (cu instanceof Polyline)
return cu.GetFeedingToolPath(dist);
else
return cu.GetOffsetCurves(dist);
}
/** 获得曲线内偏移方向*/
export function GetCurveToInDir(cu: Curve): number
{
return cu.IsClockWise ? 1 : -1;
}

Loading…
Cancel
Save