From e175e8eab7eb9afe0ceb230ed257ed6c0693f842 Mon Sep 17 00:00:00 2001 From: ChenX Date: Mon, 22 Jul 2019 17:06:18 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=A4=9A=E6=AE=B5=E7=BA=BF?= =?UTF-8?q?=E5=80=92=E8=A7=92(=E4=B8=8E=E8=87=AA=E8=BA=AB)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__snapshots__/polyline.test.ts.snap | 14 +- __test__/Polyline/Fillet.test.ts | 286 ++++++++++++++++++ .../__snapshots__/Fillet.test.ts.snap | 31 ++ package.json | 2 +- src/Add-on/FilletUtils.ts | 148 ++++----- src/Add-on/testEntity/TestFilletCode.ts | 63 ++++ src/DatabaseServices/Entity/Polyline.ts | 8 +- 7 files changed, 454 insertions(+), 98 deletions(-) create mode 100644 __test__/Polyline/__snapshots__/Fillet.test.ts.snap create mode 100644 src/Add-on/testEntity/TestFilletCode.ts diff --git a/__test__/Fillet/__snapshots__/polyline.test.ts.snap b/__test__/Fillet/__snapshots__/polyline.test.ts.snap index 629b33d59..e8377d49c 100644 --- a/__test__/Fillet/__snapshots__/polyline.test.ts.snap +++ b/__test__/Fillet/__snapshots__/polyline.test.ts.snap @@ -1,28 +1,28 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`双圆多段线倒角 1`] = `1208.375268430404`; +exports[`双圆多段线倒角 1`] = `1208.3752684304045`; -exports[`双圆多段线倒角 2`] = `1208.375268430404`; +exports[`双圆多段线倒角 2`] = `1208.3752684304045`; exports[`双圆多段线倒角 3`] = `1208.3752684304054`; exports[`双圆多段线倒角 4`] = `1208.3752684304045`; -exports[`双圆多段线倒角 5`] = `1200.7933322000163`; +exports[`双圆多段线倒角 5`] = `1200.7933322000165`; exports[`双圆多段线倒角 6`] = `1200.7933322000163`; -exports[`双圆多段线倒角 7`] = `1200.7933322000172`; +exports[`双圆多段线倒角 7`] = `1200.793332200017`; -exports[`双圆多段线倒角 8`] = `1200.7933322000165`; +exports[`双圆多段线倒角 8`] = `1200.793332200017`; exports[`多段线闭合标志首尾有弧 1`] = `1357.0494514094473`; -exports[`多段线闭合标志首尾有弧 2`] = `1357.0494514094473`; +exports[`多段线闭合标志首尾有弧 2`] = `1357.049451409447`; exports[`多段线闭合标志首尾有弧 3`] = `1357.0494514094473`; -exports[`多段线闭合标志首尾有弧 4`] = `1357.049451409447`; +exports[`多段线闭合标志首尾有弧 4`] = `1357.0494514094473`; exports[`多段线首尾倒角有圆弧 1`] = `1682.5946408278246`; diff --git a/__test__/Polyline/Fillet.test.ts b/__test__/Polyline/Fillet.test.ts index d1eec3754..63275b48c 100644 --- a/__test__/Polyline/Fillet.test.ts +++ b/__test__/Polyline/Fillet.test.ts @@ -1,6 +1,292 @@ +import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; +import { Polyline } from "../../src/DatabaseServices/Entity/Polyline"; +import { Vector3 } from "three"; +import { FilletUtils, FilletRes } from "../../src/Add-on/FilletUtils"; +import { PromptEntityResult } from "../../src/Editor/PromptResult"; +import "../Utils/jest.util"; + //#IOX9F 倒角半径100 test('', () => { [1, "Polyline", 2, 1, 104, false, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5438.7151791877595, -4532.723515247859, -1.344596967101097e-7, 1], 1, 2, 4, [-272.5963980009974, 125.26453527188733], -0.6297899607010771, [268.45496627781176, 133.9101604837315], 0, [286.92760827694747, 96.87732841911384], 0, [648.509529180903, 718.346254972786], 0, false] }); + +function excepeRes(fres: FilletRes) +{ + let len = 0; + if (fres && fres.cu1) + len = fres.cu1.Length; + + expect(len).toMatchNumberSnapshot(); +} + +test('首尾缺口倒角', () => +{ + + let f = [1, "Polyline", 5, 2, 105, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 2, 4, [547.6394707904332, 156.420708807656], 0, [1451.8754993607672, 156.420708807656], 0, [1451.8754993607672, 1354.8058069129183], 0, [563.9810857645957, 249.02319366124436], 0, false] + + let pl = LoadEntityFromFileData(f)[0] as Polyline; + + let fillet = new FilletUtils(); + + fillet.FilletRadius = 10; + + let pts = [new Vector3(694.7372611476585, 156.420708807656, 0), new Vector3(628.6117019682237, 329.5140837798733, 0), new Vector3(1391.744556282656, 156.420708807656, 0), new Vector3(1451.8754993607672, 255.1882779806288, 0), new Vector3(1451.8754993607672, 1174.0426264535326, 0), new Vector3(1364.317471005074, 1245.7611458319013, 0)]; + + + for (let i = 0; i + 1 < pts.length; i = i + 2) + { + let p1 = pts[i]; + let p2 = pts[i + 1]; + + let e1 = new PromptEntityResult(pl, p1); + let e2 = new PromptEntityResult(pl, p2); + let fres = fillet.Fillet(e1, e2); + + excepeRes(fres); + } +}); + +test('首尾开口and跨越直线1', () => +{ + + let f = [1, "Polyline", 5, 2, 109, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 2, 4, [1912.1643211330174, 150.15642306756], 0, [3347.5028363636384, 555.9731949259332], 0, [3347.5028363636384, 584.026300631579], 0, [1923.0587311157924, 1605.3772365167458], 0, false] + + let pl = LoadEntityFromFileData(f)[0] as Polyline; + + let fillet = new FilletUtils(); + + fillet.FilletRadius = 10; + + let pts = [new Vector3(3008.6463375692947, 826.9922414497031, 0), new Vector3(2953.8062841777946, 444.6624050289869, 0)]; + + + for (let i = 0; i + 1 < pts.length; i = i + 2) + { + let p1 = pts[i]; + let p2 = pts[i + 1]; + + let e1 = new PromptEntityResult(pl, p1); + let e2 = new PromptEntityResult(pl, p2); + let fres = fillet.Fillet(e1, e2); + + excepeRes(fres); + } + +}); + +test('首尾开口and跨越直线2', () => +{ + + let f = [1, "Polyline", 5, 2, 145, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 2, 7, [1765.3076108911919, 1872.4190121644488], 0, [3504.2406116319507, 2310.4177043718623], 0, [3458.7468373285233, 2322.549377519443], 0, [3495.1418567712653, 2377.141906683556], 0, [3431.0761383900667, 2352.76623008148], 0, [3520.0042980366775, 2441.6943897280908], 0, [1849.090982571283, 3377.7802807451185], 0, false] + + let pl = LoadEntityFromFileData(f)[0] as Polyline; + + let fillet = new FilletUtils(); + + fillet.FilletRadius = 10; + + let pts = [new Vector3(3175.187610856738, 2227.536544519773, 0), new Vector3(3244.4053600367315, 2596.0915538737186, 0)]; + + + for (let i = 0; i + 1 < pts.length; i = i + 2) + { + let p1 = pts[i]; + let p2 = pts[i + 1]; + + let e1 = new PromptEntityResult(pl, p1); + let e2 = new PromptEntityResult(pl, p2); + let fres = fillet.Fillet(e1, e2); + + excepeRes(fres); + } + + +}); + + +test('首尾且点重叠', () => +{ + + let f = [1, "Polyline", 5, 2, 110, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 2, 5, [4475.389771693963, 292.48317396453035], 0, [5793.726681473572, 292.48317396453035], 0, [5793.726681473572, 1165.0966523424624], 0, [4475.389771693963, 1165.0966523424624], 0, [4475.389771693963, 292.48317396453035], 0, false] + + let pl = LoadEntityFromFileData(f)[0] as Polyline; + + let fillet = new FilletUtils(); + + fillet.FilletRadius = 10; + + let pts = [new Vector3(4598.039581827028, 292.48317396453035, 0), new Vector3(4475.389771693963, 398.56637305394077, 0)]; + + + for (let i = 0; i + 1 < pts.length; i = i + 2) + { + let p1 = pts[i]; + let p2 = pts[i + 1]; + + let e1 = new PromptEntityResult(pl, p1); + let e2 = new PromptEntityResult(pl, p2); + let fres = fillet.Fillet(e1, e2); + + excepeRes(fres); + } + +}); + +test('首尾重复并且closemark', () => +{ + + let f = [1, "Polyline", 5, 2, 111, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1914.7274165846702, 12.555589616967154, 0, 1], 0, 0, 2, 5, [4475.389771693963, 292.48317396453035], 0, [5793.726681473572, 292.48317396453035], 0, [5793.726681473572, 1165.0966523424624], 0, [4475.389771693963, 1165.0966523424624], 0, [4475.389771693963, 292.48317396453035], 0, true] + + let pl = LoadEntityFromFileData(f)[0] as Polyline; + + let fillet = new FilletUtils(); + + fillet.FilletRadius = 10; + + let pts = [new Vector3(6598.6773483589595, 305.0387635814975, 0), new Vector3(6390.117188278633, 422.42066338147515, 0)]; + + + for (let i = 0; i + 1 < pts.length; i = i + 2) + { + let p1 = pts[i]; + let p2 = pts[i + 1]; + + let e1 = new PromptEntityResult(pl, p1); + let e2 = new PromptEntityResult(pl, p2); + let fres = fillet.Fillet(e1, e2); + + excepeRes(fres); + } + +}); + +test('只有closemark', () => +{ + + let f = [1, "Polyline", 5, 2, 112, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 2, 4, [8430.400501032793, 279.92758434758196], 0, [9723.626231578504, 279.92758434758196], 0, [9723.626231578504, 1309.485932937372], 0, [8430.400501032793, 1309.485932937372], 0, true] + + let pl = LoadEntityFromFileData(f)[0] as Polyline; + + let fillet = new FilletUtils(); + + fillet.FilletRadius = 10; + + let pts = [new Vector3(8537.935865598118, 279.92758434758196, 0), new Vector3(8430.400501032793, 388.47038336421406, 0)]; + + + for (let i = 0; i + 1 < pts.length; i = i + 2) + { + let p1 = pts[i]; + let p2 = pts[i + 1]; + + let e1 = new PromptEntityResult(pl, p1); + let e2 = new PromptEntityResult(pl, p2); + let fres = fillet.Fillet(e1, e2); + + excepeRes(fres); + } + +}); + + +test('跨越首尾且首尾重叠', () => +{ + + let f = [1, "Polyline", 5, 2, 121, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 2, 6, [12032.496266837241, 1167.7503167910863], 0, [10719.863427339778, 1167.7503167910863], 0, [10719.863427339778, 374.5161686031184], 0, [12222.34222567228, 374.5161686031184], 0, [12222.34222567228, 990.022185115731], 0, [12032.496266837241, 1167.7503167910868], 0, false] + + let pl = LoadEntityFromFileData(f)[0] as Polyline; + + let fillet = new FilletUtils(); + + fillet.FilletRadius = 10; + + let pts = [new Vector3(12222.34222567228, 793.6354478254848, 0), new Vector3(11763.529750469466, 1167.7503167910863, 0)]; + + + for (let i = 0; i + 1 < pts.length; i = i + 2) + { + let p1 = pts[i]; + let p2 = pts[i + 1]; + + let e1 = new PromptEntityResult(pl, p1); + let e2 = new PromptEntityResult(pl, p2); + let fres = fillet.Fillet(e1, e2); + + excepeRes(fres); + } + + pl.CloseMark = true; + + for (let i = 0; i + 1 < pts.length; i = i + 2) + { + let p1 = pts[i]; + let p2 = pts[i + 1]; + + let e1 = new PromptEntityResult(pl, p1); + let e2 = new PromptEntityResult(pl, p2); + let fres = fillet.Fillet(e1, e2); + + excepeRes(fres); + } + +}); + + +test('圆弧跨越分割线', () => +{ + + let f = [1, "Polyline", 5, 2, 150, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 17932.217574766102, 923.3102914449528, -1.344596967101097e-7, 1], 0, 0, 2, 4, [-272.5963980009974, 125.26453527188733], -0.6297899607010771, [268.45496627781176, 133.9101604837315], 0, [286.92760827694747, 96.87732841911384], 0, [648.509529180903, 718.346254972786], 0, false] + + let pl = LoadEntityFromFileData(f)[0] as Polyline; + + let fillet = new FilletUtils(); + + fillet.FilletRadius = 10; + + let pts = [new Vector3(18057.464592553017, 1195.9147384656944, -1.344596967101097e-7), new Vector3(18308.17874769076, 1173.2140591023185, -1.344596967101097e-7)]; + + + for (let i = 0; i + 1 < pts.length; i = i + 2) + { + let p1 = pts[i]; + let p2 = pts[i + 1]; + + let e1 = new PromptEntityResult(pl, p1); + let e2 = new PromptEntityResult(pl, p2); + let fres = fillet.Fillet(e1, e2); + + excepeRes(fres); + } + +}); + + +test('自交多段线', () => +{ + + let f = [1, "Polyline", 5, 2, 147, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 2, 5, [7963.40305968292, 5219.86997448622], 0, [8839.024211760872, 2266.977365882911], 0, [12322.878582794428, 3217.119467073881], 0, [5243.388417057789, 4055.4801445953253], 0, [6538.189907896463, 6756.864549942202], 0, false] + + let pl = LoadEntityFromFileData(f)[0] as Polyline; + + let fillet = new FilletUtils(); + + fillet.FilletRadius = 10; + + let pts = [new Vector3(8203.851497581623, 3704.898990322766, 0), new Vector3(8309.132884106548, 4053.951311270369, 0), new Vector3(8963.280381174896, 3614.9666225288256, 0), new Vector3(8559.839423169416, 3208.483514643456, 0), new Vector3(7775.277793586963, 3755.651139480028, 0), new Vector3(8598.964992014366, 3076.538777155703, 0), new Vector3(8325.80177953219, 3997.738121377507, 0), new Vector3(8970.970528592596, 3614.0559471767297, 0)]; + + + for (let i = 0; i + 1 < pts.length; i = i + 2) + { + let p1 = pts[i]; + let p2 = pts[i + 1]; + + let e1 = new PromptEntityResult(pl, p1); + let e2 = new PromptEntityResult(pl, p2); + let fres = fillet.Fillet(e1, e2); + + excepeRes(fres); + } + +}); diff --git a/__test__/Polyline/__snapshots__/Fillet.test.ts.snap b/__test__/Polyline/__snapshots__/Fillet.test.ts.snap new file mode 100644 index 000000000..5a5c43484 --- /dev/null +++ b/__test__/Polyline/__snapshots__/Fillet.test.ts.snap @@ -0,0 +1,31 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`只有closemark 1`] = `"4641.27612"`; + +exports[`圆弧跨越分割线 1`] = `"1420.95209"`; + +exports[`自交多段线 1`] = `"7791.00495"`; + +exports[`自交多段线 2`] = `"9003.48566"`; + +exports[`自交多段线 3`] = `"0.00000"`; + +exports[`自交多段线 4`] = `"0.00000"`; + +exports[`跨越首尾且首尾重叠 1`] = `"4587.13386"`; + +exports[`跨越首尾且首尾重叠 2`] = `"4587.13386"`; + +exports[`首尾且点重叠 1`] = `"4377.60874"`; + +exports[`首尾开口and跨越直线1 1`] = `"3288.97072"`; + +exports[`首尾开口and跨越直线2 1`] = `"4039.68024"`; + +exports[`首尾缺口倒角 1`] = `"3678.29690"`; + +exports[`首尾缺口倒角 2`] = `"3516.46578"`; + +exports[`首尾缺口倒角 3`] = `"3488.55655"`; + +exports[`首尾重复并且closemark 1`] = `"4377.60874"`; diff --git a/package.json b/package.json index 2ec3856e7..0c370d325 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "gitlog": "^3.1.2", "html-loader": "^0.5.5", "html-webpack-plugin": "^3.2.0", - "jest": "^24.8.0", + "jest": "^23.6.0", "jest-snapshot": "^24.8.0", "less": "^3.9.0", "less-loader": "^5.0.0", diff --git a/src/Add-on/FilletUtils.ts b/src/Add-on/FilletUtils.ts index 1c6cff49b..7bc8d678b 100644 --- a/src/Add-on/FilletUtils.ts +++ b/src/Add-on/FilletUtils.ts @@ -1,14 +1,14 @@ import { Matrix4, Vector3 } from "three"; import { curveLinkGroup, GetPointAtCurveDir } from "../Common/CurveUtils"; import { Arc } from "../DatabaseServices/Entity/Arc"; +import { Board } from "../DatabaseServices/Entity/Board"; 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 { PromptEntityResult, PromptPointResult } from "../Editor/PromptResult"; -import { angle, equalv3, isParallelTo, midPoint, AsVector2 } from "../Geometry/GeUtils"; +import { angle, AsVector2, equalv3, isParallelTo, midPoint } from "../Geometry/GeUtils"; import { IntersectOption } from "../GraphicsSystem/IntersectWith"; -import { Board } from "../DatabaseServices/Entity/Board"; function Encode(res: PromptEntityResult, enMap: (PromptEntityResult[])[]) { @@ -63,11 +63,11 @@ enum ExtendType End = 2, } -interface FilletRes +export interface FilletRes { - cu1: Curve; - cu2: Curve; - arc: Arc; + cu1?: Curve; + cu2?: Curve; + arc?: Arc; } type CurveExtend = { Curve: Curve, ExtType: ExtendType }; @@ -204,104 +204,74 @@ export class FilletUtils if (equalv3(c1.GetFistDeriv(1).normalize(), c2.GetFistDeriv(0).normalize())) return; - let rem = parF2 - parF1; - if (rem === 1 || (rem + 1 === pl.EndParam))//相邻线段倒角 - { - let es1 = new PromptEntityResult(); - es1.Entity = c1; - es1.Point = enRes1.Point; + let es1 = new PromptEntityResult(); + es1.Entity = c1; + es1.Point = enRes1.Point; - let es2 = new PromptEntityResult(); - es2.Entity = c2; - es2.Point = enRes2.Point; + let es2 = new PromptEntityResult(); + es2.Entity = c2; + es2.Point = enRes2.Point; + let fres = this.Fillet(es1, es2); - let res = this.Fillet(es1, es2); - if (res && res.arc) - { - let pln = pl.Clone(); - //修正凸度 - if (res.cu1 instanceof Arc) - pln.SetBulgeAt(parF1, res.cu1.Bul); - if (res.cu2 instanceof Arc) - pln.SetBulgeAt(parF2, res.cu2.Bul); + if (!fres || !fres.arc) + return; - let sp2d = AsVector2(res.arc.StartPoint.applyMatrix4(pln.OCSInv)); - let ep2d = AsVector2(res.arc.EndPoint.applyMatrix4(pln.OCSInv)); + let pln = pl.Clone(); - let isNeighbor = rem === 1; + let notCycle = equalv3(pl.GetPointAtParam(parF1), fres.cu1.StartPoint); - //#IOX26 - if (isNeighbor && res.cu1 instanceof Arc && res.cu2 instanceof Arc) - { - let ins = res.cu1.IntersectWith(res.cu2, IntersectOption.OnBothOperands); - if (ins.length === 1 && !equalv3(pln.StartPoint, ins[0])) - isNeighbor = false; - } + let c1Derv = c1.GetFistDeriv(fres.arc.StartPoint).normalize(); + let c2Derv = c2.GetFistDeriv(fres.arc.EndPoint).normalize(); + let asDerv = fres.arc.GetFistDeriv(0).normalize(); + let aeDerv = fres.arc.GetFistDeriv(1).normalize(); - if (isNeighbor) - { - pln.SetPointAt(parF2, ep2d); - pln.AddVertexAt(parF2, sp2d); - pln.SetBulgeAt(parF2, res.arc.Bul); - } - else//首尾 - { - pln.SetPointAt(0, sp2d); + //自交多段线时 + if (equalv3(c1Derv, asDerv) !== equalv3(c2Derv, aeDerv)) + return; - let plPtCount = pln.NumberOfVertices; - if (pln.EndParam === plPtCount)//CloseMark - { - pln.AddVertexAt(plPtCount, ep2d); - pln.SetBulgeAt(plPtCount, -res.arc.Bul); - } - else - { - pln.SetPointAt(plPtCount - 1, ep2d); + if (fres.cu1 instanceof Arc) + pln.SetBulgeAt(parF1, fres.cu1.Bul); - pln.SetBulgeAt(plPtCount - 1, -res.arc.Bul); - pln.AddVertexAt(plPtCount, sp2d); - } - } + if (fres.cu2 instanceof Arc) + pln.SetBulgeAt(parF2, fres.cu2.Bul); - return { - cu1: pln, - cu2: undefined, - arc: undefined - }; - } - } - else//自交多段线 + if (notCycle)//没有经过起点 { - let interPts = c1.IntersectWith(c2, IntersectOption.OnBothOperands); - if (interPts.length === 0) - return; - - if (interPts.length === 2 && c1.GetParamAtPoint(interPts[0]) > c1.GetParamAtPoint(interPts[1])) - interPts.reverse(); - - let ipt = interPts[0]; - let splitParam1 = Math.floor(param1) + c1.GetParamAtPoint(ipt); - let splitParam2 = Math.floor(param2) + c2.GetParamAtPoint(ipt); - - let cus = pl.GetSplitCurves([splitParam1, splitParam2]); - if (cus.length >= 2) + let sp = AsVector2(fres.cu1.EndPoint.applyMatrix4(pln.OCSInv)); + if (parF2 - parF1 === 1) { - cus.splice(1, 1); + pln.AddVertexAt(parF1 + 1, sp); + parF2++; + } + else + pln.SetPointAt(parF1 + 1, sp); + pln.SetBulgeAt(parF1 + 1, fres.arc.Bul); - let pl1 = cus[0]; - for (let i = 1; i < cus.length; i++) - pl1.Join(cus[i]); + let ep = AsVector2(fres.cu2.StartPoint.applyMatrix4(pln.OCSInv)); + pln.SetPointAt(parF2, ep); - let es1 = new PromptEntityResult(); - es1.Entity = pl1; - es1.Point = c1.GetPointAtParam(0.1); + //移除多余的点 + pln.LineData.splice(parF1 + 2, parF2 - parF1 - 2); + pln.Update(); + return { cu1: pln }; + } + else//经过起点 + { + let sp = AsVector2(fres.arc.EndPoint.applyMatrix4(pln.OCSInv)); + if (parF2 + 1 <= pln.LineData.length) + pln.AddVertexAt(parF2 + 1, sp) + else + pln.SetPointAt(parF2 + 1, sp); + pln.SetBulgeAt(parF2 + 1, -fres.arc.Bul); - let es2 = new PromptEntityResult(); - es2.Entity = pl1; - es2.Point = c2.GetPointAtParam(0.9); + let ep = AsVector2(fres.cu1.StartPoint.applyMatrix4(pln.OCSInv)); + pln.SetPointAt(parF1, ep); + pln.CloseMark = true; - return this.FilletPolyLineSelf(es1, es2); - } + pln.LineData.splice(parF2 + 2); + pln.LineData.splice(0, parF1); + pln.Update(); + return { cu1: pln }; } } diff --git a/src/Add-on/testEntity/TestFilletCode.ts b/src/Add-on/testEntity/TestFilletCode.ts new file mode 100644 index 000000000..6c33fd061 --- /dev/null +++ b/src/Add-on/testEntity/TestFilletCode.ts @@ -0,0 +1,63 @@ +import { Vector3 } from "three"; +import { app } from "../../ApplicationServices/Application"; +import { copyTextToClipboard } from "../../Common/Utils"; +import { CADFiler } from "../../DatabaseServices/CADFiler"; +import { Command } from "../../Editor/CommandMachine"; +import { PromptStatus } from "../../Editor/PromptResult"; +import { HotCMD } from "../../Hot/HotCommand"; + +@HotCMD +export class TestFillet implements Command +{ + async exec() + { + + let e1 = await app.Editor.GetEntity(); + + let f = new CADFiler(); + f.Write(1); + f.WriteObject(e1.Entity); + + let pts: Vector3[] = []; + while (true) + { + let ptRes = await app.Editor.GetPoint(); + if (ptRes.Status === PromptStatus.OK) + pts.push(ptRes.Point); + else + break; + } + + let ptsStr = pts.map(p => + { + return `new Vector3(${p.toArray().toString()})` + }).join(","); + + let str = ` + let f = ${JSON.stringify(f.Data)} + + let pl = LoadEntityFromFileData(f)[0] as Polyline; + + let fillet = new FilletUtils(); + + fillet.FilletRadius = 10; + + let pts = [${ptsStr}]; + + + for (let i = 0; i + 1 < pts.length; i = i + 2) + { + let p1 = pts[i]; + let p2 = pts[i + 1]; + + let e1 = new PromptEntityResult(pl, p1); + let e2 = new PromptEntityResult(pl, p2); + let fres = fillet.Fillet(e1, e2); + + excepeRes(fres); + } + `; + + await copyTextToClipboard(str); + } +} diff --git a/src/DatabaseServices/Entity/Polyline.ts b/src/DatabaseServices/Entity/Polyline.ts index d6c5b5a87..05ffb03f7 100644 --- a/src/DatabaseServices/Entity/Polyline.ts +++ b/src/DatabaseServices/Entity/Polyline.ts @@ -334,6 +334,12 @@ export class Polyline extends Curve } this.SetPointAt(this.EndParam, AsVector2(p)); } + + get CurveCount(): number + { + return this.EndParam; + } + get StartParam() { return 0; @@ -342,7 +348,7 @@ export class Polyline extends Curve /** * 表示最后一条曲线的终止参数,使用该参数可以直接遍历到多段线的所有子线段. for(i