diff --git a/__test__/Booloperate/__snapshots__/bool4.test.ts.snap b/__test__/Booloperate/__snapshots__/bool4.test.ts.snap index 52dfa7e84..5f70019c2 100644 --- a/__test__/Booloperate/__snapshots__/bool4.test.ts.snap +++ b/__test__/Booloperate/__snapshots__/bool4.test.ts.snap @@ -11,3 +11,5 @@ exports[`交点大于等于2_但是还是分离 1`] = `310430.5057844047`; exports[`交点大于等于2_但是还是分离 2`] = `40090.549687200226`; exports[`共线多余点 1`] = `618903.9999999995`; + +exports[`精度问题,导致的曲线合并失败,导致的无法重新生成轮廓 1`] = `8207.998897234036`; diff --git a/__test__/Booloperate/bool4.test.ts b/__test__/Booloperate/bool4.test.ts index c77790ce3..86c5bfe90 100644 --- a/__test__/Booloperate/bool4.test.ts +++ b/__test__/Booloperate/bool4.test.ts @@ -1,5 +1,5 @@ -import { LoadRegionsFromFileData } from "../Utils/LoadEntity.util"; import { BoolOpeartionType } from "../../src/GraphicsSystem/BoolOperateUtils"; +import { LoadRegionsFromFileData } from "../Utils/LoadEntity.util"; test('交点大于等于2_但是还是分离', () => { @@ -19,7 +19,8 @@ test('交点大于等于2_但是还是分离', () => test(`#I118PO`, () => { - let d = [2, "Region", 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, 1, 1, 1, 1, "Polyline", 5, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 2, 4, [0, 0], 0, [349.99999999999983, 0], 0, [349.99999999999983, 18], 0, [0, 18], 0, true, 0, "Region", 5, 2, 110, false, 1, 7, 0, [-0.6481962787933795, -0.7614732983883384, -3.969057490217688e-17, 0, 0.7614732983883384, -0.6481962787933795, 4.66267918753728e-17, 0, 6.123233995736766e-17, 0, -1, 0, -507.79108398045344, 1098.4374795109752, -4.082417520817821e-14, 1], 0, 0, 1, 1, 1, 1, "Polyline", 5, 2, 0, false, 0, 7, 0, [-0.6481962787933795, -0.7614732983883384, -3.969057490217688e-17, 0, -0.7614732983883384, 0.6481962787933795, -4.66267918753728e-17, 0, 6.123233995736766e-17, 0, -1, 0, -507.79108398045344, 1098.4374795109752, -4.082417520817821e-14, 1], 0, 0, 2, 4, [9.993381848422814, -884.0586414166524], 0.17863084838388266, [280.4138219783257, -1365.1880927528969], 0, [507.2825195560087, -1098.6724383169787], -0.09662306706998787, [400.5809327775901, -964.8005274526736], 0, true, 0]; + let d = + [2, "Region", 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, 1, 1, 1, 1, "Polyline", 5, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 2, 4, [0, 0], 0, [349.99999999999983, 0], 0, [349.99999999999983, 18], 0, [0, 18], 0, true, 0, "Region", 5, 2, 110, false, 1, 7, 0, [-0.6481962787933795, -0.7614732983883384, -3.969057490217688e-17, 0, 0.7614732983883384, -0.6481962787933795, 4.66267918753728e-17, 0, 6.123233995736766e-17, 0, -1, 0, -507.79108398045344, 1098.4374795109752, -4.082417520817821e-14, 1], 0, 0, 1, 1, 1, 1, "Polyline", 5, 2, 0, false, 0, 7, 0, [-0.6481962787933795, -0.7614732983883384, -3.969057490217688e-17, 0, -0.7614732983883384, 0.6481962787933795, -4.66267918753728e-17, 0, 6.123233995736766e-17, 0, -1, 0, -507.79108398045344, 1098.4374795109752, -4.082417520817821e-14, 1], 0, 0, 2, 4, [9.993381848422814, -884.0586414166524], 0.17863084838388266, [280.4138219783257, -1365.1880927528969], 0, [507.2825195560087, -1098.6724383169787], -0.09662306706998787, [400.5809327775901, -964.8005274526736], 0, true, 0]; let [reg1, reg2] = LoadRegionsFromFileData(d); let reg = reg1.Clone(); @@ -54,3 +55,12 @@ test('共线多余点', () => reg1.BooleanOper(reg2.Clone(), BoolOpeartionType.Subtract); expect(reg1.Area).toMatchSnapshot(); }); + +test('精度问题,导致的曲线合并失败,导致的无法重新生成轮廓', () => +{ + let d = + { "file": [2, "Region", 10, 2, 110, 0, 1, 7, 71, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, 1, 1, 1, 1, "Polyline", 10, 2, 0, 0, 0, 1, 71, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, 2, 4, [100, 0], 0, [400, 0], 0, [400, 864], 0, [100, 864], 0, true, 0, "Region", 10, 2, 111, 0, 1, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 1, 1, 1, 1, "Polyline", 10, 2, 0, 0, 0, 2, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -614.9118387909318, -117.20906801007538, 0, 1], 0, 0, 1, 2, 4, [0, 0], 0, [1728.0001196034718, 0], 0, [1728.0001196034718, 9.5], 0, [0, 9.5], 0, true, 0], "basePt": { "x": -0.00023216125555336475, "y": -100, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + let [reg1, reg2] = LoadRegionsFromFileData(d); + reg1.BooleanOper(reg2.Clone(), BoolOpeartionType.Intersection); + expect(reg1.Area).toMatchSnapshot(); +}); diff --git a/src/Add-on/Join.ts b/src/Add-on/Join.ts index 881ac701d..d50899e0e 100644 --- a/src/Add-on/Join.ts +++ b/src/Add-on/Join.ts @@ -72,19 +72,22 @@ export class Command_Join implements Command } else remCurves = curveCol; + + const fuzz = 0.01; //连接成多段线 - let groups = curveLinkGroup(remCurves); + let groups = curveLinkGroup(remCurves, -Math.log10(fuzz)); for (let g of groups) { if (g.length === 1) continue; let pl = new Polyline(); + pl.ColorIndex = g[0].ColorIndex; pl.OCS = ComputerCurvesNormalOCS(g); for (let cu of g) { - pl.Join(cu); - cu.Erase(); + if (pl.Join(cu, false, fuzz) === Status.True) + cu.Erase(); } if (pl.Id === undefined) diff --git a/src/Add-on/test/testIntersect.ts b/src/Add-on/test/testIntersect.ts index 41c548b0a..8a9242ef9 100644 --- a/src/Add-on/test/testIntersect.ts +++ b/src/Add-on/test/testIntersect.ts @@ -3,10 +3,10 @@ import { app } from "../../ApplicationServices/Application"; import { Arc } from "../../DatabaseServices/Entity/Arc"; import { Circle } from "../../DatabaseServices/Entity/Circle"; import { Curve } from "../../DatabaseServices/Entity/Curve"; +import { Point } from "../../DatabaseServices/Entity/Point"; import { Command } from "../../Editor/CommandMachine"; import { PromptStatus } from "../../Editor/PromptResult"; import { IntersectCircleAndCircle, IntersectOption } from "../../GraphicsSystem/IntersectWith"; -import { Point } from "../../DatabaseServices/Entity/Point"; export class TestIntersect implements Command { diff --git a/src/Add-on/testEntity/test.ts b/src/Add-on/testEntity/test.ts index 807c97d8d..978749916 100644 --- a/src/Add-on/testEntity/test.ts +++ b/src/Add-on/testEntity/test.ts @@ -1,20 +1,25 @@ import { CADFiler } from "../../DatabaseServices/CADFiler"; -import { Ellipse } from "../../DatabaseServices/Entity/Ellipse"; +import { Region } from "../../DatabaseServices/Entity/Region"; import { Command } from "../../Editor/CommandMachine"; +import { BoolOpeartionType } from "../../GraphicsSystem/BoolOperateUtils"; import { HotCMD } from "../../Hot/HotCommand"; +import { TestDraw } from "../test/TestUtil"; @HotCMD export class Test implements Command { async exec() { - let d = { "file": [2, "Ellipse", 10, 2, 103, 0, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 983.9770911100416, 940.0742538149107, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1926.3535339862863, 877.8288804632223, 0, 1], 0, 0, 1, 1, 418.15520838547974, 225.54490978414745, -0.69713252541264, 6.343188564109003, 7.616407379765725, "Ellipse", 10, 2, 104, 0, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 983.9770911100406, 940.0742538149093, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1926.3535339862863, 877.8288804632223, 0, 1], 0, 0, 1, 1, 418.15520838547974, 225.54490978414745, -0.69713252541264, 3.934994981148553, 6.34318856410901], "basePt": { "x": 655.8960059049625, "y": 620.7541549379562, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + let d = { "file": [2, "Region", 10, 2, 110, 0, 1, 7, 71, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, 1, 1, 1, 1, "Polyline", 10, 2, 0, 0, 0, 1, 71, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 863.9997678387444, -200, 0, 1], 0, 0, 1, 2, 4, [100, 0], 0, [400, 0], 0, [400, 864], 0, [100, 864], 0, true, 0, "Region", 10, 2, 111, 0, 1, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 1, 1, 1, 1, "Polyline", 10, 2, 0, 0, 0, 2, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -614.9118387909318, -117.20906801007538, 0, 1], 0, 0, 1, 2, 4, [0, 0], 0, [1728.0001196034718, 0], 0, [1728.0001196034718, 9.5], 0, [0, 9.5], 0, true, 0], "basePt": { "x": -0.00023216125555336475, "y": -100, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; let f = new CADFiler(d.file); f.Read(); - let el1 = f.ReadObject() as Ellipse; - let el2 = f.ReadObject() as Ellipse; + let el1 = f.ReadObject() as Region; + let el2 = f.ReadObject() as Region; - el1.Join(el2); + TestDraw(el1.Clone()); + TestDraw(el2.Clone()); + + el1.BooleanOper(el2, BoolOpeartionType.Intersection); } } diff --git a/src/Common/CurveUtils.ts b/src/Common/CurveUtils.ts index 609272968..ac31f627a 100644 --- a/src/Common/CurveUtils.ts +++ b/src/Common/CurveUtils.ts @@ -86,7 +86,7 @@ export function getDeterminantFor3V(v1: Vector3, v2: Vector3, v3: Vector3) * [c1,c2,c3...], * ] */ -export function curveLinkGroup(cus: Curve[]): Array> +export function curveLinkGroup(cus: Curve[], numdimensions = 4): Array> { //返回的曲线组 let groupCus = new Array>(); @@ -100,8 +100,9 @@ export function curveLinkGroup(cus: Curve[]): Array> return !isClose; }); if (cus.length === 0) return groupCus; + const fuzz = 5 * Math.pow(0.1, numdimensions); //曲线节点图 - let cuMap = new CurveMap(); + let cuMap = new CurveMap(numdimensions); cus.forEach(c => cuMap.AddCurveToMap(c)); //曲线站点表 @@ -126,14 +127,14 @@ export function curveLinkGroup(cus: Curve[]): Array> if (isEndSeach) { //保证曲线总是从起点连接到终点 - if (!equalv3(cu.StartPoint, stand.position)) + if (!equalv3(cu.StartPoint, stand.position, fuzz)) cu.Reverse(); cus.push(cu); } else { //保证曲线总是从起点连接到终点 - if (!equalv3(cu.EndPoint, stand.position)) + if (!equalv3(cu.EndPoint, stand.position, fuzz)) cu.Reverse(); cus.unshift(cu); } diff --git a/src/DatabaseServices/Contour.ts b/src/DatabaseServices/Contour.ts index 1d8f064d1..bb3c96473 100644 --- a/src/DatabaseServices/Contour.ts +++ b/src/DatabaseServices/Contour.ts @@ -523,7 +523,7 @@ export class Contour if (Array.isArray(cus[0])) cuGroups = cus as Curve[][]; else - cuGroups = curveLinkGroup(cus as Curve[]); + cuGroups = curveLinkGroup(cus as Curve[], -Math.log10(COMBINE_FUZZ)); let contours: Contour[] = []; @@ -541,7 +541,7 @@ export class Contour { if (cus.length === 0) return undefined; - let groups = needLink ? curveLinkGroup(cus) : [cus]; + let groups = needLink ? curveLinkGroup(cus, -Math.log10(tolerance)) : [cus]; for (let g of groups) { if (g.length === 1)