@itwin/core-geometry 4.0.0-dev.70 → 4.0.0-dev.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -3
- package/lib/cjs/curve/Query/PlanarSubdivision.d.ts +7 -1
- package/lib/cjs/curve/Query/PlanarSubdivision.d.ts.map +1 -1
- package/lib/cjs/curve/Query/PlanarSubdivision.js +14 -12
- package/lib/cjs/curve/Query/PlanarSubdivision.js.map +1 -1
- package/lib/cjs/curve/RegionOps.d.ts +2 -2
- package/lib/cjs/curve/RegionOps.js +2 -2
- package/lib/cjs/curve/RegionOps.js.map +1 -1
- package/lib/cjs/geometry3d/BarycentricTriangle.d.ts +134 -90
- package/lib/cjs/geometry3d/BarycentricTriangle.d.ts.map +1 -1
- package/lib/cjs/geometry3d/BarycentricTriangle.js +192 -129
- package/lib/cjs/geometry3d/BarycentricTriangle.js.map +1 -1
- package/lib/cjs/geometry3d/Ray3d.d.ts +38 -34
- package/lib/cjs/geometry3d/Ray3d.d.ts.map +1 -1
- package/lib/cjs/geometry3d/Ray3d.js +48 -45
- package/lib/cjs/geometry3d/Ray3d.js.map +1 -1
- package/lib/esm/curve/Query/PlanarSubdivision.d.ts +7 -1
- package/lib/esm/curve/Query/PlanarSubdivision.d.ts.map +1 -1
- package/lib/esm/curve/Query/PlanarSubdivision.js +14 -12
- package/lib/esm/curve/Query/PlanarSubdivision.js.map +1 -1
- package/lib/esm/curve/RegionOps.d.ts +2 -2
- package/lib/esm/curve/RegionOps.js +2 -2
- package/lib/esm/curve/RegionOps.js.map +1 -1
- package/lib/esm/geometry3d/BarycentricTriangle.d.ts +134 -90
- package/lib/esm/geometry3d/BarycentricTriangle.d.ts.map +1 -1
- package/lib/esm/geometry3d/BarycentricTriangle.js +192 -129
- package/lib/esm/geometry3d/BarycentricTriangle.js.map +1 -1
- package/lib/esm/geometry3d/Ray3d.d.ts +38 -34
- package/lib/esm/geometry3d/Ray3d.d.ts.map +1 -1
- package/lib/esm/geometry3d/Ray3d.js +48 -45
- package/lib/esm/geometry3d/Ray3d.js.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,39 @@
|
|
|
1
1
|
# Change Log - @itwin/core-geometry
|
|
2
2
|
|
|
3
|
-
This log was last generated on Wed,
|
|
3
|
+
This log was last generated on Wed, 12 Apr 2023 13:12:42 GMT and should not be manually modified.
|
|
4
|
+
|
|
5
|
+
## 3.7.2
|
|
6
|
+
Wed, 12 Apr 2023 13:12:42 GMT
|
|
7
|
+
|
|
8
|
+
_Version update only_
|
|
9
|
+
|
|
10
|
+
## 3.7.1
|
|
11
|
+
Mon, 03 Apr 2023 15:15:37 GMT
|
|
12
|
+
|
|
13
|
+
_Version update only_
|
|
14
|
+
|
|
15
|
+
## 3.7.0
|
|
16
|
+
Wed, 29 Mar 2023 15:02:27 GMT
|
|
17
|
+
|
|
18
|
+
### Updates
|
|
19
|
+
|
|
20
|
+
- ray-mesh intersection
|
|
21
|
+
- add merge tolerance to regionBooleanXY
|
|
22
|
+
|
|
23
|
+
## 3.6.3
|
|
24
|
+
Mon, 27 Mar 2023 16:26:47 GMT
|
|
25
|
+
|
|
26
|
+
_Version update only_
|
|
27
|
+
|
|
28
|
+
## 3.6.2
|
|
29
|
+
Fri, 17 Mar 2023 17:52:32 GMT
|
|
30
|
+
|
|
31
|
+
_Version update only_
|
|
32
|
+
|
|
33
|
+
## 3.6.1
|
|
34
|
+
Fri, 24 Feb 2023 22:00:48 GMT
|
|
35
|
+
|
|
36
|
+
_Version update only_
|
|
4
37
|
|
|
5
38
|
## 3.6.0
|
|
6
39
|
Wed, 08 Feb 2023 14:58:40 GMT
|
|
@@ -1032,7 +1065,7 @@ Fri, 22 Nov 2019 14:03:34 GMT
|
|
|
1032
1065
|
|
|
1033
1066
|
### Updates
|
|
1034
1067
|
|
|
1035
|
-
- PolyfaceQuery services: PolyfaceQuery.markAllEdgeVisibility PolyfaceQuery.markPairedEdgesInvisible PolyfaceQuery.setSingleEdgeVisibility PolyfaceQuery.computeFacetUnitNormal
|
|
1068
|
+
- PolyfaceQuery services: PolyfaceQuery.markAllEdgeVisibility PolyfaceQuery.markPairedEdgesInvisible PolyfaceQuery.setSingleEdgeVisibility PolyfaceQuery.computeFacetUnitNormal
|
|
1036
1069
|
- Correct sectioning of meshes with (a) nonconvex facets and (b) multicomponent plane intersections
|
|
1037
1070
|
- Intersect Ray with Sphere
|
|
1038
1071
|
- Spherical patch range; optional result in range3d.corners()
|
|
@@ -1163,7 +1196,7 @@ Mon, 13 May 2019 15:52:05 GMT
|
|
|
1163
1196
|
- Triangulation bug (multiple holes not linked correctly)
|
|
1164
1197
|
- Fix broken links
|
|
1165
1198
|
- Put sourcemap in npm package.
|
|
1166
|
-
- Setup a generic context for tracking client requests, and made various related enhancements to logging, usage tracking and authorization.
|
|
1199
|
+
- Setup a generic context for tracking client requests, and made various related enhancements to logging, usage tracking and authorization.
|
|
1167
1200
|
- New code for regularizing a single face.
|
|
1168
1201
|
- Upgrade TypeDoc dependency to 0.14.2
|
|
1169
1202
|
|
|
@@ -19,7 +19,13 @@ export declare class PlanarSubdivision {
|
|
|
19
19
|
* @param point1 end point
|
|
20
20
|
*/
|
|
21
21
|
private static addHalfEdge;
|
|
22
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Based on computed (and toleranced) area, push the loop (pointer) onto the appropriate array of positive, negative, or sliver loops.
|
|
24
|
+
* @param zeroAreaTolerance absolute area tolerance for sliver face detection
|
|
25
|
+
* @param isSliverFace whether the loop is known a priori (e.g., via topology) to have zero area
|
|
26
|
+
* @returns the area (forced to zero if within tolerance)
|
|
27
|
+
*/
|
|
28
|
+
static collectSignedLoop(loop: Loop, outLoops: SignedLoops, zeroAreaTolerance?: number, isSliverFace?: boolean): number;
|
|
23
29
|
static createLoopInFace(faceSeed: HalfEdge, announce?: (he: HalfEdge, curve: CurvePrimitive, loop: Loop) => void): Loop;
|
|
24
30
|
private static isNullFace;
|
|
25
31
|
private static nonNullEdgeMate;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlanarSubdivision.d.ts","sourceRoot":"","sources":["../../../../src/curve/Query/PlanarSubdivision.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAG/D,OAAO,EAAuB,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,IAAI,EAAsB,WAAW,EAAE,MAAM,SAAS,CAAC;AAqDhE;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,qGAAqG;WACvF,qBAAqB,CAAC,UAAU,EAAE,cAAc,EAAE,EAAE,QAAQ,EAAE,uBAAuB,EAAE,GAAG,aAAa;IA+
|
|
1
|
+
{"version":3,"file":"PlanarSubdivision.d.ts","sourceRoot":"","sources":["../../../../src/curve/Query/PlanarSubdivision.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAG/D,OAAO,EAAuB,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,IAAI,EAAsB,WAAW,EAAE,MAAM,SAAS,CAAC;AAqDhE;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,qGAAqG;WACvF,qBAAqB,CAAC,UAAU,EAAE,cAAc,EAAE,EAAE,QAAQ,EAAE,uBAAuB,EAAE,GAAG,aAAa;IA+BrH;;;;;;;;;OASG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAa1B;;;;;OAKG;WACW,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,iBAAiB,GAAE,MAAgB,EAAE,YAAY,CAAC,EAAE,OAAO,GAAG,MAAM;WAezH,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAC/C,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI;IAsB7E,OAAO,CAAC,MAAM,CAAC,UAAU;IAYzB,OAAO,CAAC,MAAM,CAAC,eAAe;WAWhB,oCAAoC,CAAC,KAAK,EAAE,aAAa,EAAE,iBAAiB,GAAE,MAAgB,GAAG,WAAW,EAAE;CAkC7H"}
|
|
@@ -123,21 +123,25 @@ class PlanarSubdivision {
|
|
|
123
123
|
mate.sortAngle = sortAngle(detail01.curve, detail01.fraction1, true);
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
/**
|
|
127
|
+
* Based on computed (and toleranced) area, push the loop (pointer) onto the appropriate array of positive, negative, or sliver loops.
|
|
128
|
+
* @param zeroAreaTolerance absolute area tolerance for sliver face detection
|
|
129
|
+
* @param isSliverFace whether the loop is known a priori (e.g., via topology) to have zero area
|
|
130
|
+
* @returns the area (forced to zero if within tolerance)
|
|
131
|
+
*/
|
|
132
|
+
static collectSignedLoop(loop, outLoops, zeroAreaTolerance = 1.0e-10, isSliverFace) {
|
|
133
|
+
let area = isSliverFace ? 0.0 : RegionOps_1.RegionOps.computeXYArea(loop);
|
|
130
134
|
if (area === undefined)
|
|
131
135
|
area = 0;
|
|
132
136
|
if (Math.abs(area) < zeroAreaTolerance)
|
|
133
137
|
area = 0.0;
|
|
134
138
|
loop.computedAreaInPlanarSubdivision = area;
|
|
135
139
|
if (area > 0)
|
|
136
|
-
|
|
140
|
+
outLoops.positiveAreaLoops.push(loop);
|
|
137
141
|
else if (area < 0)
|
|
138
|
-
|
|
142
|
+
outLoops.negativeAreaLoops.push(loop);
|
|
139
143
|
else
|
|
140
|
-
|
|
144
|
+
outLoops.slivers.push(loop);
|
|
141
145
|
return area;
|
|
142
146
|
}
|
|
143
147
|
static createLoopInFace(faceSeed, announce) {
|
|
@@ -193,11 +197,9 @@ class PlanarSubdivision {
|
|
|
193
197
|
const componentAreas = { positiveAreaLoops: [], negativeAreaLoops: [], slivers: [] };
|
|
194
198
|
const edges = [];
|
|
195
199
|
for (const faceSeed of faceSeeds) {
|
|
200
|
+
const isNullFace = this.isNullFace(faceSeed);
|
|
196
201
|
const loop = this.createLoopInFace(faceSeed, (he, curveC, loopC) => {
|
|
197
|
-
if (
|
|
198
|
-
// Ignore all edges of null faces.
|
|
199
|
-
}
|
|
200
|
-
else {
|
|
202
|
+
if (!isNullFace) {
|
|
201
203
|
const mate = this.nonNullEdgeMate(graph, he);
|
|
202
204
|
if (mate !== undefined) {
|
|
203
205
|
const e = edgeMap.get(mate);
|
|
@@ -214,7 +216,7 @@ class PlanarSubdivision {
|
|
|
214
216
|
}
|
|
215
217
|
}
|
|
216
218
|
});
|
|
217
|
-
this.collectSignedLoop(loop, componentAreas, zeroAreaTolerance);
|
|
219
|
+
this.collectSignedLoop(loop, componentAreas, zeroAreaTolerance, isNullFace);
|
|
218
220
|
}
|
|
219
221
|
componentAreas.edges = edges;
|
|
220
222
|
result.push(componentAreas);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlanarSubdivision.js","sourceRoot":"","sources":["../../../../src/curve/Query/PlanarSubdivision.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport { Geometry } from \"../../Geometry\";\r\nimport { Point3d } from \"../../geometry3d/Point3dVector3d\";\r\nimport { HalfEdge, HalfEdgeGraph } from \"../../topology/Graph\";\r\nimport { HalfEdgeGraphSearch } from \"../../topology/HalfEdgeGraphSearch\";\r\nimport { HalfEdgeGraphMerge } from \"../../topology/Merging\";\r\nimport { CurveLocationDetail, CurveLocationDetailPair } from \"../CurveLocationDetail\";\r\nimport { CurvePrimitive } from \"../CurvePrimitive\";\r\nimport { Loop, LoopCurveLoopCurve, SignedLoops } from \"../Loop\";\r\nimport { RegionOps } from \"../RegionOps\";\r\n\r\n/** @packageDocumentation\r\n * @module Curve\r\n */\r\n\r\nclass MapCurvePrimitiveToCurveLocationDetailPairArray {\r\n public primitiveToPair = new Map<CurvePrimitive, CurveLocationDetailPair[]>();\r\n // index assigned to this primitive for this calculation.\r\n public primitiveToIndex = new Map<CurvePrimitive, number>();\r\n private _numIndexedPrimitives: number = 0;\r\n public assignPrimitiveIndex(primitive: CurvePrimitive | undefined) {\r\n if (primitive !== undefined) {\r\n const index = this.primitiveToIndex.get(primitive);\r\n if (index === undefined) {\r\n this.primitiveToIndex.set(primitive, this._numIndexedPrimitives++);\r\n }\r\n }\r\n }\r\n public insertPrimitiveToPair(primitive: CurvePrimitive | undefined, pair: CurveLocationDetailPair) {\r\n if (primitive) {\r\n const priorPairs = this.primitiveToPair.get(primitive);\r\n this.assignPrimitiveIndex(primitive);\r\n if (!priorPairs) {\r\n this.primitiveToPair.set(primitive, [pair]);\r\n } else {\r\n priorPairs.push(pair);\r\n }\r\n }\r\n }\r\n public insertPair(pair: CurveLocationDetailPair) {\r\n const primitiveA = pair.detailA.curve;\r\n if (primitiveA)\r\n this.insertPrimitiveToPair(primitiveA, pair);\r\n const primitiveB = pair.detailB.curve;\r\n if (primitiveB)\r\n this.insertPrimitiveToPair(primitiveB, pair);\r\n }\r\n}\r\n/*\r\n function getDetailString(detail: CurveLocationDetail | undefined): string {\r\n if (!detail)\r\n return \"{}\";\r\n else return tagString(\"primitive\", this.primitiveToIndex.get(detail.curve!)) + tagString(\"f0\", detail.fraction) + tagString(\"f1\", detail.fraction1);\r\n }\r\n}\r\nfunction tagString(name: string, value: number | undefined): string {\r\n if (value !== undefined)\r\n return \"(\" + name + \" \" + value + \")\";\r\n return \"\";\r\n}\r\n*/\r\n/**\r\n * @internal\r\n */\r\nexport class PlanarSubdivision {\r\n /** Create a graph from an array of curves, and an array of the curves' precomputed intersections. */\r\n public static assembleHalfEdgeGraph(primitives: CurvePrimitive[], allPairs: CurveLocationDetailPair[]): HalfEdgeGraph {\r\n const detailByPrimitive = new MapCurvePrimitiveToCurveLocationDetailPairArray(); // map from key CurvePrimitive to CurveLocationDetailPair.\r\n for (const p of primitives)\r\n detailByPrimitive.assignPrimitiveIndex(p);\r\n for (const pair of allPairs) {\r\n detailByPrimitive.insertPair(pair);\r\n }\r\n const graph = new HalfEdgeGraph();\r\n for (const entry of detailByPrimitive.primitiveToPair.entries()) {\r\n const p = entry[0];\r\n const details = entry[1];\r\n details.sort((pairA: CurveLocationDetailPair, pairB: CurveLocationDetailPair) => {\r\n const fractionA = getFractionOnCurve(pairA, p);\r\n const fractionB = getFractionOnCurve(pairB, p);\r\n if (fractionA === undefined || fractionB === undefined)\r\n return -1000.0;\r\n return fractionA - fractionB;\r\n });\r\n let detail0 = getDetailOnCurve(details[0], p)!;\r\n this.addHalfEdge(graph, p, p.startPoint (), 0.0, detail0.point, detail0.fraction);\r\n for (let i = 1; i < details.length; i++) {\r\n // create (both sides of) a graph edge . . .\r\n const detail1 = getDetailOnCurve(details[i], p)!;\r\n this.addHalfEdge(graph, p, detail0.point, detail0.fraction, detail1.point, detail1.fraction);\r\n detail0 = detail1;\r\n }\r\n this.addHalfEdge(graph, p, detail0.point, detail0.fraction, p.endPoint(), 1.0);\r\n }\r\n HalfEdgeGraphMerge.clusterAndMergeXYTheta(graph, (he: HalfEdge) => he.sortAngle!);\r\n return graph;\r\n }\r\n/**\r\n * Create a pair of mated half edges referencing an interval of a primitive\r\n * * no action if start and end points are identical.\r\n * @param graph containing graph.\r\n * @param p the curve\r\n * @param fraction0 starting fraction\r\n * @param point0 start point\r\n * @param fraction1 end fraction\r\n * @param point1 end point\r\n */\r\n private static addHalfEdge(graph: HalfEdgeGraph, p: CurvePrimitive, point0: Point3d, fraction0: number, point1: Point3d, fraction1: number) {\r\n if (!point0.isAlmostEqual (point1)){\r\n const halfEdge = graph.createEdgeXYAndZ(point0, 0, point1, 0);\r\n const detail01 = CurveLocationDetail.createCurveEvaluatedFractionFraction(p, fraction0, fraction1);\r\n const mate = halfEdge.edgeMate;\r\n halfEdge.edgeTag = detail01;\r\n halfEdge.sortData = 1.0;\r\n mate.edgeTag = detail01;\r\n mate.sortData = -1.0;\r\n halfEdge.sortAngle = sortAngle(detail01.curve!, detail01.fraction, false);\r\n mate.sortAngle = sortAngle(detail01.curve!, detail01.fraction1!, true);\r\n }\r\n }\r\n// based on computed (and toleranced) area, push the loop (pointer) onto the appropriate array of positive, negative, or sliver loops.\r\n // return the area (forced to zero if within tolerance)\r\n public static collectSignedLoop(loop: Loop, signedAreas: SignedLoops, zeroAreaTolerance: number = 1.0e-10): number{\r\n let area = RegionOps.computeXYArea(loop);\r\n if (area === undefined)\r\n area = 0;\r\n if (Math.abs(area) < zeroAreaTolerance)\r\n area = 0.0;\r\n (loop as any).computedAreaInPlanarSubdivision = area;\r\n if (area > 0)\r\n signedAreas.positiveAreaLoops.push(loop);\r\n else if (area < 0)\r\n signedAreas.negativeAreaLoops.push(loop);\r\n else\r\n signedAreas.slivers.push(loop);\r\n return area;\r\n }\r\n public static createLoopInFace(faceSeed: HalfEdge,\r\n announce?: (he: HalfEdge, curve: CurvePrimitive, loop: Loop) => void): Loop {\r\n let he = faceSeed;\r\n const loop = Loop.create();\r\n do {\r\n const detail = he.edgeTag as CurveLocationDetail;\r\n if (detail) {\r\n let curve;\r\n if (he.sortData! > 0)\r\n curve = detail.curve!.clonePartialCurve(detail.fraction, detail.fraction1!);\r\n else\r\n curve = detail.curve!.clonePartialCurve(detail.fraction1!, detail.fraction);\r\n if (curve) {\r\n if (announce !== undefined)\r\n announce(he, curve, loop);\r\n loop.tryAddChild(curve);\r\n }\r\n }\r\n he = he.faceSuccessor;\r\n } while (he !== faceSeed);\r\n return loop;\r\n }\r\n // Return true if there are only two edges in the face loop, and their start curvatures are the same.\r\n private static isNullFace(he: HalfEdge): boolean {\r\n const faceHasTwoEdges = (he.faceSuccessor.faceSuccessor === he);\r\n let faceIsBanana = false;\r\n if (faceHasTwoEdges) {\r\n const c0 = HalfEdgeGraphMerge.curvatureSortKey(he);\r\n const c1 = HalfEdgeGraphMerge.curvatureSortKey(he.faceSuccessor.edgeMate);\r\n if (!Geometry.isSameCoordinate(c0, c1)) // default tol!\r\n faceIsBanana = true; // heuristic: we could also check end curvatures, and/or higher derivatives...\r\n }\r\n return faceHasTwoEdges && !faceIsBanana;\r\n }\r\n // Look across edge mates (possibly several) for a nonnull mate face.\r\n private static nonNullEdgeMate(_graph: HalfEdgeGraph, e: HalfEdge): HalfEdge | undefined {\r\n if (this.isNullFace (e))\r\n return undefined;\r\n let e1 = e.edgeMate;\r\n while (this.isNullFace(e1)){\r\n e1 = e1.faceSuccessor.edgeMate;\r\n if (e1 === e)\r\n return undefined;\r\n }\r\n return e1;\r\n }\r\n public static collectSignedLoopSetsInHalfEdgeGraph(graph: HalfEdgeGraph, zeroAreaTolerance: number = 1.0e-10): SignedLoops[] {\r\n const q = HalfEdgeGraphSearch.collectConnectedComponentsWithExteriorParityMasks(graph, undefined);\r\n const result: SignedLoops[] = [];\r\n const edgeMap = new Map<HalfEdge, LoopCurveLoopCurve>();\r\n for (const faceSeeds of q) {\r\n const componentAreas: SignedLoops = { positiveAreaLoops: [], negativeAreaLoops: [], slivers: [] };\r\n const edges: LoopCurveLoopCurve[] = [];\r\n for (const faceSeed of faceSeeds) {\r\n const loop = this.createLoopInFace(faceSeed, (he: HalfEdge, curveC: CurvePrimitive, loopC: Loop) => {\r\n if (this.isNullFace(he)) {\r\n // Ignore all edges of null faces.\r\n } else {\r\n const mate = this.nonNullEdgeMate(graph, he);\r\n if (mate !== undefined){\r\n const e = edgeMap.get(mate);\r\n if (e === undefined) {\r\n // Record this as loopA,edgeA of a shared edge to be completed later from the other side of the edge\r\n const e1 = new LoopCurveLoopCurve(loopC, curveC, undefined, undefined);\r\n edgeMap.set(he, e1);\r\n } else if (e instanceof LoopCurveLoopCurve) {\r\n e.setB(loopC, curveC);\r\n edges.push(e);\r\n edgeMap.delete(mate);\r\n }\r\n }\r\n }\r\n });\r\n this.collectSignedLoop(loop, componentAreas, zeroAreaTolerance);\r\n }\r\n componentAreas.edges = edges;\r\n result.push(componentAreas);\r\n edgeMap.clear();\r\n }\r\n return result;\r\n }\r\n}\r\n\r\nfunction sortAngle(curve: CurvePrimitive, fraction: number, reverse: boolean): number {\r\n const ray = curve.fractionToPointAndDerivative(fraction);\r\n const s = reverse ? -1.0 : 1.0;\r\n return Math.atan2(s * ray.direction.y, s * ray.direction.x);\r\n}\r\n\r\nfunction getFractionOnCurve(pair: CurveLocationDetailPair, curve: CurvePrimitive): number | undefined {\r\n if (pair.detailA.curve === curve)\r\n return pair.detailA.fraction;\r\n if (pair.detailB.curve === curve)\r\n return pair.detailB.fraction;\r\n return undefined;\r\n}\r\nfunction getDetailOnCurve(pair: CurveLocationDetailPair, curve: CurvePrimitive): CurveLocationDetail | undefined {\r\n if (pair.detailA.curve === curve)\r\n return pair.detailA;\r\n if (pair.detailB.curve === curve)\r\n return pair.detailB;\r\n return undefined;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"PlanarSubdivision.js","sourceRoot":"","sources":["../../../../src/curve/Query/PlanarSubdivision.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport { Geometry } from \"../../Geometry\";\r\nimport { Point3d } from \"../../geometry3d/Point3dVector3d\";\r\nimport { HalfEdge, HalfEdgeGraph } from \"../../topology/Graph\";\r\nimport { HalfEdgeGraphSearch } from \"../../topology/HalfEdgeGraphSearch\";\r\nimport { HalfEdgeGraphMerge } from \"../../topology/Merging\";\r\nimport { CurveLocationDetail, CurveLocationDetailPair } from \"../CurveLocationDetail\";\r\nimport { CurvePrimitive } from \"../CurvePrimitive\";\r\nimport { Loop, LoopCurveLoopCurve, SignedLoops } from \"../Loop\";\r\nimport { RegionOps } from \"../RegionOps\";\r\n\r\n/** @packageDocumentation\r\n * @module Curve\r\n */\r\n\r\nclass MapCurvePrimitiveToCurveLocationDetailPairArray {\r\n public primitiveToPair = new Map<CurvePrimitive, CurveLocationDetailPair[]>();\r\n // index assigned to this primitive for this calculation.\r\n public primitiveToIndex = new Map<CurvePrimitive, number>();\r\n private _numIndexedPrimitives: number = 0;\r\n public assignPrimitiveIndex(primitive: CurvePrimitive | undefined) {\r\n if (primitive !== undefined) {\r\n const index = this.primitiveToIndex.get(primitive);\r\n if (index === undefined) {\r\n this.primitiveToIndex.set(primitive, this._numIndexedPrimitives++);\r\n }\r\n }\r\n }\r\n public insertPrimitiveToPair(primitive: CurvePrimitive | undefined, pair: CurveLocationDetailPair) {\r\n if (primitive) {\r\n const priorPairs = this.primitiveToPair.get(primitive);\r\n this.assignPrimitiveIndex(primitive);\r\n if (!priorPairs) {\r\n this.primitiveToPair.set(primitive, [pair]);\r\n } else {\r\n priorPairs.push(pair);\r\n }\r\n }\r\n }\r\n public insertPair(pair: CurveLocationDetailPair) {\r\n const primitiveA = pair.detailA.curve;\r\n if (primitiveA)\r\n this.insertPrimitiveToPair(primitiveA, pair);\r\n const primitiveB = pair.detailB.curve;\r\n if (primitiveB)\r\n this.insertPrimitiveToPair(primitiveB, pair);\r\n }\r\n}\r\n/*\r\n function getDetailString(detail: CurveLocationDetail | undefined): string {\r\n if (!detail)\r\n return \"{}\";\r\n else return tagString(\"primitive\", this.primitiveToIndex.get(detail.curve!)) + tagString(\"f0\", detail.fraction) + tagString(\"f1\", detail.fraction1);\r\n }\r\n}\r\nfunction tagString(name: string, value: number | undefined): string {\r\n if (value !== undefined)\r\n return \"(\" + name + \" \" + value + \")\";\r\n return \"\";\r\n}\r\n*/\r\n/**\r\n * @internal\r\n */\r\nexport class PlanarSubdivision {\r\n /** Create a graph from an array of curves, and an array of the curves' precomputed intersections. */\r\n public static assembleHalfEdgeGraph(primitives: CurvePrimitive[], allPairs: CurveLocationDetailPair[]): HalfEdgeGraph {\r\n const detailByPrimitive = new MapCurvePrimitiveToCurveLocationDetailPairArray(); // map from key CurvePrimitive to CurveLocationDetailPair.\r\n for (const p of primitives)\r\n detailByPrimitive.assignPrimitiveIndex(p);\r\n for (const pair of allPairs) {\r\n detailByPrimitive.insertPair(pair);\r\n }\r\n const graph = new HalfEdgeGraph();\r\n for (const entry of detailByPrimitive.primitiveToPair.entries()) {\r\n const p = entry[0];\r\n const details = entry[1];\r\n details.sort((pairA: CurveLocationDetailPair, pairB: CurveLocationDetailPair) => {\r\n const fractionA = getFractionOnCurve(pairA, p);\r\n const fractionB = getFractionOnCurve(pairB, p);\r\n if (fractionA === undefined || fractionB === undefined)\r\n return -1000.0;\r\n return fractionA - fractionB;\r\n });\r\n let detail0 = getDetailOnCurve(details[0], p)!;\r\n this.addHalfEdge(graph, p, p.startPoint (), 0.0, detail0.point, detail0.fraction);\r\n for (let i = 1; i < details.length; i++) {\r\n // create (both sides of) a graph edge . . .\r\n const detail1 = getDetailOnCurve(details[i], p)!;\r\n this.addHalfEdge(graph, p, detail0.point, detail0.fraction, detail1.point, detail1.fraction);\r\n detail0 = detail1;\r\n }\r\n this.addHalfEdge(graph, p, detail0.point, detail0.fraction, p.endPoint(), 1.0);\r\n }\r\n HalfEdgeGraphMerge.clusterAndMergeXYTheta(graph, (he: HalfEdge) => he.sortAngle!);\r\n return graph;\r\n }\r\n /**\r\n * Create a pair of mated half edges referencing an interval of a primitive\r\n * * no action if start and end points are identical.\r\n * @param graph containing graph.\r\n * @param p the curve\r\n * @param fraction0 starting fraction\r\n * @param point0 start point\r\n * @param fraction1 end fraction\r\n * @param point1 end point\r\n */\r\n private static addHalfEdge(graph: HalfEdgeGraph, p: CurvePrimitive, point0: Point3d, fraction0: number, point1: Point3d, fraction1: number) {\r\n if (!point0.isAlmostEqual (point1)){\r\n const halfEdge = graph.createEdgeXYAndZ(point0, 0, point1, 0);\r\n const detail01 = CurveLocationDetail.createCurveEvaluatedFractionFraction(p, fraction0, fraction1);\r\n const mate = halfEdge.edgeMate;\r\n halfEdge.edgeTag = detail01;\r\n halfEdge.sortData = 1.0;\r\n mate.edgeTag = detail01;\r\n mate.sortData = -1.0;\r\n halfEdge.sortAngle = sortAngle(detail01.curve!, detail01.fraction, false);\r\n mate.sortAngle = sortAngle(detail01.curve!, detail01.fraction1!, true);\r\n }\r\n }\r\n /**\r\n * Based on computed (and toleranced) area, push the loop (pointer) onto the appropriate array of positive, negative, or sliver loops.\r\n * @param zeroAreaTolerance absolute area tolerance for sliver face detection\r\n * @param isSliverFace whether the loop is known a priori (e.g., via topology) to have zero area\r\n * @returns the area (forced to zero if within tolerance)\r\n */\r\n public static collectSignedLoop(loop: Loop, outLoops: SignedLoops, zeroAreaTolerance: number = 1.0e-10, isSliverFace?: boolean): number{\r\n let area = isSliverFace ? 0.0 : RegionOps.computeXYArea(loop);\r\n if (area === undefined)\r\n area = 0;\r\n if (Math.abs(area) < zeroAreaTolerance)\r\n area = 0.0;\r\n (loop as any).computedAreaInPlanarSubdivision = area;\r\n if (area > 0)\r\n outLoops.positiveAreaLoops.push(loop);\r\n else if (area < 0)\r\n outLoops.negativeAreaLoops.push(loop);\r\n else\r\n outLoops.slivers.push(loop);\r\n return area;\r\n }\r\n public static createLoopInFace(faceSeed: HalfEdge,\r\n announce?: (he: HalfEdge, curve: CurvePrimitive, loop: Loop) => void): Loop {\r\n let he = faceSeed;\r\n const loop = Loop.create();\r\n do {\r\n const detail = he.edgeTag as CurveLocationDetail;\r\n if (detail) {\r\n let curve;\r\n if (he.sortData! > 0)\r\n curve = detail.curve!.clonePartialCurve(detail.fraction, detail.fraction1!);\r\n else\r\n curve = detail.curve!.clonePartialCurve(detail.fraction1!, detail.fraction);\r\n if (curve) {\r\n if (announce !== undefined)\r\n announce(he, curve, loop);\r\n loop.tryAddChild(curve);\r\n }\r\n }\r\n he = he.faceSuccessor;\r\n } while (he !== faceSeed);\r\n return loop;\r\n }\r\n // Return true if there are only two edges in the face loop, and their start curvatures are the same.\r\n private static isNullFace(he: HalfEdge): boolean {\r\n const faceHasTwoEdges = (he.faceSuccessor.faceSuccessor === he);\r\n let faceIsBanana = false;\r\n if (faceHasTwoEdges) {\r\n const c0 = HalfEdgeGraphMerge.curvatureSortKey(he);\r\n const c1 = HalfEdgeGraphMerge.curvatureSortKey(he.faceSuccessor.edgeMate);\r\n if (!Geometry.isSameCoordinate(c0, c1)) // default tol!\r\n faceIsBanana = true; // heuristic: we could also check end curvatures, and/or higher derivatives...\r\n }\r\n return faceHasTwoEdges && !faceIsBanana;\r\n }\r\n // Look across edge mates (possibly several) for a nonnull mate face.\r\n private static nonNullEdgeMate(_graph: HalfEdgeGraph, e: HalfEdge): HalfEdge | undefined {\r\n if (this.isNullFace (e))\r\n return undefined;\r\n let e1 = e.edgeMate;\r\n while (this.isNullFace(e1)){\r\n e1 = e1.faceSuccessor.edgeMate;\r\n if (e1 === e)\r\n return undefined;\r\n }\r\n return e1;\r\n }\r\n public static collectSignedLoopSetsInHalfEdgeGraph(graph: HalfEdgeGraph, zeroAreaTolerance: number = 1.0e-10): SignedLoops[] {\r\n const q = HalfEdgeGraphSearch.collectConnectedComponentsWithExteriorParityMasks(graph, undefined);\r\n const result: SignedLoops[] = [];\r\n const edgeMap = new Map<HalfEdge, LoopCurveLoopCurve>();\r\n for (const faceSeeds of q) {\r\n const componentAreas: SignedLoops = { positiveAreaLoops: [], negativeAreaLoops: [], slivers: [] };\r\n const edges: LoopCurveLoopCurve[] = [];\r\n for (const faceSeed of faceSeeds) {\r\n const isNullFace = this.isNullFace(faceSeed);\r\n const loop = this.createLoopInFace(faceSeed, (he: HalfEdge, curveC: CurvePrimitive, loopC: Loop) => {\r\n if (!isNullFace) {\r\n const mate = this.nonNullEdgeMate(graph, he);\r\n if (mate !== undefined) {\r\n const e = edgeMap.get(mate);\r\n if (e === undefined) {\r\n // Record this as loopA,edgeA of a shared edge to be completed later from the other side of the edge\r\n const e1 = new LoopCurveLoopCurve(loopC, curveC, undefined, undefined);\r\n edgeMap.set(he, e1);\r\n } else if (e instanceof LoopCurveLoopCurve) {\r\n e.setB(loopC, curveC);\r\n edges.push(e);\r\n edgeMap.delete(mate);\r\n }\r\n }\r\n }\r\n });\r\n this.collectSignedLoop(loop, componentAreas, zeroAreaTolerance, isNullFace);\r\n }\r\n componentAreas.edges = edges;\r\n result.push(componentAreas);\r\n edgeMap.clear();\r\n }\r\n return result;\r\n }\r\n}\r\n\r\nfunction sortAngle(curve: CurvePrimitive, fraction: number, reverse: boolean): number {\r\n const ray = curve.fractionToPointAndDerivative(fraction);\r\n const s = reverse ? -1.0 : 1.0;\r\n return Math.atan2(s * ray.direction.y, s * ray.direction.x);\r\n}\r\n\r\nfunction getFractionOnCurve(pair: CurveLocationDetailPair, curve: CurvePrimitive): number | undefined {\r\n if (pair.detailA.curve === curve)\r\n return pair.detailA.fraction;\r\n if (pair.detailB.curve === curve)\r\n return pair.detailB.fraction;\r\n return undefined;\r\n}\r\nfunction getDetailOnCurve(pair: CurveLocationDetailPair, curve: CurvePrimitive): CurveLocationDetail | undefined {\r\n if (pair.detailA.curve === curve)\r\n return pair.detailA;\r\n if (pair.detailB.curve === curve)\r\n return pair.detailB;\r\n return undefined;\r\n}\r\n"]}
|
|
@@ -291,8 +291,8 @@ export declare class RegionOps {
|
|
|
291
291
|
/**
|
|
292
292
|
* Find all areas bounded by the unstructured, possibly intersecting curves.
|
|
293
293
|
* * This method performs no merging of nearly coincident edges and vertices, which can lead to unexpected results
|
|
294
|
-
* given sufficiently imprecise input. Input geometry consisting of regions can be merged for better results
|
|
295
|
-
* [[regionBooleanXY]]
|
|
294
|
+
* given sufficiently imprecise input. Input geometry consisting of regions can be merged for better results by pre-processing with
|
|
295
|
+
* [[regionBooleanXY]].
|
|
296
296
|
* @param curvesAndRegions Any collection of curves. Each Loop/ParityRegion/UnionRegion contributes its curve primitives.
|
|
297
297
|
* @returns array of [[SignedLoops]], each entry of which describes the faces in a single connected component:
|
|
298
298
|
* * `positiveAreaLoops` contains "interior" loops, _including holes in ParityRegion input_. These loops have positive area and counterclockwise orientation.
|
|
@@ -566,8 +566,8 @@ class RegionOps {
|
|
|
566
566
|
/**
|
|
567
567
|
* Find all areas bounded by the unstructured, possibly intersecting curves.
|
|
568
568
|
* * This method performs no merging of nearly coincident edges and vertices, which can lead to unexpected results
|
|
569
|
-
* given sufficiently imprecise input. Input geometry consisting of regions can be merged for better results
|
|
570
|
-
* [[regionBooleanXY]]
|
|
569
|
+
* given sufficiently imprecise input. Input geometry consisting of regions can be merged for better results by pre-processing with
|
|
570
|
+
* [[regionBooleanXY]].
|
|
571
571
|
* @param curvesAndRegions Any collection of curves. Each Loop/ParityRegion/UnionRegion contributes its curve primitives.
|
|
572
572
|
* @returns array of [[SignedLoops]], each entry of which describes the faces in a single connected component:
|
|
573
573
|
* * `positiveAreaLoops` contains "interior" loops, _including holes in ParityRegion input_. These loops have positive area and counterclockwise orientation.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RegionOps.js","sourceRoot":"","sources":["../../../src/curve/RegionOps.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/** @packageDocumentation\r\n * @module Curve\r\n */\r\n\r\nimport { Geometry } from \"../Geometry\";\r\nimport { GrowableXYZArray } from \"../geometry3d/GrowableXYZArray\";\r\nimport { IndexedXYZCollection } from \"../geometry3d/IndexedXYZCollection\";\r\nimport { Point3dArrayCarrier } from \"../geometry3d/Point3dArrayCarrier\";\r\nimport { Point3d } from \"../geometry3d/Point3dVector3d\";\r\nimport { PolylineCompressionContext } from \"../geometry3d/PolylineCompressionByEdgeOffset\";\r\nimport { Range3d } from \"../geometry3d/Range\";\r\nimport { SortablePolygon } from \"../geometry3d/SortablePolygon\";\r\nimport { Transform } from \"../geometry3d/Transform\";\r\nimport { MomentData } from \"../geometry4d/MomentData\";\r\nimport { Polyface } from \"../polyface/Polyface\";\r\nimport { PolyfaceBuilder } from \"../polyface/PolyfaceBuilder\";\r\nimport { HalfEdge, HalfEdgeGraph, HalfEdgeMask } from \"../topology/Graph\";\r\nimport { LineStringDataVariant, MultiLineStringDataVariant, Triangulator } from \"../topology/Triangulation\";\r\nimport { ChainCollectorContext } from \"./ChainCollectorContext\";\r\nimport { AnyCurve, AnyRegion } from \"./CurveChain\";\r\nimport { BagOfCurves, ConsolidateAdjacentCurvePrimitivesOptions, CurveChain, CurveCollection } from \"./CurveCollection\";\r\nimport { CurveCurve } from \"./CurveCurve\";\r\nimport { CurvePrimitive } from \"./CurvePrimitive\";\r\nimport { CurveWireMomentsXYZ } from \"./CurveWireMomentsXYZ\";\r\nimport { CurveChainWireOffsetContext, JointOptions, OffsetOptions, PolygonWireOffsetContext } from \"./internalContexts/PolygonOffsetContext\";\r\nimport { LineString3d } from \"./LineString3d\";\r\nimport { Loop, SignedLoops } from \"./Loop\";\r\nimport { Path } from \"./Path\";\r\nimport { ConsolidateAdjacentCurvePrimitivesContext } from \"./Query/ConsolidateAdjacentPrimitivesContext\";\r\nimport { CurveSplitContext } from \"./Query/CurveSplitContext\";\r\nimport { PointInOnOutContext } from \"./Query/InOutTests\";\r\nimport { PlanarSubdivision } from \"./Query/PlanarSubdivision\";\r\nimport { RegionMomentsXY } from \"./RegionMomentsXY\";\r\nimport { OffsetHelpers } from \"./internalContexts/MultiChainCollector\";\r\nimport { GeometryQuery } from \"./GeometryQuery\";\r\nimport { RegionBooleanContext, RegionGroupOpType, RegionOpsFaceToFaceSearch } from \"./RegionOpsClassificationSweeps\";\r\nimport { UnionRegion } from \"./UnionRegion\";\r\nimport { HalfEdgeGraphSearch } from \"../topology/HalfEdgeGraphSearch\";\r\nimport { ParityRegion } from \"./ParityRegion\";\r\n/**\r\n * Possible return types from [[splitToPathsBetweenBreaks]], [[collectInsideAndOutsideOffsets]] and [[collectChains]].\r\n * @public\r\n */\r\nexport type ChainTypes = CurvePrimitive | Path | BagOfCurves | Loop | undefined;\r\n\r\n/**\r\n * * `properties` is a string with special characters indicating\r\n * * \"U\" -- contains unmerged stick data\r\n * * \"M\" -- merged\r\n * * \"R\" -- regularized\r\n * * \"X\" -- has exterior markup\r\n * @internal\r\n */\r\nexport type GraphCheckPointFunction = (name: string, graph: HalfEdgeGraph, properties: string, extraData?: any) => any;\r\n/**\r\n * Enumeration of the binary operation types for a booleans among regions\r\n * @public\r\n */\r\nexport enum RegionBinaryOpType {\r\n Union = 0,\r\n Parity = 1,\r\n Intersection = 2,\r\n AMinusB = 3,\r\n BMinusA = 4,\r\n}\r\n\r\n/**\r\n * Class `RegionOps` has static members for calculations on regions (areas).\r\n * * Regions are represented by these `CurveCollection` subclasses:\r\n * * `Loop` -- a single loop\r\n * * `ParityRegion` -- a collection of loops, interpreted by parity rules.\r\n * The common \"One outer loop and many Inner loops\" is a parity region.\r\n * * `UnionRegion` -- a collection of `Loop` and `ParityRegion` objects understood as a (probably disjoint) union.\r\n * * Most of the methods in this class ignore z-coordinates, so callers should ensure that input geometry has been rotated parallel to the xy-plane.\r\n * @public\r\n */\r\nexport class RegionOps {\r\n /**\r\n * Return moment sums for a loop, parity region, or union region.\r\n * * If `rawMomentData` is the MomentData returned by computeXYAreaMoments, convert to principal axes and moments with\r\n * call `principalMomentData = MomentData.inertiaProductsToPrincipalAxes (rawMomentData.origin, rawMomentData.sums);`\r\n * @param root any Loop, ParityRegion, or UnionRegion.\r\n */\r\n public static computeXYAreaMoments(root: AnyRegion): MomentData | undefined {\r\n const handler = new RegionMomentsXY();\r\n const result = root.dispatchToGeometryHandler(handler);\r\n if (result instanceof MomentData) {\r\n result.shiftOriginAndSumsToCentroidOfSums();\r\n return result;\r\n }\r\n return undefined;\r\n }\r\n /** Return an area tolerance for a given xy-range and optional distance tolerance.\r\n * @param range range of planar region to tolerance\r\n * @param distanceTolerance optional absolute distance tolerance\r\n */\r\n public static computeXYAreaTolerance(range: Range3d, distanceTolerance: number = Geometry.smallMetricDistance): number {\r\n // if A = bh and e is distance tolerance, then A' := (b+e/2)(h+e/2) = A + e/2(b+h+e/2), so A'-A = e/2(b+h+e/2).\r\n const halfDistTol = 0.5 * distanceTolerance;\r\n return halfDistTol * (range.xLength() + range.yLength() + halfDistTol);\r\n }\r\n /**\r\n * Return an xy area for a loop, parity region, or union region.\r\n * * If `rawMomentData` is the MomentData returned by computeXYAreaMoments, convert to principal axes and moments with\r\n * call `principalMomentData = MomentData.inertiaProductsToPrincipalAxes (rawMomentData.origin, rawMomentData.sums);`\r\n * @param root any Loop, ParityRegion, or UnionRegion.\r\n */\r\n public static computeXYArea(root: AnyRegion): number | undefined {\r\n const handler = new RegionMomentsXY();\r\n const result = root.dispatchToGeometryHandler(handler);\r\n if (result instanceof MomentData) {\r\n return result.quantitySum;\r\n }\r\n return undefined;\r\n }\r\n /** Return MomentData with the sums of wire moments.\r\n * * If `rawMomentData` is the MomentData returned by computeXYAreaMoments, convert to principal axes and moments with\r\n * call `principalMomentData = MomentData.inertiaProductsToPrincipalAxes (rawMomentData.origin, rawMomentData.sums);`\r\n * @param root any CurveCollection or CurvePrimitive.\r\n */\r\n public static computeXYZWireMomentSums(root: AnyCurve): MomentData | undefined {\r\n const handler = new CurveWireMomentsXYZ();\r\n handler.visitLeaves(root);\r\n const result = handler.momentData;\r\n result.shiftOriginAndSumsToCentroidOfSums();\r\n return result;\r\n }\r\n\r\n /**\r\n * * create loops in the graph.\r\n * @internal\r\n */\r\n public static addLoopsToGraph(graph: HalfEdgeGraph, data: MultiLineStringDataVariant, announceIsolatedLoop: (graph: HalfEdgeGraph, seed: HalfEdge) => void) {\r\n if (data instanceof Loop) {\r\n const points = data.getPackedStrokes();\r\n if (points)\r\n this.addLoopsToGraph(graph, points, announceIsolatedLoop);\r\n } else if (data instanceof ParityRegion) {\r\n for (const child of data.children) {\r\n const points = child.getPackedStrokes();\r\n if (points)\r\n this.addLoopsToGraph(graph, points, announceIsolatedLoop);\r\n }\r\n } else if (data instanceof IndexedXYZCollection) {\r\n const loopSeed = Triangulator.directCreateFaceLoopFromCoordinates(graph, data);\r\n if (loopSeed !== undefined)\r\n announceIsolatedLoop(graph, loopSeed);\r\n } else if (Array.isArray(data)) {\r\n if (data.length > 0) {\r\n if (Point3d.isAnyImmediatePointType(data[0])) {\r\n const loopSeed = Triangulator.directCreateFaceLoopFromCoordinates(graph, data as LineStringDataVariant);\r\n if (loopSeed !== undefined)\r\n announceIsolatedLoop(graph, loopSeed);\r\n\r\n } else if (data[0] instanceof IndexedXYZCollection) {\r\n for (const loop of data) {\r\n const loopSeed = Triangulator.directCreateFaceLoopFromCoordinates(graph, loop as IndexedXYZCollection);\r\n if (loopSeed !== undefined)\r\n announceIsolatedLoop(graph, loopSeed);\r\n }\r\n } else {\r\n for (const child of data) {\r\n if (Array.isArray(child))\r\n this.addLoopsToGraph(graph, child as MultiLineStringDataVariant, announceIsolatedLoop);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n /** Add multiple loops to a graph.\r\n * * Apply edgeTag and mask to each edge.\r\n * @internal\r\n */\r\n public static addLoopsWithEdgeTagToGraph(graph: HalfEdgeGraph, data: MultiLineStringDataVariant, mask: HalfEdgeMask, edgeTag: any): HalfEdge[] | undefined {\r\n const loopSeeds: HalfEdge[] = [];\r\n this.addLoopsToGraph(graph, data, (_graph: HalfEdgeGraph, seed: HalfEdge) => {\r\n if (seed) {\r\n loopSeeds.push(seed);\r\n seed.setMaskAndEdgeTagAroundFace(mask, edgeTag, true);\r\n }\r\n });\r\n if (loopSeeds.length > 0)\r\n return loopSeeds;\r\n return undefined;\r\n }\r\n /**\r\n * Given a graph just produced by booleans, convert to a polyface\r\n * * \"just produced\" implies exterior face markup.\r\n *\r\n * @param graph\r\n * @param triangulate\r\n */\r\n private static finishGraphToPolyface(graph: HalfEdgeGraph | undefined, triangulate: boolean): Polyface | undefined {\r\n if (graph) {\r\n if (triangulate) {\r\n Triangulator.triangulateAllPositiveAreaFaces(graph);\r\n Triangulator.flipTriangles(graph);\r\n }\r\n return PolyfaceBuilder.graphToPolyface(graph);\r\n }\r\n return undefined;\r\n }\r\n /**\r\n * Return a polyface containing the area intersection of two XY regions.\r\n * * Within each region, in and out is determined by parity rules.\r\n * * Any face that is an odd number of crossings from the far outside is IN\r\n * * Any face that is an even number of crossings from the far outside is OUT\r\n * @param loopsA first set of loops\r\n * @param loopsB second set of loops\r\n * @param triangulate whether to triangulate the result\r\n */\r\n public static polygonXYAreaIntersectLoopsToPolyface(loopsA: MultiLineStringDataVariant, loopsB: MultiLineStringDataVariant, triangulate: boolean = false): Polyface | undefined {\r\n const graph = RegionOpsFaceToFaceSearch.doPolygonBoolean(loopsA, loopsB,\r\n (inA: boolean, inB: boolean) => (inA && inB),\r\n this._graphCheckPointFunction);\r\n return this.finishGraphToPolyface(graph, triangulate);\r\n }\r\n\r\n /**\r\n * Return a polyface containing the area union of two XY regions.\r\n * * Within each region, in and out is determined by parity rules.\r\n * * Any face that is an odd number of crossings from the far outside is IN\r\n * * Any face that is an even number of crossings from the far outside is OUT\r\n * @param loopsA first set of loops\r\n * @param loopsB second set of loops\r\n * @param triangulate whether to triangulate the result\r\n */\r\n public static polygonXYAreaUnionLoopsToPolyface(loopsA: MultiLineStringDataVariant, loopsB: MultiLineStringDataVariant, triangulate: boolean = false): Polyface | undefined {\r\n const graph = RegionOpsFaceToFaceSearch.doPolygonBoolean(loopsA, loopsB,\r\n (inA: boolean, inB: boolean) => (inA || inB),\r\n this._graphCheckPointFunction);\r\n return this.finishGraphToPolyface(graph, triangulate);\r\n }\r\n /**\r\n * Return a polyface containing the area difference of two XY regions.\r\n * * Within each region, in and out is determined by parity rules.\r\n * * Any face that is an odd number of crossings from the far outside is IN\r\n * * Any face that is an even number of crossings from the far outside is OUT\r\n * @param loopsA first set of loops\r\n * @param loopsB second set of loops\r\n * @param triangulate whether to triangulate the result\r\n */\r\n public static polygonXYAreaDifferenceLoopsToPolyface(loopsA: MultiLineStringDataVariant, loopsB: MultiLineStringDataVariant, triangulate: boolean = false): Polyface | undefined {\r\n const graph = RegionOpsFaceToFaceSearch.doPolygonBoolean(loopsA, loopsB,\r\n (inA: boolean, inB: boolean) => (inA && !inB),\r\n this._graphCheckPointFunction);\r\n return this.finishGraphToPolyface(graph, triangulate);\r\n }\r\n\r\n /**\r\n * Return areas defined by a boolean operation.\r\n * * If there are multiple regions in loopsA, they are treated as a union.\r\n * * If there are multiple regions in loopsB, they are treated as a union.\r\n * @param loopsA first set of loops\r\n * @param loopsB second set of loops\r\n * @param operation indicates Union, Intersection, Parity, AMinusB, or BMinusA\r\n * @param mergeTolerance absolute distance tolerance for merging loops\r\n * @returns a region resulting from merging input loops and the boolean operation. May contain bridge edges connecting interior loops to exterior loops.\r\n */\r\n public static regionBooleanXY(loopsA: AnyRegion | AnyRegion[] | undefined, loopsB: AnyRegion | AnyRegion[] | undefined, operation: RegionBinaryOpType, mergeTolerance: number = Geometry.smallMetricDistance): AnyRegion | undefined {\r\n const result = UnionRegion.create();\r\n const context = RegionBooleanContext.create(RegionGroupOpType.Union, RegionGroupOpType.Union);\r\n context.addMembers(loopsA, loopsB);\r\n context.annotateAndMergeCurvesInGraph(mergeTolerance);\r\n const range = context.groupA.range().union(context.groupB.range());\r\n const areaTol = this.computeXYAreaTolerance(range);\r\n context.runClassificationSweep(operation, (_graph: HalfEdgeGraph, face: HalfEdge, faceType: -1 | 0 | 1, area: number) => {\r\n // ignore danglers and null faces, but not 2-edge \"banana\" faces with nonzero area\r\n if (face.countEdgesAroundFace() < 2)\r\n return;\r\n if (Math.abs(area) < areaTol)\r\n return;\r\n if (faceType === 1) {\r\n const loop = PlanarSubdivision.createLoopInFace(face);\r\n if (loop)\r\n result.tryAddChild(loop);\r\n }\r\n });\r\n return result;\r\n }\r\n\r\n /**\r\n * Return a polyface whose facets are a boolean operation between the input regions.\r\n * * Each of the two inputs is an array of multiple loops or parity regions.\r\n * * Within each of these input arrays, the various entries (loop or set of loops) are interpreted as a union.\r\n * * In each \"array of loops and parity regions\", each entry inputA[i] or inputB[i] is one of:\r\n * * A simple loop, e.g. array of Point3d.\r\n * * Several simple loops, each of which is an array of Point3d.\r\n * @param inputA first set of loops\r\n * @param operation indicates Union, Intersection, Parity, AMinusB, or BMinusA\r\n * @param inputB second set of loops\r\n * @param triangulate whether to triangulate the result\r\n */\r\n public static polygonBooleanXYToPolyface(inputA: MultiLineStringDataVariant[], operation: RegionBinaryOpType,\r\n inputB: MultiLineStringDataVariant[], triangulate: boolean = false): Polyface | undefined {\r\n const graph = RegionOpsFaceToFaceSearch.doBinaryBooleanBetweenMultiLoopInputs(\r\n inputA, RegionGroupOpType.Union,\r\n operation,\r\n inputB, RegionGroupOpType.Union, true);\r\n return this.finishGraphToPolyface(graph, triangulate);\r\n }\r\n /**\r\n * Return loops of linestrings around areas of a boolean operation between the input regions.\r\n * * Each of the two inputs is an array of multiple loops or parity regions.\r\n * * Within each of these input arrays, the various entries (loop or set of loops) are interpreted as a union.\r\n * * In each \"array of loops and parity regions\", each entry inputA[i] or inputB[i] is one of:\r\n * * A simple loop, e.g. array of Point3d.\r\n * * Several simple loops, each of which is an array of Point3d.\r\n * @param inputA first set of loops\r\n * @param operation indicates Union, Intersection, Parity, AMinusB, or BMinusA\r\n * @param inputB second set of loops\r\n */\r\n public static polygonBooleanXYToLoops(\r\n inputA: MultiLineStringDataVariant[],\r\n operation: RegionBinaryOpType,\r\n inputB: MultiLineStringDataVariant[]): AnyRegion | undefined {\r\n const graph = RegionOpsFaceToFaceSearch.doBinaryBooleanBetweenMultiLoopInputs(\r\n inputA, RegionGroupOpType.Union,\r\n operation,\r\n inputB, RegionGroupOpType.Union, true);\r\n if (!graph)\r\n return undefined;\r\n const loopEdges = HalfEdgeGraphSearch.collectExtendedBoundaryLoopsInGraph(graph, HalfEdgeMask.EXTERIOR);\r\n const allLoops: Loop[] = [];\r\n for (const graphLoop of loopEdges) {\r\n const points = new GrowableXYZArray();\r\n for (const edge of graphLoop)\r\n points.pushXYZ(edge.x, edge.y, edge.z);\r\n points.pushWrap(1);\r\n const loop = Loop.create();\r\n loop.tryAddChild(LineString3d.createCapture(points));\r\n allLoops.push(loop);\r\n }\r\n return RegionOps.sortOuterAndHoleLoopsXY(allLoops);\r\n }\r\n\r\n /** Construct a wire (not area!!) that is offset from given polyline or polygon.\r\n * * This is a simple wire offset, not an area.\r\n * * The construction algorithm attempts to eliminate some self-intersections within the offsets, but does not guarantee a simple area offset.\r\n * * The construction algorithm is subject to being changed, resulting in different (hopefully better) self-intersection behavior on the future.\r\n * @param points a single loop or path\r\n * @param wrap true to include wraparound\r\n * @param offsetDistance distance of offset from wire. Positive is left.\r\n */\r\n public static constructPolygonWireXYOffset(points: Point3d[], wrap: boolean, offsetDistance: number): CurveCollection | undefined {\r\n const context = new PolygonWireOffsetContext();\r\n return context.constructPolygonWireXYOffset(points, wrap, offsetDistance);\r\n }\r\n /**\r\n * Construct curves that are offset from a Path or Loop as viewed in xy-plane (ignoring z).\r\n * * The construction will remove \"some\" local effects of features smaller than the offset distance, but will not detect self intersection among widely separated edges.\r\n * * If offsetDistance is given as a number, default OffsetOptions are applied.\r\n * * When the offset needs to do an \"outside\" turn, the first applicable construction is applied:\r\n * * If the turn is larger than `options.minArcDegrees`, a circular arc is constructed.\r\n * * If the turn is less than or equal to `options.maxChamferTurnDegrees`, extend curves along tangent to single intersection point.\r\n * * If the turn is larger than `options.maxChamferDegrees`, the turn is constructed as a sequence of straight lines that are:\r\n * * outside the arc\r\n * * have uniform turn angle less than `options.maxChamferDegrees`\r\n * * each line segment (except first and last) touches the arc at its midpoint.\r\n * @param curves base curves.\r\n * @param offsetDistanceOrOptions offset distance (positive to left of curve, negative to right) or options object.\r\n */\r\n public static constructCurveXYOffset(curves: Path | Loop, offsetDistanceOrOptions: number | JointOptions | OffsetOptions): CurveCollection | undefined {\r\n return CurveChainWireOffsetContext.constructCurveXYOffset(curves, offsetDistanceOrOptions);\r\n }\r\n /**\r\n * Test if point (x,y) is IN, OUT or ON a region.\r\n * @return (1) for in, (-1) for OUT, (0) for ON\r\n * @param curves input region\r\n * @param x x coordinate of point to test\r\n * @param y y coordinate of point to test\r\n */\r\n public static testPointInOnOutRegionXY(curves: AnyRegion, x: number, y: number): number {\r\n return PointInOnOutContext.testPointInOnOutRegionXY(curves, x, y);\r\n }\r\n /** Create curve collection of subtype determined by gaps between the input curves.\r\n * * If (a) wrap is requested and (b) all curves connect head-to-tail (including wraparound), assemble as a `loop`.\r\n * * If all curves connect head-to-tail except for closure, return a `Path`.\r\n * * If there are internal gaps, return a `BagOfCurves`\r\n * * If input array has zero length, return undefined.\r\n * @param curves input curves\r\n * @param wrap whether to create a Loop (true) or Path (false) if maximum gap is minimal\r\n * @param consolidateAdjacentPrimitives whether to simplify the result by calling [[consolidateAdjacentPrimitives]]\r\n */\r\n public static createLoopPathOrBagOfCurves(curves: CurvePrimitive[], wrap: boolean = true, consolidateAdjacentPrimitives: boolean = false): CurveCollection | undefined {\r\n const n = curves.length;\r\n if (n === 0)\r\n return undefined;\r\n let maxGap = 0.0;\r\n let isPath = false;\r\n if (wrap)\r\n maxGap = Geometry.maxXY(maxGap, curves[0].startPoint().distance(curves[n - 1].endPoint()));\r\n for (let i = 0; i + 1 < n; i++)\r\n maxGap = Geometry.maxXY(maxGap, curves[i].endPoint().distance(curves[i + 1].startPoint()));\r\n let collection: Loop | Path | BagOfCurves;\r\n if (Geometry.isSmallMetricDistance(maxGap)) {\r\n collection = wrap ? Loop.create() : Path.create();\r\n isPath = true;\r\n } else {\r\n collection = BagOfCurves.create();\r\n }\r\n for (const c of curves)\r\n collection.tryAddChild(c);\r\n if (isPath && consolidateAdjacentPrimitives)\r\n RegionOps.consolidateAdjacentPrimitives(collection);\r\n return collection;\r\n }\r\n\r\n private static _graphCheckPointFunction?: GraphCheckPointFunction;\r\n /**\r\n * Announce Checkpoint function for use during booleans\r\n * @internal\r\n */\r\n public static setCheckPointFunction(f?: GraphCheckPointFunction) { this._graphCheckPointFunction = f; }\r\n /**\r\n * Find all intersections among curves in `curvesToCut` and `cutterCurves` and return fragments of `curvesToCut`.\r\n * * For a `Loop`, `ParityRegion`, or `UnionRegion` in `curvesToCut`:\r\n * * if it is never cut by any `cutter` curve, it will be left unchanged.\r\n * * if cut, the input is downgraded to a set of `Path` curves joining at the cut points.\r\n * * All cutting is \"as viewed in the xy plane\"\r\n * @param curvesToCut input curves to be fragmented at intersections with `cutterCurves`\r\n * @param cutterCurves input curves to intersect with `curvesToCut`\r\n */\r\n public static cloneCurvesWithXYSplits(curvesToCut: AnyCurve | undefined, cutterCurves: CurveCollection): AnyCurve | undefined {\r\n return CurveSplitContext.cloneCurvesWithXYSplits(curvesToCut, cutterCurves);\r\n }\r\n /**\r\n * Create paths assembled from many curves.\r\n * * Assemble paths from consecutive curves NOT separated by either gaps or the split markup set by [[cloneCurvesWithXYSplits]].\r\n * * Return simplest form -- single primitive, single path, or bag of curves.\r\n */\r\n public static splitToPathsBetweenBreaks(source: AnyCurve | undefined, makeClones: boolean): ChainTypes {\r\n if (source === undefined)\r\n return undefined;\r\n if (source instanceof CurvePrimitive)\r\n return source;\r\n // source is a collection . ..\r\n const primitives = source.collectCurvePrimitives();\r\n const chainCollector = new ChainCollectorContext(makeClones);\r\n for (const primitive of primitives) {\r\n chainCollector.announceCurvePrimitive(primitive);\r\n }\r\n return chainCollector.grabResult();\r\n }\r\n /**\r\n * Restructure curve fragments as chains, and construct (left and right) chain offsets in the xy-plane.\r\n * * BEWARE that if the input is not a loop, the classification of outputs is suspect.\r\n * @param fragments fragments to be chained, z-coordinates ignored\r\n * @param offsetDistance offset distance\r\n * @param gapTolerance absolute endpoint tolerance for computing chains\r\n * @returns object with named chains, insideOffsets, outsideOffsets\r\n */\r\n public static collectInsideAndOutsideOffsets(fragments: AnyCurve[], offsetDistance: number, gapTolerance: number): { insideOffsets: AnyCurve[], outsideOffsets: AnyCurve[], chains: ChainTypes } {\r\n return OffsetHelpers.collectInsideAndOutsideOffsets(fragments, offsetDistance, gapTolerance);\r\n }\r\n /**\r\n * Restructure curve fragments as chains.\r\n * @param fragments fragments to be chained\r\n * @param gapTolerance absolute endpoint tolerance for computing chains\r\n * @returns chains, possibly wrapped in BagOfCurves if there multiple chains\r\n */\r\n public static collectChains(fragments: AnyCurve[], gapTolerance: number = Geometry.smallMetricDistance): ChainTypes {\r\n return OffsetHelpers.collectChains(fragments, gapTolerance);\r\n }\r\n\r\n /**\r\n * Find all intersections among curves in `curvesToCut` against the boundaries of `region` and return fragments of `curvesToCut`.\r\n * * Break `curvesToCut` into parts inside, outside, and coincident.\r\n * @returns output object with all fragments split among `insideParts`, `outsideParts`, and `coincidentParts`\r\n */\r\n public static splitPathsByRegionInOnOutXY(curvesToCut: AnyCurve | undefined, region: AnyRegion): { insideParts: AnyCurve[], outsideParts: AnyCurve[], coincidentParts: AnyCurve[] } {\r\n const result = { insideParts: [], outsideParts: [], coincidentParts: [] };\r\n const pathWithIntersectionMarkup = RegionOps.cloneCurvesWithXYSplits(curvesToCut, region);\r\n const splitPaths = RegionOps.splitToPathsBetweenBreaks(pathWithIntersectionMarkup, true);\r\n if (splitPaths instanceof CurveCollection) {\r\n for (const child of splitPaths.children) {\r\n const pointOnChild = CurveCollection.createCurveLocationDetailOnAnyCurvePrimitive(child);\r\n if (pointOnChild) {\r\n const inOnOut = RegionOps.testPointInOnOutRegionXY(region, pointOnChild.point.x, pointOnChild.point.y);\r\n pushToInOnOutArrays(child, inOnOut, result.outsideParts, result.coincidentParts, result.insideParts);\r\n }\r\n }\r\n } else if (splitPaths instanceof CurvePrimitive) {\r\n const pointOnChild = CurveCollection.createCurveLocationDetailOnAnyCurvePrimitive(splitPaths);\r\n if (pointOnChild) {\r\n const inOnOut = RegionOps.testPointInOnOutRegionXY(region, pointOnChild.point.x, pointOnChild.point.y);\r\n pushToInOnOutArrays(splitPaths, inOnOut, result.outsideParts, result.coincidentParts, result.insideParts);\r\n }\r\n }\r\n return result;\r\n }\r\n /** If `data` is one of several forms of a rectangle, return its edge Transform.\r\n * * Points are considered a rectangle if, within the first 4 points:\r\n * * vectors from 0 to 1 and 0 to 3 are perpendicular and have a non-zero cross product\r\n * * vectors from 0 to 3 and 1 to 2 are the same\r\n * @param data points in one of several formats:\r\n * * LineString\r\n * * Loop containing rectangle content\r\n * * Path containing rectangle content\r\n * * Array of Point3d[]\r\n * * IndexedXYZCollection\r\n * @param requireClosurePoint whether to require a 5th point equal to the 1st point.\r\n * @returns Transform with origin at one corner, x and y columns extending along two adjacent sides, and unit normal in z column. If not a rectangle, return undefined.\r\n */\r\n public static rectangleEdgeTransform(data: AnyCurve | Point3d[] | IndexedXYZCollection, requireClosurePoint: boolean = true): Transform | undefined {\r\n if (data instanceof LineString3d) {\r\n return this.rectangleEdgeTransform(data.packedPoints);\r\n } else if (data instanceof IndexedXYZCollection) {\r\n let dataToUse;\r\n if (requireClosurePoint && data.length === 5) {\r\n if (!Geometry.isSmallMetricDistance(data.distanceIndexIndex(0, 4)!))\r\n return undefined;\r\n dataToUse = data;\r\n } else if (!requireClosurePoint && data.length === 4) {\r\n dataToUse = data;\r\n } else if (data.length < (requireClosurePoint ? 5 : 4)) {\r\n return undefined;\r\n } else {\r\n dataToUse = GrowableXYZArray.create(data);\r\n PolylineCompressionContext.compressInPlaceByShortEdgeLength(dataToUse, Geometry.smallMetricDistance);\r\n if (dataToUse.length < (requireClosurePoint ? 5 : 4))\r\n return undefined;\r\n }\r\n const vector01 = dataToUse.vectorIndexIndex(0, 1)!;\r\n const vector03 = dataToUse.vectorIndexIndex(0, 3)!;\r\n const vector12 = dataToUse.vectorIndexIndex(1, 2)!;\r\n const normalVector = vector01.crossProduct(vector03);\r\n if (normalVector.normalizeInPlace()\r\n && vector12.isAlmostEqual(vector03)\r\n && vector01.isPerpendicularTo(vector03)) {\r\n return Transform.createOriginAndMatrixColumns(dataToUse.getPoint3dAtUncheckedPointIndex(0), vector01, vector03, normalVector);\r\n }\r\n } else if (Array.isArray(data)) {\r\n return this.rectangleEdgeTransform(new Point3dArrayCarrier(data), requireClosurePoint);\r\n } else if (data instanceof Loop && data.children.length === 1 && data.children[0] instanceof LineString3d) {\r\n return this.rectangleEdgeTransform(data.children[0].packedPoints, true);\r\n } else if (data instanceof Path && data.children.length === 1 && data.children[0] instanceof LineString3d) {\r\n return this.rectangleEdgeTransform(data.children[0].packedPoints, requireClosurePoint);\r\n } else if (data instanceof CurveChain) {\r\n if (!data.checkForNonLinearPrimitives()) {\r\n // const linestring = LineString3d.create();\r\n const strokes = data.getPackedStrokes();\r\n if (strokes) {\r\n return this.rectangleEdgeTransform(strokes);\r\n }\r\n }\r\n }\r\n return undefined;\r\n }\r\n /**\r\n * Look for and simplify:\r\n * * Contiguous `LineSegment3d` and `LineString3d` objects.\r\n * * collect all points\r\n * * eliminate duplicated points\r\n * * eliminate points colinear with surrounding points.\r\n * * Contiguous concentric circular or elliptic arcs\r\n * * combine angular ranges\r\n * @param curves Path or loop (or larger collection containing paths and loops) to be simplified\r\n * @param options options for tolerance and selective simplification.\r\n */\r\n public static consolidateAdjacentPrimitives(curves: CurveCollection, options?: ConsolidateAdjacentCurvePrimitivesOptions) {\r\n const context = new ConsolidateAdjacentCurvePrimitivesContext(options);\r\n curves.dispatchToGeometryHandler(context);\r\n }\r\n /**\r\n * Reverse and reorder loops in the xy-plane for consistency and containment.\r\n * @param loops multiple loops in any order and orientation, z-coordinates ignored\r\n * @returns a region that captures the input pointers. This region is a:\r\n * * `Loop` if there is exactly one input loop. It is oriented counterclockwise.\r\n * * `ParityRegion` if input consists of exactly one outer loop with at least one hole loop.\r\n * Its first child is an outer loop oriented counterclockwise; all subsequent children are holes oriented clockwise.\r\n * * `UnionRegion` if any other input configuration. Its children are individually ordered/oriented as in the above cases.\r\n * @see [[PolygonOps.sortOuterAndHoleLoopsXY]]\r\n */\r\n public static sortOuterAndHoleLoopsXY(loops: Array<Loop | IndexedXYZCollection>): AnyRegion {\r\n const loopAndArea: SortablePolygon[] = [];\r\n for (const candidate of loops) {\r\n if (candidate instanceof Loop)\r\n SortablePolygon.pushLoop(loopAndArea, candidate);\r\n else if (candidate instanceof IndexedXYZCollection) {\r\n const loop = Loop.createPolygon(candidate);\r\n SortablePolygon.pushLoop(loopAndArea, loop);\r\n }\r\n }\r\n return SortablePolygon.sortAsAnyRegion(loopAndArea);\r\n }\r\n /**\r\n * Find all areas bounded by the unstructured, possibly intersecting curves.\r\n * * This method performs no merging of nearly coincident edges and vertices, which can lead to unexpected results\r\n * given sufficiently imprecise input. Input geometry consisting of regions can be merged for better results: call\r\n * [[regionBooleanXY]](regions, undefined, RegionBinaryOpType.Union) and pass the merged region into [[constructAllXYRegionLoops]].\r\n * @param curvesAndRegions Any collection of curves. Each Loop/ParityRegion/UnionRegion contributes its curve primitives.\r\n * @returns array of [[SignedLoops]], each entry of which describes the faces in a single connected component:\r\n * * `positiveAreaLoops` contains \"interior\" loops, _including holes in ParityRegion input_. These loops have positive area and counterclockwise orientation.\r\n * * `negativeAreaLoops` contains (probably just one) \"exterior\" loop which is ordered clockwise.\r\n * * `slivers` contains sliver loops that have zero area, such as appear between coincident curves.\r\n * * `edges` contains a [[LoopCurveLoopCurve]] object for each component edge, collecting both loops adjacent to the edge and a constituent curve in each.\r\n */\r\n public static constructAllXYRegionLoops(curvesAndRegions: AnyCurve | AnyCurve[]): SignedLoops[] {\r\n const primitivesA = RegionOps.collectCurvePrimitives(curvesAndRegions, undefined, true);\r\n const primitivesB = this.expandLineStrings(primitivesA);\r\n const range = this.curveArrayRange(primitivesB);\r\n const areaTol = this.computeXYAreaTolerance(range);\r\n const intersections = CurveCurve.allIntersectionsAmongPrimitivesXY(primitivesB);\r\n const graph = PlanarSubdivision.assembleHalfEdgeGraph(primitivesB, intersections);\r\n return PlanarSubdivision.collectSignedLoopSetsInHalfEdgeGraph(graph, areaTol);\r\n }\r\n\r\n /**\r\n * Collect all `CurvePrimitives` in loosely typed input.\r\n * * Always recurses into primitives within explicit collections (Path, Loop, ParityRegion, UnionRegion).\r\n * * Optionally recurses into hidden primitives if `smallestPossiblePrimitives` is true.\r\n * @param candidates input curves\r\n * @param collectorArray optional pre-defined output array. If defined, it is NOT cleared: primitives are appended.\r\n * @param smallestPossiblePrimitives if true, recurse into the children of a [[CurveChainWithDistanceIndex]]. If false, push the [[CurveChainWithDistanceIndex]] instead.\r\n * @param explodeLinestrings if true, push a [[LineSegment3d]] for each segment of a [[LineString3d]]. If false, push the [[LineString3d]] instead.\r\n */\r\n public static collectCurvePrimitives(candidates: AnyCurve | AnyCurve[], collectorArray?: CurvePrimitive[],\r\n smallestPossiblePrimitives: boolean = false,\r\n explodeLinestrings: boolean = false): CurvePrimitive[] {\r\n const results: CurvePrimitive[] = collectorArray === undefined ? [] : collectorArray;\r\n if (candidates instanceof CurvePrimitive) {\r\n candidates.collectCurvePrimitives(results, smallestPossiblePrimitives, explodeLinestrings);\r\n } else if (candidates instanceof CurveCollection) {\r\n candidates.collectCurvePrimitives(results, smallestPossiblePrimitives, explodeLinestrings);\r\n } else if (Array.isArray(candidates)) {\r\n for (const c of candidates) {\r\n this.collectCurvePrimitives(c, results, smallestPossiblePrimitives, explodeLinestrings);\r\n }\r\n }\r\n return results;\r\n }\r\n /**\r\n * Copy primitive pointers from candidates to result array, replacing each [[LineString3d]] by newly constructed instances of [[LineSegment3d]].\r\n * @param candidates input curves\r\n * @return copied (captured) inputs except for the linestrings, which are exploded\r\n */\r\n public static expandLineStrings(candidates: CurvePrimitive[]): CurvePrimitive[] {\r\n const result: CurvePrimitive[] = [];\r\n for (const c of candidates) {\r\n if (c instanceof LineString3d) {\r\n for (let i = 0; i + 1 < c.packedPoints.length; i++) {\r\n const q = c.getIndexedSegment(i);\r\n if (q !== undefined)\r\n result.push(q);\r\n }\r\n } else {\r\n result.push(c);\r\n }\r\n }\r\n return result;\r\n }\r\n /**\r\n * Return the overall range of given curves.\r\n * @param data candidate curves\r\n * @param worldToLocal transform to apply to data before computing its range\r\n */\r\n public static curveArrayRange(data: any, worldToLocal?: Transform): Range3d {\r\n const range = Range3d.create();\r\n if (data instanceof GeometryQuery)\r\n data.extendRange(range, worldToLocal);\r\n else if (Array.isArray(data)) {\r\n for (const c of data) {\r\n if (c instanceof GeometryQuery)\r\n c.extendRange(range, worldToLocal);\r\n else if (c instanceof Point3d)\r\n range.extendPoint(c, worldToLocal);\r\n else if (c instanceof GrowableXYZArray)\r\n range.extendRange(c.getRange(worldToLocal));\r\n else if (Array.isArray(c))\r\n range.extendRange(this.curveArrayRange(c, worldToLocal));\r\n }\r\n }\r\n return range;\r\n }\r\n}\r\n\r\n/** @internal */\r\nfunction pushToInOnOutArrays(curve: AnyCurve, select: number, arrayNegative: AnyCurve[], array0: AnyCurve[], arrayPositive: AnyCurve[]) {\r\n if (select > 0)\r\n arrayPositive.push(curve);\r\n else if (select < 0)\r\n arrayNegative.push(curve);\r\n else\r\n array0.push(curve);\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"RegionOps.js","sourceRoot":"","sources":["../../../src/curve/RegionOps.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/** @packageDocumentation\r\n * @module Curve\r\n */\r\n\r\nimport { Geometry } from \"../Geometry\";\r\nimport { GrowableXYZArray } from \"../geometry3d/GrowableXYZArray\";\r\nimport { IndexedXYZCollection } from \"../geometry3d/IndexedXYZCollection\";\r\nimport { Point3dArrayCarrier } from \"../geometry3d/Point3dArrayCarrier\";\r\nimport { Point3d } from \"../geometry3d/Point3dVector3d\";\r\nimport { PolylineCompressionContext } from \"../geometry3d/PolylineCompressionByEdgeOffset\";\r\nimport { Range3d } from \"../geometry3d/Range\";\r\nimport { SortablePolygon } from \"../geometry3d/SortablePolygon\";\r\nimport { Transform } from \"../geometry3d/Transform\";\r\nimport { MomentData } from \"../geometry4d/MomentData\";\r\nimport { Polyface } from \"../polyface/Polyface\";\r\nimport { PolyfaceBuilder } from \"../polyface/PolyfaceBuilder\";\r\nimport { HalfEdge, HalfEdgeGraph, HalfEdgeMask } from \"../topology/Graph\";\r\nimport { LineStringDataVariant, MultiLineStringDataVariant, Triangulator } from \"../topology/Triangulation\";\r\nimport { ChainCollectorContext } from \"./ChainCollectorContext\";\r\nimport { AnyCurve, AnyRegion } from \"./CurveChain\";\r\nimport { BagOfCurves, ConsolidateAdjacentCurvePrimitivesOptions, CurveChain, CurveCollection } from \"./CurveCollection\";\r\nimport { CurveCurve } from \"./CurveCurve\";\r\nimport { CurvePrimitive } from \"./CurvePrimitive\";\r\nimport { CurveWireMomentsXYZ } from \"./CurveWireMomentsXYZ\";\r\nimport { CurveChainWireOffsetContext, JointOptions, OffsetOptions, PolygonWireOffsetContext } from \"./internalContexts/PolygonOffsetContext\";\r\nimport { LineString3d } from \"./LineString3d\";\r\nimport { Loop, SignedLoops } from \"./Loop\";\r\nimport { Path } from \"./Path\";\r\nimport { ConsolidateAdjacentCurvePrimitivesContext } from \"./Query/ConsolidateAdjacentPrimitivesContext\";\r\nimport { CurveSplitContext } from \"./Query/CurveSplitContext\";\r\nimport { PointInOnOutContext } from \"./Query/InOutTests\";\r\nimport { PlanarSubdivision } from \"./Query/PlanarSubdivision\";\r\nimport { RegionMomentsXY } from \"./RegionMomentsXY\";\r\nimport { OffsetHelpers } from \"./internalContexts/MultiChainCollector\";\r\nimport { GeometryQuery } from \"./GeometryQuery\";\r\nimport { RegionBooleanContext, RegionGroupOpType, RegionOpsFaceToFaceSearch } from \"./RegionOpsClassificationSweeps\";\r\nimport { UnionRegion } from \"./UnionRegion\";\r\nimport { HalfEdgeGraphSearch } from \"../topology/HalfEdgeGraphSearch\";\r\nimport { ParityRegion } from \"./ParityRegion\";\r\n/**\r\n * Possible return types from [[splitToPathsBetweenBreaks]], [[collectInsideAndOutsideOffsets]] and [[collectChains]].\r\n * @public\r\n */\r\nexport type ChainTypes = CurvePrimitive | Path | BagOfCurves | Loop | undefined;\r\n\r\n/**\r\n * * `properties` is a string with special characters indicating\r\n * * \"U\" -- contains unmerged stick data\r\n * * \"M\" -- merged\r\n * * \"R\" -- regularized\r\n * * \"X\" -- has exterior markup\r\n * @internal\r\n */\r\nexport type GraphCheckPointFunction = (name: string, graph: HalfEdgeGraph, properties: string, extraData?: any) => any;\r\n/**\r\n * Enumeration of the binary operation types for a booleans among regions\r\n * @public\r\n */\r\nexport enum RegionBinaryOpType {\r\n Union = 0,\r\n Parity = 1,\r\n Intersection = 2,\r\n AMinusB = 3,\r\n BMinusA = 4,\r\n}\r\n\r\n/**\r\n * Class `RegionOps` has static members for calculations on regions (areas).\r\n * * Regions are represented by these `CurveCollection` subclasses:\r\n * * `Loop` -- a single loop\r\n * * `ParityRegion` -- a collection of loops, interpreted by parity rules.\r\n * The common \"One outer loop and many Inner loops\" is a parity region.\r\n * * `UnionRegion` -- a collection of `Loop` and `ParityRegion` objects understood as a (probably disjoint) union.\r\n * * Most of the methods in this class ignore z-coordinates, so callers should ensure that input geometry has been rotated parallel to the xy-plane.\r\n * @public\r\n */\r\nexport class RegionOps {\r\n /**\r\n * Return moment sums for a loop, parity region, or union region.\r\n * * If `rawMomentData` is the MomentData returned by computeXYAreaMoments, convert to principal axes and moments with\r\n * call `principalMomentData = MomentData.inertiaProductsToPrincipalAxes (rawMomentData.origin, rawMomentData.sums);`\r\n * @param root any Loop, ParityRegion, or UnionRegion.\r\n */\r\n public static computeXYAreaMoments(root: AnyRegion): MomentData | undefined {\r\n const handler = new RegionMomentsXY();\r\n const result = root.dispatchToGeometryHandler(handler);\r\n if (result instanceof MomentData) {\r\n result.shiftOriginAndSumsToCentroidOfSums();\r\n return result;\r\n }\r\n return undefined;\r\n }\r\n /** Return an area tolerance for a given xy-range and optional distance tolerance.\r\n * @param range range of planar region to tolerance\r\n * @param distanceTolerance optional absolute distance tolerance\r\n */\r\n public static computeXYAreaTolerance(range: Range3d, distanceTolerance: number = Geometry.smallMetricDistance): number {\r\n // if A = bh and e is distance tolerance, then A' := (b+e/2)(h+e/2) = A + e/2(b+h+e/2), so A'-A = e/2(b+h+e/2).\r\n const halfDistTol = 0.5 * distanceTolerance;\r\n return halfDistTol * (range.xLength() + range.yLength() + halfDistTol);\r\n }\r\n /**\r\n * Return an xy area for a loop, parity region, or union region.\r\n * * If `rawMomentData` is the MomentData returned by computeXYAreaMoments, convert to principal axes and moments with\r\n * call `principalMomentData = MomentData.inertiaProductsToPrincipalAxes (rawMomentData.origin, rawMomentData.sums);`\r\n * @param root any Loop, ParityRegion, or UnionRegion.\r\n */\r\n public static computeXYArea(root: AnyRegion): number | undefined {\r\n const handler = new RegionMomentsXY();\r\n const result = root.dispatchToGeometryHandler(handler);\r\n if (result instanceof MomentData) {\r\n return result.quantitySum;\r\n }\r\n return undefined;\r\n }\r\n /** Return MomentData with the sums of wire moments.\r\n * * If `rawMomentData` is the MomentData returned by computeXYAreaMoments, convert to principal axes and moments with\r\n * call `principalMomentData = MomentData.inertiaProductsToPrincipalAxes (rawMomentData.origin, rawMomentData.sums);`\r\n * @param root any CurveCollection or CurvePrimitive.\r\n */\r\n public static computeXYZWireMomentSums(root: AnyCurve): MomentData | undefined {\r\n const handler = new CurveWireMomentsXYZ();\r\n handler.visitLeaves(root);\r\n const result = handler.momentData;\r\n result.shiftOriginAndSumsToCentroidOfSums();\r\n return result;\r\n }\r\n\r\n /**\r\n * * create loops in the graph.\r\n * @internal\r\n */\r\n public static addLoopsToGraph(graph: HalfEdgeGraph, data: MultiLineStringDataVariant, announceIsolatedLoop: (graph: HalfEdgeGraph, seed: HalfEdge) => void) {\r\n if (data instanceof Loop) {\r\n const points = data.getPackedStrokes();\r\n if (points)\r\n this.addLoopsToGraph(graph, points, announceIsolatedLoop);\r\n } else if (data instanceof ParityRegion) {\r\n for (const child of data.children) {\r\n const points = child.getPackedStrokes();\r\n if (points)\r\n this.addLoopsToGraph(graph, points, announceIsolatedLoop);\r\n }\r\n } else if (data instanceof IndexedXYZCollection) {\r\n const loopSeed = Triangulator.directCreateFaceLoopFromCoordinates(graph, data);\r\n if (loopSeed !== undefined)\r\n announceIsolatedLoop(graph, loopSeed);\r\n } else if (Array.isArray(data)) {\r\n if (data.length > 0) {\r\n if (Point3d.isAnyImmediatePointType(data[0])) {\r\n const loopSeed = Triangulator.directCreateFaceLoopFromCoordinates(graph, data as LineStringDataVariant);\r\n if (loopSeed !== undefined)\r\n announceIsolatedLoop(graph, loopSeed);\r\n\r\n } else if (data[0] instanceof IndexedXYZCollection) {\r\n for (const loop of data) {\r\n const loopSeed = Triangulator.directCreateFaceLoopFromCoordinates(graph, loop as IndexedXYZCollection);\r\n if (loopSeed !== undefined)\r\n announceIsolatedLoop(graph, loopSeed);\r\n }\r\n } else {\r\n for (const child of data) {\r\n if (Array.isArray(child))\r\n this.addLoopsToGraph(graph, child as MultiLineStringDataVariant, announceIsolatedLoop);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n /** Add multiple loops to a graph.\r\n * * Apply edgeTag and mask to each edge.\r\n * @internal\r\n */\r\n public static addLoopsWithEdgeTagToGraph(graph: HalfEdgeGraph, data: MultiLineStringDataVariant, mask: HalfEdgeMask, edgeTag: any): HalfEdge[] | undefined {\r\n const loopSeeds: HalfEdge[] = [];\r\n this.addLoopsToGraph(graph, data, (_graph: HalfEdgeGraph, seed: HalfEdge) => {\r\n if (seed) {\r\n loopSeeds.push(seed);\r\n seed.setMaskAndEdgeTagAroundFace(mask, edgeTag, true);\r\n }\r\n });\r\n if (loopSeeds.length > 0)\r\n return loopSeeds;\r\n return undefined;\r\n }\r\n /**\r\n * Given a graph just produced by booleans, convert to a polyface\r\n * * \"just produced\" implies exterior face markup.\r\n *\r\n * @param graph\r\n * @param triangulate\r\n */\r\n private static finishGraphToPolyface(graph: HalfEdgeGraph | undefined, triangulate: boolean): Polyface | undefined {\r\n if (graph) {\r\n if (triangulate) {\r\n Triangulator.triangulateAllPositiveAreaFaces(graph);\r\n Triangulator.flipTriangles(graph);\r\n }\r\n return PolyfaceBuilder.graphToPolyface(graph);\r\n }\r\n return undefined;\r\n }\r\n /**\r\n * Return a polyface containing the area intersection of two XY regions.\r\n * * Within each region, in and out is determined by parity rules.\r\n * * Any face that is an odd number of crossings from the far outside is IN\r\n * * Any face that is an even number of crossings from the far outside is OUT\r\n * @param loopsA first set of loops\r\n * @param loopsB second set of loops\r\n * @param triangulate whether to triangulate the result\r\n */\r\n public static polygonXYAreaIntersectLoopsToPolyface(loopsA: MultiLineStringDataVariant, loopsB: MultiLineStringDataVariant, triangulate: boolean = false): Polyface | undefined {\r\n const graph = RegionOpsFaceToFaceSearch.doPolygonBoolean(loopsA, loopsB,\r\n (inA: boolean, inB: boolean) => (inA && inB),\r\n this._graphCheckPointFunction);\r\n return this.finishGraphToPolyface(graph, triangulate);\r\n }\r\n\r\n /**\r\n * Return a polyface containing the area union of two XY regions.\r\n * * Within each region, in and out is determined by parity rules.\r\n * * Any face that is an odd number of crossings from the far outside is IN\r\n * * Any face that is an even number of crossings from the far outside is OUT\r\n * @param loopsA first set of loops\r\n * @param loopsB second set of loops\r\n * @param triangulate whether to triangulate the result\r\n */\r\n public static polygonXYAreaUnionLoopsToPolyface(loopsA: MultiLineStringDataVariant, loopsB: MultiLineStringDataVariant, triangulate: boolean = false): Polyface | undefined {\r\n const graph = RegionOpsFaceToFaceSearch.doPolygonBoolean(loopsA, loopsB,\r\n (inA: boolean, inB: boolean) => (inA || inB),\r\n this._graphCheckPointFunction);\r\n return this.finishGraphToPolyface(graph, triangulate);\r\n }\r\n /**\r\n * Return a polyface containing the area difference of two XY regions.\r\n * * Within each region, in and out is determined by parity rules.\r\n * * Any face that is an odd number of crossings from the far outside is IN\r\n * * Any face that is an even number of crossings from the far outside is OUT\r\n * @param loopsA first set of loops\r\n * @param loopsB second set of loops\r\n * @param triangulate whether to triangulate the result\r\n */\r\n public static polygonXYAreaDifferenceLoopsToPolyface(loopsA: MultiLineStringDataVariant, loopsB: MultiLineStringDataVariant, triangulate: boolean = false): Polyface | undefined {\r\n const graph = RegionOpsFaceToFaceSearch.doPolygonBoolean(loopsA, loopsB,\r\n (inA: boolean, inB: boolean) => (inA && !inB),\r\n this._graphCheckPointFunction);\r\n return this.finishGraphToPolyface(graph, triangulate);\r\n }\r\n\r\n /**\r\n * Return areas defined by a boolean operation.\r\n * * If there are multiple regions in loopsA, they are treated as a union.\r\n * * If there are multiple regions in loopsB, they are treated as a union.\r\n * @param loopsA first set of loops\r\n * @param loopsB second set of loops\r\n * @param operation indicates Union, Intersection, Parity, AMinusB, or BMinusA\r\n * @param mergeTolerance absolute distance tolerance for merging loops\r\n * @returns a region resulting from merging input loops and the boolean operation. May contain bridge edges connecting interior loops to exterior loops.\r\n */\r\n public static regionBooleanXY(loopsA: AnyRegion | AnyRegion[] | undefined, loopsB: AnyRegion | AnyRegion[] | undefined, operation: RegionBinaryOpType, mergeTolerance: number = Geometry.smallMetricDistance): AnyRegion | undefined {\r\n const result = UnionRegion.create();\r\n const context = RegionBooleanContext.create(RegionGroupOpType.Union, RegionGroupOpType.Union);\r\n context.addMembers(loopsA, loopsB);\r\n context.annotateAndMergeCurvesInGraph(mergeTolerance);\r\n const range = context.groupA.range().union(context.groupB.range());\r\n const areaTol = this.computeXYAreaTolerance(range);\r\n context.runClassificationSweep(operation, (_graph: HalfEdgeGraph, face: HalfEdge, faceType: -1 | 0 | 1, area: number) => {\r\n // ignore danglers and null faces, but not 2-edge \"banana\" faces with nonzero area\r\n if (face.countEdgesAroundFace() < 2)\r\n return;\r\n if (Math.abs(area) < areaTol)\r\n return;\r\n if (faceType === 1) {\r\n const loop = PlanarSubdivision.createLoopInFace(face);\r\n if (loop)\r\n result.tryAddChild(loop);\r\n }\r\n });\r\n return result;\r\n }\r\n\r\n /**\r\n * Return a polyface whose facets are a boolean operation between the input regions.\r\n * * Each of the two inputs is an array of multiple loops or parity regions.\r\n * * Within each of these input arrays, the various entries (loop or set of loops) are interpreted as a union.\r\n * * In each \"array of loops and parity regions\", each entry inputA[i] or inputB[i] is one of:\r\n * * A simple loop, e.g. array of Point3d.\r\n * * Several simple loops, each of which is an array of Point3d.\r\n * @param inputA first set of loops\r\n * @param operation indicates Union, Intersection, Parity, AMinusB, or BMinusA\r\n * @param inputB second set of loops\r\n * @param triangulate whether to triangulate the result\r\n */\r\n public static polygonBooleanXYToPolyface(inputA: MultiLineStringDataVariant[], operation: RegionBinaryOpType,\r\n inputB: MultiLineStringDataVariant[], triangulate: boolean = false): Polyface | undefined {\r\n const graph = RegionOpsFaceToFaceSearch.doBinaryBooleanBetweenMultiLoopInputs(\r\n inputA, RegionGroupOpType.Union,\r\n operation,\r\n inputB, RegionGroupOpType.Union, true);\r\n return this.finishGraphToPolyface(graph, triangulate);\r\n }\r\n /**\r\n * Return loops of linestrings around areas of a boolean operation between the input regions.\r\n * * Each of the two inputs is an array of multiple loops or parity regions.\r\n * * Within each of these input arrays, the various entries (loop or set of loops) are interpreted as a union.\r\n * * In each \"array of loops and parity regions\", each entry inputA[i] or inputB[i] is one of:\r\n * * A simple loop, e.g. array of Point3d.\r\n * * Several simple loops, each of which is an array of Point3d.\r\n * @param inputA first set of loops\r\n * @param operation indicates Union, Intersection, Parity, AMinusB, or BMinusA\r\n * @param inputB second set of loops\r\n */\r\n public static polygonBooleanXYToLoops(\r\n inputA: MultiLineStringDataVariant[],\r\n operation: RegionBinaryOpType,\r\n inputB: MultiLineStringDataVariant[]): AnyRegion | undefined {\r\n const graph = RegionOpsFaceToFaceSearch.doBinaryBooleanBetweenMultiLoopInputs(\r\n inputA, RegionGroupOpType.Union,\r\n operation,\r\n inputB, RegionGroupOpType.Union, true);\r\n if (!graph)\r\n return undefined;\r\n const loopEdges = HalfEdgeGraphSearch.collectExtendedBoundaryLoopsInGraph(graph, HalfEdgeMask.EXTERIOR);\r\n const allLoops: Loop[] = [];\r\n for (const graphLoop of loopEdges) {\r\n const points = new GrowableXYZArray();\r\n for (const edge of graphLoop)\r\n points.pushXYZ(edge.x, edge.y, edge.z);\r\n points.pushWrap(1);\r\n const loop = Loop.create();\r\n loop.tryAddChild(LineString3d.createCapture(points));\r\n allLoops.push(loop);\r\n }\r\n return RegionOps.sortOuterAndHoleLoopsXY(allLoops);\r\n }\r\n\r\n /** Construct a wire (not area!!) that is offset from given polyline or polygon.\r\n * * This is a simple wire offset, not an area.\r\n * * The construction algorithm attempts to eliminate some self-intersections within the offsets, but does not guarantee a simple area offset.\r\n * * The construction algorithm is subject to being changed, resulting in different (hopefully better) self-intersection behavior on the future.\r\n * @param points a single loop or path\r\n * @param wrap true to include wraparound\r\n * @param offsetDistance distance of offset from wire. Positive is left.\r\n */\r\n public static constructPolygonWireXYOffset(points: Point3d[], wrap: boolean, offsetDistance: number): CurveCollection | undefined {\r\n const context = new PolygonWireOffsetContext();\r\n return context.constructPolygonWireXYOffset(points, wrap, offsetDistance);\r\n }\r\n /**\r\n * Construct curves that are offset from a Path or Loop as viewed in xy-plane (ignoring z).\r\n * * The construction will remove \"some\" local effects of features smaller than the offset distance, but will not detect self intersection among widely separated edges.\r\n * * If offsetDistance is given as a number, default OffsetOptions are applied.\r\n * * When the offset needs to do an \"outside\" turn, the first applicable construction is applied:\r\n * * If the turn is larger than `options.minArcDegrees`, a circular arc is constructed.\r\n * * If the turn is less than or equal to `options.maxChamferTurnDegrees`, extend curves along tangent to single intersection point.\r\n * * If the turn is larger than `options.maxChamferDegrees`, the turn is constructed as a sequence of straight lines that are:\r\n * * outside the arc\r\n * * have uniform turn angle less than `options.maxChamferDegrees`\r\n * * each line segment (except first and last) touches the arc at its midpoint.\r\n * @param curves base curves.\r\n * @param offsetDistanceOrOptions offset distance (positive to left of curve, negative to right) or options object.\r\n */\r\n public static constructCurveXYOffset(curves: Path | Loop, offsetDistanceOrOptions: number | JointOptions | OffsetOptions): CurveCollection | undefined {\r\n return CurveChainWireOffsetContext.constructCurveXYOffset(curves, offsetDistanceOrOptions);\r\n }\r\n /**\r\n * Test if point (x,y) is IN, OUT or ON a region.\r\n * @return (1) for in, (-1) for OUT, (0) for ON\r\n * @param curves input region\r\n * @param x x coordinate of point to test\r\n * @param y y coordinate of point to test\r\n */\r\n public static testPointInOnOutRegionXY(curves: AnyRegion, x: number, y: number): number {\r\n return PointInOnOutContext.testPointInOnOutRegionXY(curves, x, y);\r\n }\r\n /** Create curve collection of subtype determined by gaps between the input curves.\r\n * * If (a) wrap is requested and (b) all curves connect head-to-tail (including wraparound), assemble as a `loop`.\r\n * * If all curves connect head-to-tail except for closure, return a `Path`.\r\n * * If there are internal gaps, return a `BagOfCurves`\r\n * * If input array has zero length, return undefined.\r\n * @param curves input curves\r\n * @param wrap whether to create a Loop (true) or Path (false) if maximum gap is minimal\r\n * @param consolidateAdjacentPrimitives whether to simplify the result by calling [[consolidateAdjacentPrimitives]]\r\n */\r\n public static createLoopPathOrBagOfCurves(curves: CurvePrimitive[], wrap: boolean = true, consolidateAdjacentPrimitives: boolean = false): CurveCollection | undefined {\r\n const n = curves.length;\r\n if (n === 0)\r\n return undefined;\r\n let maxGap = 0.0;\r\n let isPath = false;\r\n if (wrap)\r\n maxGap = Geometry.maxXY(maxGap, curves[0].startPoint().distance(curves[n - 1].endPoint()));\r\n for (let i = 0; i + 1 < n; i++)\r\n maxGap = Geometry.maxXY(maxGap, curves[i].endPoint().distance(curves[i + 1].startPoint()));\r\n let collection: Loop | Path | BagOfCurves;\r\n if (Geometry.isSmallMetricDistance(maxGap)) {\r\n collection = wrap ? Loop.create() : Path.create();\r\n isPath = true;\r\n } else {\r\n collection = BagOfCurves.create();\r\n }\r\n for (const c of curves)\r\n collection.tryAddChild(c);\r\n if (isPath && consolidateAdjacentPrimitives)\r\n RegionOps.consolidateAdjacentPrimitives(collection);\r\n return collection;\r\n }\r\n\r\n private static _graphCheckPointFunction?: GraphCheckPointFunction;\r\n /**\r\n * Announce Checkpoint function for use during booleans\r\n * @internal\r\n */\r\n public static setCheckPointFunction(f?: GraphCheckPointFunction) { this._graphCheckPointFunction = f; }\r\n /**\r\n * Find all intersections among curves in `curvesToCut` and `cutterCurves` and return fragments of `curvesToCut`.\r\n * * For a `Loop`, `ParityRegion`, or `UnionRegion` in `curvesToCut`:\r\n * * if it is never cut by any `cutter` curve, it will be left unchanged.\r\n * * if cut, the input is downgraded to a set of `Path` curves joining at the cut points.\r\n * * All cutting is \"as viewed in the xy plane\"\r\n * @param curvesToCut input curves to be fragmented at intersections with `cutterCurves`\r\n * @param cutterCurves input curves to intersect with `curvesToCut`\r\n */\r\n public static cloneCurvesWithXYSplits(curvesToCut: AnyCurve | undefined, cutterCurves: CurveCollection): AnyCurve | undefined {\r\n return CurveSplitContext.cloneCurvesWithXYSplits(curvesToCut, cutterCurves);\r\n }\r\n /**\r\n * Create paths assembled from many curves.\r\n * * Assemble paths from consecutive curves NOT separated by either gaps or the split markup set by [[cloneCurvesWithXYSplits]].\r\n * * Return simplest form -- single primitive, single path, or bag of curves.\r\n */\r\n public static splitToPathsBetweenBreaks(source: AnyCurve | undefined, makeClones: boolean): ChainTypes {\r\n if (source === undefined)\r\n return undefined;\r\n if (source instanceof CurvePrimitive)\r\n return source;\r\n // source is a collection . ..\r\n const primitives = source.collectCurvePrimitives();\r\n const chainCollector = new ChainCollectorContext(makeClones);\r\n for (const primitive of primitives) {\r\n chainCollector.announceCurvePrimitive(primitive);\r\n }\r\n return chainCollector.grabResult();\r\n }\r\n /**\r\n * Restructure curve fragments as chains, and construct (left and right) chain offsets in the xy-plane.\r\n * * BEWARE that if the input is not a loop, the classification of outputs is suspect.\r\n * @param fragments fragments to be chained, z-coordinates ignored\r\n * @param offsetDistance offset distance\r\n * @param gapTolerance absolute endpoint tolerance for computing chains\r\n * @returns object with named chains, insideOffsets, outsideOffsets\r\n */\r\n public static collectInsideAndOutsideOffsets(fragments: AnyCurve[], offsetDistance: number, gapTolerance: number): { insideOffsets: AnyCurve[], outsideOffsets: AnyCurve[], chains: ChainTypes } {\r\n return OffsetHelpers.collectInsideAndOutsideOffsets(fragments, offsetDistance, gapTolerance);\r\n }\r\n /**\r\n * Restructure curve fragments as chains.\r\n * @param fragments fragments to be chained\r\n * @param gapTolerance absolute endpoint tolerance for computing chains\r\n * @returns chains, possibly wrapped in BagOfCurves if there multiple chains\r\n */\r\n public static collectChains(fragments: AnyCurve[], gapTolerance: number = Geometry.smallMetricDistance): ChainTypes {\r\n return OffsetHelpers.collectChains(fragments, gapTolerance);\r\n }\r\n\r\n /**\r\n * Find all intersections among curves in `curvesToCut` against the boundaries of `region` and return fragments of `curvesToCut`.\r\n * * Break `curvesToCut` into parts inside, outside, and coincident.\r\n * @returns output object with all fragments split among `insideParts`, `outsideParts`, and `coincidentParts`\r\n */\r\n public static splitPathsByRegionInOnOutXY(curvesToCut: AnyCurve | undefined, region: AnyRegion): { insideParts: AnyCurve[], outsideParts: AnyCurve[], coincidentParts: AnyCurve[] } {\r\n const result = { insideParts: [], outsideParts: [], coincidentParts: [] };\r\n const pathWithIntersectionMarkup = RegionOps.cloneCurvesWithXYSplits(curvesToCut, region);\r\n const splitPaths = RegionOps.splitToPathsBetweenBreaks(pathWithIntersectionMarkup, true);\r\n if (splitPaths instanceof CurveCollection) {\r\n for (const child of splitPaths.children) {\r\n const pointOnChild = CurveCollection.createCurveLocationDetailOnAnyCurvePrimitive(child);\r\n if (pointOnChild) {\r\n const inOnOut = RegionOps.testPointInOnOutRegionXY(region, pointOnChild.point.x, pointOnChild.point.y);\r\n pushToInOnOutArrays(child, inOnOut, result.outsideParts, result.coincidentParts, result.insideParts);\r\n }\r\n }\r\n } else if (splitPaths instanceof CurvePrimitive) {\r\n const pointOnChild = CurveCollection.createCurveLocationDetailOnAnyCurvePrimitive(splitPaths);\r\n if (pointOnChild) {\r\n const inOnOut = RegionOps.testPointInOnOutRegionXY(region, pointOnChild.point.x, pointOnChild.point.y);\r\n pushToInOnOutArrays(splitPaths, inOnOut, result.outsideParts, result.coincidentParts, result.insideParts);\r\n }\r\n }\r\n return result;\r\n }\r\n /** If `data` is one of several forms of a rectangle, return its edge Transform.\r\n * * Points are considered a rectangle if, within the first 4 points:\r\n * * vectors from 0 to 1 and 0 to 3 are perpendicular and have a non-zero cross product\r\n * * vectors from 0 to 3 and 1 to 2 are the same\r\n * @param data points in one of several formats:\r\n * * LineString\r\n * * Loop containing rectangle content\r\n * * Path containing rectangle content\r\n * * Array of Point3d[]\r\n * * IndexedXYZCollection\r\n * @param requireClosurePoint whether to require a 5th point equal to the 1st point.\r\n * @returns Transform with origin at one corner, x and y columns extending along two adjacent sides, and unit normal in z column. If not a rectangle, return undefined.\r\n */\r\n public static rectangleEdgeTransform(data: AnyCurve | Point3d[] | IndexedXYZCollection, requireClosurePoint: boolean = true): Transform | undefined {\r\n if (data instanceof LineString3d) {\r\n return this.rectangleEdgeTransform(data.packedPoints);\r\n } else if (data instanceof IndexedXYZCollection) {\r\n let dataToUse;\r\n if (requireClosurePoint && data.length === 5) {\r\n if (!Geometry.isSmallMetricDistance(data.distanceIndexIndex(0, 4)!))\r\n return undefined;\r\n dataToUse = data;\r\n } else if (!requireClosurePoint && data.length === 4) {\r\n dataToUse = data;\r\n } else if (data.length < (requireClosurePoint ? 5 : 4)) {\r\n return undefined;\r\n } else {\r\n dataToUse = GrowableXYZArray.create(data);\r\n PolylineCompressionContext.compressInPlaceByShortEdgeLength(dataToUse, Geometry.smallMetricDistance);\r\n if (dataToUse.length < (requireClosurePoint ? 5 : 4))\r\n return undefined;\r\n }\r\n const vector01 = dataToUse.vectorIndexIndex(0, 1)!;\r\n const vector03 = dataToUse.vectorIndexIndex(0, 3)!;\r\n const vector12 = dataToUse.vectorIndexIndex(1, 2)!;\r\n const normalVector = vector01.crossProduct(vector03);\r\n if (normalVector.normalizeInPlace()\r\n && vector12.isAlmostEqual(vector03)\r\n && vector01.isPerpendicularTo(vector03)) {\r\n return Transform.createOriginAndMatrixColumns(dataToUse.getPoint3dAtUncheckedPointIndex(0), vector01, vector03, normalVector);\r\n }\r\n } else if (Array.isArray(data)) {\r\n return this.rectangleEdgeTransform(new Point3dArrayCarrier(data), requireClosurePoint);\r\n } else if (data instanceof Loop && data.children.length === 1 && data.children[0] instanceof LineString3d) {\r\n return this.rectangleEdgeTransform(data.children[0].packedPoints, true);\r\n } else if (data instanceof Path && data.children.length === 1 && data.children[0] instanceof LineString3d) {\r\n return this.rectangleEdgeTransform(data.children[0].packedPoints, requireClosurePoint);\r\n } else if (data instanceof CurveChain) {\r\n if (!data.checkForNonLinearPrimitives()) {\r\n // const linestring = LineString3d.create();\r\n const strokes = data.getPackedStrokes();\r\n if (strokes) {\r\n return this.rectangleEdgeTransform(strokes);\r\n }\r\n }\r\n }\r\n return undefined;\r\n }\r\n /**\r\n * Look for and simplify:\r\n * * Contiguous `LineSegment3d` and `LineString3d` objects.\r\n * * collect all points\r\n * * eliminate duplicated points\r\n * * eliminate points colinear with surrounding points.\r\n * * Contiguous concentric circular or elliptic arcs\r\n * * combine angular ranges\r\n * @param curves Path or loop (or larger collection containing paths and loops) to be simplified\r\n * @param options options for tolerance and selective simplification.\r\n */\r\n public static consolidateAdjacentPrimitives(curves: CurveCollection, options?: ConsolidateAdjacentCurvePrimitivesOptions) {\r\n const context = new ConsolidateAdjacentCurvePrimitivesContext(options);\r\n curves.dispatchToGeometryHandler(context);\r\n }\r\n /**\r\n * Reverse and reorder loops in the xy-plane for consistency and containment.\r\n * @param loops multiple loops in any order and orientation, z-coordinates ignored\r\n * @returns a region that captures the input pointers. This region is a:\r\n * * `Loop` if there is exactly one input loop. It is oriented counterclockwise.\r\n * * `ParityRegion` if input consists of exactly one outer loop with at least one hole loop.\r\n * Its first child is an outer loop oriented counterclockwise; all subsequent children are holes oriented clockwise.\r\n * * `UnionRegion` if any other input configuration. Its children are individually ordered/oriented as in the above cases.\r\n * @see [[PolygonOps.sortOuterAndHoleLoopsXY]]\r\n */\r\n public static sortOuterAndHoleLoopsXY(loops: Array<Loop | IndexedXYZCollection>): AnyRegion {\r\n const loopAndArea: SortablePolygon[] = [];\r\n for (const candidate of loops) {\r\n if (candidate instanceof Loop)\r\n SortablePolygon.pushLoop(loopAndArea, candidate);\r\n else if (candidate instanceof IndexedXYZCollection) {\r\n const loop = Loop.createPolygon(candidate);\r\n SortablePolygon.pushLoop(loopAndArea, loop);\r\n }\r\n }\r\n return SortablePolygon.sortAsAnyRegion(loopAndArea);\r\n }\r\n /**\r\n * Find all areas bounded by the unstructured, possibly intersecting curves.\r\n * * This method performs no merging of nearly coincident edges and vertices, which can lead to unexpected results\r\n * given sufficiently imprecise input. Input geometry consisting of regions can be merged for better results by pre-processing with\r\n * [[regionBooleanXY]].\r\n * @param curvesAndRegions Any collection of curves. Each Loop/ParityRegion/UnionRegion contributes its curve primitives.\r\n * @returns array of [[SignedLoops]], each entry of which describes the faces in a single connected component:\r\n * * `positiveAreaLoops` contains \"interior\" loops, _including holes in ParityRegion input_. These loops have positive area and counterclockwise orientation.\r\n * * `negativeAreaLoops` contains (probably just one) \"exterior\" loop which is ordered clockwise.\r\n * * `slivers` contains sliver loops that have zero area, such as appear between coincident curves.\r\n * * `edges` contains a [[LoopCurveLoopCurve]] object for each component edge, collecting both loops adjacent to the edge and a constituent curve in each.\r\n */\r\n public static constructAllXYRegionLoops(curvesAndRegions: AnyCurve | AnyCurve[]): SignedLoops[] {\r\n const primitivesA = RegionOps.collectCurvePrimitives(curvesAndRegions, undefined, true);\r\n const primitivesB = this.expandLineStrings(primitivesA);\r\n const range = this.curveArrayRange(primitivesB);\r\n const areaTol = this.computeXYAreaTolerance(range);\r\n const intersections = CurveCurve.allIntersectionsAmongPrimitivesXY(primitivesB);\r\n const graph = PlanarSubdivision.assembleHalfEdgeGraph(primitivesB, intersections);\r\n return PlanarSubdivision.collectSignedLoopSetsInHalfEdgeGraph(graph, areaTol);\r\n }\r\n\r\n /**\r\n * Collect all `CurvePrimitives` in loosely typed input.\r\n * * Always recurses into primitives within explicit collections (Path, Loop, ParityRegion, UnionRegion).\r\n * * Optionally recurses into hidden primitives if `smallestPossiblePrimitives` is true.\r\n * @param candidates input curves\r\n * @param collectorArray optional pre-defined output array. If defined, it is NOT cleared: primitives are appended.\r\n * @param smallestPossiblePrimitives if true, recurse into the children of a [[CurveChainWithDistanceIndex]]. If false, push the [[CurveChainWithDistanceIndex]] instead.\r\n * @param explodeLinestrings if true, push a [[LineSegment3d]] for each segment of a [[LineString3d]]. If false, push the [[LineString3d]] instead.\r\n */\r\n public static collectCurvePrimitives(candidates: AnyCurve | AnyCurve[], collectorArray?: CurvePrimitive[],\r\n smallestPossiblePrimitives: boolean = false,\r\n explodeLinestrings: boolean = false): CurvePrimitive[] {\r\n const results: CurvePrimitive[] = collectorArray === undefined ? [] : collectorArray;\r\n if (candidates instanceof CurvePrimitive) {\r\n candidates.collectCurvePrimitives(results, smallestPossiblePrimitives, explodeLinestrings);\r\n } else if (candidates instanceof CurveCollection) {\r\n candidates.collectCurvePrimitives(results, smallestPossiblePrimitives, explodeLinestrings);\r\n } else if (Array.isArray(candidates)) {\r\n for (const c of candidates) {\r\n this.collectCurvePrimitives(c, results, smallestPossiblePrimitives, explodeLinestrings);\r\n }\r\n }\r\n return results;\r\n }\r\n /**\r\n * Copy primitive pointers from candidates to result array, replacing each [[LineString3d]] by newly constructed instances of [[LineSegment3d]].\r\n * @param candidates input curves\r\n * @return copied (captured) inputs except for the linestrings, which are exploded\r\n */\r\n public static expandLineStrings(candidates: CurvePrimitive[]): CurvePrimitive[] {\r\n const result: CurvePrimitive[] = [];\r\n for (const c of candidates) {\r\n if (c instanceof LineString3d) {\r\n for (let i = 0; i + 1 < c.packedPoints.length; i++) {\r\n const q = c.getIndexedSegment(i);\r\n if (q !== undefined)\r\n result.push(q);\r\n }\r\n } else {\r\n result.push(c);\r\n }\r\n }\r\n return result;\r\n }\r\n /**\r\n * Return the overall range of given curves.\r\n * @param data candidate curves\r\n * @param worldToLocal transform to apply to data before computing its range\r\n */\r\n public static curveArrayRange(data: any, worldToLocal?: Transform): Range3d {\r\n const range = Range3d.create();\r\n if (data instanceof GeometryQuery)\r\n data.extendRange(range, worldToLocal);\r\n else if (Array.isArray(data)) {\r\n for (const c of data) {\r\n if (c instanceof GeometryQuery)\r\n c.extendRange(range, worldToLocal);\r\n else if (c instanceof Point3d)\r\n range.extendPoint(c, worldToLocal);\r\n else if (c instanceof GrowableXYZArray)\r\n range.extendRange(c.getRange(worldToLocal));\r\n else if (Array.isArray(c))\r\n range.extendRange(this.curveArrayRange(c, worldToLocal));\r\n }\r\n }\r\n return range;\r\n }\r\n}\r\n\r\n/** @internal */\r\nfunction pushToInOnOutArrays(curve: AnyCurve, select: number, arrayNegative: AnyCurve[], array0: AnyCurve[], arrayPositive: AnyCurve[]) {\r\n if (select > 0)\r\n arrayPositive.push(curve);\r\n else if (select < 0)\r\n arrayNegative.push(curve);\r\n else\r\n array0.push(curve);\r\n}\r\n"]}
|