@itwin/core-geometry 5.1.0-dev.52 → 5.1.0-dev.53
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/lib/cjs/Geometry.d.ts +1 -1
- package/lib/cjs/Geometry.js.map +1 -1
- package/lib/cjs/bspline/BSplineSurface.d.ts.map +1 -1
- package/lib/cjs/bspline/BSplineSurface.js +0 -2
- package/lib/cjs/bspline/BSplineSurface.js.map +1 -1
- package/lib/cjs/curve/CurveCollection.d.ts +7 -0
- package/lib/cjs/curve/CurveCollection.d.ts.map +1 -1
- package/lib/cjs/curve/CurveCollection.js +11 -0
- package/lib/cjs/curve/CurveCollection.js.map +1 -1
- package/lib/cjs/curve/CurveFactory.d.ts +3 -2
- package/lib/cjs/curve/CurveFactory.d.ts.map +1 -1
- package/lib/cjs/curve/CurveFactory.js +6 -5
- package/lib/cjs/curve/CurveFactory.js.map +1 -1
- package/lib/cjs/curve/CurveLocationDetail.d.ts +3 -1
- package/lib/cjs/curve/CurveLocationDetail.d.ts.map +1 -1
- package/lib/cjs/curve/CurveLocationDetail.js +6 -1
- package/lib/cjs/curve/CurveLocationDetail.js.map +1 -1
- package/lib/cjs/curve/CurvePrimitive.d.ts +7 -0
- package/lib/cjs/curve/CurvePrimitive.d.ts.map +1 -1
- package/lib/cjs/curve/CurvePrimitive.js +11 -0
- package/lib/cjs/curve/CurvePrimitive.js.map +1 -1
- package/lib/cjs/curve/LineSegment3d.d.ts +2 -0
- package/lib/cjs/curve/LineSegment3d.d.ts.map +1 -1
- package/lib/cjs/curve/LineSegment3d.js +4 -0
- package/lib/cjs/curve/LineSegment3d.js.map +1 -1
- package/lib/cjs/curve/LineString3d.d.ts +7 -0
- package/lib/cjs/curve/LineString3d.d.ts.map +1 -1
- package/lib/cjs/curve/LineString3d.js +15 -3
- package/lib/cjs/curve/LineString3d.js.map +1 -1
- package/lib/cjs/curve/Query/ConsolidateAdjacentPrimitivesContext.d.ts.map +1 -1
- package/lib/cjs/curve/Query/ConsolidateAdjacentPrimitivesContext.js +28 -4
- package/lib/cjs/curve/Query/ConsolidateAdjacentPrimitivesContext.js.map +1 -1
- package/lib/cjs/curve/Query/PlanarSubdivision.d.ts +25 -3
- package/lib/cjs/curve/Query/PlanarSubdivision.d.ts.map +1 -1
- package/lib/cjs/curve/Query/PlanarSubdivision.js +102 -22
- package/lib/cjs/curve/Query/PlanarSubdivision.js.map +1 -1
- package/lib/cjs/curve/Query/StrokeCountChain.d.ts +4 -3
- package/lib/cjs/curve/Query/StrokeCountChain.d.ts.map +1 -1
- package/lib/cjs/curve/Query/StrokeCountChain.js +20 -9
- package/lib/cjs/curve/Query/StrokeCountChain.js.map +1 -1
- package/lib/cjs/curve/RegionMomentsXY.d.ts +1 -1
- package/lib/cjs/curve/RegionMomentsXY.d.ts.map +1 -1
- package/lib/cjs/curve/RegionMomentsXY.js +6 -3
- package/lib/cjs/curve/RegionMomentsXY.js.map +1 -1
- package/lib/cjs/curve/RegionOps.d.ts +23 -14
- package/lib/cjs/curve/RegionOps.d.ts.map +1 -1
- package/lib/cjs/curve/RegionOps.js +60 -21
- package/lib/cjs/curve/RegionOps.js.map +1 -1
- package/lib/cjs/curve/RegionOpsClassificationSweeps.d.ts +9 -1
- package/lib/cjs/curve/RegionOpsClassificationSweeps.d.ts.map +1 -1
- package/lib/cjs/curve/RegionOpsClassificationSweeps.js +91 -1
- package/lib/cjs/curve/RegionOpsClassificationSweeps.js.map +1 -1
- package/lib/cjs/curve/internalContexts/CurveCurveCloseApproachXY.d.ts +2 -2
- package/lib/cjs/curve/internalContexts/CurveCurveCloseApproachXY.js +6 -6
- package/lib/cjs/curve/internalContexts/CurveCurveCloseApproachXY.js.map +1 -1
- package/lib/cjs/geometry3d/AngleSweep.d.ts +1 -1
- package/lib/cjs/geometry3d/AngleSweep.d.ts.map +1 -1
- package/lib/cjs/geometry3d/AngleSweep.js +1 -1
- package/lib/cjs/geometry3d/AngleSweep.js.map +1 -1
- package/lib/cjs/geometry3d/Ellipsoid.js +1 -1
- package/lib/cjs/geometry3d/Ellipsoid.js.map +1 -1
- package/lib/cjs/geometry3d/IndexedXYZCollection.d.ts +9 -0
- package/lib/cjs/geometry3d/IndexedXYZCollection.d.ts.map +1 -1
- package/lib/cjs/geometry3d/IndexedXYZCollection.js +14 -0
- package/lib/cjs/geometry3d/IndexedXYZCollection.js.map +1 -1
- package/lib/cjs/geometry3d/Ray3d.d.ts +7 -9
- package/lib/cjs/geometry3d/Ray3d.d.ts.map +1 -1
- package/lib/cjs/geometry3d/Ray3d.js +12 -22
- package/lib/cjs/geometry3d/Ray3d.js.map +1 -1
- package/lib/cjs/geometry3d/SortablePolygon.d.ts +1 -4
- package/lib/cjs/geometry3d/SortablePolygon.d.ts.map +1 -1
- package/lib/cjs/geometry3d/SortablePolygon.js +48 -43
- package/lib/cjs/geometry3d/SortablePolygon.js.map +1 -1
- package/lib/cjs/polyface/PolyfaceBuilder.js +3 -3
- package/lib/cjs/polyface/PolyfaceBuilder.js.map +1 -1
- package/lib/cjs/solid/Sphere.js +1 -1
- package/lib/cjs/solid/Sphere.js.map +1 -1
- package/lib/cjs/solid/SweepContour.d.ts +1 -1
- package/lib/cjs/solid/SweepContour.js +1 -1
- package/lib/cjs/solid/SweepContour.js.map +1 -1
- package/lib/cjs/topology/Graph.d.ts +64 -14
- package/lib/cjs/topology/Graph.d.ts.map +1 -1
- package/lib/cjs/topology/Graph.js +149 -32
- package/lib/cjs/topology/Graph.js.map +1 -1
- package/lib/cjs/topology/HalfEdgeGraphSearch.d.ts +2 -2
- package/lib/cjs/topology/HalfEdgeGraphSearch.d.ts.map +1 -1
- package/lib/cjs/topology/HalfEdgeGraphSearch.js +2 -2
- package/lib/cjs/topology/HalfEdgeGraphSearch.js.map +1 -1
- package/lib/cjs/topology/RegularizeFace.d.ts.map +1 -1
- package/lib/cjs/topology/RegularizeFace.js +2 -1
- package/lib/cjs/topology/RegularizeFace.js.map +1 -1
- package/lib/esm/Geometry.d.ts +1 -1
- package/lib/esm/Geometry.js.map +1 -1
- package/lib/esm/bspline/BSplineSurface.d.ts.map +1 -1
- package/lib/esm/bspline/BSplineSurface.js +0 -2
- package/lib/esm/bspline/BSplineSurface.js.map +1 -1
- package/lib/esm/curve/CurveCollection.d.ts +7 -0
- package/lib/esm/curve/CurveCollection.d.ts.map +1 -1
- package/lib/esm/curve/CurveCollection.js +11 -0
- package/lib/esm/curve/CurveCollection.js.map +1 -1
- package/lib/esm/curve/CurveFactory.d.ts +3 -2
- package/lib/esm/curve/CurveFactory.d.ts.map +1 -1
- package/lib/esm/curve/CurveFactory.js +6 -5
- package/lib/esm/curve/CurveFactory.js.map +1 -1
- package/lib/esm/curve/CurveLocationDetail.d.ts +3 -1
- package/lib/esm/curve/CurveLocationDetail.d.ts.map +1 -1
- package/lib/esm/curve/CurveLocationDetail.js +6 -1
- package/lib/esm/curve/CurveLocationDetail.js.map +1 -1
- package/lib/esm/curve/CurvePrimitive.d.ts +7 -0
- package/lib/esm/curve/CurvePrimitive.d.ts.map +1 -1
- package/lib/esm/curve/CurvePrimitive.js +11 -0
- package/lib/esm/curve/CurvePrimitive.js.map +1 -1
- package/lib/esm/curve/LineSegment3d.d.ts +2 -0
- package/lib/esm/curve/LineSegment3d.d.ts.map +1 -1
- package/lib/esm/curve/LineSegment3d.js +4 -0
- package/lib/esm/curve/LineSegment3d.js.map +1 -1
- package/lib/esm/curve/LineString3d.d.ts +7 -0
- package/lib/esm/curve/LineString3d.d.ts.map +1 -1
- package/lib/esm/curve/LineString3d.js +15 -3
- package/lib/esm/curve/LineString3d.js.map +1 -1
- package/lib/esm/curve/Query/ConsolidateAdjacentPrimitivesContext.d.ts.map +1 -1
- package/lib/esm/curve/Query/ConsolidateAdjacentPrimitivesContext.js +28 -4
- package/lib/esm/curve/Query/ConsolidateAdjacentPrimitivesContext.js.map +1 -1
- package/lib/esm/curve/Query/PlanarSubdivision.d.ts +25 -3
- package/lib/esm/curve/Query/PlanarSubdivision.d.ts.map +1 -1
- package/lib/esm/curve/Query/PlanarSubdivision.js +104 -24
- package/lib/esm/curve/Query/PlanarSubdivision.js.map +1 -1
- package/lib/esm/curve/Query/StrokeCountChain.d.ts +4 -3
- package/lib/esm/curve/Query/StrokeCountChain.d.ts.map +1 -1
- package/lib/esm/curve/Query/StrokeCountChain.js +20 -9
- package/lib/esm/curve/Query/StrokeCountChain.js.map +1 -1
- package/lib/esm/curve/RegionMomentsXY.d.ts +1 -1
- package/lib/esm/curve/RegionMomentsXY.d.ts.map +1 -1
- package/lib/esm/curve/RegionMomentsXY.js +6 -3
- package/lib/esm/curve/RegionMomentsXY.js.map +1 -1
- package/lib/esm/curve/RegionOps.d.ts +23 -14
- package/lib/esm/curve/RegionOps.d.ts.map +1 -1
- package/lib/esm/curve/RegionOps.js +60 -21
- package/lib/esm/curve/RegionOps.js.map +1 -1
- package/lib/esm/curve/RegionOpsClassificationSweeps.d.ts +9 -1
- package/lib/esm/curve/RegionOpsClassificationSweeps.d.ts.map +1 -1
- package/lib/esm/curve/RegionOpsClassificationSweeps.js +91 -2
- package/lib/esm/curve/RegionOpsClassificationSweeps.js.map +1 -1
- package/lib/esm/curve/internalContexts/CurveCurveCloseApproachXY.d.ts +2 -2
- package/lib/esm/curve/internalContexts/CurveCurveCloseApproachXY.js +6 -6
- package/lib/esm/curve/internalContexts/CurveCurveCloseApproachXY.js.map +1 -1
- package/lib/esm/geometry3d/AngleSweep.d.ts +1 -1
- package/lib/esm/geometry3d/AngleSweep.d.ts.map +1 -1
- package/lib/esm/geometry3d/AngleSweep.js +1 -1
- package/lib/esm/geometry3d/AngleSweep.js.map +1 -1
- package/lib/esm/geometry3d/Ellipsoid.js +1 -1
- package/lib/esm/geometry3d/Ellipsoid.js.map +1 -1
- package/lib/esm/geometry3d/IndexedXYZCollection.d.ts +9 -0
- package/lib/esm/geometry3d/IndexedXYZCollection.d.ts.map +1 -1
- package/lib/esm/geometry3d/IndexedXYZCollection.js +14 -0
- package/lib/esm/geometry3d/IndexedXYZCollection.js.map +1 -1
- package/lib/esm/geometry3d/Ray3d.d.ts +7 -9
- package/lib/esm/geometry3d/Ray3d.d.ts.map +1 -1
- package/lib/esm/geometry3d/Ray3d.js +12 -22
- package/lib/esm/geometry3d/Ray3d.js.map +1 -1
- package/lib/esm/geometry3d/SortablePolygon.d.ts +1 -4
- package/lib/esm/geometry3d/SortablePolygon.d.ts.map +1 -1
- package/lib/esm/geometry3d/SortablePolygon.js +48 -43
- package/lib/esm/geometry3d/SortablePolygon.js.map +1 -1
- package/lib/esm/polyface/PolyfaceBuilder.js +3 -3
- package/lib/esm/polyface/PolyfaceBuilder.js.map +1 -1
- package/lib/esm/solid/Sphere.js +1 -1
- package/lib/esm/solid/Sphere.js.map +1 -1
- package/lib/esm/solid/SweepContour.d.ts +1 -1
- package/lib/esm/solid/SweepContour.js +1 -1
- package/lib/esm/solid/SweepContour.js.map +1 -1
- package/lib/esm/topology/Graph.d.ts +64 -14
- package/lib/esm/topology/Graph.d.ts.map +1 -1
- package/lib/esm/topology/Graph.js +149 -32
- package/lib/esm/topology/Graph.js.map +1 -1
- package/lib/esm/topology/HalfEdgeGraphSearch.d.ts +2 -2
- package/lib/esm/topology/HalfEdgeGraphSearch.d.ts.map +1 -1
- package/lib/esm/topology/HalfEdgeGraphSearch.js +2 -2
- package/lib/esm/topology/HalfEdgeGraphSearch.js.map +1 -1
- package/lib/esm/topology/RegularizeFace.d.ts.map +1 -1
- package/lib/esm/topology/RegularizeFace.js +2 -1
- package/lib/esm/topology/RegularizeFace.js.map +1 -1
- package/package.json +3 -3
|
@@ -8,6 +8,7 @@ exports.HalfEdgeGraph = exports.HalfEdge = exports.HalfEdgeMask = void 0;
|
|
|
8
8
|
/** @packageDocumentation
|
|
9
9
|
* @module Topology
|
|
10
10
|
*/
|
|
11
|
+
const core_bentley_1 = require("@itwin/core-bentley");
|
|
11
12
|
const LineSegment3d_1 = require("../curve/LineSegment3d");
|
|
12
13
|
const Geometry_1 = require("../Geometry");
|
|
13
14
|
const Angle_1 = require("../geometry3d/Angle");
|
|
@@ -17,7 +18,6 @@ const SmallSystem_1 = require("../numerics/SmallSystem");
|
|
|
17
18
|
const MaskManager_1 = require("./MaskManager");
|
|
18
19
|
// import { GraphChecker } from "../test/topology/Graph.test"; // used for debugging
|
|
19
20
|
/* eslint-disable @typescript-eslint/no-this-alias */
|
|
20
|
-
// cspell:word CONSTU CONSTV USEAM VSEAM internaldocs
|
|
21
21
|
/**
|
|
22
22
|
* * Each node of the graph has a mask member.
|
|
23
23
|
* * The mask member is a number which is used as set of single bit boolean values.
|
|
@@ -32,14 +32,6 @@ const MaskManager_1 = require("./MaskManager");
|
|
|
32
32
|
*/
|
|
33
33
|
var HalfEdgeMask;
|
|
34
34
|
(function (HalfEdgeMask) {
|
|
35
|
-
// REMARK: Various mask names are COMMENTED here for reference to native legacy code.
|
|
36
|
-
// CONSTU_MASK = 0x00000004,
|
|
37
|
-
// CONSTV_MASK = 0x00000008,
|
|
38
|
-
// USEAM_MASK = 0x00000010,
|
|
39
|
-
// VSEAM_MASK = 0x00000020,
|
|
40
|
-
// BOUNDARY_VERTEX_MASK = 0x00000040,
|
|
41
|
-
// PRIMARY_VERTEX_MASK = 0x00000080,
|
|
42
|
-
// DIRECTED_EDGE_MASK = 0x00000100,
|
|
43
35
|
/**
|
|
44
36
|
* Mask commonly set consistently around exterior faces.
|
|
45
37
|
* * A boundary edge with interior to one side, exterior to the other, will have EXTERIOR only on the outside.
|
|
@@ -62,22 +54,22 @@ var HalfEdgeMask;
|
|
|
62
54
|
* BOUNDARY_EDGE nor EXTERIOR_EDGE.
|
|
63
55
|
*/
|
|
64
56
|
HalfEdgeMask[HalfEdgeMask["PRIMARY_EDGE"] = 4] = "PRIMARY_EDGE";
|
|
65
|
-
/** Mask
|
|
66
|
-
HalfEdgeMask[HalfEdgeMask["
|
|
57
|
+
/** Mask set on both sides of a bridge edge added by algorithms to join loops. */
|
|
58
|
+
HalfEdgeMask[HalfEdgeMask["BRIDGE_EDGE"] = 8] = "BRIDGE_EDGE";
|
|
59
|
+
/** Mask set on both sides of an edge added during graph regularization. */
|
|
60
|
+
HalfEdgeMask[HalfEdgeMask["REGULARIZED_EDGE"] = 16] = "REGULARIZED_EDGE";
|
|
67
61
|
/** Mask applied to triangles by earcut triangulator. */
|
|
68
62
|
HalfEdgeMask[HalfEdgeMask["TRIANGULATED_FACE"] = 256] = "TRIANGULATED_FACE";
|
|
69
63
|
/** Mask applied in a face with 2 edges. */
|
|
70
64
|
HalfEdgeMask[HalfEdgeMask["NULL_FACE"] = 512] = "NULL_FACE";
|
|
65
|
+
/** Temporary mask used for low level searches to identify previously-visited nodes. */
|
|
66
|
+
HalfEdgeMask[HalfEdgeMask["VISITED"] = 65536] = "VISITED";
|
|
71
67
|
/** No mask bits. */
|
|
72
68
|
HalfEdgeMask[HalfEdgeMask["NULL_MASK"] = 0] = "NULL_MASK";
|
|
73
69
|
/** The "upper 12" bits of 32 bit integer reserved for grab/drop. */
|
|
74
70
|
HalfEdgeMask[HalfEdgeMask["ALL_GRAB_DROP_MASKS"] = 4293918720] = "ALL_GRAB_DROP_MASKS";
|
|
75
71
|
/** All mask bits */
|
|
76
72
|
HalfEdgeMask[HalfEdgeMask["ALL_MASK"] = 4294967295] = "ALL_MASK";
|
|
77
|
-
// informal convention on preassigned mask bit numbers:
|
|
78
|
-
// byte0 (EXTERIOR, BOUNDARY_EDGE, PRIMARY_EDGE) -- edge properties
|
|
79
|
-
// byte1 (VISITED, VISIT_A, WORK_MASK0, WORK_MASK1) -- temp masks for algorithms.
|
|
80
|
-
// byte2 (TRIANGULATED_FACE, NULL_FACE) -- face properties.
|
|
81
73
|
})(HalfEdgeMask || (exports.HalfEdgeMask = HalfEdgeMask = {}));
|
|
82
74
|
/**
|
|
83
75
|
* A HalfEdge is "one side of an edge" in a structure of faces, edges and vertices. From a node there are
|
|
@@ -273,6 +265,37 @@ class HalfEdge {
|
|
|
273
265
|
}
|
|
274
266
|
return newA;
|
|
275
267
|
}
|
|
268
|
+
/**
|
|
269
|
+
* Reverse of [[splitEdge]]: remove the vertex at `doomed` and merge its two incident edges.
|
|
270
|
+
* @param doomed one of two nodes added by [[splitEdge]]. These nodes should form a vertex loop of two nodes.
|
|
271
|
+
* On successful return this node and its mate are isolated.
|
|
272
|
+
* @param checkParallel whether to check that the doomed edge and the preceding edge in its face loop are parallel.
|
|
273
|
+
* When passing `true` the assumption is that edge geometry is linear. If nonlinear edge geometry is attached, the
|
|
274
|
+
* caller should a) verify that the geometry on either side of the doomed vertex can be merged, and if so, they
|
|
275
|
+
* should b) call this method passing `false`, and c) adjust the geometry of the returned edge and its edge mate
|
|
276
|
+
* as appropriate.
|
|
277
|
+
* @returns the former (surviving) face predecessor of `doomed`, or undefined if the edge can't be healed.
|
|
278
|
+
*/
|
|
279
|
+
static healEdge(doomed, checkParallel = true) {
|
|
280
|
+
if (doomed.isIsolatedEdge)
|
|
281
|
+
return undefined;
|
|
282
|
+
const doomed1 = doomed.vertexSuccessor;
|
|
283
|
+
if (doomed1.vertexSuccessor !== doomed)
|
|
284
|
+
return undefined; // v-loop not a 2-cycle
|
|
285
|
+
if (checkParallel && !doomed.vectorToFaceSuccessor().isParallelTo(doomed.facePredecessor.vectorToFaceSuccessor(), false, true))
|
|
286
|
+
return undefined; // removing this vertex does not leave a straight edge behind
|
|
287
|
+
const fPred = doomed.facePredecessor;
|
|
288
|
+
const fSucc = doomed.faceSuccessor;
|
|
289
|
+
const fPred1 = doomed1.facePredecessor;
|
|
290
|
+
const fSucc1 = doomed1.faceSuccessor;
|
|
291
|
+
this.setFaceLinks(fPred, fSucc);
|
|
292
|
+
this.setFaceLinks(fPred1, fSucc1);
|
|
293
|
+
this.setEdgeMates(fPred, fPred1);
|
|
294
|
+
this.setFaceLinks(doomed, doomed1);
|
|
295
|
+
this.setFaceLinks(doomed1, doomed);
|
|
296
|
+
this.setEdgeMates(doomed, doomed1);
|
|
297
|
+
return fPred;
|
|
298
|
+
}
|
|
276
299
|
/**
|
|
277
300
|
* Create a new sliver face "inside" an existing edge.
|
|
278
301
|
* * This creates two nodes that are each face predecessor and successor to the other.
|
|
@@ -300,14 +323,14 @@ class HalfEdge {
|
|
|
300
323
|
newB.copyDataFrom(baseB, true, true, false, false);
|
|
301
324
|
return newA;
|
|
302
325
|
}
|
|
303
|
-
/**
|
|
326
|
+
/** Masks copied when an edge is split. */
|
|
304
327
|
static _edgePropertyMasks = [
|
|
305
|
-
HalfEdgeMask.
|
|
328
|
+
HalfEdgeMask.EXTERIOR, HalfEdgeMask.BOUNDARY_EDGE, HalfEdgeMask.PRIMARY_EDGE, HalfEdgeMask.BRIDGE_EDGE, HalfEdgeMask.REGULARIZED_EDGE, HalfEdgeMask.NULL_FACE
|
|
306
329
|
];
|
|
307
330
|
/**
|
|
308
331
|
* Copy "edge based" content of `fromNode` to `toNode`:
|
|
309
332
|
* * edgeTag
|
|
310
|
-
* * masks
|
|
333
|
+
* * edge masks
|
|
311
334
|
*/
|
|
312
335
|
static transferEdgeProperties(fromNode, toNode) {
|
|
313
336
|
toNode.edgeTag = fromNode.edgeTag;
|
|
@@ -480,7 +503,7 @@ class HalfEdge {
|
|
|
480
503
|
/**
|
|
481
504
|
* Returns the number of nodes that match (or do not match) the given mask value around this face loop.
|
|
482
505
|
* @param mask the mask to check.
|
|
483
|
-
* @param value true for mask match and false for mask not match.
|
|
506
|
+
* @param value true for mask match and false for mask not match. Default is `true`.
|
|
484
507
|
*/
|
|
485
508
|
countMaskAroundFace(mask, value = true) {
|
|
486
509
|
let count = 0;
|
|
@@ -527,16 +550,17 @@ class HalfEdge {
|
|
|
527
550
|
}
|
|
528
551
|
/**
|
|
529
552
|
* Returns the first node that matches (or does not match) the given mask value around this vertex loop, starting
|
|
530
|
-
* with the instance node and proceeding via
|
|
553
|
+
* with the instance node and proceeding via `vertexSuccessor`.
|
|
531
554
|
* @param mask the mask to check.
|
|
532
|
-
* @param value true for mask match and false for mask not match.
|
|
555
|
+
* @param value true for mask match and false for mask not match. Default is `true`.
|
|
556
|
+
* @param reverse if true, search in reverse order via `vertexPredecessor`. Default is `false`.
|
|
533
557
|
*/
|
|
534
|
-
findMaskAroundVertex(mask, value = true) {
|
|
558
|
+
findMaskAroundVertex(mask, value = true, reverse = false) {
|
|
535
559
|
let node = this;
|
|
536
560
|
do {
|
|
537
561
|
if (node.isMaskSet(mask) === value)
|
|
538
562
|
return node;
|
|
539
|
-
node = node.vertexSuccessor;
|
|
563
|
+
node = reverse ? node.vertexPredecessor : node.vertexSuccessor;
|
|
540
564
|
} while (node !== this);
|
|
541
565
|
return undefined;
|
|
542
566
|
}
|
|
@@ -544,7 +568,7 @@ class HalfEdge {
|
|
|
544
568
|
* Returns the first node that matches (or does not match) the given mask value around this face loop, starting
|
|
545
569
|
* with the instance node and proceeding via face successors.
|
|
546
570
|
* @param mask the mask to check.
|
|
547
|
-
* @param value true for mask match and false for mask not match.
|
|
571
|
+
* @param value true for mask match and false for mask not match. Default is `true`.
|
|
548
572
|
*/
|
|
549
573
|
findMaskAroundFace(mask, value = true) {
|
|
550
574
|
let node = this;
|
|
@@ -656,6 +680,10 @@ class HalfEdge {
|
|
|
656
680
|
predA._faceSuccessor = nodeB;
|
|
657
681
|
}
|
|
658
682
|
}
|
|
683
|
+
/** Return whether the edge is dangling at its base. */
|
|
684
|
+
get isDangling() {
|
|
685
|
+
return this.edgeMate.faceSuccessor === this;
|
|
686
|
+
}
|
|
659
687
|
/**
|
|
660
688
|
* Pinch this half edge out of its base vertex loop.
|
|
661
689
|
* @return the surviving HalfEdge in the vertex loop or `undefined` if the instance HalfEdge is already dangling.
|
|
@@ -859,7 +887,10 @@ class HalfEdge {
|
|
|
859
887
|
this.yankFromVertexLoop();
|
|
860
888
|
mate.yankFromVertexLoop();
|
|
861
889
|
}
|
|
862
|
-
/**
|
|
890
|
+
/**
|
|
891
|
+
* Specify whether this edge is isolated from the rest of the graph.
|
|
892
|
+
* * Both edge mates of an isolated edge return true for [[isDangling]].
|
|
893
|
+
*/
|
|
863
894
|
get isIsolatedEdge() {
|
|
864
895
|
return this === this.vertexSuccessor && this.edgeMate === this.edgeMate.vertexSuccessor;
|
|
865
896
|
}
|
|
@@ -907,6 +938,71 @@ class HalfEdge {
|
|
|
907
938
|
distanceXYZ(other) {
|
|
908
939
|
return Geometry_1.Geometry.distanceXYZXYZ(this.x, this.y, this.z, other.x, other.y, other.z);
|
|
909
940
|
}
|
|
941
|
+
/**
|
|
942
|
+
* Search around the instance's face loop for nodes with the specified mask value.
|
|
943
|
+
* * Returned nodes satisfy `node.isMaskSet(mask) === value`.
|
|
944
|
+
* @param mask target mask.
|
|
945
|
+
* @param value target boolean value for mask on half edges (default `true`).
|
|
946
|
+
* @param result optional array to be cleared, populated with masked nodes, and returned.
|
|
947
|
+
* @return array of masked half edges
|
|
948
|
+
*/
|
|
949
|
+
collectMaskedEdgesAroundFace(mask, value = true, result) {
|
|
950
|
+
if (result === undefined)
|
|
951
|
+
result = [];
|
|
952
|
+
else
|
|
953
|
+
result.length = 0;
|
|
954
|
+
let node = this;
|
|
955
|
+
do {
|
|
956
|
+
if (node.isMaskSet(mask) === value)
|
|
957
|
+
result.push(node);
|
|
958
|
+
node = node.faceSuccessor;
|
|
959
|
+
} while (node !== this);
|
|
960
|
+
return result;
|
|
961
|
+
}
|
|
962
|
+
/**
|
|
963
|
+
* Announce edges in the face loop, starting with the instance and proceeding in a `faceSuccessor` traversal.
|
|
964
|
+
* @param announceEdge function to call at each edge
|
|
965
|
+
*/
|
|
966
|
+
announceEdgesInFace(announceEdge) {
|
|
967
|
+
let node = this;
|
|
968
|
+
do {
|
|
969
|
+
announceEdge(node);
|
|
970
|
+
node = node.faceSuccessor;
|
|
971
|
+
} while (node !== this);
|
|
972
|
+
}
|
|
973
|
+
/**
|
|
974
|
+
* Announce edges in the super face loop, starting with the instance.
|
|
975
|
+
* * A super face admits a `faceSuccessor` traversal, where the next edge at the far vertex is the first one lacking `skipMask` in a `vertexPredecessor` traversal.
|
|
976
|
+
* @param skipMask mask on edges to skip.
|
|
977
|
+
* @param announceEdge function to call at each edge that is not skipped.
|
|
978
|
+
* @param announceSkipped optional function to call at each edge that is skipped.
|
|
979
|
+
* @return whether a super face was found. Specifically, if a vertex loop has all edges with `skipMask` set, the return value is `false`.
|
|
980
|
+
*/
|
|
981
|
+
announceEdgesInSuperFace(skipMask, announceEdge, announceSkipped) {
|
|
982
|
+
const maxIter = 1000; // safeguard against infinite loops
|
|
983
|
+
let iter = 0;
|
|
984
|
+
const findNextNodeAroundVertex = (he) => {
|
|
985
|
+
let vNode = he;
|
|
986
|
+
do {
|
|
987
|
+
if (!vNode.isMaskSet(skipMask))
|
|
988
|
+
return vNode;
|
|
989
|
+
announceSkipped?.(vNode);
|
|
990
|
+
vNode = vNode.vertexPredecessor;
|
|
991
|
+
} while (vNode !== he);
|
|
992
|
+
return undefined;
|
|
993
|
+
};
|
|
994
|
+
const firstNode = findNextNodeAroundVertex(this);
|
|
995
|
+
if (!firstNode)
|
|
996
|
+
return false;
|
|
997
|
+
let node = firstNode;
|
|
998
|
+
do {
|
|
999
|
+
announceEdge(node);
|
|
1000
|
+
node = findNextNodeAroundVertex(node.faceSuccessor);
|
|
1001
|
+
if (!node)
|
|
1002
|
+
return false;
|
|
1003
|
+
} while (node !== firstNode && iter++ < maxIter);
|
|
1004
|
+
return iter < maxIter;
|
|
1005
|
+
}
|
|
910
1006
|
/**
|
|
911
1007
|
* Evaluate `f(node)` at each node around `this` node's face loop. Collect the function values.
|
|
912
1008
|
* @param f optional node function. If `undefined`, collect the nodes themselves.
|
|
@@ -1184,16 +1280,37 @@ class HalfEdge {
|
|
|
1184
1280
|
this.y = source.y;
|
|
1185
1281
|
this.z = source.z;
|
|
1186
1282
|
}
|
|
1187
|
-
if (copyVertexData)
|
|
1283
|
+
if (copyVertexData)
|
|
1188
1284
|
this.i = source.i;
|
|
1189
|
-
|
|
1190
|
-
if (copyEdgeData) {
|
|
1285
|
+
if (copyEdgeData)
|
|
1191
1286
|
HalfEdge.transferEdgeProperties(source, this);
|
|
1192
|
-
|
|
1193
|
-
}
|
|
1194
|
-
if (copyFaceData) {
|
|
1287
|
+
if (copyFaceData)
|
|
1195
1288
|
this.faceTag = source.faceTag;
|
|
1289
|
+
}
|
|
1290
|
+
/**
|
|
1291
|
+
* Is the instance's face loop a split-washer type face?
|
|
1292
|
+
* * A split-washer face contains at least one bridge edge.
|
|
1293
|
+
* * A bridge edge and its edge mate have the same `bridgeMask` and live in the same face loop.
|
|
1294
|
+
* * By connecting hole/outer loops with bridge edges, a split-washer face can represent a parity region.
|
|
1295
|
+
* @param bridgeMask mask preset on bridge edges (default is [[HalfEdgeMask.BRIDGE_EDGE]]).
|
|
1296
|
+
*/
|
|
1297
|
+
isSplitWasherFace(bridgeMask = HalfEdgeMask.BRIDGE_EDGE) {
|
|
1298
|
+
if (!this.countMaskAroundFace(HalfEdgeMask.BRIDGE_EDGE))
|
|
1299
|
+
return false;
|
|
1300
|
+
const bridges = new core_bentley_1.OrderedSet((a, b) => a.id - b.id);
|
|
1301
|
+
let node = this;
|
|
1302
|
+
do {
|
|
1303
|
+
if (node.isMaskSet(bridgeMask))
|
|
1304
|
+
bridges.add(node);
|
|
1305
|
+
node = node.faceSuccessor;
|
|
1306
|
+
} while (node !== this);
|
|
1307
|
+
if (bridges.size === 0)
|
|
1308
|
+
return false;
|
|
1309
|
+
for (const bridge of bridges) {
|
|
1310
|
+
if (!bridges.has(bridge.edgeMate) || !bridge.edgeMate.isMaskSet(bridgeMask))
|
|
1311
|
+
return false;
|
|
1196
1312
|
}
|
|
1313
|
+
return true;
|
|
1197
1314
|
}
|
|
1198
1315
|
}
|
|
1199
1316
|
exports.HalfEdge = HalfEdge;
|
|
@@ -1214,7 +1331,7 @@ class HalfEdgeGraph {
|
|
|
1214
1331
|
}
|
|
1215
1332
|
/**
|
|
1216
1333
|
* Ask for a mask (from the graph's free pool) for caller's use.
|
|
1217
|
-
*
|
|
1334
|
+
* @param clearInAllHalfEdges optionally clear the mask throughout the graph (default `true`).
|
|
1218
1335
|
*/
|
|
1219
1336
|
grabMask(clearInAllHalfEdges = true) {
|
|
1220
1337
|
const mask = this._maskManager.grabMask();
|