@itwin/core-geometry 4.3.0-dev.37 → 4.3.0-dev.39

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.
Files changed (451) hide show
  1. package/lib/cjs/Constant.js.map +1 -1
  2. package/lib/cjs/Geometry.d.ts +14 -2
  3. package/lib/cjs/Geometry.d.ts.map +1 -1
  4. package/lib/cjs/Geometry.js +14 -2
  5. package/lib/cjs/Geometry.js.map +1 -1
  6. package/lib/cjs/bspline/AkimaCurve3d.js.map +1 -1
  7. package/lib/cjs/bspline/BSpline1dNd.js.map +1 -1
  8. package/lib/cjs/bspline/BSplineCurve.js.map +1 -1
  9. package/lib/cjs/bspline/BSplineCurve3dH.js.map +1 -1
  10. package/lib/cjs/bspline/BSplineCurveOps.js.map +1 -1
  11. package/lib/cjs/bspline/BSplineSurface.js.map +1 -1
  12. package/lib/cjs/bspline/Bezier1dNd.js.map +1 -1
  13. package/lib/cjs/bspline/BezierCurve3d.js.map +1 -1
  14. package/lib/cjs/bspline/BezierCurve3dH.js.map +1 -1
  15. package/lib/cjs/bspline/BezierCurveBase.js.map +1 -1
  16. package/lib/cjs/bspline/InterpolationCurve3d.js.map +1 -1
  17. package/lib/cjs/bspline/KnotVector.js.map +1 -1
  18. package/lib/cjs/bspline/SurfaceLocationDetail.js.map +1 -1
  19. package/lib/cjs/clipping/AlternatingConvexClipTree.js.map +1 -1
  20. package/lib/cjs/clipping/BooleanClipFactory.js.map +1 -1
  21. package/lib/cjs/clipping/BooleanClipNode.js.map +1 -1
  22. package/lib/cjs/clipping/ClipPlane.js.map +1 -1
  23. package/lib/cjs/clipping/ClipPrimitive.js.map +1 -1
  24. package/lib/cjs/clipping/ClipUtils.js.map +1 -1
  25. package/lib/cjs/clipping/ClipVector.js.map +1 -1
  26. package/lib/cjs/clipping/ConvexClipPlaneSet.js.map +1 -1
  27. package/lib/cjs/clipping/UnionOfConvexClipPlaneSets.js.map +1 -1
  28. package/lib/cjs/clipping/internalContexts/LineStringOffsetClipperContext.js.map +1 -1
  29. package/lib/cjs/core-geometry.js.map +1 -1
  30. package/lib/cjs/curve/Arc3d.js.map +1 -1
  31. package/lib/cjs/curve/ConstructCurveBetweenCurves.js.map +1 -1
  32. package/lib/cjs/curve/CoordinateXYZ.js.map +1 -1
  33. package/lib/cjs/curve/CurveChainWithDistanceIndex.js.map +1 -1
  34. package/lib/cjs/curve/CurveCollection.js.map +1 -1
  35. package/lib/cjs/curve/CurveCurve.js.map +1 -1
  36. package/lib/cjs/curve/CurveExtendMode.js.map +1 -1
  37. package/lib/cjs/curve/CurveFactory.js.map +1 -1
  38. package/lib/cjs/curve/CurveLocationDetail.js.map +1 -1
  39. package/lib/cjs/curve/CurveOps.js.map +1 -1
  40. package/lib/cjs/curve/CurvePrimitive.js.map +1 -1
  41. package/lib/cjs/curve/CurveProcessor.js.map +1 -1
  42. package/lib/cjs/curve/CurveTypes.js.map +1 -1
  43. package/lib/cjs/curve/CurveWireMomentsXYZ.js.map +1 -1
  44. package/lib/cjs/curve/GeometryQuery.js.map +1 -1
  45. package/lib/cjs/curve/LineSegment3d.js.map +1 -1
  46. package/lib/cjs/curve/LineString3d.js.map +1 -1
  47. package/lib/cjs/curve/Loop.js.map +1 -1
  48. package/lib/cjs/curve/OffsetOptions.js.map +1 -1
  49. package/lib/cjs/curve/ParityRegion.js.map +1 -1
  50. package/lib/cjs/curve/Path.js.map +1 -1
  51. package/lib/cjs/curve/PointString3d.js.map +1 -1
  52. package/lib/cjs/curve/ProxyCurve.js.map +1 -1
  53. package/lib/cjs/curve/Query/ConsolidateAdjacentPrimitivesContext.js.map +1 -1
  54. package/lib/cjs/curve/Query/CurveSplitContext.js.map +1 -1
  55. package/lib/cjs/curve/Query/CylindricalRange.js.map +1 -1
  56. package/lib/cjs/curve/Query/InOutTests.js.map +1 -1
  57. package/lib/cjs/curve/Query/PlanarSubdivision.js.map +1 -1
  58. package/lib/cjs/curve/Query/StrokeCountChain.js.map +1 -1
  59. package/lib/cjs/curve/Query/StrokeCountMap.js.map +1 -1
  60. package/lib/cjs/curve/RegionMomentsXY.js.map +1 -1
  61. package/lib/cjs/curve/RegionOps.js.map +1 -1
  62. package/lib/cjs/curve/RegionOpsClassificationSweeps.js.map +1 -1
  63. package/lib/cjs/curve/StrokeOptions.js.map +1 -1
  64. package/lib/cjs/curve/UnionRegion.js.map +1 -1
  65. package/lib/cjs/curve/internalContexts/AppendPlaneIntersectionStrokeHandler.js.map +1 -1
  66. package/lib/cjs/curve/internalContexts/ChainCollectorContext.js.map +1 -1
  67. package/lib/cjs/curve/internalContexts/CloneCurvesContext.js.map +1 -1
  68. package/lib/cjs/curve/internalContexts/CloneWithExpandedLineStrings.js.map +1 -1
  69. package/lib/cjs/curve/internalContexts/ClosestPointStrokeHandler.js.map +1 -1
  70. package/lib/cjs/curve/internalContexts/CountLinearPartsSearchContext.js.map +1 -1
  71. package/lib/cjs/curve/internalContexts/CurveCurveCloseApproachXY.js.map +1 -1
  72. package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -1
  73. package/lib/cjs/curve/internalContexts/CurveCurveIntersectXYZ.js.map +1 -1
  74. package/lib/cjs/curve/internalContexts/CurveLengthContext.js.map +1 -1
  75. package/lib/cjs/curve/internalContexts/CurveOffsetXYHandler.js.map +1 -1
  76. package/lib/cjs/curve/internalContexts/GapSearchContext.js.map +1 -1
  77. package/lib/cjs/curve/internalContexts/MultiChainCollector.js.map +1 -1
  78. package/lib/cjs/curve/internalContexts/NewtonRtoRStrokeHandler.js.map +1 -1
  79. package/lib/cjs/curve/internalContexts/PlaneAltitudeRangeContext.js.map +1 -1
  80. package/lib/cjs/curve/internalContexts/PolygonOffsetContext.js.map +1 -1
  81. package/lib/cjs/curve/internalContexts/SumLengthsContext.js.map +1 -1
  82. package/lib/cjs/curve/internalContexts/TransformInPlaceContext.js.map +1 -1
  83. package/lib/cjs/curve/spiral/AustralianRailCorpXYEvaluator.js.map +1 -1
  84. package/lib/cjs/curve/spiral/ClothoidSeries.js.map +1 -1
  85. package/lib/cjs/curve/spiral/CubicEvaluator.js.map +1 -1
  86. package/lib/cjs/curve/spiral/CzechSpiralEvaluator.js.map +1 -1
  87. package/lib/cjs/curve/spiral/DirectHalfCosineSpiralEvaluator.js.map +1 -1
  88. package/lib/cjs/curve/spiral/DirectSpiral3d.js.map +1 -1
  89. package/lib/cjs/curve/spiral/IntegratedSpiral3d.js.map +1 -1
  90. package/lib/cjs/curve/spiral/MXCubicAlongArcSpiralEvaluator.js.map +1 -1
  91. package/lib/cjs/curve/spiral/NormalizedTransition.js.map +1 -1
  92. package/lib/cjs/curve/spiral/PolishCubicSpiralEvaluator.js.map +1 -1
  93. package/lib/cjs/curve/spiral/TransitionConditionalProperties.js.map +1 -1
  94. package/lib/cjs/curve/spiral/TransitionSpiral3d.js.map +1 -1
  95. package/lib/cjs/curve/spiral/XYCurveEvaluator.js.map +1 -1
  96. package/lib/cjs/geometry3d/Angle.d.ts +0 -1
  97. package/lib/cjs/geometry3d/Angle.d.ts.map +1 -1
  98. package/lib/cjs/geometry3d/Angle.js +0 -1
  99. package/lib/cjs/geometry3d/Angle.js.map +1 -1
  100. package/lib/cjs/geometry3d/AngleSweep.js.map +1 -1
  101. package/lib/cjs/geometry3d/BarycentricTriangle.js.map +1 -1
  102. package/lib/cjs/geometry3d/BilinearPatch.js.map +1 -1
  103. package/lib/cjs/geometry3d/CoincidentGeometryOps.js.map +1 -1
  104. package/lib/cjs/geometry3d/Ellipsoid.js.map +1 -1
  105. package/lib/cjs/geometry3d/FrameBuilder.js.map +1 -1
  106. package/lib/cjs/geometry3d/FrustumAnimation.js.map +1 -1
  107. package/lib/cjs/geometry3d/GeometryHandler.js.map +1 -1
  108. package/lib/cjs/geometry3d/GrowableBlockedArray.js.map +1 -1
  109. package/lib/cjs/geometry3d/GrowableFloat64Array.js.map +1 -1
  110. package/lib/cjs/geometry3d/GrowableXYArray.js.map +1 -1
  111. package/lib/cjs/geometry3d/GrowableXYZArray.js.map +1 -1
  112. package/lib/cjs/geometry3d/IndexedCollectionInterval.js.map +1 -1
  113. package/lib/cjs/geometry3d/IndexedXYCollection.js.map +1 -1
  114. package/lib/cjs/geometry3d/IndexedXYZCollection.js.map +1 -1
  115. package/lib/cjs/geometry3d/LongitudeLatitudeAltitude.js.map +1 -1
  116. package/lib/cjs/geometry3d/Matrix3d.js.map +1 -1
  117. package/lib/cjs/geometry3d/OrderedRotationAngles.js.map +1 -1
  118. package/lib/cjs/geometry3d/Plane3d.js.map +1 -1
  119. package/lib/cjs/geometry3d/Plane3dByOriginAndUnitNormal.js.map +1 -1
  120. package/lib/cjs/geometry3d/Plane3dByOriginAndVectors.js.map +1 -1
  121. package/lib/cjs/geometry3d/Point2dArrayCarrier.js.map +1 -1
  122. package/lib/cjs/geometry3d/Point2dVector2d.js.map +1 -1
  123. package/lib/cjs/geometry3d/Point3dArrayCarrier.js.map +1 -1
  124. package/lib/cjs/geometry3d/Point3dVector3d.js.map +1 -1
  125. package/lib/cjs/geometry3d/PointHelpers.js.map +1 -1
  126. package/lib/cjs/geometry3d/PointStreaming.js.map +1 -1
  127. package/lib/cjs/geometry3d/PolygonOps.js.map +1 -1
  128. package/lib/cjs/geometry3d/PolylineCompressionByEdgeOffset.js.map +1 -1
  129. package/lib/cjs/geometry3d/PolylineOps.js.map +1 -1
  130. package/lib/cjs/geometry3d/Range.js.map +1 -1
  131. package/lib/cjs/geometry3d/Ray2d.js.map +1 -1
  132. package/lib/cjs/geometry3d/Ray3d.js.map +1 -1
  133. package/lib/cjs/geometry3d/ReusableObjectCache.js.map +1 -1
  134. package/lib/cjs/geometry3d/Segment1d.js.map +1 -1
  135. package/lib/cjs/geometry3d/SortablePolygon.js.map +1 -1
  136. package/lib/cjs/geometry3d/Transform.js.map +1 -1
  137. package/lib/cjs/geometry3d/UVSurfaceOps.js.map +1 -1
  138. package/lib/cjs/geometry3d/XYZProps.js.map +1 -1
  139. package/lib/cjs/geometry3d/YawPitchRollAngles.js.map +1 -1
  140. package/lib/cjs/geometry4d/Map4d.js.map +1 -1
  141. package/lib/cjs/geometry4d/Matrix4d.js.map +1 -1
  142. package/lib/cjs/geometry4d/MomentData.js.map +1 -1
  143. package/lib/cjs/geometry4d/PlaneByOriginAndVectors4d.js.map +1 -1
  144. package/lib/cjs/geometry4d/Point4d.js.map +1 -1
  145. package/lib/cjs/numerics/BandedSystem.js.map +1 -1
  146. package/lib/cjs/numerics/BezierPolynomials.js.map +1 -1
  147. package/lib/cjs/numerics/ClusterableArray.js.map +1 -1
  148. package/lib/cjs/numerics/Complex.js.map +1 -1
  149. package/lib/cjs/numerics/ConvexPolygon2d.js.map +1 -1
  150. package/lib/cjs/numerics/Newton.js.map +1 -1
  151. package/lib/cjs/numerics/PascalCoefficients.js.map +1 -1
  152. package/lib/cjs/numerics/PolarData.js.map +1 -1
  153. package/lib/cjs/numerics/Polynomials.js.map +1 -1
  154. package/lib/cjs/numerics/Quadrature.js.map +1 -1
  155. package/lib/cjs/numerics/Range1dArray.js.map +1 -1
  156. package/lib/cjs/numerics/TriDiagonalSystem.js.map +1 -1
  157. package/lib/cjs/numerics/UnionFind.js.map +1 -1
  158. package/lib/cjs/numerics/UsageSums.js.map +1 -1
  159. package/lib/cjs/polyface/AuxData.js.map +1 -1
  160. package/lib/cjs/polyface/BoxTopology.js.map +1 -1
  161. package/lib/cjs/polyface/FacetFaceData.js.map +1 -1
  162. package/lib/cjs/polyface/FacetLocationDetail.js.map +1 -1
  163. package/lib/cjs/polyface/FacetOrientation.js.map +1 -1
  164. package/lib/cjs/polyface/GreedyTriangulationBetweenLineStrings.js.map +1 -1
  165. package/lib/cjs/polyface/IndexedEdgeMatcher.js.map +1 -1
  166. package/lib/cjs/polyface/IndexedPolyfaceVisitor.js.map +1 -1
  167. package/lib/cjs/polyface/Polyface.js.map +1 -1
  168. package/lib/cjs/polyface/PolyfaceBuilder.js.map +1 -1
  169. package/lib/cjs/polyface/PolyfaceClip.js.map +1 -1
  170. package/lib/cjs/polyface/PolyfaceData.js.map +1 -1
  171. package/lib/cjs/polyface/PolyfaceQuery.js.map +1 -1
  172. package/lib/cjs/polyface/RangeLengthData.js.map +1 -1
  173. package/lib/cjs/polyface/TaggedNumericData.js.map +1 -1
  174. package/lib/cjs/polyface/TriangleCandidate.js.map +1 -1
  175. package/lib/cjs/polyface/multiclip/BuildAverageNormalsContext.js.map +1 -1
  176. package/lib/cjs/polyface/multiclip/GriddedRaggedRange2dSet.js.map +1 -1
  177. package/lib/cjs/polyface/multiclip/GriddedRaggedRange2dSetWithOverflow.js.map +1 -1
  178. package/lib/cjs/polyface/multiclip/LinearSearchRange2dArray.js.map +1 -1
  179. package/lib/cjs/polyface/multiclip/OffsetMeshContext.js.map +1 -1
  180. package/lib/cjs/polyface/multiclip/Range2dSearchInterface.js.map +1 -1
  181. package/lib/cjs/polyface/multiclip/RangeSearch.js.map +1 -1
  182. package/lib/cjs/polyface/multiclip/SweepLineStringToFacetContext.js.map +1 -1
  183. package/lib/cjs/polyface/multiclip/XYPointBuckets.js.map +1 -1
  184. package/lib/cjs/serialization/BGFBAccessors.js.map +1 -1
  185. package/lib/cjs/serialization/BGFBReader.js.map +1 -1
  186. package/lib/cjs/serialization/BGFBWriter.js.map +1 -1
  187. package/lib/cjs/serialization/BentleyGeometryFlatBuffer.js.map +1 -1
  188. package/lib/cjs/serialization/DeepCompare.js.map +1 -1
  189. package/lib/cjs/serialization/GeometrySamples.js.map +1 -1
  190. package/lib/cjs/serialization/IModelJsonSchema.js.map +1 -1
  191. package/lib/cjs/serialization/SerializationHelpers.js.map +1 -1
  192. package/lib/cjs/solid/Box.js.map +1 -1
  193. package/lib/cjs/solid/Cone.js.map +1 -1
  194. package/lib/cjs/solid/LinearSweep.js.map +1 -1
  195. package/lib/cjs/solid/RotationalSweep.js.map +1 -1
  196. package/lib/cjs/solid/RuledSweep.js.map +1 -1
  197. package/lib/cjs/solid/SolidPrimitive.js.map +1 -1
  198. package/lib/cjs/solid/Sphere.js.map +1 -1
  199. package/lib/cjs/solid/SweepContour.js.map +1 -1
  200. package/lib/cjs/solid/TorusPipe.js.map +1 -1
  201. package/lib/cjs/topology/ChainMerge.js.map +1 -1
  202. package/lib/cjs/topology/Graph.d.ts +399 -366
  203. package/lib/cjs/topology/Graph.d.ts.map +1 -1
  204. package/lib/cjs/topology/Graph.js +531 -464
  205. package/lib/cjs/topology/Graph.js.map +1 -1
  206. package/lib/cjs/topology/HalfEdgeGraphFromIndexedLoopsContext.js.map +1 -1
  207. package/lib/cjs/topology/HalfEdgeGraphSearch.js.map +1 -1
  208. package/lib/cjs/topology/HalfEdgeGraphSpineContext.js.map +1 -1
  209. package/lib/cjs/topology/HalfEdgeGraphValidation.js.map +1 -1
  210. package/lib/cjs/topology/HalfEdgeMarkSet.js.map +1 -1
  211. package/lib/cjs/topology/HalfEdgeNodeXYZUV.js.map +1 -1
  212. package/lib/cjs/topology/HalfEdgePointInGraphSearch.js.map +1 -1
  213. package/lib/cjs/topology/HalfEdgePositionDetail.js.map +1 -1
  214. package/lib/cjs/topology/HalfEdgePriorityQueue.js.map +1 -1
  215. package/lib/cjs/topology/InsertAndRetriangulateContext.js.map +1 -1
  216. package/lib/cjs/topology/MaskManager.d.ts +8 -9
  217. package/lib/cjs/topology/MaskManager.d.ts.map +1 -1
  218. package/lib/cjs/topology/MaskManager.js +11 -12
  219. package/lib/cjs/topology/MaskManager.js.map +1 -1
  220. package/lib/cjs/topology/Merging.js.map +1 -1
  221. package/lib/cjs/topology/RegularizeFace.js.map +1 -1
  222. package/lib/cjs/topology/SignedDataSummary.js.map +1 -1
  223. package/lib/cjs/topology/SpaceTriangulation.js.map +1 -1
  224. package/lib/cjs/topology/Triangulation.js.map +1 -1
  225. package/lib/cjs/topology/XYParitySearchContext.js.map +1 -1
  226. package/lib/esm/Constant.js.map +1 -1
  227. package/lib/esm/Geometry.d.ts +14 -2
  228. package/lib/esm/Geometry.d.ts.map +1 -1
  229. package/lib/esm/Geometry.js +14 -2
  230. package/lib/esm/Geometry.js.map +1 -1
  231. package/lib/esm/bspline/AkimaCurve3d.js.map +1 -1
  232. package/lib/esm/bspline/BSpline1dNd.js.map +1 -1
  233. package/lib/esm/bspline/BSplineCurve.js.map +1 -1
  234. package/lib/esm/bspline/BSplineCurve3dH.js.map +1 -1
  235. package/lib/esm/bspline/BSplineCurveOps.js.map +1 -1
  236. package/lib/esm/bspline/BSplineSurface.js.map +1 -1
  237. package/lib/esm/bspline/Bezier1dNd.js.map +1 -1
  238. package/lib/esm/bspline/BezierCurve3d.js.map +1 -1
  239. package/lib/esm/bspline/BezierCurve3dH.js.map +1 -1
  240. package/lib/esm/bspline/BezierCurveBase.js.map +1 -1
  241. package/lib/esm/bspline/InterpolationCurve3d.js.map +1 -1
  242. package/lib/esm/bspline/KnotVector.js.map +1 -1
  243. package/lib/esm/bspline/SurfaceLocationDetail.js.map +1 -1
  244. package/lib/esm/clipping/AlternatingConvexClipTree.js.map +1 -1
  245. package/lib/esm/clipping/BooleanClipFactory.js.map +1 -1
  246. package/lib/esm/clipping/BooleanClipNode.js.map +1 -1
  247. package/lib/esm/clipping/ClipPlane.js.map +1 -1
  248. package/lib/esm/clipping/ClipPrimitive.js.map +1 -1
  249. package/lib/esm/clipping/ClipUtils.js.map +1 -1
  250. package/lib/esm/clipping/ClipVector.js.map +1 -1
  251. package/lib/esm/clipping/ConvexClipPlaneSet.js.map +1 -1
  252. package/lib/esm/clipping/UnionOfConvexClipPlaneSets.js.map +1 -1
  253. package/lib/esm/clipping/internalContexts/LineStringOffsetClipperContext.js.map +1 -1
  254. package/lib/esm/core-geometry.js.map +1 -1
  255. package/lib/esm/curve/Arc3d.js.map +1 -1
  256. package/lib/esm/curve/ConstructCurveBetweenCurves.js.map +1 -1
  257. package/lib/esm/curve/CoordinateXYZ.js.map +1 -1
  258. package/lib/esm/curve/CurveChainWithDistanceIndex.js.map +1 -1
  259. package/lib/esm/curve/CurveCollection.js.map +1 -1
  260. package/lib/esm/curve/CurveCurve.js.map +1 -1
  261. package/lib/esm/curve/CurveExtendMode.js.map +1 -1
  262. package/lib/esm/curve/CurveFactory.js.map +1 -1
  263. package/lib/esm/curve/CurveLocationDetail.js.map +1 -1
  264. package/lib/esm/curve/CurveOps.js.map +1 -1
  265. package/lib/esm/curve/CurvePrimitive.js.map +1 -1
  266. package/lib/esm/curve/CurveProcessor.js.map +1 -1
  267. package/lib/esm/curve/CurveTypes.js.map +1 -1
  268. package/lib/esm/curve/CurveWireMomentsXYZ.js.map +1 -1
  269. package/lib/esm/curve/GeometryQuery.js.map +1 -1
  270. package/lib/esm/curve/LineSegment3d.js.map +1 -1
  271. package/lib/esm/curve/LineString3d.js.map +1 -1
  272. package/lib/esm/curve/Loop.js.map +1 -1
  273. package/lib/esm/curve/OffsetOptions.js.map +1 -1
  274. package/lib/esm/curve/ParityRegion.js.map +1 -1
  275. package/lib/esm/curve/Path.js.map +1 -1
  276. package/lib/esm/curve/PointString3d.js.map +1 -1
  277. package/lib/esm/curve/ProxyCurve.js.map +1 -1
  278. package/lib/esm/curve/Query/ConsolidateAdjacentPrimitivesContext.js.map +1 -1
  279. package/lib/esm/curve/Query/CurveSplitContext.js.map +1 -1
  280. package/lib/esm/curve/Query/CylindricalRange.js.map +1 -1
  281. package/lib/esm/curve/Query/InOutTests.js.map +1 -1
  282. package/lib/esm/curve/Query/PlanarSubdivision.js.map +1 -1
  283. package/lib/esm/curve/Query/StrokeCountChain.js.map +1 -1
  284. package/lib/esm/curve/Query/StrokeCountMap.js.map +1 -1
  285. package/lib/esm/curve/RegionMomentsXY.js.map +1 -1
  286. package/lib/esm/curve/RegionOps.js.map +1 -1
  287. package/lib/esm/curve/RegionOpsClassificationSweeps.js.map +1 -1
  288. package/lib/esm/curve/StrokeOptions.js.map +1 -1
  289. package/lib/esm/curve/UnionRegion.js.map +1 -1
  290. package/lib/esm/curve/internalContexts/AppendPlaneIntersectionStrokeHandler.js.map +1 -1
  291. package/lib/esm/curve/internalContexts/ChainCollectorContext.js.map +1 -1
  292. package/lib/esm/curve/internalContexts/CloneCurvesContext.js.map +1 -1
  293. package/lib/esm/curve/internalContexts/CloneWithExpandedLineStrings.js.map +1 -1
  294. package/lib/esm/curve/internalContexts/ClosestPointStrokeHandler.js.map +1 -1
  295. package/lib/esm/curve/internalContexts/CountLinearPartsSearchContext.js.map +1 -1
  296. package/lib/esm/curve/internalContexts/CurveCurveCloseApproachXY.js.map +1 -1
  297. package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -1
  298. package/lib/esm/curve/internalContexts/CurveCurveIntersectXYZ.js.map +1 -1
  299. package/lib/esm/curve/internalContexts/CurveLengthContext.js.map +1 -1
  300. package/lib/esm/curve/internalContexts/CurveOffsetXYHandler.js.map +1 -1
  301. package/lib/esm/curve/internalContexts/GapSearchContext.js.map +1 -1
  302. package/lib/esm/curve/internalContexts/MultiChainCollector.js.map +1 -1
  303. package/lib/esm/curve/internalContexts/NewtonRtoRStrokeHandler.js.map +1 -1
  304. package/lib/esm/curve/internalContexts/PlaneAltitudeRangeContext.js.map +1 -1
  305. package/lib/esm/curve/internalContexts/PolygonOffsetContext.js.map +1 -1
  306. package/lib/esm/curve/internalContexts/SumLengthsContext.js.map +1 -1
  307. package/lib/esm/curve/internalContexts/TransformInPlaceContext.js.map +1 -1
  308. package/lib/esm/curve/spiral/AustralianRailCorpXYEvaluator.js.map +1 -1
  309. package/lib/esm/curve/spiral/ClothoidSeries.js.map +1 -1
  310. package/lib/esm/curve/spiral/CubicEvaluator.js.map +1 -1
  311. package/lib/esm/curve/spiral/CzechSpiralEvaluator.js.map +1 -1
  312. package/lib/esm/curve/spiral/DirectHalfCosineSpiralEvaluator.js.map +1 -1
  313. package/lib/esm/curve/spiral/DirectSpiral3d.js.map +1 -1
  314. package/lib/esm/curve/spiral/IntegratedSpiral3d.js.map +1 -1
  315. package/lib/esm/curve/spiral/MXCubicAlongArcSpiralEvaluator.js.map +1 -1
  316. package/lib/esm/curve/spiral/NormalizedTransition.js.map +1 -1
  317. package/lib/esm/curve/spiral/PolishCubicSpiralEvaluator.js.map +1 -1
  318. package/lib/esm/curve/spiral/TransitionConditionalProperties.js.map +1 -1
  319. package/lib/esm/curve/spiral/TransitionSpiral3d.js.map +1 -1
  320. package/lib/esm/curve/spiral/XYCurveEvaluator.js.map +1 -1
  321. package/lib/esm/geometry3d/Angle.d.ts +0 -1
  322. package/lib/esm/geometry3d/Angle.d.ts.map +1 -1
  323. package/lib/esm/geometry3d/Angle.js +0 -1
  324. package/lib/esm/geometry3d/Angle.js.map +1 -1
  325. package/lib/esm/geometry3d/AngleSweep.js.map +1 -1
  326. package/lib/esm/geometry3d/BarycentricTriangle.js.map +1 -1
  327. package/lib/esm/geometry3d/BilinearPatch.js.map +1 -1
  328. package/lib/esm/geometry3d/CoincidentGeometryOps.js.map +1 -1
  329. package/lib/esm/geometry3d/Ellipsoid.js.map +1 -1
  330. package/lib/esm/geometry3d/FrameBuilder.js.map +1 -1
  331. package/lib/esm/geometry3d/FrustumAnimation.js.map +1 -1
  332. package/lib/esm/geometry3d/GeometryHandler.js.map +1 -1
  333. package/lib/esm/geometry3d/GrowableBlockedArray.js.map +1 -1
  334. package/lib/esm/geometry3d/GrowableFloat64Array.js.map +1 -1
  335. package/lib/esm/geometry3d/GrowableXYArray.js.map +1 -1
  336. package/lib/esm/geometry3d/GrowableXYZArray.js.map +1 -1
  337. package/lib/esm/geometry3d/IndexedCollectionInterval.js.map +1 -1
  338. package/lib/esm/geometry3d/IndexedXYCollection.js.map +1 -1
  339. package/lib/esm/geometry3d/IndexedXYZCollection.js.map +1 -1
  340. package/lib/esm/geometry3d/LongitudeLatitudeAltitude.js.map +1 -1
  341. package/lib/esm/geometry3d/Matrix3d.js.map +1 -1
  342. package/lib/esm/geometry3d/OrderedRotationAngles.js.map +1 -1
  343. package/lib/esm/geometry3d/Plane3d.js.map +1 -1
  344. package/lib/esm/geometry3d/Plane3dByOriginAndUnitNormal.js.map +1 -1
  345. package/lib/esm/geometry3d/Plane3dByOriginAndVectors.js.map +1 -1
  346. package/lib/esm/geometry3d/Point2dArrayCarrier.js.map +1 -1
  347. package/lib/esm/geometry3d/Point2dVector2d.js.map +1 -1
  348. package/lib/esm/geometry3d/Point3dArrayCarrier.js.map +1 -1
  349. package/lib/esm/geometry3d/Point3dVector3d.js.map +1 -1
  350. package/lib/esm/geometry3d/PointHelpers.js.map +1 -1
  351. package/lib/esm/geometry3d/PointStreaming.js.map +1 -1
  352. package/lib/esm/geometry3d/PolygonOps.js.map +1 -1
  353. package/lib/esm/geometry3d/PolylineCompressionByEdgeOffset.js.map +1 -1
  354. package/lib/esm/geometry3d/PolylineOps.js.map +1 -1
  355. package/lib/esm/geometry3d/Range.js.map +1 -1
  356. package/lib/esm/geometry3d/Ray2d.js.map +1 -1
  357. package/lib/esm/geometry3d/Ray3d.js.map +1 -1
  358. package/lib/esm/geometry3d/ReusableObjectCache.js.map +1 -1
  359. package/lib/esm/geometry3d/Segment1d.js.map +1 -1
  360. package/lib/esm/geometry3d/SortablePolygon.js.map +1 -1
  361. package/lib/esm/geometry3d/Transform.js.map +1 -1
  362. package/lib/esm/geometry3d/UVSurfaceOps.js.map +1 -1
  363. package/lib/esm/geometry3d/XYZProps.js.map +1 -1
  364. package/lib/esm/geometry3d/YawPitchRollAngles.js.map +1 -1
  365. package/lib/esm/geometry4d/Map4d.js.map +1 -1
  366. package/lib/esm/geometry4d/Matrix4d.js.map +1 -1
  367. package/lib/esm/geometry4d/MomentData.js.map +1 -1
  368. package/lib/esm/geometry4d/PlaneByOriginAndVectors4d.js.map +1 -1
  369. package/lib/esm/geometry4d/Point4d.js.map +1 -1
  370. package/lib/esm/numerics/BandedSystem.js.map +1 -1
  371. package/lib/esm/numerics/BezierPolynomials.js.map +1 -1
  372. package/lib/esm/numerics/ClusterableArray.js.map +1 -1
  373. package/lib/esm/numerics/Complex.js.map +1 -1
  374. package/lib/esm/numerics/ConvexPolygon2d.js.map +1 -1
  375. package/lib/esm/numerics/Newton.js.map +1 -1
  376. package/lib/esm/numerics/PascalCoefficients.js.map +1 -1
  377. package/lib/esm/numerics/PolarData.js.map +1 -1
  378. package/lib/esm/numerics/Polynomials.js.map +1 -1
  379. package/lib/esm/numerics/Quadrature.js.map +1 -1
  380. package/lib/esm/numerics/Range1dArray.js.map +1 -1
  381. package/lib/esm/numerics/TriDiagonalSystem.js.map +1 -1
  382. package/lib/esm/numerics/UnionFind.js.map +1 -1
  383. package/lib/esm/numerics/UsageSums.js.map +1 -1
  384. package/lib/esm/polyface/AuxData.js.map +1 -1
  385. package/lib/esm/polyface/BoxTopology.js.map +1 -1
  386. package/lib/esm/polyface/FacetFaceData.js.map +1 -1
  387. package/lib/esm/polyface/FacetLocationDetail.js.map +1 -1
  388. package/lib/esm/polyface/FacetOrientation.js.map +1 -1
  389. package/lib/esm/polyface/GreedyTriangulationBetweenLineStrings.js.map +1 -1
  390. package/lib/esm/polyface/IndexedEdgeMatcher.js.map +1 -1
  391. package/lib/esm/polyface/IndexedPolyfaceVisitor.js.map +1 -1
  392. package/lib/esm/polyface/Polyface.js.map +1 -1
  393. package/lib/esm/polyface/PolyfaceBuilder.js.map +1 -1
  394. package/lib/esm/polyface/PolyfaceClip.js.map +1 -1
  395. package/lib/esm/polyface/PolyfaceData.js.map +1 -1
  396. package/lib/esm/polyface/PolyfaceQuery.js.map +1 -1
  397. package/lib/esm/polyface/RangeLengthData.js.map +1 -1
  398. package/lib/esm/polyface/TaggedNumericData.js.map +1 -1
  399. package/lib/esm/polyface/TriangleCandidate.js.map +1 -1
  400. package/lib/esm/polyface/multiclip/BuildAverageNormalsContext.js.map +1 -1
  401. package/lib/esm/polyface/multiclip/GriddedRaggedRange2dSet.js.map +1 -1
  402. package/lib/esm/polyface/multiclip/GriddedRaggedRange2dSetWithOverflow.js.map +1 -1
  403. package/lib/esm/polyface/multiclip/LinearSearchRange2dArray.js.map +1 -1
  404. package/lib/esm/polyface/multiclip/OffsetMeshContext.js.map +1 -1
  405. package/lib/esm/polyface/multiclip/Range2dSearchInterface.js.map +1 -1
  406. package/lib/esm/polyface/multiclip/RangeSearch.js.map +1 -1
  407. package/lib/esm/polyface/multiclip/SweepLineStringToFacetContext.js.map +1 -1
  408. package/lib/esm/polyface/multiclip/XYPointBuckets.js.map +1 -1
  409. package/lib/esm/serialization/BGFBAccessors.js.map +1 -1
  410. package/lib/esm/serialization/BGFBReader.js.map +1 -1
  411. package/lib/esm/serialization/BGFBWriter.js.map +1 -1
  412. package/lib/esm/serialization/BentleyGeometryFlatBuffer.js.map +1 -1
  413. package/lib/esm/serialization/DeepCompare.js.map +1 -1
  414. package/lib/esm/serialization/GeometrySamples.js.map +1 -1
  415. package/lib/esm/serialization/IModelJsonSchema.js.map +1 -1
  416. package/lib/esm/serialization/SerializationHelpers.js.map +1 -1
  417. package/lib/esm/solid/Box.js.map +1 -1
  418. package/lib/esm/solid/Cone.js.map +1 -1
  419. package/lib/esm/solid/LinearSweep.js.map +1 -1
  420. package/lib/esm/solid/RotationalSweep.js.map +1 -1
  421. package/lib/esm/solid/RuledSweep.js.map +1 -1
  422. package/lib/esm/solid/SolidPrimitive.js.map +1 -1
  423. package/lib/esm/solid/Sphere.js.map +1 -1
  424. package/lib/esm/solid/SweepContour.js.map +1 -1
  425. package/lib/esm/solid/TorusPipe.js.map +1 -1
  426. package/lib/esm/topology/ChainMerge.js.map +1 -1
  427. package/lib/esm/topology/Graph.d.ts +399 -366
  428. package/lib/esm/topology/Graph.d.ts.map +1 -1
  429. package/lib/esm/topology/Graph.js +531 -464
  430. package/lib/esm/topology/Graph.js.map +1 -1
  431. package/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js.map +1 -1
  432. package/lib/esm/topology/HalfEdgeGraphSearch.js.map +1 -1
  433. package/lib/esm/topology/HalfEdgeGraphSpineContext.js.map +1 -1
  434. package/lib/esm/topology/HalfEdgeGraphValidation.js.map +1 -1
  435. package/lib/esm/topology/HalfEdgeMarkSet.js.map +1 -1
  436. package/lib/esm/topology/HalfEdgeNodeXYZUV.js.map +1 -1
  437. package/lib/esm/topology/HalfEdgePointInGraphSearch.js.map +1 -1
  438. package/lib/esm/topology/HalfEdgePositionDetail.js.map +1 -1
  439. package/lib/esm/topology/HalfEdgePriorityQueue.js.map +1 -1
  440. package/lib/esm/topology/InsertAndRetriangulateContext.js.map +1 -1
  441. package/lib/esm/topology/MaskManager.d.ts +8 -9
  442. package/lib/esm/topology/MaskManager.d.ts.map +1 -1
  443. package/lib/esm/topology/MaskManager.js +11 -12
  444. package/lib/esm/topology/MaskManager.js.map +1 -1
  445. package/lib/esm/topology/Merging.js.map +1 -1
  446. package/lib/esm/topology/RegularizeFace.js.map +1 -1
  447. package/lib/esm/topology/SignedDataSummary.js.map +1 -1
  448. package/lib/esm/topology/SpaceTriangulation.js.map +1 -1
  449. package/lib/esm/topology/Triangulation.js.map +1 -1
  450. package/lib/esm/topology/XYParitySearchContext.js.map +1 -1
  451. package/package.json +3 -3
@@ -15,18 +15,16 @@ const Point2dVector2d_1 = require("../geometry3d/Point2dVector2d");
15
15
  const Point3dVector3d_1 = require("../geometry3d/Point3dVector3d");
16
16
  const Polynomials_1 = require("../numerics/Polynomials");
17
17
  const MaskManager_1 = require("./MaskManager");
18
- // import { GraphChecker } from "../test/topology/Graph.test";
18
+ // import { GraphChecker } from "../test/topology/Graph.test"; // used for debugging
19
19
  /* eslint-disable @typescript-eslint/no-this-alias */
20
- // cspell:word CONSTU
21
- // cspell:word CONSTV
22
- // cspell:word USEAM
23
- // cspell:word VSEAM
20
+ // cspell:word CONSTU CONSTV USEAM VSEAM internaldocs
24
21
  /**
25
22
  * * Each node of the graph has a mask member.
26
23
  * * The mask member is a number which is used as set of single bit boolean values.
27
24
  * * Particular meanings of the various bits are HIGHLY application dependent.
28
25
  * * The EXTERIOR mask bit is widely used to mark nodes that are "outside" the active areas
29
- * * The PRIMARY_EDGE bit is widely used to indicate linework created directly from input data, hence protected from triangle edge flipping.
26
+ * * The PRIMARY_EDGE bit is widely used to indicate linework created directly from input data, hence protected from
27
+ * triangle edge flipping.
30
28
  * * The BOUNDARY bit is widely used to indicate that crossing this edge is a transition from outside to inside.
31
29
  * * VISITED is used locally in many searches.
32
30
  * * Never use VISITED unless the search logic is highly self contained.
@@ -34,17 +32,6 @@ const MaskManager_1 = require("./MaskManager");
34
32
  */
35
33
  var HalfEdgeMask;
36
34
  (function (HalfEdgeMask) {
37
- /** Mask commonly set consistently around exterior faces.
38
- * * A boundary edge with interior to one side, exterior to the other will have EXTERIOR only on the outside.
39
- * * An an edge inserted "within a purely exterior face" can have EXTERIOR on both sides.
40
- * * An interior edge (such as added during triangulation) will have no EXTERIOR bits.
41
- */
42
- HalfEdgeMask[HalfEdgeMask["EXTERIOR"] = 1] = "EXTERIOR";
43
- /** Mask commonly set (on both sides) of original geometry edges that are transition from outside from to inside.
44
- * * At the moment of creating an edge from primary user boundary loop coordinates, the fact that an edge is BOUNDARY is often clear even though
45
- * there is uncertainty about which side should be EXTERIOR.
46
- */
47
- HalfEdgeMask[HalfEdgeMask["BOUNDARY_EDGE"] = 2] = "BOUNDARY_EDGE";
48
35
  // REMARK: Various mask names are COMMENTED here for reference to native legacy code.
49
36
  // CONSTU_MASK = 0x00000004,
50
37
  // CONSTV_MASK = 0x00000008,
@@ -53,21 +40,37 @@ var HalfEdgeMask;
53
40
  // BOUNDARY_VERTEX_MASK = 0x00000040,
54
41
  // PRIMARY_VERTEX_MASK = 0x00000080,
55
42
  // DIRECTED_EDGE_MASK = 0x00000100,
56
- /** Mask commonly set (on both sides) of original geometry edges, but NOT indicating that the edge is certainly a boundary between outside and inside.
57
- * * For instance, if geometry is provided as stray sticks (not loops), it can be marked PRIMARY_EDGE but neither BOUNDARY_EDGE nor EXTERIOR_EDGE
43
+ /**
44
+ * Mask commonly set consistently around exterior faces.
45
+ * * A boundary edge with interior to one side, exterior to the other, will have EXTERIOR only on the outside.
46
+ * * An an edge inserted "within a purely exterior face" can have EXTERIOR on both sides.
47
+ * * An interior edge (such as added during triangulation) will have no EXTERIOR bits.
48
+ */
49
+ HalfEdgeMask[HalfEdgeMask["EXTERIOR"] = 1] = "EXTERIOR";
50
+ /**
51
+ * Mask commonly set (on both sides) of original geometry edges that are transition from outside from to inside.
52
+ * * At the moment of creating an edge from primary user boundary loop coordinates, the fact that an edge is BOUNDARY
53
+ * is often clear even though there is uncertainty about which side should be EXTERIOR.
54
+ */
55
+ HalfEdgeMask[HalfEdgeMask["BOUNDARY_EDGE"] = 2] = "BOUNDARY_EDGE";
56
+ /**
57
+ * Mask commonly set (on both sides) of original geometry edges, but NOT indicating that the edge is certainly a
58
+ * boundary between outside and inside.
59
+ * * For instance, if geometry is provided as stray sticks (not loops), it can be marked PRIMARY_EDGE but neither
60
+ * BOUNDARY_EDGE nor EXTERIOR_EDGE.
58
61
  */
59
62
  HalfEdgeMask[HalfEdgeMask["PRIMARY_EDGE"] = 4] = "PRIMARY_EDGE";
60
- /** Mask used for low level searches to identify previously-visited nodes */
63
+ /** Mask used for low level searches to identify previously-visited nodes. */
61
64
  HalfEdgeMask[HalfEdgeMask["VISITED"] = 16] = "VISITED";
62
- /** Mask applied to triangles by earcut triangulator */
65
+ /** Mask applied to triangles by earcut triangulator. */
63
66
  HalfEdgeMask[HalfEdgeMask["TRIANGULATED_FACE"] = 256] = "TRIANGULATED_FACE";
64
- /** mask applied in a face with 2 edges. */
67
+ /** Mask applied in a face with 2 edges. */
65
68
  HalfEdgeMask[HalfEdgeMask["NULL_FACE"] = 512] = "NULL_FACE";
66
- /** no mask bits */
69
+ /** No mask bits. */
67
70
  HalfEdgeMask[HalfEdgeMask["NULL_MASK"] = 0] = "NULL_MASK";
68
- /** The "upper 12 " bits of 32 bit integer. */
71
+ /** The "upper 12" bits of 32 bit integer reserved for grab/drop. */
69
72
  HalfEdgeMask[HalfEdgeMask["ALL_GRAB_DROP_MASKS"] = 4293918720] = "ALL_GRAB_DROP_MASKS";
70
- /** all mask bits */
73
+ /** All mask bits */
71
74
  HalfEdgeMask[HalfEdgeMask["ALL_MASK"] = 4294967295] = "ALL_MASK";
72
75
  // informal convention on preassigned mask bit numbers:
73
76
  // byte0 (EXTERIOR, BOUNDARY_EDGE, PRIMARY_EDGE) -- edge properties
@@ -75,35 +78,61 @@ var HalfEdgeMask;
75
78
  // byte2 (TRIANGULATED_FACE, NULL_FACE) -- face properties.
76
79
  })(HalfEdgeMask = exports.HalfEdgeMask || (exports.HalfEdgeMask = {}));
77
80
  /**
81
+ * A HalfEdge is "one side of an edge" in a structure of faces, edges and vertices. From a node there are
82
+ * navigational links to:
83
+ * * "faceSuccessor" -- the next half edge in a loop around a face.
84
+ * * "facePredecessor" -- the previous half edge in a loop around a face.
85
+ * * "edgeMate" -- the node's partner on the other side of the edge.
86
+ *
87
+ * The next, prev, and mate are the essential connectivity. Additional node content is for application-specific
88
+ * uses. The most useful ones are:
89
+ * * x,y -- coordinates in the xy plane
90
+ * * z -- z coordinate. This is normally ignored during planar setup, but used for output.
91
+ * * maskBits -- an integer value manipulated as individual bits.
78
92
  *
79
- * * A HalfEdge is "one side of an edge" in a structure of faces, edges and vertices. From a node there are navigational links to:
80
- * ** "faceSuccessor" -- the next half edge in a loop around a face.
81
- * ** "facePredecessor" -- the previous half edge in a loop around a face.
82
- * ** "edgeMate" -- the node's partner on the other side of the edge.
83
- * * The next, prev, and mate are the essential connectivity. Additional node content is for application-specific
84
- * uses. The most useful ones are:
85
- * ** x,y -- coordinates in the xy plane
86
- * ** z -- z coordinate. This is normally ignored during planar setup, but used for output.
87
- * ** buffer -- a integer value manipulated as individual bits.
88
- * * In properly connected planar graph, interior face loops are counterclockwise. But that property (along with
89
- * expected masking) is a result of extensive validation of inputs, and is not true in intermediate phases
90
- * of graph manipulation.
93
+ * In properly connected planar graph, interior face loops are counterclockwise. But that property (along with
94
+ * expected masking) is a result of extensive validation of inputs, and is not true in intermediate phases of
95
+ * graph manipulation.
91
96
  * @internal
92
97
  */
93
98
  class HalfEdge {
94
- /** id assigned sequentially during construction --- useful for debugging. */
95
- get id() { return this._id; }
96
- /** previous half edge "around the face"
97
- */
98
- get facePredecessor() { return this._facePredecessor; }
99
- /** next half edge "around the face" */
100
- get faceSuccessor() { return this._faceSuccessor; }
101
- /** Half edge on the other side of this edge.
102
- */
103
- get edgeMate() { return this._edgeMate; }
104
- /** Take numStep face steps and return y coordinate
105
- * * positive steps are through faceSuccessor
106
- * * negative steps are through facePredecessor
99
+ /** Immutable ID assigned sequentially during construction --- useful for debugging. */
100
+ get id() {
101
+ return this._id;
102
+ }
103
+ /** Previous half edge "around the face" */
104
+ get facePredecessor() {
105
+ return this._facePredecessor;
106
+ }
107
+ /** Next half edge "around the face" */
108
+ get faceSuccessor() {
109
+ return this._faceSuccessor;
110
+ }
111
+ /** Half edge on the other side of this edge. */
112
+ get edgeMate() {
113
+ return this._edgeMate;
114
+ }
115
+ constructor(x = 0, y = 0, z = 0, i = 0) {
116
+ this._id = HalfEdge._totalNodesCreated++;
117
+ this.i = i;
118
+ this.maskBits = 0x00000000;
119
+ this.x = x;
120
+ this.y = y;
121
+ this.z = z;
122
+ // explicit init to undefined is important for performance here
123
+ this.sortAngle = undefined;
124
+ this.sortData = undefined;
125
+ this.edgeTag = undefined;
126
+ this.faceTag = undefined;
127
+ // always created in pairs, init here to make TS compiler and JS runtime happy
128
+ this._facePredecessor = this;
129
+ this._faceSuccessor = this;
130
+ this._edgeMate = this;
131
+ }
132
+ /**
133
+ * Take numStep face steps and return y coordinate.
134
+ * * Positive steps are through faceSuccessor.
135
+ * * Negative steps are through facePredecessor.
107
136
  */
108
137
  faceStepY(numStep) {
109
138
  let node = this;
@@ -116,12 +145,13 @@ class HalfEdge {
116
145
  return node.y;
117
146
  }
118
147
  /**
119
- * * Create 2 half edges.
148
+ * Create 2 half edges.
120
149
  * * The two edges are joined as edgeMate pair.
121
150
  * * The two edges are a 2-half-edge face loop in both the faceSuccessor and facePredecessor directions.
122
- * @returns Returns the reference to the first half edge created
151
+ * @returns the reference to the first half edge created.
123
152
  */
124
153
  static createHalfEdgePair(heArray) {
154
+ // Visualization can be found at geometry/internaldocs/Graph.md
125
155
  const a = new HalfEdge();
126
156
  const b = new HalfEdge();
127
157
  if (heArray) {
@@ -137,8 +167,8 @@ class HalfEdge {
137
167
  * * Create 2 half edges.
138
168
  * * The two edges are joined as edgeMate pair.
139
169
  * * The two edges are a 2-half-edge face loop in both the faceSuccessor and facePredecessor directions.
140
- * * Properties x,y,z,i are inserted in each
141
- * @returns Returns the reference to the first half edge created
170
+ * * Properties x,y,z,i are inserted in each half edge.
171
+ * @returns the reference to the first half edge created.
142
172
  */
143
173
  static createHalfEdgePairWithCoordinates(xA = 0, yA = 0, zA = 0, iA = 0, xB = 0, yB = 0, zB = 0, iB = 0, heArray) {
144
174
  const a = HalfEdge.createHalfEdgePair(heArray);
@@ -154,32 +184,32 @@ class HalfEdge {
154
184
  return a;
155
185
  }
156
186
  /**
157
- * * set heA <==> heB pointer relation through heA._faceSuccessor and heB._facePredecessor
187
+ * * Set heA <==> heB pointer relation through heA._faceSuccessor and heB._facePredecessor.
158
188
  * * This changes heA._faceSuccessor and heB._facePredecessor, but not heA._facePredecessor and heB._faceSuccessor.
159
- * * this must always be done with another call to reestablish the entire double-linked list.
189
+ * * This must always be done with another call to setFaceLinks(heB,heA) in order to re-establish the entire
190
+ * double-linked list.
160
191
  */
161
192
  static setFaceLinks(heA, heB) {
162
193
  heA._faceSuccessor = heB;
163
194
  heB._facePredecessor = heA;
164
195
  }
165
- /**
166
- * * set heA <==> heB pointer relation edgeMate
167
- */
196
+ /** set heA <==> heB pointer relation edgeMate. */
168
197
  static setEdgeMates(heA, heB) {
169
198
  heA._edgeMate = heB;
170
199
  heB._edgeMate = heA;
171
200
  }
172
201
  /**
173
- * * Create a new vertex within the edge from base.
174
- * * Insert it "within" the base edge.
175
- * * This requires two new half edges.
176
- * * if the base is undefined, create a single-edge loop.
177
- * * This (unlike pinch) breaks the edgeMate pairing of the base edge.
178
- * * This preserves xyz and i properties at all existing vertices.
179
- * * on each side, if edgeTag is present it is copied to the new edge.
180
- * @returns Returns the reference to the half edge created.
202
+ * Create a new vertex within the edge beginning at `baseA`.
203
+ * * This creates two new nodes in their own vertex loop.
204
+ * * If the base is undefined, create a single-edge loop.
205
+ * * Existing nodes stay in their face and vertex loops and retain xyz and i values.
206
+ * * Unlike [[pinch]], this breaks the edgeMate pairing of the input edge:
207
+ * each node of the input edge gets a new node as its edge mate.
208
+ * * On each side of the edge, if edgeTag is present, it is copied to the new node on that side.
209
+ * @returns reference to the half edge created, the new face successor of `baseA`.
181
210
  */
182
211
  static splitEdge(baseA, xA = 0, yA = 0, zA = 0, iA = 0, heArray) {
212
+ // Visualization can be found at geometry/internaldocs/Graph.md
183
213
  const newA = new HalfEdge(xA, yA, zA, iA);
184
214
  const newB = new HalfEdge(xA, yA, zA, iA);
185
215
  if (heArray) {
@@ -195,10 +225,12 @@ class HalfEdge {
195
225
  const nextA = baseA._faceSuccessor;
196
226
  const mateA = baseA._edgeMate;
197
227
  const vPredA = mateA._faceSuccessor;
228
+ // insert newA and newB between existing half edges
198
229
  HalfEdge.setFaceLinks(newA, nextA);
199
230
  HalfEdge.setFaceLinks(baseA, newA);
200
231
  HalfEdge.setFaceLinks(mateA, newB);
201
232
  HalfEdge.setFaceLinks(newB, vPredA);
233
+ // set correct edge mates
202
234
  HalfEdge.setEdgeMates(newA, mateA);
203
235
  HalfEdge.setEdgeMates(newB, baseA);
204
236
  this.transferEdgeProperties(baseA, newA);
@@ -207,29 +239,26 @@ class HalfEdge {
207
239
  return newA;
208
240
  }
209
241
  /**
210
- * * Create a new sliver face "inside" an existing edge.
211
- * * Insert it "within" the base edge.
212
- * * This requires two new half edges.
213
- * * if the base is undefined, create a single-edge loop.
214
- * * This (unlike pinch) breaks the edgeMate pairing of the base edge.
215
- * * This preserves xyz and i properties at all existing vertices.
216
- * * The two new half edges are a sliver face (via their predecessor and successor)
217
- * * Each new edge mates to one existing edge.
218
- * @returns Returns the reference to the half edge created.
242
+ * Create a new sliver face "inside" an existing edge.
243
+ * * This creates two nodes that are each face predecessor and successor to the other.
244
+ * * Existing nodes stay in their face and vertex loops and retain xyz and i values.
245
+ * * Unlike [[pinch]], this breaks the edgeMate pairing of the input edge:
246
+ * each node of the input edge gets a new node as its edge mate.
247
+ * * New nodes get the xyz and i values shared by the nodes in the vertex loops into which they are placed.
248
+ * * New nodes' faceTag and edgeTag are `undefined`.
249
+ * @returns reference to the half edge created in the vertex loop of baseA.
219
250
  */
220
251
  static splitEdgeCreateSliverFace(baseA, heArray) {
221
- // raw edges ...
252
+ // Visualization can be found at geometry/internaldocs/Graph.md
253
+ const baseB = baseA.edgeMate;
222
254
  const newA = new HalfEdge();
223
255
  const newB = new HalfEdge();
224
- const baseB = baseA.edgeMate;
225
256
  if (heArray) {
226
257
  heArray.push(newA);
227
258
  heArray.push(newB);
228
259
  }
229
260
  newA._faceSuccessor = newA._facePredecessor = newB;
230
261
  newB._faceSuccessor = newB._facePredecessor = newA;
231
- // newA is in vertex loop with baseA etc.
232
- // newA mates to baseB
233
262
  HalfEdge.setEdgeMates(newA, baseB);
234
263
  HalfEdge.setEdgeMates(newB, baseA);
235
264
  newA.copyDataFrom(baseA, true, true, false, false);
@@ -237,11 +266,9 @@ class HalfEdge {
237
266
  return newA;
238
267
  }
239
268
  /**
240
- * Copy "edge based" content of fromNode to toNode
269
+ * Copy "edge based" content of `fromNode` to `toNode`:
241
270
  * * edgeTag
242
- * * masks in _edgePropertyMasks: EXTERIOR, BOUNDARY_EDGE, NULL_FACE, PRIMARY_EDGE
243
- * @param fromNode
244
- * @param toNode
271
+ * * masks EXTERIOR, BOUNDARY_EDGE, NULL_FACE, PRIMARY_EDGE
245
272
  */
246
273
  static transferEdgeProperties(fromNode, toNode) {
247
274
  toNode.edgeTag = fromNode.edgeTag;
@@ -252,49 +279,38 @@ class HalfEdge {
252
279
  toNode.clearMask(mask);
253
280
  }
254
281
  }
255
- constructor(x = 0, y = 0, z = 0, i = 0) {
256
- this._id = HalfEdge._totalNodesCreated++;
257
- this.i = i;
258
- this.maskBits = 0x00000000;
259
- this.x = x;
260
- this.y = y;
261
- this.z = z;
262
- // Explicit init to undefined is important for performance here
263
- this.sortAngle = undefined;
264
- this.sortData = undefined;
265
- this.edgeTag = undefined;
266
- this.faceTag = undefined;
267
- // Always created in pairs, init here to make TS compiler and JS runtime happy
268
- this._facePredecessor = this;
269
- this._faceSuccessor = this;
270
- this._edgeMate = this;
282
+ /** Return the next half edge around this vertex in the CCW direction. */
283
+ get vertexSuccessor() {
284
+ return this.facePredecessor.edgeMate;
285
+ }
286
+ /** Return the next half edge around this vertex in the CW direction. */
287
+ get vertexPredecessor() {
288
+ return this.edgeMate.faceSuccessor;
271
289
  }
272
290
  /**
273
- * Return the next outbound half edge around this vertex in the CCW direction
274
- */
275
- get vertexSuccessor() { return this.facePredecessor.edgeMate; }
276
- /**
277
- * Return the next outbound half edge around this vertex in the CW direction
278
- */
279
- get vertexPredecessor() { return this.edgeMate.faceSuccessor; }
280
- /**
281
- * Set mask bits on this HalfEdge
282
- * @param mask mask to apply
291
+ * Set mask bits on this HalfEdge.
292
+ * @param mask mask bits to apply
283
293
  */
284
- setMask(mask) { this.maskBits |= mask; }
294
+ setMask(mask) {
295
+ this.maskBits |= mask;
296
+ }
285
297
  /**
286
- * Get mask bits from this HalfEdge
287
- * @param mask mask to query
298
+ * Get mask bits from this HalfEdge.
299
+ * @param mask mask bits to query
288
300
  */
289
- getMask(mask) { return (this.maskBits & mask); }
301
+ getMask(mask) {
302
+ return (this.maskBits & mask);
303
+ }
290
304
  /**
291
- * Clear mask bits from this HalfEdge
292
- * @param mask mask to clear
305
+ * Clear mask bits from this HalfEdge.
306
+ * @param mask mask bits to clear
293
307
  */
294
- clearMask(mask) { this.maskBits &= ~mask; }
308
+ clearMask(mask) {
309
+ this.maskBits &= ~mask;
310
+ }
295
311
  /**
296
312
  * Set a mask at all nodes around a vertex.
297
- * @param mask mask to apply to the half edges around this HalfEdge's vertex loop
313
+ * @param mask mask to apply to the half edges around this HalfEdge's vertex loop.
298
314
  */
299
315
  setMaskAroundVertex(mask) {
300
316
  let node = this;
@@ -303,10 +319,7 @@ class HalfEdge {
303
319
  node = node.vertexSuccessor;
304
320
  } while (node !== this);
305
321
  }
306
- /**
307
- * Set x,y,z at all nodes around a vertex.
308
- * @param mask mask to apply to the half edges around this HalfEdge's vertex loop
309
- */
322
+ /** Set x,y,z at all nodes around a vertex. */
310
323
  setXYZAroundVertex(x, y, z) {
311
324
  let node = this;
312
325
  do {
@@ -318,7 +331,7 @@ class HalfEdge {
318
331
  }
319
332
  /**
320
333
  * Apply a mask to all edges around a face.
321
- * @param mask mask to apply to the half edges around this HalfEdge's face loop
334
+ * @param mask mask to apply to the half edges around this HalfEdge's face loop.
322
335
  */
323
336
  setMaskAroundFace(mask) {
324
337
  let node = this;
@@ -329,7 +342,7 @@ class HalfEdge {
329
342
  }
330
343
  /**
331
344
  * Apply a mask to both sides of an edge.
332
- * @param mask mask to apply to this edge and its `edgeMate`
345
+ * @param mask mask to apply to this edge and its edgeMate.
333
346
  */
334
347
  setMaskAroundEdge(mask) {
335
348
  this.setMask(mask);
@@ -337,7 +350,7 @@ class HalfEdge {
337
350
  }
338
351
  /**
339
352
  * Clear a mask on both sides of an edge.
340
- * @param mask mask to clear on this edge and its `edgeMate`
353
+ * @param mask mask to clear on this edge and its edgeMate.
341
354
  */
342
355
  clearMaskAroundEdge(mask) {
343
356
  this.clearMask(mask);
@@ -353,7 +366,7 @@ class HalfEdge {
353
366
  } while (node !== this);
354
367
  return count;
355
368
  }
356
- /** Return true if other is in the vertex loop around this. */
369
+ /** Return true if `other` node is in the vertex loop around `this` node. */
357
370
  findAroundVertex(other) {
358
371
  let node = this;
359
372
  do {
@@ -363,7 +376,7 @@ class HalfEdge {
363
376
  } while (node !== this);
364
377
  return false;
365
378
  }
366
- /** Return true if other is in the face loop around this. */
379
+ /** Return true if `other` node is in the face loop around `this` node. */
367
380
  findAroundFace(other) {
368
381
  let node = this;
369
382
  do {
@@ -374,7 +387,9 @@ class HalfEdge {
374
387
  return false;
375
388
  }
376
389
  /**
377
- * @return whether the mask is set (or unset) on all nodes of the face loop
390
+ * Returns whether the mask is set or unset on all nodes of the face loop.
391
+ * @param mask the mask to check.
392
+ * @param value true for mask set and false for mask unset.
378
393
  */
379
394
  isMaskedAroundFace(mask, value = true) {
380
395
  let node = this;
@@ -395,10 +410,10 @@ class HalfEdge {
395
410
  return true;
396
411
  }
397
412
  /**
398
- * Apply a edgeTag and mask to all edges around a face.
399
- * optionally apply it to all edge mates.
400
- * @param edgeTag tag to apply
401
- * @param bothSides If true, also apply the tag to the mates around the face.
413
+ * Apply a mask and edgeTag to all edges around a face. Optionally apply it to all edge mates.
414
+ * @param mask mask to apply.
415
+ * @param tag edgeTag to apply
416
+ * @param applyToMate If true, also apply the tag to the edge mates around the face.
402
417
  */
403
418
  setMaskAndEdgeTagAroundFace(mask, tag, applyToMate = false) {
404
419
  let node = this;
@@ -407,8 +422,8 @@ class HalfEdge {
407
422
  node.edgeTag = tag;
408
423
  if (applyToMate) {
409
424
  const mate = node.edgeMate;
410
- mate.edgeTag = tag;
411
425
  mate.setMask(mask);
426
+ mate.edgeTag = tag;
412
427
  }
413
428
  node = node.faceSuccessor;
414
429
  } while (node !== this);
@@ -423,7 +438,11 @@ class HalfEdge {
423
438
  } while (node !== this);
424
439
  return count;
425
440
  }
426
- /** Returns the number of nodes found with the given mask value around this vertex loop. */
441
+ /**
442
+ * Returns the number of nodes that match (or do not match) the given mask value around this face loop.
443
+ * @param mask the mask to check.
444
+ * @param value true for mask match and false for mask not match.
445
+ */
427
446
  countMaskAroundFace(mask, value = true) {
428
447
  let count = 0;
429
448
  let node = this;
@@ -443,7 +462,11 @@ class HalfEdge {
443
462
  }
444
463
  return count;
445
464
  }
446
- /** Returns the number of nodes found with the given mask value around this vertex loop. */
465
+ /**
466
+ * Returns the number of nodes that match (or do not match) the given mask value around this vertex loop.
467
+ * @param mask the mask to check.
468
+ * @param value true for mask match and false for mask not match.
469
+ */
447
470
  countMaskAroundVertex(mask, value = true) {
448
471
  let count = 0;
449
472
  let node = this;
@@ -463,7 +486,12 @@ class HalfEdge {
463
486
  }
464
487
  return count;
465
488
  }
466
- /** Returns the first node with given mask value around this vertex loop. */
489
+ /**
490
+ * Returns the first node that matches (or does not match) the given mask value around this vertex loop, starting
491
+ * with the instance node and proceeding via vertex successors.
492
+ * @param mask the mask to check.
493
+ * @param value true for mask match and false for mask not match.
494
+ */
467
495
  findMaskAroundVertex(mask, value = true) {
468
496
  let node = this;
469
497
  do {
@@ -473,7 +501,12 @@ class HalfEdge {
473
501
  } while (node !== this);
474
502
  return undefined;
475
503
  }
476
- /** Returns the first node with given mask value around this face loop. */
504
+ /**
505
+ * Returns the first node that matches (or does not match) the given mask value around this face loop, starting
506
+ * with the instance node and proceeding via face successors.
507
+ * @param mask the mask to check.
508
+ * @param value true for mask match and false for mask not match.
509
+ */
477
510
  findMaskAroundFace(mask, value = true) {
478
511
  let node = this;
479
512
  do {
@@ -483,7 +516,12 @@ class HalfEdge {
483
516
  } while (node !== this);
484
517
  return undefined;
485
518
  }
486
- /** Returns the first node with given mask value on this edge (i.e. examining this and this.mate) */
519
+ /**
520
+ * Returns the first node that matches (or does not match) the given mask value around this edge, starting
521
+ * with the instance node and then checking its edge mate.
522
+ * @param mask the mask to check.
523
+ * @param value true for mask match and false for mask not match.
524
+ */
487
525
  findMaskAroundEdge(mask, value = true) {
488
526
  if (this.isMaskSet(mask) === value)
489
527
  return this;
@@ -492,8 +530,9 @@ class HalfEdge {
492
530
  return mate;
493
531
  return undefined;
494
532
  }
495
- /** Set a mask, and return prior value.
496
- * @param mask mask to apply
533
+ /**
534
+ * Set a mask and return prior value.
535
+ * @param mask mask to apply.
497
536
  */
498
537
  testAndSetMask(mask) {
499
538
  const oldMask = this.maskBits & mask;
@@ -501,8 +540,8 @@ class HalfEdge {
501
540
  return oldMask;
502
541
  }
503
542
  /**
504
- * Set (copy) the this.x, this.y, this.z from node.x, node.y, node.z
505
- * @param node node containing xyz
543
+ * Set `this.x`, `this.y`, `this.z` from `node.x`, `node.y`, `node.z`.
544
+ * @param node node containing xyz.
506
545
  */
507
546
  setXYZFrom(node) {
508
547
  this.x = node.x;
@@ -510,7 +549,7 @@ class HalfEdge {
510
549
  this.z = node.z;
511
550
  }
512
551
  /**
513
- * Set (copy) the this.x, this.y, this.z from xyz.x, xyz.y, xyz.z
552
+ * Set `this.x`, `this.y`, `this.z` from `xyz.x`, `xyz.y`, `xyz.z`.
514
553
  * @param node source with x,y,z properties
515
554
  */
516
555
  setXYZ(xyz) {
@@ -519,32 +558,37 @@ class HalfEdge {
519
558
  this.z = xyz.z;
520
559
  }
521
560
  /**
522
- * Test if mask bits are set in the node's bitMask.
523
- * @return Return true (as a simple boolean, not a mask) if any bits of the mask parameter match bits of the node's bitMask
561
+ * Test if any of the `mask` bits are set in the node's bitMask.
562
+ * @return true (as a simple boolean, not a mask) if any bits of the `mask` match bits of the node's bitMask.
524
563
  */
525
- isMaskSet(mask) { return (this.maskBits & mask) !== 0; }
526
- /** (static!) method to test if a mask is set on a node.
527
- * This is used as filter in searches.
528
- * @returns true iff `node.isMaskSet (mask)`
564
+ isMaskSet(mask) {
565
+ return (this.maskBits & mask) !== 0;
566
+ }
567
+ /**
568
+ * Static method to test if any of the `mask` bits are set in the `node`'s bitMask.
569
+ * * This is used as filter in searches.
570
+ * @returns `node.isMaskSet(mask)`
529
571
  */
530
572
  static filterIsMaskOn(node, mask) {
531
573
  return node.isMaskSet(mask);
532
574
  }
533
- /** (static!) method to test if a mask is set on a node.
534
- * This is used as filter in searches.
535
- * @returns true iff `!node.isMaskSet (mask)`
575
+ /**
576
+ * Static method to test if any of the `mask` bits are set in the `node`'s bitMask.
577
+ * * This is used as filter in searches.
578
+ * @returns `!node.isMaskSet(mask)`
536
579
  */
537
580
  static filterIsMaskOff(node, mask) {
538
581
  return !node.isMaskSet(mask);
539
582
  }
540
583
  /**
541
584
  * Create an edge with initial id,x,y at each end.
542
- * @param id0 id for first node
543
- * @param x0 x coordinate for first node
544
- * @param y0 y coordinate for first node
545
- * @param id1 id for second node
546
- * @param x1 x coordinate for second node
547
- * @param y1 y coordinate for second node
585
+ * @param id0 id for first node.
586
+ * @param x0 x coordinate for first node.
587
+ * @param y0 y coordinate for first node.
588
+ * @param id1 id for second node.
589
+ * @param x1 x coordinate for second node.
590
+ * @param y1 y coordinate for second node.
591
+ * @returns the reference to the new node at (x0,y0).
548
592
  */
549
593
  static createEdgeXYXY(id0, x0, y0, id1, x1, y1) {
550
594
  const node0 = new HalfEdge(x0, y0);
@@ -555,15 +599,15 @@ class HalfEdge {
555
599
  node1._id = id1;
556
600
  return node0;
557
601
  }
558
- /** "pinch" ...
559
- *
560
- * * is the universal manipulator for manipulating a node's next and prev pointers
561
- * * swaps face predecessors of nodeA and nodeB.
562
- * * is its own inverse.
563
- * * if nodeA, nodeB are in different face loops, the loops join to one loop.
564
- * * if nodeA, nodeB are in the same face loop, the loop splits into two loops.
602
+ /**
603
+ *"Pinch" is the universal operator for manipulating a node's next and previous pointers.
604
+ * * It is its own inverse: applying it twice on the same inputs (i.e., `pinch(a,b); pinch(a,b);`) gets back to
605
+ * where you started.
606
+ * * If the inputs are in different face loops, the loops join to one face loop after the pinch.
607
+ * * If the inputs are in the same face loop, the loop splits into two face loops after the pinch.
565
608
  */
566
609
  static pinch(nodeA, nodeB) {
610
+ // Visualization can be found at geometry/internaldocs/Graph.md
567
611
  if (nodeA !== nodeB) {
568
612
  const predA = nodeA._facePredecessor;
569
613
  const predB = nodeB._facePredecessor;
@@ -575,17 +619,19 @@ class HalfEdge {
575
619
  }
576
620
  /**
577
621
  * Pinch this half edge out of its base vertex loop.
578
- * @return the surviving HalfEdge in the vertex loop, or undefined if the instance HalfEdge is already dangling
622
+ * @return the surviving HalfEdge in the vertex loop or `undefined` if the instance HalfEdge is already dangling.
579
623
  */
580
624
  yankFromVertexLoop() {
581
625
  const other = this.edgeMate.faceSuccessor;
582
626
  if (other === this)
583
627
  return undefined;
628
+ // at this point "other" is the vertex predecessor of "this"
584
629
  HalfEdge.pinch(this, other);
585
630
  return other;
586
631
  }
587
- /** Turn all pointers to undefined so garbage collector can reuse the object.
588
- * This is to be called only by a Graph object that is being decommissioned.
632
+ /**
633
+ * Turn all pointers to `undefined` so garbage collector can reuse the object.
634
+ * * This is to be called only by a Graph object that is being decommissioned.
589
635
  */
590
636
  decommission() {
591
637
  this._facePredecessor = undefined;
@@ -593,27 +639,34 @@ class HalfEdge {
593
639
  this._edgeMate = undefined;
594
640
  }
595
641
  /** Return the node. This identity function is useful as the NodeFunction in collector methods. */
596
- static nodeToSelf(node) { return node; }
597
- /** Return the id of a node. Useful for collector methods. */
598
- static nodeToId(node) { return node.id; }
599
- /** Return the id of a node.Useful for collector methods. */
600
- static nodeToIdString(node) { return node.id.toString(); }
601
- /** Return the [id, [x,y]] of a node. Useful for collector methods. */
642
+ static nodeToSelf(node) {
643
+ return node;
644
+ }
645
+ /** Return the id of a node. Useful for collector methods. */
646
+ static nodeToId(node) {
647
+ return node.id;
648
+ }
649
+ /** Return the id of a node as string. Useful for collector methods. */
650
+ static nodeToIdString(node) {
651
+ return node.id.toString();
652
+ }
653
+ /** Return the [id, mask, [x,y]] of a node. Useful for collector methods. */
602
654
  static nodeToIdMaskXY(node) {
603
655
  return { id: node.id, mask: HalfEdge.nodeToMaskString(node), xy: [node.x, node.y] };
604
656
  }
605
- /** Return the [id, [x,y]] of a node. Useful for collector methods. */
657
+ /** Return the [id, mask, [x,y]] of a node as string. Useful for collector methods. */
606
658
  static nodeToIdXYString(node) {
607
659
  const s = `${node.id.toString()}+${HalfEdge.nodeToMaskString(node)}[${node.x},${node.y}]`;
608
660
  return s;
609
661
  }
610
- /** Return the [id, [x,y],z] of a node. Useful for collector methods. */
662
+ /** Return the [id, [x,y,z]] of a node as string. Useful for collector methods. */
611
663
  static nodeToIdXYZString(node) {
612
664
  return `[${node.id.toString()}: ${node.x},${node.y},${node.z}]`;
613
665
  }
614
- /** Create a string representation of the mask
666
+ /**
667
+ * Create a string representation of the mask.
615
668
  * * Null mask is empty string.
616
- * * Appended characters B,P,X for Boundary, Primary, Exterior mask bits.
669
+ * * Appended characters B,P,X,N are for BOUNDARY_EDGE, PRIMARY_EDGE, EXTERIOR, and NULL_FACE mask bits.
617
670
  */
618
671
  static nodeToMaskString(node) {
619
672
  let s = "";
@@ -627,49 +680,46 @@ class HalfEdge {
627
680
  s += "N";
628
681
  return s;
629
682
  }
630
- /** Return [x,y] with coordinates of node */
631
- static nodeToXY(node) { return [node.x, node.y]; }
632
- /** Return Vector2d to face successor, with only xy coordinates */
683
+ /** Return [x,y] with coordinates of node. */
684
+ static nodeToXY(node) {
685
+ return [node.x, node.y];
686
+ }
687
+ /** Return Vector2d from `this` to face successor (with only xy coordinates). */
633
688
  vectorToFaceSuccessorXY(result) {
634
689
  return Point2dVector2d_1.Vector2d.create(this.faceSuccessor.x - this.x, this.faceSuccessor.y - this.y, result);
635
690
  }
636
- /** Return Vector3d to face successor */
691
+ /** Return Vector3d from `this` to face successor. */
637
692
  vectorToFaceSuccessor(result) {
638
693
  const other = this.faceSuccessor;
639
694
  return Point3dVector3d_1.Vector3d.create(other.x - this.x, other.y - this.y, other.z - this.z, result);
640
695
  }
641
- /** Return Vector3d to face successor */
696
+ /** Return Vector3d from `this` to face successor. */
642
697
  vectorToFacePredecessor(result) {
643
698
  const other = this.facePredecessor;
644
699
  return Point3dVector3d_1.Vector3d.create(other.x - this.x, other.y - this.y, other.z - this.z, result);
645
700
  }
646
- /** test if spaceNode is in the sector at sectorNode */
701
+ /** Test if `spaceNode` is in the sector at `sectorNode`. */
647
702
  static isNodeVisibleInSector(spaceNode, sectorNode) {
648
- // remark: fussy details ported from native code.
649
- // The obscure cases seemed "unlikely" at first. But preexisting unit tests for triangulation pinged just about everything.
650
- // So it really matters to do the "0" cases this way.
651
- // (As usual, hard coded zero is suspect, but it seems to work nicely in the discrete decisions.)
703
+ // remark: fussy details ported from native code. The obscure cases seemed "unlikely" at first. But pre-existing
704
+ // unit tests for triangulation pinged just about everything. So it really matters to do the "0" cases this way
705
+ // (as usual, hard coded zero is suspect, but it seems to work nicely in the discrete decisions).
652
706
  if (sectorNode.vertexSuccessor === sectorNode)
653
707
  return true;
654
708
  const successor = sectorNode.faceSuccessor;
655
709
  const predecessor = sectorNode.facePredecessor;
656
710
  const successorCross = this.crossProductXYToTargets(sectorNode, successor, spaceNode);
657
711
  const predecessorCross = this.crossProductXYToTargets(predecessor, sectorNode, spaceNode);
658
- // simplest case: two positives
712
+ // simplest case: two positives
659
713
  if (successorCross > 0.0 && predecessorCross > 0.0)
660
714
  return true;
661
715
  const sectorCross = this.crossProductXYToTargets(predecessor, sectorNode, successor);
662
716
  if (predecessorCross <= 0.0 && successorCross <= 0.0) {
663
717
  if (predecessorCross === 0.0 && successorCross === 0.0 && sectorCross === 0.0) {
664
- /* Everything is on a line.*/
665
- /* If the sector is a degenerate face, nodeP can only be
666
- in if it is the other node in the degenerate face.
667
- */
718
+ // Everything is on a line. If the sector is a degenerate face, nodeP
719
+ // can only be in if it is the other node in the degenerate face.
668
720
  if (predecessor === successor && sectorNode.vertexSuccessor !== sectorNode)
669
721
  return spaceNode === successor;
670
- /* Sector is 360 degrees. Call it in only if vector from predP
671
- to sectorP points forward to nodeP.
672
- */
722
+ // Sector is 360 degrees. Call it in only if vector from predP to sectorP points forward to nodeP.
673
723
  return HalfEdge.dotProductNodeToNodeVectorsXY(predecessor, sectorNode, sectorNode, spaceNode) > 0.0;
674
724
  }
675
725
  else {
@@ -678,56 +728,59 @@ class HalfEdge {
678
728
  }
679
729
  else {
680
730
  if (sectorCross === 0.0 && predecessorCross !== 0.0 && successorCross !== 0.0) {
681
- // The incoming and outgoing edges at the sector are identical direction.
682
- // We have to decide if this node is inside the degenerate face (i.e. a geometrically empty sector)
683
- // or outside (i.e. a nearly complete sector).
684
- // In the inside case, the face is just two nodes.
685
- // Exact equality for zero is ok because cross product should be using identical
686
- // coordinates in subtracted terms. (All furrow eyebrows in unison ....)
731
+ // The incoming and outgoing edges at the sector are identical direction. We have to decide if this node is
732
+ // inside the degenerate face (i.e. a geometrically empty sector) or outside (i.e. a nearly complete sector).
733
+ // In the inside case, the face is just two nodes. Exact equality for zero is ok because cross product should
734
+ // be using identical coordinates in subtracted terms (all furrow eyebrows in unison).
687
735
  return predecessor !== successor;
688
736
  }
689
737
  return sectorCross < 0.0;
690
738
  }
691
739
  }
692
- /** Returns Return cross product (2d) of vectors from baseA to targetA and baseB to targetB */
740
+ /** Returns 2D cross product of vectors from `base` to `targetA` and from `base` to `targetB`. */
693
741
  static crossProductXYToTargets(base, targetA, targetB) {
694
742
  return Geometry_1.Geometry.crossProductXYXY(targetA.x - base.x, targetA.y - base.y, targetB.x - base.x, targetB.y - base.y);
695
743
  }
696
- /** Returns Return dot product (2d) of vectors along two edges. */
744
+ /** Returns 2D dot product of vectors from `baseA` to `targetA` and from `baseB` to `targetB`. */
697
745
  static dotProductNodeToNodeVectorsXY(baseA, targetA, baseB, targetB) {
698
746
  return Geometry_1.Geometry.dotProductXYXY(targetA.x - baseA.x, targetA.y - baseA.y, targetB.x - baseB.x, targetB.y - baseB.y);
699
747
  }
700
- /** Return cross product (2d) of vectors from nodeA to nodeB and nodeB to nodeC
701
- */
748
+ /** Return 2D cross product of vectors from `nodeA` to `nodeB` and from `nodeB` to `nodeC`. */
702
749
  static crossProductXYAlongChain(nodeA, nodeB, nodeC) {
703
750
  return Geometry_1.Geometry.crossProductXYXY(nodeB.x - nodeA.x, nodeB.y - nodeA.y, nodeC.x - nodeB.x, nodeC.y - nodeB.y);
704
751
  }
705
752
  /**
706
753
  * Compute whether the sector defined by the chain of nodes is convex.
754
+ * * This function is determining if, in the traversal of the HalfEdges in a face loop, a corner makes a left turn
755
+ * (convex) or a right turn (not-convex). Note that if we have a convex face, then to traverse it in ccw orientation,
756
+ * we always do left turns. However, if the face is not convex, we make both left and right turns.
707
757
  * * This computation ignores z-coordinates and connectivity, so the nodes are not required to be in the same face loop.
708
- * @param nodeA the first node in the chain, nominally the face predecessor of nodeB
709
- * @param nodeB the second node in the chain; the node at the sector vertex
710
- * @param nodeC the third node in the chain, nominally the face successor of nodeB
711
- * @param signedAreaTol optional signed area tolerance to use in test for parallel vectors.
712
- * Typically this is a fraction of the sector's face's signed area. We can't compute area here, so if undefined, zero tolerance is used.
713
- * @returns true iff the sector is convex
758
+ * @param nodeA the first node in the chain, nominally the face predecessor of nodeB.
759
+ * @param nodeB the second node in the chain; the node at the sector vertex.
760
+ * @param nodeC the third node in the chain, nominally the face successor of nodeB.
761
+ * @param signedAreaTol optional signed area tolerance to use in test for parallel vectors. Typically this is a
762
+ * fraction of the sector's face's signed area. We can't compute area here, so if undefined, zero tolerance is used.
763
+ * @returns true iff the sector is convex. A degenerate sector, where the incident edges overlap, returns false.
714
764
  */
715
765
  static isSectorConvex(nodeA, nodeB, nodeC, signedAreaTol = 0) {
716
766
  const signedSectorArea = 0.5 * HalfEdge.crossProductXYAlongChain(nodeA, nodeB, nodeC);
717
767
  signedAreaTol = signedAreaTol ?? 0.0;
718
768
  if (Math.abs(signedSectorArea) <= Math.abs(signedAreaTol)) {
719
- // the sector vectors are nearly parallel or antiparallel; only the former is deemed convex.
769
+ // the sector vectors are nearly parallel or anti-parallel; only the former is deemed convex.
720
770
  return HalfEdge.dotProductNodeToNodeVectorsXY(nodeA, nodeB, nodeB, nodeC) > 0.0;
721
771
  }
722
- return signedSectorArea > -signedAreaTol; // call it convex even if we are a little bit on the other side of zero
772
+ // // sector is convex if the area is positive. Call it convex even if we are a little bit on the other side of zero.
773
+ return signedSectorArea > -signedAreaTol;
723
774
  }
724
775
  /**
725
776
  * Compute whether the sector at this node is convex.
777
+ * * This function is determining if, in the traversal of the HalfEdges in a face loop, a corner makes a left turn
778
+ * (convex) or a right turn (not-convex). Note that if we have a convex face, then to traverse it in ccw orientation,
779
+ * we always do left turns. However, if the face is not convex, we make both left and right turns.
726
780
  * * This computation ignores z-coordinates.
727
- * @param signedAreaTol optional signed area tolerance to use in test for parallel vectors.
728
- * If undefined, a fraction ([[Geometry.smallMetricDistanceSquared]]) of the computed signed area is used.
729
- * Pass zero to skip toleranced computation.
730
- * @returns true iff the sector is convex and its two edges are not antiparallel.
781
+ * @param signedAreaTol optional signed area tolerance to use in test for parallel vectors. If undefined, a fraction
782
+ * (`Geometry.smallMetricDistanceSquared`) of the computed signed area is used. Pass 0 to skip toleranced computation.
783
+ * @returns true iff the sector is convex. A degenerate sector, where the incident edges overlap, returns false.
731
784
  */
732
785
  isSectorConvex(signedAreaTol) {
733
786
  if (signedAreaTol === undefined)
@@ -736,10 +789,11 @@ class HalfEdge {
736
789
  }
737
790
  /**
738
791
  * Compute whether this face is convex.
792
+ * * Note that if we have a convex face, then to traverse it in ccw orientation, we always do left turns.
793
+ * However, if the face is not convex, we make both left and right turns.
739
794
  * * This computation ignores z-coordinates.
740
- * @param tolerance optional relative tolerance to use in test for parallel vectors.
741
- * Default value is [[Geometry.smallMetricDistanceSquared]].
742
- * Pass zero to skip toleranced computation.
795
+ * @param tolerance optional relative tolerance to use in test for parallel vectors. Default value is
796
+ * `Geometry.smallMetricDistanceSquared`. Pass 0 to skip toleranced computation.
743
797
  * @returns true iff this face is convex.
744
798
  */
745
799
  isFaceConvex(tolerance = Geometry_1.Geometry.smallMetricDistanceSquared) {
@@ -752,83 +806,80 @@ class HalfEdge {
752
806
  } while (node !== this);
753
807
  return true;
754
808
  }
755
- /**
756
- * Isolate the edge from the graph by yanking each end from its vertex loop.
757
- */
809
+ /** Isolate the edge from the graph by yanking each end from its vertex loop. */
758
810
  isolateEdge() {
759
811
  const mate = this.edgeMate;
760
812
  this.yankFromVertexLoop();
761
813
  mate.yankFromVertexLoop();
762
814
  }
763
- /**
764
- * @return whether this edge is isolated from the rest of the graph.
765
- */
815
+ /** Specify whether this edge is isolated from the rest of the graph. */
766
816
  get isIsolatedEdge() {
767
817
  return this === this.vertexSuccessor && this.edgeMate === this.edgeMate.vertexSuccessor;
768
818
  }
769
- /** Return true if `this` is lexically below `other`, comparing y first then x. */
819
+ /** Return true if `this` is lexically below `other`. We compare y first, then x, and ignore z. */
770
820
  belowYX(other) {
771
- // Check y's
772
- // if (!Geometry.isSameCoordinate(a.y, b.y))
773
821
  if (this.y < other.y)
774
822
  return true;
775
823
  if (this.y > other.y)
776
824
  return false;
777
- // same y.
778
- // Check x's
779
825
  if (this.x < other.x)
780
826
  return true;
781
827
  return false;
782
828
  }
783
- /** Returns Returns true if the node does NOT have Mask.EXTERIOR_MASK set. */
784
- static testNodeMaskNotExterior(node) { return !node.isMaskSet(HalfEdgeMask.EXTERIOR); }
785
- /** Returns Returns true if the edge mate has Mask.EXTERIOR_MASK set. */
786
- static testMateMaskExterior(node) { return node.edgeMate.isMaskSet(HalfEdgeMask.EXTERIOR); }
787
- /** Returns radians between this edge and its face predecessor edge, using all three coordinates x,y,z and given normal to resolve sweep direction.
788
- * * The returned angle is positive, i.e. may be larger than PI radians.
789
- */
829
+ /** Returns `true` if the node does NOT have `Mask.EXTERIOR_MASK` set. */
830
+ static testNodeMaskNotExterior(node) {
831
+ return !node.isMaskSet(HalfEdgeMask.EXTERIOR);
832
+ }
833
+ /** Returns `true` if the edge mate has `Mask.EXTERIOR_MASK` set. */
834
+ static testMateMaskExterior(node) {
835
+ return node.edgeMate.isMaskSet(HalfEdgeMask.EXTERIOR);
836
+ }
837
+ /**
838
+ * Returns radians between this edge and its face predecessor edge, using all three coordinates x,y,z and
839
+ * given normal to resolve sweep direction.
840
+ * * The returned angle is non-negative: 0 <= radians < 2*PI.
841
+ */
790
842
  static sectorSweepRadiansXYZ(node, normal) {
791
- const nodeB = node.faceSuccessor;
792
- const nodeC = node.facePredecessor;
793
- return Angle_1.Angle.orientedRadiansBetweenVectorsXYZ(nodeB.x - node.x, nodeB.y - node.y, nodeB.z - node.z, nodeC.x - node.x, nodeC.y - node.y, nodeC.z - node.z, normal.x, normal.y, normal.z, true);
843
+ const suc = node.faceSuccessor;
844
+ const pred = node.facePredecessor;
845
+ return Angle_1.Angle.orientedRadiansBetweenVectorsXYZ(suc.x - node.x, suc.y - node.y, suc.z - node.z, pred.x - node.x, pred.y - node.y, pred.z - node.z, normal.x, normal.y, normal.z, true);
794
846
  }
795
- /** Returns Returns true if the face has positive area in xy parts. */
847
+ /** Returns true if the face has positive area in xy parts. */
796
848
  static testFacePositiveAreaXY(node) {
797
849
  return node.countEdgesAroundFace() > 2 && node.signedFaceArea() > 0.0;
798
850
  }
799
- /** Return true if x and y coordinates of this and other are exactly equal */
851
+ /** Return true if x and y coordinates of `this` and `other` are exactly equal .*/
800
852
  isEqualXY(other) {
801
853
  return this.x === other.x && this.y === other.y;
802
854
  }
803
- /** Return distance between xy coordinates of this and other node */
855
+ /** Return distance between xy coordinates of `this` and `other` node. */
804
856
  distanceXY(other) {
805
857
  return Geometry_1.Geometry.distanceXYXY(this.x, this.y, other.x, other.y);
806
858
  }
807
- /** Return distance between xyz coordinates of this and other node */
859
+ /** Return distance between xyz coordinates of `this` and `other` node. */
808
860
  distanceXYZ(other) {
809
861
  return Geometry_1.Geometry.distanceXYZXYZ(this.x, this.y, this.z, other.x, other.y, other.z);
810
862
  }
811
863
  /**
812
- *
813
- * * Evaluate f(node) at each node around a face loop.
814
- * * Collect the function values.
815
- * @returns Return the array of function values.
864
+ * Evaluate `f(node)` at each node around `this` node's face loop. Collect the function values.
865
+ * @param f optional node function. If `undefined`, collect the nodes themselves.
866
+ * @returns the array of function values.
816
867
  */
817
868
  collectAroundFace(f) {
818
869
  const nodes = [];
819
870
  let node = this;
820
871
  do {
821
- nodes.push(f ? f(node) : node);
872
+ nodes.push(f ? f(node) : node); // push the node itself if "f" is undefined
822
873
  node = node.faceSuccessor;
823
874
  } while (node !== this);
824
875
  return nodes;
825
876
  }
826
877
  /**
827
- * search around a vertex for nodes that have a specified mask setting.
828
- * @param vertexSeed first node to search
829
- * @param mask target mask
830
- * @param value target value for mask on half edges.
831
- * @param collectedNodes optional array to be cleared and receive masked nodes
878
+ * Search around `this` node's vertex loop for nodes with the specified mask value.
879
+ * * Returned nodes satisfy `node.isMaskSet(mask) === value`.
880
+ * @param mask target mask.
881
+ * @param value target boolean value for mask on half edges.
882
+ * @param result optional array to be cleared and receive masked nodes.
832
883
  */
833
884
  collectMaskedEdgesAroundVertex(mask, value = true, result) {
834
885
  if (result === undefined)
@@ -844,25 +895,23 @@ class HalfEdge {
844
895
  return result;
845
896
  }
846
897
  /**
847
- *
848
- * * Evaluate f(node) at each outbound node around this node's vertex loop.
849
- * * Collect the function values.
850
- * @returns Return the array of function values.
898
+ * Evaluate `f(node)` at each node around `this` node's vertex loop. Collect the function values.
899
+ * @param f optional node function. If `undefined`, collect the nodes themselves.
900
+ * @returns the array of function values.
851
901
  */
852
902
  collectAroundVertex(f) {
853
903
  const nodes = [];
854
904
  let node = this;
855
905
  do {
856
- nodes.push(f ? f(node) : node);
906
+ nodes.push(f ? f(node) : node); // push the node itself if "f" is undefined
857
907
  node = node.vertexSuccessor;
858
908
  } while (node !== this);
859
909
  return nodes;
860
910
  }
861
911
  /**
862
- *
863
- * * Evaluate f(node) at each node around a face loop.
864
- * * Sum the function values
865
- * @returns Return the sum
912
+ * Evaluate `f(node)` at each node around `this` node's face loop. Sum the function values.
913
+ * @param f node to number function.
914
+ * @returns the sum of function values.
866
915
  */
867
916
  sumAroundFace(f) {
868
917
  let node = this;
@@ -874,10 +923,9 @@ class HalfEdge {
874
923
  return sum;
875
924
  }
876
925
  /**
877
- *
878
- * * Evaluate f(node) at each outbound node around this node's vertex loop.
879
- * * Sum the function values
880
- * @returns Return the sum
926
+ * Evaluate `f(node)` at each node around `this` node's vertex loop. Sum the function values.
927
+ * @param f node to number function.
928
+ * @returns the sum of function values.
881
929
  */
882
930
  sumAroundVertex(f) {
883
931
  let node = this;
@@ -888,7 +936,7 @@ class HalfEdge {
888
936
  } while (node !== this);
889
937
  return sum;
890
938
  }
891
- /** For all the nodes in the face loop of the given node, clear out the mask given */
939
+ /** Clear the given mask bits for all nodes in `this` node's face loop. */
892
940
  clearMaskAroundFace(mask) {
893
941
  let node = this;
894
942
  do {
@@ -896,7 +944,7 @@ class HalfEdge {
896
944
  node = node.faceSuccessor;
897
945
  } while (node !== this);
898
946
  }
899
- /** For all the nodes in the vertex loop of the given node, clear out the mask given */
947
+ /** Clear out the given mask bits for all nodes in `this` node's vertex loop. */
900
948
  clearMaskAroundVertex(mask) {
901
949
  let node = this;
902
950
  do {
@@ -905,29 +953,39 @@ class HalfEdge {
905
953
  } while (node !== this);
906
954
  }
907
955
  /**
908
- * Compute the signed sum of xy areas of triangles from first node to edges.
956
+ * Compute the signed xy area of `this` node's face.
909
957
  * * A positive area is counterclockwise.
910
958
  * * A negative area is clockwise.
911
- * @returns signed area of this node's face
959
+ * @returns signed area of `this` node's face.
912
960
  */
913
961
  signedFaceArea() {
914
962
  let sum = 0;
915
- // sum area of trapezoids.
916
- // * the formula in the loop gives twice the area (because it does not average the y values).
917
- // * this is fixed up at the end by a single multiply by 0.5
918
- // * individual trapezoid heights are measured from y at the start node to keep area values numerical smaller.
963
+ // We start from `this` node and traverse the face, forming trapezoids with vertical bases.
964
+ // Some trapezoids will have a zero-length base, e.g., a triangle.
965
+ // Trapezoid bases are measured from `this.y` to keep area values numerically smaller.
966
+ // Split each trapezoid into two triangles whose y-coordinates are above/below `this.y`.
967
+ // Each trapezoid's signed area is computed by summing the signed areas of these two triangles.
968
+ // Area signs depend on careful assignment of signs to trapezoid height (relative to `this.x`) and trapezoid
969
+ // bases (relative to `this.y`).
970
+ // Some trapezoids have signed areas outside the face that are cancelled out by subsequent trapezoids.
971
+ // The formula in the loop accumulates twice the trapezoid areas, so at the end we halve the sum.
972
+ // Illustration of the algorithm can be found at geometry/internaldocs/Graph.md
973
+ let x0 = this.x;
974
+ let x1 = 0.0;
919
975
  const y0 = this.y;
920
976
  let dy0 = 0.0;
921
977
  let dy1 = 0.0;
922
- let x0 = this.x;
923
- let x1;
924
978
  let node1;
925
979
  let node0 = this;
926
980
  do {
927
981
  node1 = node0.faceSuccessor;
928
982
  x1 = node1.x;
929
983
  dy1 = node1.y - y0;
930
- sum += (x0 - x1) * (dy0 + dy1);
984
+ // When trapezoid bases dy0 and dy1 have opposite sign, this product is (twice) the difference of the areas
985
+ // of the trapezoid above and below y=y0. This is equal to (twice) the difference of the areas of the congruent
986
+ // triangles formed by the trapezoid diagonals and bases, a consequence of the other two triangles having equal
987
+ // area, and thus cancelling out.
988
+ sum += (x0 - x1) * (dy0 + dy1); // twice trapezoid area = trapezoid height * sum of trapezoid bases
931
989
  x0 = x1;
932
990
  dy0 = dy1;
933
991
  node0 = node1;
@@ -935,108 +993,105 @@ class HalfEdge {
935
993
  return 0.5 * sum;
936
994
  }
937
995
  /**
938
- * interpolate xy coordinates between this node and its face successor.
996
+ * Interpolate xy coordinates between `this` node and its face successor.
939
997
  * @param fraction fractional position along this edge.
940
- * @param result xy coordinates
998
+ * @param result optional point to populate and return.
941
999
  */
942
1000
  fractionToPoint2d(fraction, result) {
943
- const node1 = this.faceSuccessor;
944
- return Point2dVector2d_1.Point2d.create(this.x + (node1.x - this.x) * fraction, this.y + (node1.y - this.y) * fraction, result);
1001
+ const suc = this.faceSuccessor;
1002
+ return Point2dVector2d_1.Point2d.create(this.x + (suc.x - this.x) * fraction, this.y + (suc.y - this.y) * fraction, result);
945
1003
  }
946
1004
  /**
947
- * interpolate xy coordinates between this node and its face successor.
1005
+ * Interpolate xyz coordinates between `this` node and its face successor.
948
1006
  * @param fraction fractional position along this edge.
949
- * @param result xy coordinates
1007
+ * @param result optional point to populate and return.
950
1008
  */
951
1009
  fractionToPoint3d(fraction, result) {
952
- const node1 = this.faceSuccessor;
953
- return Point3dVector3d_1.Point3d.create(this.x + (node1.x - this.x) * fraction, this.y + (node1.y - this.y) * fraction, this.z + (node1.z - this.z) * fraction, result);
1010
+ const suc = this.faceSuccessor;
1011
+ return Point3dVector3d_1.Point3d.create(this.x + (suc.x - this.x) * fraction, this.y + (suc.y - this.y) * fraction, this.z + (suc.z - this.z) * fraction, result);
954
1012
  }
955
1013
  /**
956
- * * interpolate xy coordinates at fractionAlong between this node and its face successor.
957
- * * shift to left by fractionPerpendicular
958
- * @param fraction fractional position along this edge.
959
- * @param result xy coordinates
1014
+ * Interpolate xy coordinates at `fractionAlong` between this node and its face successor. Then shift perpendicular
1015
+ * to the left of this edge by `fractionPerpendicular`.
1016
+ * @param fractionAlong fractional position along this edge.
1017
+ * @param fractionPerpendicular fractional position along the left perpendicular with the same length as this edge.
1018
+ * @param result optional xy coordinates.
960
1019
  */
961
1020
  fractionAlongAndPerpendicularToPoint2d(fractionAlong, fractionPerpendicular, result) {
962
- const node1 = this.faceSuccessor;
963
- const dx = node1.x - this.x;
964
- const dy = node1.y - this.y;
1021
+ const suc = this.faceSuccessor;
1022
+ const dx = suc.x - this.x;
1023
+ const dy = suc.y - this.y;
965
1024
  return Point2dVector2d_1.Point2d.create(this.x + dx * fractionAlong - dy * fractionPerpendicular, this.y + dy * fractionAlong + dx * fractionPerpendicular, result);
966
1025
  }
967
- /**
968
- * return the 3d coordinates at this half edge base
969
- */
1026
+ /** Return the 3d coordinates at this half edge. */
970
1027
  getPoint3d(result) {
971
1028
  return Point3dVector3d_1.Point3d.create(this.x, this.y, this.z, result);
972
1029
  }
973
- /**
974
- * return the 2d coordinates at this half edge base
975
- */
1030
+ /** Return the 2d coordinates at this half edge. */
976
1031
  getPoint2d(result) {
977
1032
  return Point2dVector2d_1.Point2d.create(this.x, this.y, result);
978
1033
  }
979
- /**
980
- * return a 3d vector from start to end of this half edge.
981
- */
1034
+ /** Return a 3d vector from start to end of this half edge. */
982
1035
  getVector3dAlongEdge(result) {
983
- const nodeB = this.faceSuccessor;
984
- return Point3dVector3d_1.Vector3d.create(nodeB.x - this.x, nodeB.y - this.y, nodeB.z - this.z, result);
1036
+ const suc = this.faceSuccessor;
1037
+ return Point3dVector3d_1.Vector3d.create(suc.x - this.x, suc.y - this.y, suc.z - this.z, result);
985
1038
  }
986
- /**
987
- * return a 2d vector from start to end of this half edge
988
- */
1039
+ /** Return a 2d vector from start to end of this half edge. */
989
1040
  getVector2dAlongEdge(result) {
990
- const nodeB = this.faceSuccessor;
991
- return Point2dVector2d_1.Vector2d.create(nodeB.x - this.x, nodeB.y - this.y, result);
1041
+ const suc = this.faceSuccessor;
1042
+ return Point2dVector2d_1.Vector2d.create(suc.x - this.x, suc.y - this.y, result);
992
1043
  }
993
1044
  /**
994
- * Return the interpolated x coordinate between this node and its face successor.
1045
+ * Return the interpolated x coordinate between `this` node and its face successor.
995
1046
  * @param fraction fractional position along this edge.
996
1047
  */
997
1048
  fractionToX(fraction) {
998
- const node1 = this.faceSuccessor;
999
- return this.x + (node1.x - this.x) * fraction;
1049
+ const suc = this.faceSuccessor;
1050
+ return this.x + (suc.x - this.x) * fraction;
1000
1051
  }
1001
1052
  /**
1002
- * Return the interpolated y coordinate between this node and its face successor.
1053
+ * Return the interpolated y coordinate between `this` node and its face successor.
1003
1054
  * @param fraction fractional position along this edge.
1004
1055
  */
1005
1056
  fractionToY(fraction) {
1006
- const node1 = this.faceSuccessor;
1007
- return this.y + (node1.y - this.y) * fraction;
1057
+ const suc = this.faceSuccessor;
1058
+ return this.y + (suc.y - this.y) * fraction;
1008
1059
  }
1009
1060
  /**
1010
- * Return the interpolated z coordinate between this node and its face successor.
1061
+ * Return the interpolated z coordinate between `this` node and its face successor.
1011
1062
  * @param fraction fractional position along this edge.
1012
1063
  */
1013
1064
  fractionToZ(fraction) {
1014
- const node1 = this.faceSuccessor;
1015
- return this.z + (node1.z - this.z) * fraction;
1065
+ const suc = this.faceSuccessor;
1066
+ return this.z + (suc.z - this.z) * fraction;
1016
1067
  }
1017
1068
  /**
1018
- * * Compute fractional coordinates of the intersection of edges from given base nodes
1069
+ * Compute fractional coordinates of the intersection of edges from given base nodes.
1019
1070
  * * If parallel or colinear, return undefined.
1020
1071
  * * If (possibly extended) lines intersect, return the fractions of intersection as x,y in the result.
1021
- * @param nodeA0 Base node of edge A
1022
- * @param nodeB0 Base node of edge B
1023
- * @param result optional preallocated result
1072
+ * @param nodeA0 base node of edge A.
1073
+ * @param nodeB0 base node of edge B.
1074
+ * @param result optional preallocated result.
1024
1075
  */
1025
1076
  static transverseIntersectionFractions(nodeA0, nodeB0, result) {
1026
1077
  const nodeA1 = nodeA0.faceSuccessor;
1027
1078
  const nodeB1 = nodeB0.faceSuccessor;
1028
1079
  if (!result)
1029
1080
  result = Point2dVector2d_1.Vector2d.create();
1081
+ // To find the fraction of intersection (ta,tb), you need to solve these 2 equations:
1082
+ // (nodeA1.x - nodeA0.x)ta + (nodeB0.x - nodeB1.x)tb = nodeB0.x - nodeA0.x
1083
+ // (nodeA1.y - nodeA0.y)ta + (nodeB0.y - nodeB1.y)tb = nodeB0.y - nodeA0.y
1084
+ // Proof can be found at geometry/internaldocs/Graph.md
1030
1085
  if (Polynomials_1.SmallSystem.linearSystem2d(nodeA1.x - nodeA0.x, nodeB0.x - nodeB1.x, nodeA1.y - nodeA0.y, nodeB0.y - nodeB1.y, nodeB0.x - nodeA0.x, nodeB0.y - nodeA0.y, result))
1031
1086
  return result;
1032
1087
  return undefined;
1033
1088
  }
1034
1089
  /**
1035
- * * Compute fractional coordinates of the intersection of a horizontal line with an edge.
1090
+ * Compute fractional position (possibly outside 0..1) of the intersection of a horizontal line with an edge.
1036
1091
  * * If the edge is horizontal with (approximate) identical y, return the node.
1037
- * * If the edge is horizontal with different y, return undefined.
1038
- * * If the edge is not horizontal, return the fractional position (possibly outside 0..1) of the intersection.
1039
- * @param node0 Base node of edge
1092
+ * * If the edge is horizontal with different y, return `undefined`.
1093
+ * @param node0 base node of edge.
1094
+ * @param y y coordinate of the horizontal line.
1040
1095
  */
1041
1096
  static horizontalScanFraction(node0, y) {
1042
1097
  const node1 = node0.faceSuccessor;
@@ -1045,13 +1100,16 @@ class HalfEdge {
1045
1100
  return node0;
1046
1101
  if (Geometry_1.Geometry.isSameCoordinate(dy, 0.0))
1047
1102
  return undefined;
1103
+ // parametric equation of line is (1-t)y0 + ty1 which is equal to y at the intersection so
1104
+ // (1-t)y0 + ty1 = y or t = (y-y0)/(y1-y0)
1048
1105
  return Geometry_1.Geometry.conditionalDivideFraction(y - node0.y, dy);
1049
1106
  }
1050
1107
  /**
1051
- * * Compute fractional coordinates of the intersection of a horizontal line with an edge.
1052
- * * If the edge is horizontal return undefined (no test for horizontal at y!!!)
1053
- * * If the edge is not horizontal and y is between its end y's, return the fraction
1054
- * @param node0 Base node of edge
1108
+ * Compute fractional position (inside 0..1) of the intersection of a horizontal line with an edge.
1109
+ * * If fractional position is outside 0..1, return `undefined`.
1110
+ * * If the edge is horizontal return `undefined` (no test for horizontal at y).
1111
+ * @param node0 base node of edge.
1112
+ * @param y y coordinate of the horizontal line.
1055
1113
  */
1056
1114
  static horizontalScanFraction01(node0, y) {
1057
1115
  const node1 = node0.faceSuccessor;
@@ -1066,12 +1124,12 @@ class HalfEdge {
1066
1124
  return undefined;
1067
1125
  }
1068
1126
  /**
1069
- * Copy various data from source to this.
1070
- * @param source other half edge.
1071
- * @param XYZ copy simple coordinates
1072
- * @param copyVertexData true to copy data belonging to the vertex. (i.e. the "i" member)
1073
- * @param copyVertexData true to copy data belonging to the edge. (i.e. call transferEdgeData)
1074
- * @param copyFaceData true to copy faceTag
1127
+ * Copy various data from source to `this`.
1128
+ * @param source source half edge.
1129
+ * @param copyXYZ true to copy xyz coordinates.
1130
+ * @param copyVertexData true to copy data belonging to the vertex (i.e. the `i` member).
1131
+ * @param copyEdgeData true to copy data belonging to the edge (i.e. edge masks, `edgeTag`).
1132
+ * @param copyFaceData true to copy `faceTag`.
1075
1133
  */
1076
1134
  copyDataFrom(source, copyXYZ, copyVertexData, copyEdgeData, copyFaceData) {
1077
1135
  if (copyXYZ) {
@@ -1091,13 +1149,16 @@ class HalfEdge {
1091
1149
  }
1092
1150
  }
1093
1151
  }
1094
- HalfEdge._edgePropertyMasks = [HalfEdgeMask.BOUNDARY_EDGE, HalfEdgeMask.EXTERIOR, HalfEdgeMask.PRIMARY_EDGE, HalfEdgeMask.NULL_FACE];
1095
1152
  HalfEdge._totalNodesCreated = 0;
1153
+ /** Edge property masks. */
1154
+ HalfEdge._edgePropertyMasks = [
1155
+ HalfEdgeMask.BOUNDARY_EDGE, HalfEdgeMask.EXTERIOR, HalfEdgeMask.PRIMARY_EDGE, HalfEdgeMask.NULL_FACE,
1156
+ ];
1096
1157
  exports.HalfEdge = HalfEdge;
1097
1158
  /**
1098
1159
  * A HalfEdgeGraph has:
1099
- * * An array of (pointers to ) HalfEdge objects.
1100
- * * A pool of masks for grab/drop use by algorithms.
1160
+ * * An array of (pointers to) HalfEdge objects.
1161
+ * * A pool of masks for grab/drop used by algorithms.
1101
1162
  * @internal
1102
1163
  */
1103
1164
  class HalfEdgeGraph {
@@ -1106,7 +1167,8 @@ class HalfEdgeGraph {
1106
1167
  this.allHalfEdges = [];
1107
1168
  this._maskManager = MaskManager_1.MaskManager.create(HalfEdgeMask.ALL_GRAB_DROP_MASKS);
1108
1169
  }
1109
- /** Ask for a mask (from the graph's free pool.) for caller's use.
1170
+ /**
1171
+ * Ask for a mask (from the graph's free pool) for caller's use.
1110
1172
  * * Optionally clear the mask throughout the graph.
1111
1173
  */
1112
1174
  grabMask(clearInAllHalfEdges = true) {
@@ -1116,49 +1178,49 @@ class HalfEdgeGraph {
1116
1178
  }
1117
1179
  return mask;
1118
1180
  }
1181
+ /** Return `mask` to the free pool. */
1182
+ dropMask(mask) {
1183
+ this._maskManager.dropMask(mask);
1184
+ }
1119
1185
  /**
1120
- * Return `mask` to the free pool.
1121
- */
1122
- dropMask(mask) { this._maskManager.dropMask(mask); }
1123
- /**
1124
- * * Create 2 half edges forming 2 vertices, 1 edge, and 1 face
1125
- * * The two edges are joined as edgeMate pair.
1126
- * * The two edges are a 2-half-edge face loop in both the faceSuccessor and facePredecessor directions.
1127
- * * The two edges are added to the graph's HalfEdge set
1128
- * @returns Return pointer to the first half edge created.
1186
+ * Create 2 half edges forming 2 vertices, 1 edge, and 1 face.
1187
+ * * The two half edges are joined as edgeMate pair.
1188
+ * * The two half edges are a 2-half-edge face loop in both the faceSuccessor and facePredecessor directions.
1189
+ * * The two half edges are added to the graph's HalfEdge set.
1190
+ * @returns pointer to the first half edge created.
1129
1191
  */
1130
1192
  createEdgeXYZXYZ(xA = 0, yA = 0, zA = 0, iA = 0, xB = 0, yB = 0, zB = 0, iB = 0) {
1131
- const a = HalfEdge.createHalfEdgePairWithCoordinates(xA, yA, zA, iA, xB, yB, zB, iB, this.allHalfEdges);
1132
- return a;
1193
+ return HalfEdge.createHalfEdgePairWithCoordinates(xA, yA, zA, iA, xB, yB, zB, iB, this.allHalfEdges);
1133
1194
  }
1134
1195
  /**
1135
- * * Create 2 half edges forming 2 vertices, 1 edge, and 1 face
1136
- * * The two edges are joined as edgeMate pair.
1137
- * * The two edges are a 2-half-edge face loop in both the faceSuccessor and facePredecessor directions.
1138
- * * The two edges are added to the graph's HalfEdge set
1196
+ * Create 2 half edges forming 2 vertices, 1 edge, and 1 face.
1197
+ * * The two half edges are joined as edgeMate pair.
1198
+ * * The two half edges are a 2-half-edge face loop in both the faceSuccessor and facePredecessor directions.
1199
+ * * The two half edges are added to the graph's HalfEdge set.
1139
1200
  * * Coordinates are set to zero.
1140
- * * ids are installed in the two half edges.
1141
- * @returns Return pointer to the first half edge created. (This has idA as its id.)
1201
+ * * IDs are installed in the two half edges.
1202
+ * @returns pointer to the first half edge created, with ID set to iA.
1142
1203
  */
1143
1204
  createEdgeIdId(iA = 0, iB = 0) {
1144
- const a = HalfEdge.createHalfEdgePairWithCoordinates(0.0, 0.0, 0.0, iA, 0.0, 0.0, 0.0, iB, this.allHalfEdges);
1145
- return a;
1205
+ return HalfEdge.createHalfEdgePairWithCoordinates(0.0, 0.0, 0.0, iA, 0.0, 0.0, 0.0, iB, this.allHalfEdges);
1146
1206
  }
1147
1207
  /**
1148
- * * create an edge from coordinates x,y,z to (the tail of) an existing half edge.
1149
- * @returns Return pointer to the half edge with tail at x,y,z
1208
+ * Create an edge from coordinates x,y,z connected to the graph at the vertex of the given `node`.
1209
+ * @returns pointer to the dangling node at x,y,z.
1150
1210
  */
1151
1211
  createEdgeXYZHalfEdge(xA = 0, yA = 0, zA = 0, iA = 0, node, iB = 0) {
1212
+ // Visualization can be found at geometry/internaldocs/Graph.md
1152
1213
  const a = HalfEdge.createHalfEdgePairWithCoordinates(xA, yA, zA, iA, node.x, node.y, node.z, iB, this.allHalfEdges);
1153
1214
  const b = a.faceSuccessor;
1154
1215
  HalfEdge.pinch(node, b);
1155
1216
  return a;
1156
1217
  }
1157
1218
  /**
1158
- * * create an edge from coordinates x,y,z to (the tail of) an existing half edge.
1159
- * @returns Return pointer to the half edge with tail at x,y,z
1219
+ * Create an edge from the vertex of `nodeA` to the vertex of `nodeB`.
1220
+ * @returns pointer to the new half edge at the vertex of `nodeA`.
1160
1221
  */
1161
1222
  createEdgeHalfEdgeHalfEdge(nodeA, idA, nodeB, idB = 0) {
1223
+ // Visualization can be found at geometry/internaldocs/Graph.md
1162
1224
  const a = HalfEdge.createHalfEdgePairWithCoordinates(nodeA.x, nodeA.y, nodeA.z, idA, nodeB.x, nodeB.y, nodeB.z, idB, this.allHalfEdges);
1163
1225
  const b = a.faceSuccessor;
1164
1226
  HalfEdge.pinch(nodeA, a);
@@ -1166,56 +1228,56 @@ class HalfEdgeGraph {
1166
1228
  return a;
1167
1229
  }
1168
1230
  /**
1169
- * * Create 2 half edges forming 2 vertices, 1 edge, and 1 face
1170
- * * The two edges are joined as edgeMate pair.
1171
- * * The two edges are a 2-half-edge face loop in both the faceSuccessor and facePredecessor directions.
1172
- * * The two edges are added to the graph's HalfEdge set
1173
- * @returns Return pointer to the first half edge created.
1231
+ * Create 2 half edges forming 2 vertices, 1 edge, and 1 face
1232
+ * * The two half edges are joined as edgeMate pair.
1233
+ * * The two half edges are a 2-half-edge face loop in both the faceSuccessor and facePredecessor directions.
1234
+ * * The two half edges are added to the graph's HalfEdge set.
1235
+ * @returns pointer to the first half edge created, with coordinates `xyz0`.
1174
1236
  */
1175
1237
  createEdgeXYAndZ(xyz0, id0, xyz1, id1) {
1176
- const a = HalfEdge.createHalfEdgePairWithCoordinates(xyz0.x, xyz0.y, xyz0.z, id0, xyz1.x, xyz1.y, xyz1.z, id1, this.allHalfEdges);
1177
- return a;
1238
+ return HalfEdge.createHalfEdgePairWithCoordinates(xyz0.x, xyz0.y, xyz0.z, id0, xyz1.x, xyz1.y, xyz1.z, id1, this.allHalfEdges);
1178
1239
  }
1179
1240
  /**
1180
- * * Insert a vertex in the edge beginning at base.
1181
- * * this creates two half edges.
1182
- * * The base of the new edge is 'after' the (possibly undefined) start node in its face loop.
1183
- * * The existing mate retains its base xyz and i properties but is no longer the mate of base.
1184
- * * The base and existing mate each become mates with a new half edge.
1185
- * @returns Returns the reference to the half edge created.
1241
+ * Create a new vertex within the edge beginning at `base`.
1242
+ * * This creates two new nodes in their own vertex loop.
1243
+ * * If the base is undefined, create a single-edge loop.
1244
+ * * Existing nodes stay in their face and vertex loops and retain xyz and i values.
1245
+ * * Unlike [[pinch]], this breaks the edgeMate pairing of the input edge:
1246
+ * each node of the input edge gets a new node as its edge mate.
1247
+ * * On each side of the edge, if edgeTag is present, it is copied to the new node on that side.
1248
+ * @returns reference to the half edge created, the new face successor of `base`.
1186
1249
  */
1187
1250
  splitEdge(base, xA = 0, yA = 0, zA = 0, iA = 0) {
1188
- const he = HalfEdge.splitEdge(base, xA, yA, zA, iA, this.allHalfEdges);
1189
- return he;
1251
+ return HalfEdge.splitEdge(base, xA, yA, zA, iA, this.allHalfEdges);
1190
1252
  }
1191
1253
  /**
1192
- * * Create a sliver face "within" an edge.
1193
- * * this creates two half edges.
1194
- * * The existing edges both stay in their same face loops and retain coordinates and i value.
1195
- * * Each existing edge's mate is a new edge (rather than original mate)
1196
- * * Coordinates are copied to the new edges at respective vertices.
1197
- * * New faceTag and edgeTag undefined.
1198
- * * i members are copied around their respective vertices.
1199
- * @returns Returns the reference to the half edge created.
1254
+ * Create a new sliver face "inside" an existing edge.
1255
+ * * This creates two nodes that are each face predecessor and successor to the other.
1256
+ * * Existing nodes stay in their face and vertex loops and retain xyz and i values.
1257
+ * * Unlike [[pinch]], this breaks the edgeMate pairing of the input edge:
1258
+ * each node of the input edge gets a new node as its edge mate.
1259
+ * * New nodes get the xyz and i values shared by the nodes in the vertex loops into which they are placed.
1260
+ * * New nodes' faceTag and edgeTag are `undefined`.
1261
+ * @returns reference to the half edge created in the vertex loop of baseA.
1200
1262
  */
1201
1263
  splitEdgeCreateSliverFace(base) {
1202
- const he = HalfEdge.splitEdgeCreateSliverFace(base, this.allHalfEdges);
1203
- return he;
1264
+ return HalfEdge.splitEdgeCreateSliverFace(base, this.allHalfEdges);
1204
1265
  }
1205
1266
  /**
1206
- * * Insert a vertex in the edge beginning at base, with coordinates specified as a fraction along the existing edge.
1207
- * * this creates two half edges.
1208
- * * The base of the new edge is 'after' the (possibly undefined) start node in its face loop.
1209
- * * The existing mate retains its base xyz and i properties but is no longer the mate of base.
1210
- * * The base and existing mate each become mates with a new half edge.
1211
- * @returns Returns the reference to the half edge created.
1267
+ * Create a new vertex within the edge beginning at `base`, with coordinates specified by a fraction along the edge.
1268
+ * * This creates two new nodes in their own vertex loop.
1269
+ * * Existing nodes stay in their face and vertex loops and retain xyz and i values.
1270
+ * * Unlike [[pinch]], this breaks the edgeMate pairing of the input edge:
1271
+ * each node of the input edge gets a new node as its edge mate.
1272
+ * * On each side of the edge, if edgeTag is present, it is copied to the new node on that side.
1273
+ * @returns reference to the half edge created, the new face successor of `base`.
1212
1274
  */
1213
1275
  splitEdgeAtFraction(base, fraction) {
1214
- const he = HalfEdge.splitEdge(base, base.fractionToX(fraction), base.fractionToY(fraction), base.fractionToZ(fraction), 0, this.allHalfEdges);
1215
- return he;
1276
+ return HalfEdge.splitEdge(base, base.fractionToX(fraction), base.fractionToY(fraction), base.fractionToZ(fraction), 0, this.allHalfEdges);
1216
1277
  }
1217
- /** This is a destructor-like action that eliminates all interconnection among the graph's nodes.
1218
- * After this is called the graph is unusable.
1278
+ /**
1279
+ * This is a destructor-like action that eliminates all inter-connections among the graph's nodes.
1280
+ * After this is called, the graph is unusable.
1219
1281
  */
1220
1282
  decommission() {
1221
1283
  for (const node of this.allHalfEdges) {
@@ -1224,8 +1286,9 @@ class HalfEdgeGraph {
1224
1286
  this.allHalfEdges.length = 0;
1225
1287
  this.allHalfEdges = undefined;
1226
1288
  }
1227
- /** create two nodes of a new edge.
1228
- * @returns Return one of the two nodes, which the caller may consider as the start of the edge.
1289
+ /**
1290
+ * Create two nodes of a new edge.
1291
+ * @returns the reference to the new node at (x0,y0).
1229
1292
  */
1230
1293
  addEdgeXY(x0, y0, x1, y1) {
1231
1294
  const baseNode = HalfEdge.createEdgeXYXY(this._numNodesCreated, x0, y0, this._numNodesCreated + 1, x1, y1);
@@ -1234,17 +1297,17 @@ class HalfEdgeGraph {
1234
1297
  this.allHalfEdges.push(baseNode.faceSuccessor);
1235
1298
  return baseNode;
1236
1299
  }
1237
- /** Clear selected bits in all nodes of the graph. */
1300
+ /** Clear selected `mask` bits in all nodes of the graph. */
1238
1301
  clearMask(mask) {
1239
1302
  for (const node of this.allHalfEdges)
1240
1303
  node.maskBits &= ~mask;
1241
1304
  }
1242
- /** Set selected bits in all nodes of the graph. */
1305
+ /** Set selected `mask` bits in all nodes of the graph. */
1243
1306
  setMask(mask) {
1244
1307
  for (const node of this.allHalfEdges)
1245
1308
  node.maskBits |= mask;
1246
1309
  }
1247
- /** toggle selected bits in all nodes of the graph. */
1310
+ /** Toggle selected `mask` bits in all nodes of the graph. */
1248
1311
  reverseMask(mask) {
1249
1312
  for (const node of this.allHalfEdges) {
1250
1313
  node.maskBits ^= mask;
@@ -1261,10 +1324,11 @@ class HalfEdgeGraph {
1261
1324
  n++;
1262
1325
  return n;
1263
1326
  }
1264
- /** Return an array LineSegment3d.
1265
- * * The array has one segment per edge
1327
+ /**
1328
+ * Return an array of LineSegment3d.
1329
+ * * The array has one segment per edge.
1266
1330
  * * The coordinates are taken from a node and its face successor.
1267
- * * On each edge, the line segment start at the HalfEdge with lower id than its edgeMate.
1331
+ * * On each edge, the line segment starts at the HalfEdge with lower ID than its edgeMate.
1268
1332
  */
1269
1333
  collectSegments() {
1270
1334
  const segments = [];
@@ -1274,24 +1338,27 @@ class HalfEdgeGraph {
1274
1338
  }
1275
1339
  return segments;
1276
1340
  }
1277
- /** Returns the number of vertex loops in a graph structure */
1341
+ /** Returns the number of vertex loops in a graph structure. */
1278
1342
  countVertexLoops() {
1279
1343
  this.clearMask(HalfEdgeMask.VISITED);
1280
1344
  let count = 0;
1281
- this.announceVertexLoops((_graph, _seed) => { count++; return true; });
1345
+ this.announceVertexLoops((_graph, _seed) => {
1346
+ count++;
1347
+ return true;
1348
+ });
1282
1349
  return count;
1283
1350
  }
1284
- /** Returns the number of face loops */
1351
+ /** Returns the number of face loops in a graph structure. */
1285
1352
  countFaceLoops() {
1286
1353
  this.clearMask(HalfEdgeMask.VISITED);
1287
1354
  let count = 0;
1288
- this.announceFaceLoops((_graph, _seed) => { count++; return true; });
1355
+ this.announceFaceLoops((_graph, _seed) => {
1356
+ count++;
1357
+ return true;
1358
+ });
1289
1359
  return count;
1290
1360
  }
1291
- /**
1292
- * Returns the number of face loops satisfying a filter function with mask argument.
1293
- *
1294
- */
1361
+ /** Returns the number of face loops satisfying a filter function with mask argument. */
1295
1362
  countFaceLoopsWithMaskFilter(filter, mask) {
1296
1363
  this.clearMask(HalfEdgeMask.VISITED);
1297
1364
  let count = 0;
@@ -1302,32 +1369,47 @@ class HalfEdgeGraph {
1302
1369
  });
1303
1370
  return count;
1304
1371
  }
1305
- /** Returns an array of nodes, where each node represents a starting point of a face loop.
1306
- */
1372
+ /** Returns an array of nodes, where each node represents a starting point of a vertex loop. */
1373
+ collectVertexLoops() {
1374
+ const returnArray = [];
1375
+ this.announceVertexLoops((_graph, node) => {
1376
+ returnArray.push(node);
1377
+ return true;
1378
+ });
1379
+ return returnArray;
1380
+ }
1381
+ /** Returns an array of nodes, where each node represents a starting point of a face loop. */
1307
1382
  collectFaceLoops() {
1308
1383
  const returnArray = [];
1309
- this.announceFaceLoops((_graph, node) => { returnArray.push(node); return true; });
1384
+ this.announceFaceLoops((_graph, node) => {
1385
+ returnArray.push(node);
1386
+ return true;
1387
+ });
1310
1388
  return returnArray;
1311
1389
  }
1312
- /** Returns an array of nodes, where each node represents a starting point of a vertex loop.
1390
+ /**
1391
+ * Visit each vertex loop of the graph once.
1392
+ * * Call the `announceVertex` function.
1393
+ * * Continue search if `announceVertex(graph, node)` returns `true`.
1394
+ * * Terminate search if `announceVertex(graph, node)` returns `false`.
1395
+ * @param announceVertex function to apply at one node of each vertex.
1313
1396
  */
1314
- collectVertexLoops() {
1397
+ announceVertexLoops(announceVertex) {
1315
1398
  this.clearMask(HalfEdgeMask.VISITED);
1316
- const returnArray = [];
1317
1399
  for (const node of this.allHalfEdges) {
1318
1400
  if (node.getMask(HalfEdgeMask.VISITED))
1319
1401
  continue;
1320
- returnArray.push(node);
1321
1402
  node.setMaskAroundVertex(HalfEdgeMask.VISITED);
1403
+ if (!announceVertex(this, node))
1404
+ break;
1322
1405
  }
1323
- return returnArray;
1324
1406
  }
1325
1407
  /**
1326
- * * Visit each facet of the graph once.
1327
- * * Call the announceFace function
1328
- * * continue search if announceFace(graph, node) returns true
1329
- * * terminate search if announce face (graph, node) returns false
1330
- * @param announceFace function to apply at one node of each face.
1408
+ * Visit each facet of the graph once.
1409
+ * * Call the `announceFace` function.
1410
+ * * Continue search if `announceFace(graph, node)` returns `true`.
1411
+ * * Terminate search if `announceFace(graph, node)` returns `false`.
1412
+ * @param announceFace function to apply at one node of each face.
1331
1413
  */
1332
1414
  announceFaceLoops(announceFace) {
1333
1415
  this.clearMask(HalfEdgeMask.VISITED);
@@ -1340,13 +1422,13 @@ class HalfEdgeGraph {
1340
1422
  }
1341
1423
  }
1342
1424
  /**
1343
- * * Visit each edge of the graph once.
1344
- * * Call the announceEdge function.
1345
- * * the edge mate will NOT appear in an announceEdge call.
1346
- * * continue search if announceEdge(graph, node) returns true
1347
- * * terminate search if announceEdge (graph, node) returns false
1348
- * @param announceEdge function to apply at one node of each edge.
1349
- */
1425
+ * Visit each edge of the graph once.
1426
+ * * Call the `announceEdge` function.
1427
+ * * The edge mate will NOT appear in an announceEdge call.
1428
+ * * Continue search if `announceEdge(graph, node)` returns `true`.
1429
+ * * Terminate search if `announceEdge(graph, node)` returns `false`.
1430
+ * @param announceEdge function to apply at one node of each edge.
1431
+ */
1350
1432
  announceEdges(announceEdge) {
1351
1433
  this.clearMask(HalfEdgeMask.VISITED);
1352
1434
  for (const node of this.allHalfEdges) {
@@ -1360,28 +1442,11 @@ class HalfEdgeGraph {
1360
1442
  }
1361
1443
  }
1362
1444
  /**
1363
- * * Visit each vertex loop of the graph once.
1364
- * * Call the announceVertex function
1365
- * * continue search if announceVertex(graph, node) returns true
1366
- * * terminate search if announce vertex (graph, node) returns false
1367
- * @param announceVertex function to apply at one node of each face.
1368
- */
1369
- announceVertexLoops(announceVertex) {
1370
- this.clearMask(HalfEdgeMask.VISITED);
1371
- for (const node of this.allHalfEdges) {
1372
- if (node.getMask(HalfEdgeMask.VISITED))
1373
- continue;
1374
- node.setMaskAroundVertex(HalfEdgeMask.VISITED);
1375
- if (!announceVertex(this, node))
1376
- break;
1377
- }
1378
- }
1379
- /**
1380
- * * Visit each half edge (node) of the graph once.
1381
- * * Call the announceNode function
1382
- * * continue search if announceNode(graph, node) returns true
1383
- * * terminate search if announce face (graph, node) returns false
1384
- * @param announceNode function to apply at one node of each face.
1445
+ * Visit each half edge (node) of the graph once.
1446
+ * * Call the `announceNode` function.
1447
+ * * Continue search if `announceNode(graph, node)` returns `true`.
1448
+ * * Terminate search if `announceFace(graph, node)` returns `false`.
1449
+ * @param announceNode function to apply at each node.
1385
1450
  */
1386
1451
  announceNodes(announceNode) {
1387
1452
  for (const node of this.allHalfEdges) {
@@ -1389,8 +1454,10 @@ class HalfEdgeGraph {
1389
1454
  break;
1390
1455
  }
1391
1456
  }
1392
- /** Return the number of nodes in the graph */
1393
- countNodes() { return this.allHalfEdges.length; }
1457
+ /** Return the number of nodes in the graph. */
1458
+ countNodes() {
1459
+ return this.allHalfEdges.length;
1460
+ }
1394
1461
  /** Apply transform to the xyz coordinates in the graph. */
1395
1462
  transformInPlace(transform) {
1396
1463
  for (const node of this.allHalfEdges) {
@@ -1398,8 +1465,8 @@ class HalfEdgeGraph {
1398
1465
  }
1399
1466
  }
1400
1467
  /**
1401
- * disconnect and delete all nodes that satisfy a filter condition.
1402
- * @param deleteThisNode returns true to delete the corresponding edge. Should act symmetrically on the edgeMate.
1468
+ * Disconnect and delete all nodes that satisfy a filter condition.
1469
+ * @param deleteThisNode returns true to delete the corresponding node. Should act symmetrically on the edgeMate.
1403
1470
  * @returns the number of nodes deleted (twice the number of deleted edges).
1404
1471
  */
1405
1472
  yankAndDeleteEdges(deleteThisNode) {
@@ -1408,9 +1475,9 @@ class HalfEdgeGraph {
1408
1475
  for (let i = 0; i < numTotal; i++) {
1409
1476
  const candidate = this.allHalfEdges[i];
1410
1477
  if (!deleteThisNode(candidate))
1411
- this.allHalfEdges[numAccepted++] = candidate;
1478
+ this.allHalfEdges[numAccepted++] = candidate; // overwrite a previously "deleted node"
1412
1479
  else
1413
- candidate.yankFromVertexLoop(); // ASSUME callback symmetry so we eventually yank the mate!
1480
+ candidate.yankFromVertexLoop(); // assume callback symmetry so we eventually yank the mate
1414
1481
  }
1415
1482
  const numDeleted = numTotal - numAccepted;
1416
1483
  this.allHalfEdges.length = numAccepted;