@itwin/core-geometry 4.4.0-dev.1 → 4.4.0-dev.10

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 (446) hide show
  1. package/CHANGELOG.md +30 -1
  2. package/lib/cjs/Constant.js.map +1 -1
  3. package/lib/cjs/Geometry.js.map +1 -1
  4. package/lib/cjs/bspline/AkimaCurve3d.js.map +1 -1
  5. package/lib/cjs/bspline/BSpline1dNd.js.map +1 -1
  6. package/lib/cjs/bspline/BSplineCurve.js.map +1 -1
  7. package/lib/cjs/bspline/BSplineCurve3dH.js.map +1 -1
  8. package/lib/cjs/bspline/BSplineCurveOps.js.map +1 -1
  9. package/lib/cjs/bspline/BSplineSurface.js.map +1 -1
  10. package/lib/cjs/bspline/Bezier1dNd.js.map +1 -1
  11. package/lib/cjs/bspline/BezierCurve3d.js.map +1 -1
  12. package/lib/cjs/bspline/BezierCurve3dH.js.map +1 -1
  13. package/lib/cjs/bspline/BezierCurveBase.js.map +1 -1
  14. package/lib/cjs/bspline/InterpolationCurve3d.js.map +1 -1
  15. package/lib/cjs/bspline/KnotVector.js.map +1 -1
  16. package/lib/cjs/bspline/SurfaceLocationDetail.js.map +1 -1
  17. package/lib/cjs/clipping/AlternatingConvexClipTree.js.map +1 -1
  18. package/lib/cjs/clipping/BooleanClipFactory.js.map +1 -1
  19. package/lib/cjs/clipping/BooleanClipNode.js.map +1 -1
  20. package/lib/cjs/clipping/ClipPlane.js.map +1 -1
  21. package/lib/cjs/clipping/ClipPrimitive.js.map +1 -1
  22. package/lib/cjs/clipping/ClipUtils.js.map +1 -1
  23. package/lib/cjs/clipping/ClipVector.js.map +1 -1
  24. package/lib/cjs/clipping/ConvexClipPlaneSet.js.map +1 -1
  25. package/lib/cjs/clipping/UnionOfConvexClipPlaneSets.js.map +1 -1
  26. package/lib/cjs/clipping/internalContexts/LineStringOffsetClipperContext.js.map +1 -1
  27. package/lib/cjs/core-geometry.js.map +1 -1
  28. package/lib/cjs/curve/Arc3d.js.map +1 -1
  29. package/lib/cjs/curve/ConstructCurveBetweenCurves.js.map +1 -1
  30. package/lib/cjs/curve/CoordinateXYZ.js.map +1 -1
  31. package/lib/cjs/curve/CurveChainWithDistanceIndex.js.map +1 -1
  32. package/lib/cjs/curve/CurveCollection.js.map +1 -1
  33. package/lib/cjs/curve/CurveCurve.js.map +1 -1
  34. package/lib/cjs/curve/CurveExtendMode.js.map +1 -1
  35. package/lib/cjs/curve/CurveFactory.js.map +1 -1
  36. package/lib/cjs/curve/CurveLocationDetail.js.map +1 -1
  37. package/lib/cjs/curve/CurveOps.js.map +1 -1
  38. package/lib/cjs/curve/CurvePrimitive.js.map +1 -1
  39. package/lib/cjs/curve/CurveProcessor.js.map +1 -1
  40. package/lib/cjs/curve/CurveTypes.js.map +1 -1
  41. package/lib/cjs/curve/CurveWireMomentsXYZ.js.map +1 -1
  42. package/lib/cjs/curve/GeometryQuery.js.map +1 -1
  43. package/lib/cjs/curve/LineSegment3d.js.map +1 -1
  44. package/lib/cjs/curve/LineString3d.js.map +1 -1
  45. package/lib/cjs/curve/Loop.js.map +1 -1
  46. package/lib/cjs/curve/OffsetOptions.js.map +1 -1
  47. package/lib/cjs/curve/ParityRegion.js.map +1 -1
  48. package/lib/cjs/curve/Path.js.map +1 -1
  49. package/lib/cjs/curve/PointString3d.js.map +1 -1
  50. package/lib/cjs/curve/ProxyCurve.js.map +1 -1
  51. package/lib/cjs/curve/Query/ConsolidateAdjacentPrimitivesContext.js.map +1 -1
  52. package/lib/cjs/curve/Query/CurveSplitContext.js.map +1 -1
  53. package/lib/cjs/curve/Query/CylindricalRange.js.map +1 -1
  54. package/lib/cjs/curve/Query/InOutTests.js.map +1 -1
  55. package/lib/cjs/curve/Query/PlanarSubdivision.js.map +1 -1
  56. package/lib/cjs/curve/Query/StrokeCountChain.js.map +1 -1
  57. package/lib/cjs/curve/Query/StrokeCountMap.js.map +1 -1
  58. package/lib/cjs/curve/RegionMomentsXY.js.map +1 -1
  59. package/lib/cjs/curve/RegionOps.js.map +1 -1
  60. package/lib/cjs/curve/RegionOpsClassificationSweeps.js.map +1 -1
  61. package/lib/cjs/curve/StrokeOptions.js.map +1 -1
  62. package/lib/cjs/curve/UnionRegion.js.map +1 -1
  63. package/lib/cjs/curve/internalContexts/AppendPlaneIntersectionStrokeHandler.js.map +1 -1
  64. package/lib/cjs/curve/internalContexts/ChainCollectorContext.js.map +1 -1
  65. package/lib/cjs/curve/internalContexts/CloneCurvesContext.js.map +1 -1
  66. package/lib/cjs/curve/internalContexts/CloneWithExpandedLineStrings.js.map +1 -1
  67. package/lib/cjs/curve/internalContexts/ClosestPointStrokeHandler.js.map +1 -1
  68. package/lib/cjs/curve/internalContexts/CountLinearPartsSearchContext.js.map +1 -1
  69. package/lib/cjs/curve/internalContexts/CurveCurveCloseApproachXY.js.map +1 -1
  70. package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -1
  71. package/lib/cjs/curve/internalContexts/CurveCurveIntersectXYZ.js.map +1 -1
  72. package/lib/cjs/curve/internalContexts/CurveLengthContext.js.map +1 -1
  73. package/lib/cjs/curve/internalContexts/CurveOffsetXYHandler.js.map +1 -1
  74. package/lib/cjs/curve/internalContexts/GapSearchContext.js.map +1 -1
  75. package/lib/cjs/curve/internalContexts/MultiChainCollector.js.map +1 -1
  76. package/lib/cjs/curve/internalContexts/NewtonRtoRStrokeHandler.js.map +1 -1
  77. package/lib/cjs/curve/internalContexts/PlaneAltitudeRangeContext.js.map +1 -1
  78. package/lib/cjs/curve/internalContexts/PolygonOffsetContext.js.map +1 -1
  79. package/lib/cjs/curve/internalContexts/SumLengthsContext.js.map +1 -1
  80. package/lib/cjs/curve/internalContexts/TransformInPlaceContext.js.map +1 -1
  81. package/lib/cjs/curve/spiral/AustralianRailCorpXYEvaluator.js.map +1 -1
  82. package/lib/cjs/curve/spiral/ClothoidSeries.js.map +1 -1
  83. package/lib/cjs/curve/spiral/CubicEvaluator.js.map +1 -1
  84. package/lib/cjs/curve/spiral/CzechSpiralEvaluator.js.map +1 -1
  85. package/lib/cjs/curve/spiral/DirectHalfCosineSpiralEvaluator.js.map +1 -1
  86. package/lib/cjs/curve/spiral/DirectSpiral3d.js.map +1 -1
  87. package/lib/cjs/curve/spiral/IntegratedSpiral3d.js.map +1 -1
  88. package/lib/cjs/curve/spiral/MXCubicAlongArcSpiralEvaluator.js.map +1 -1
  89. package/lib/cjs/curve/spiral/NormalizedTransition.js.map +1 -1
  90. package/lib/cjs/curve/spiral/PolishCubicSpiralEvaluator.js.map +1 -1
  91. package/lib/cjs/curve/spiral/TransitionConditionalProperties.js.map +1 -1
  92. package/lib/cjs/curve/spiral/TransitionSpiral3d.js.map +1 -1
  93. package/lib/cjs/curve/spiral/XYCurveEvaluator.js.map +1 -1
  94. package/lib/cjs/geometry3d/Angle.js.map +1 -1
  95. package/lib/cjs/geometry3d/AngleSweep.js.map +1 -1
  96. package/lib/cjs/geometry3d/BarycentricTriangle.js.map +1 -1
  97. package/lib/cjs/geometry3d/BilinearPatch.js.map +1 -1
  98. package/lib/cjs/geometry3d/CoincidentGeometryOps.js.map +1 -1
  99. package/lib/cjs/geometry3d/Ellipsoid.js.map +1 -1
  100. package/lib/cjs/geometry3d/FrameBuilder.js.map +1 -1
  101. package/lib/cjs/geometry3d/FrustumAnimation.js.map +1 -1
  102. package/lib/cjs/geometry3d/GeometryHandler.js.map +1 -1
  103. package/lib/cjs/geometry3d/GrowableBlockedArray.js.map +1 -1
  104. package/lib/cjs/geometry3d/GrowableFloat64Array.js.map +1 -1
  105. package/lib/cjs/geometry3d/GrowableXYArray.js.map +1 -1
  106. package/lib/cjs/geometry3d/GrowableXYZArray.js.map +1 -1
  107. package/lib/cjs/geometry3d/IndexedCollectionInterval.js.map +1 -1
  108. package/lib/cjs/geometry3d/IndexedXYCollection.js.map +1 -1
  109. package/lib/cjs/geometry3d/IndexedXYZCollection.js.map +1 -1
  110. package/lib/cjs/geometry3d/LongitudeLatitudeAltitude.js.map +1 -1
  111. package/lib/cjs/geometry3d/Matrix3d.js.map +1 -1
  112. package/lib/cjs/geometry3d/OrderedRotationAngles.js.map +1 -1
  113. package/lib/cjs/geometry3d/Plane3d.js.map +1 -1
  114. package/lib/cjs/geometry3d/Plane3dByOriginAndUnitNormal.js.map +1 -1
  115. package/lib/cjs/geometry3d/Plane3dByOriginAndVectors.js.map +1 -1
  116. package/lib/cjs/geometry3d/Point2dArrayCarrier.js.map +1 -1
  117. package/lib/cjs/geometry3d/Point2dVector2d.js.map +1 -1
  118. package/lib/cjs/geometry3d/Point3dArrayCarrier.js.map +1 -1
  119. package/lib/cjs/geometry3d/Point3dVector3d.js.map +1 -1
  120. package/lib/cjs/geometry3d/PointHelpers.js.map +1 -1
  121. package/lib/cjs/geometry3d/PointStreaming.js.map +1 -1
  122. package/lib/cjs/geometry3d/PolygonOps.js.map +1 -1
  123. package/lib/cjs/geometry3d/PolylineCompressionByEdgeOffset.js.map +1 -1
  124. package/lib/cjs/geometry3d/PolylineOps.js.map +1 -1
  125. package/lib/cjs/geometry3d/Range.js.map +1 -1
  126. package/lib/cjs/geometry3d/Ray2d.js.map +1 -1
  127. package/lib/cjs/geometry3d/Ray3d.js.map +1 -1
  128. package/lib/cjs/geometry3d/ReusableObjectCache.js.map +1 -1
  129. package/lib/cjs/geometry3d/Segment1d.js.map +1 -1
  130. package/lib/cjs/geometry3d/SortablePolygon.js.map +1 -1
  131. package/lib/cjs/geometry3d/Transform.js.map +1 -1
  132. package/lib/cjs/geometry3d/UVSurfaceOps.js.map +1 -1
  133. package/lib/cjs/geometry3d/XYZProps.js.map +1 -1
  134. package/lib/cjs/geometry3d/YawPitchRollAngles.js.map +1 -1
  135. package/lib/cjs/geometry4d/Map4d.js.map +1 -1
  136. package/lib/cjs/geometry4d/Matrix4d.js.map +1 -1
  137. package/lib/cjs/geometry4d/MomentData.js.map +1 -1
  138. package/lib/cjs/geometry4d/PlaneByOriginAndVectors4d.js.map +1 -1
  139. package/lib/cjs/geometry4d/Point4d.js.map +1 -1
  140. package/lib/cjs/numerics/BandedSystem.js.map +1 -1
  141. package/lib/cjs/numerics/BezierPolynomials.js.map +1 -1
  142. package/lib/cjs/numerics/ClusterableArray.js.map +1 -1
  143. package/lib/cjs/numerics/Complex.js.map +1 -1
  144. package/lib/cjs/numerics/ConvexPolygon2d.js.map +1 -1
  145. package/lib/cjs/numerics/Newton.js.map +1 -1
  146. package/lib/cjs/numerics/PascalCoefficients.js.map +1 -1
  147. package/lib/cjs/numerics/PolarData.js.map +1 -1
  148. package/lib/cjs/numerics/Polynomials.js.map +1 -1
  149. package/lib/cjs/numerics/Quadrature.js.map +1 -1
  150. package/lib/cjs/numerics/Range1dArray.js.map +1 -1
  151. package/lib/cjs/numerics/TriDiagonalSystem.js.map +1 -1
  152. package/lib/cjs/numerics/UnionFind.js.map +1 -1
  153. package/lib/cjs/numerics/UsageSums.js.map +1 -1
  154. package/lib/cjs/polyface/AuxData.js.map +1 -1
  155. package/lib/cjs/polyface/BoxTopology.js.map +1 -1
  156. package/lib/cjs/polyface/FacetFaceData.js.map +1 -1
  157. package/lib/cjs/polyface/FacetLocationDetail.js.map +1 -1
  158. package/lib/cjs/polyface/FacetOrientation.js.map +1 -1
  159. package/lib/cjs/polyface/GreedyTriangulationBetweenLineStrings.js.map +1 -1
  160. package/lib/cjs/polyface/IndexedEdgeMatcher.js.map +1 -1
  161. package/lib/cjs/polyface/IndexedPolyfaceVisitor.js.map +1 -1
  162. package/lib/cjs/polyface/Polyface.js.map +1 -1
  163. package/lib/cjs/polyface/PolyfaceBuilder.js.map +1 -1
  164. package/lib/cjs/polyface/PolyfaceClip.js.map +1 -1
  165. package/lib/cjs/polyface/PolyfaceData.js.map +1 -1
  166. package/lib/cjs/polyface/PolyfaceQuery.js.map +1 -1
  167. package/lib/cjs/polyface/RangeLengthData.js.map +1 -1
  168. package/lib/cjs/polyface/TaggedNumericData.js.map +1 -1
  169. package/lib/cjs/polyface/TriangleCandidate.js.map +1 -1
  170. package/lib/cjs/polyface/multiclip/BuildAverageNormalsContext.js.map +1 -1
  171. package/lib/cjs/polyface/multiclip/GriddedRaggedRange2dSet.js.map +1 -1
  172. package/lib/cjs/polyface/multiclip/GriddedRaggedRange2dSetWithOverflow.js.map +1 -1
  173. package/lib/cjs/polyface/multiclip/LinearSearchRange2dArray.js.map +1 -1
  174. package/lib/cjs/polyface/multiclip/OffsetMeshContext.js.map +1 -1
  175. package/lib/cjs/polyface/multiclip/Range2dSearchInterface.js.map +1 -1
  176. package/lib/cjs/polyface/multiclip/RangeSearch.js.map +1 -1
  177. package/lib/cjs/polyface/multiclip/SweepLineStringToFacetContext.js.map +1 -1
  178. package/lib/cjs/polyface/multiclip/XYPointBuckets.js.map +1 -1
  179. package/lib/cjs/serialization/BGFBAccessors.js.map +1 -1
  180. package/lib/cjs/serialization/BGFBReader.js.map +1 -1
  181. package/lib/cjs/serialization/BGFBWriter.js.map +1 -1
  182. package/lib/cjs/serialization/BentleyGeometryFlatBuffer.js.map +1 -1
  183. package/lib/cjs/serialization/DeepCompare.js.map +1 -1
  184. package/lib/cjs/serialization/GeometrySamples.js.map +1 -1
  185. package/lib/cjs/serialization/IModelJsonSchema.js.map +1 -1
  186. package/lib/cjs/serialization/SerializationHelpers.js.map +1 -1
  187. package/lib/cjs/solid/Box.js.map +1 -1
  188. package/lib/cjs/solid/Cone.js.map +1 -1
  189. package/lib/cjs/solid/LinearSweep.js.map +1 -1
  190. package/lib/cjs/solid/RotationalSweep.js.map +1 -1
  191. package/lib/cjs/solid/RuledSweep.js.map +1 -1
  192. package/lib/cjs/solid/SolidPrimitive.js.map +1 -1
  193. package/lib/cjs/solid/Sphere.js.map +1 -1
  194. package/lib/cjs/solid/SweepContour.js.map +1 -1
  195. package/lib/cjs/solid/TorusPipe.js.map +1 -1
  196. package/lib/cjs/topology/ChainMerge.js.map +1 -1
  197. package/lib/cjs/topology/Graph.d.ts +19 -9
  198. package/lib/cjs/topology/Graph.d.ts.map +1 -1
  199. package/lib/cjs/topology/Graph.js +19 -9
  200. package/lib/cjs/topology/Graph.js.map +1 -1
  201. package/lib/cjs/topology/HalfEdgeGraphFromIndexedLoopsContext.js.map +1 -1
  202. package/lib/cjs/topology/HalfEdgeGraphSearch.js.map +1 -1
  203. package/lib/cjs/topology/HalfEdgeGraphSpineContext.js.map +1 -1
  204. package/lib/cjs/topology/HalfEdgeGraphValidation.d.ts +23 -18
  205. package/lib/cjs/topology/HalfEdgeGraphValidation.d.ts.map +1 -1
  206. package/lib/cjs/topology/HalfEdgeGraphValidation.js +23 -18
  207. package/lib/cjs/topology/HalfEdgeGraphValidation.js.map +1 -1
  208. package/lib/cjs/topology/HalfEdgeMarkSet.js.map +1 -1
  209. package/lib/cjs/topology/HalfEdgeNodeXYZUV.d.ts +17 -10
  210. package/lib/cjs/topology/HalfEdgeNodeXYZUV.d.ts.map +1 -1
  211. package/lib/cjs/topology/HalfEdgeNodeXYZUV.js +38 -17
  212. package/lib/cjs/topology/HalfEdgeNodeXYZUV.js.map +1 -1
  213. package/lib/cjs/topology/HalfEdgePointInGraphSearch.js.map +1 -1
  214. package/lib/cjs/topology/HalfEdgePositionDetail.js.map +1 -1
  215. package/lib/cjs/topology/HalfEdgePriorityQueue.js.map +1 -1
  216. package/lib/cjs/topology/InsertAndRetriangulateContext.js.map +1 -1
  217. package/lib/cjs/topology/MaskManager.js.map +1 -1
  218. package/lib/cjs/topology/Merging.js.map +1 -1
  219. package/lib/cjs/topology/RegularizeFace.js.map +1 -1
  220. package/lib/cjs/topology/SignedDataSummary.js.map +1 -1
  221. package/lib/cjs/topology/SpaceTriangulation.js.map +1 -1
  222. package/lib/cjs/topology/Triangulation.js.map +1 -1
  223. package/lib/cjs/topology/XYParitySearchContext.js.map +1 -1
  224. package/lib/esm/Constant.js.map +1 -1
  225. package/lib/esm/Geometry.js.map +1 -1
  226. package/lib/esm/bspline/AkimaCurve3d.js.map +1 -1
  227. package/lib/esm/bspline/BSpline1dNd.js.map +1 -1
  228. package/lib/esm/bspline/BSplineCurve.js.map +1 -1
  229. package/lib/esm/bspline/BSplineCurve3dH.js.map +1 -1
  230. package/lib/esm/bspline/BSplineCurveOps.js.map +1 -1
  231. package/lib/esm/bspline/BSplineSurface.js.map +1 -1
  232. package/lib/esm/bspline/Bezier1dNd.js.map +1 -1
  233. package/lib/esm/bspline/BezierCurve3d.js.map +1 -1
  234. package/lib/esm/bspline/BezierCurve3dH.js.map +1 -1
  235. package/lib/esm/bspline/BezierCurveBase.js.map +1 -1
  236. package/lib/esm/bspline/InterpolationCurve3d.js.map +1 -1
  237. package/lib/esm/bspline/KnotVector.js.map +1 -1
  238. package/lib/esm/bspline/SurfaceLocationDetail.js.map +1 -1
  239. package/lib/esm/clipping/AlternatingConvexClipTree.js.map +1 -1
  240. package/lib/esm/clipping/BooleanClipFactory.js.map +1 -1
  241. package/lib/esm/clipping/BooleanClipNode.js.map +1 -1
  242. package/lib/esm/clipping/ClipPlane.js.map +1 -1
  243. package/lib/esm/clipping/ClipPrimitive.js.map +1 -1
  244. package/lib/esm/clipping/ClipUtils.js.map +1 -1
  245. package/lib/esm/clipping/ClipVector.js.map +1 -1
  246. package/lib/esm/clipping/ConvexClipPlaneSet.js.map +1 -1
  247. package/lib/esm/clipping/UnionOfConvexClipPlaneSets.js.map +1 -1
  248. package/lib/esm/clipping/internalContexts/LineStringOffsetClipperContext.js.map +1 -1
  249. package/lib/esm/core-geometry.js.map +1 -1
  250. package/lib/esm/curve/Arc3d.js.map +1 -1
  251. package/lib/esm/curve/ConstructCurveBetweenCurves.js.map +1 -1
  252. package/lib/esm/curve/CoordinateXYZ.js.map +1 -1
  253. package/lib/esm/curve/CurveChainWithDistanceIndex.js.map +1 -1
  254. package/lib/esm/curve/CurveCollection.js.map +1 -1
  255. package/lib/esm/curve/CurveCurve.js.map +1 -1
  256. package/lib/esm/curve/CurveExtendMode.js.map +1 -1
  257. package/lib/esm/curve/CurveFactory.js.map +1 -1
  258. package/lib/esm/curve/CurveLocationDetail.js.map +1 -1
  259. package/lib/esm/curve/CurveOps.js.map +1 -1
  260. package/lib/esm/curve/CurvePrimitive.js.map +1 -1
  261. package/lib/esm/curve/CurveProcessor.js.map +1 -1
  262. package/lib/esm/curve/CurveTypes.js.map +1 -1
  263. package/lib/esm/curve/CurveWireMomentsXYZ.js.map +1 -1
  264. package/lib/esm/curve/GeometryQuery.js.map +1 -1
  265. package/lib/esm/curve/LineSegment3d.js.map +1 -1
  266. package/lib/esm/curve/LineString3d.js.map +1 -1
  267. package/lib/esm/curve/Loop.js.map +1 -1
  268. package/lib/esm/curve/OffsetOptions.js.map +1 -1
  269. package/lib/esm/curve/ParityRegion.js.map +1 -1
  270. package/lib/esm/curve/Path.js.map +1 -1
  271. package/lib/esm/curve/PointString3d.js.map +1 -1
  272. package/lib/esm/curve/ProxyCurve.js.map +1 -1
  273. package/lib/esm/curve/Query/ConsolidateAdjacentPrimitivesContext.js.map +1 -1
  274. package/lib/esm/curve/Query/CurveSplitContext.js.map +1 -1
  275. package/lib/esm/curve/Query/CylindricalRange.js.map +1 -1
  276. package/lib/esm/curve/Query/InOutTests.js.map +1 -1
  277. package/lib/esm/curve/Query/PlanarSubdivision.js.map +1 -1
  278. package/lib/esm/curve/Query/StrokeCountChain.js.map +1 -1
  279. package/lib/esm/curve/Query/StrokeCountMap.js.map +1 -1
  280. package/lib/esm/curve/RegionMomentsXY.js.map +1 -1
  281. package/lib/esm/curve/RegionOps.js.map +1 -1
  282. package/lib/esm/curve/RegionOpsClassificationSweeps.js.map +1 -1
  283. package/lib/esm/curve/StrokeOptions.js.map +1 -1
  284. package/lib/esm/curve/UnionRegion.js.map +1 -1
  285. package/lib/esm/curve/internalContexts/AppendPlaneIntersectionStrokeHandler.js.map +1 -1
  286. package/lib/esm/curve/internalContexts/ChainCollectorContext.js.map +1 -1
  287. package/lib/esm/curve/internalContexts/CloneCurvesContext.js.map +1 -1
  288. package/lib/esm/curve/internalContexts/CloneWithExpandedLineStrings.js.map +1 -1
  289. package/lib/esm/curve/internalContexts/ClosestPointStrokeHandler.js.map +1 -1
  290. package/lib/esm/curve/internalContexts/CountLinearPartsSearchContext.js.map +1 -1
  291. package/lib/esm/curve/internalContexts/CurveCurveCloseApproachXY.js.map +1 -1
  292. package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -1
  293. package/lib/esm/curve/internalContexts/CurveCurveIntersectXYZ.js.map +1 -1
  294. package/lib/esm/curve/internalContexts/CurveLengthContext.js.map +1 -1
  295. package/lib/esm/curve/internalContexts/CurveOffsetXYHandler.js.map +1 -1
  296. package/lib/esm/curve/internalContexts/GapSearchContext.js.map +1 -1
  297. package/lib/esm/curve/internalContexts/MultiChainCollector.js.map +1 -1
  298. package/lib/esm/curve/internalContexts/NewtonRtoRStrokeHandler.js.map +1 -1
  299. package/lib/esm/curve/internalContexts/PlaneAltitudeRangeContext.js.map +1 -1
  300. package/lib/esm/curve/internalContexts/PolygonOffsetContext.js.map +1 -1
  301. package/lib/esm/curve/internalContexts/SumLengthsContext.js.map +1 -1
  302. package/lib/esm/curve/internalContexts/TransformInPlaceContext.js.map +1 -1
  303. package/lib/esm/curve/spiral/AustralianRailCorpXYEvaluator.js.map +1 -1
  304. package/lib/esm/curve/spiral/ClothoidSeries.js.map +1 -1
  305. package/lib/esm/curve/spiral/CubicEvaluator.js.map +1 -1
  306. package/lib/esm/curve/spiral/CzechSpiralEvaluator.js.map +1 -1
  307. package/lib/esm/curve/spiral/DirectHalfCosineSpiralEvaluator.js.map +1 -1
  308. package/lib/esm/curve/spiral/DirectSpiral3d.js.map +1 -1
  309. package/lib/esm/curve/spiral/IntegratedSpiral3d.js.map +1 -1
  310. package/lib/esm/curve/spiral/MXCubicAlongArcSpiralEvaluator.js.map +1 -1
  311. package/lib/esm/curve/spiral/NormalizedTransition.js.map +1 -1
  312. package/lib/esm/curve/spiral/PolishCubicSpiralEvaluator.js.map +1 -1
  313. package/lib/esm/curve/spiral/TransitionConditionalProperties.js.map +1 -1
  314. package/lib/esm/curve/spiral/TransitionSpiral3d.js.map +1 -1
  315. package/lib/esm/curve/spiral/XYCurveEvaluator.js.map +1 -1
  316. package/lib/esm/geometry3d/Angle.js.map +1 -1
  317. package/lib/esm/geometry3d/AngleSweep.js.map +1 -1
  318. package/lib/esm/geometry3d/BarycentricTriangle.js.map +1 -1
  319. package/lib/esm/geometry3d/BilinearPatch.js.map +1 -1
  320. package/lib/esm/geometry3d/CoincidentGeometryOps.js.map +1 -1
  321. package/lib/esm/geometry3d/Ellipsoid.js.map +1 -1
  322. package/lib/esm/geometry3d/FrameBuilder.js.map +1 -1
  323. package/lib/esm/geometry3d/FrustumAnimation.js.map +1 -1
  324. package/lib/esm/geometry3d/GeometryHandler.js.map +1 -1
  325. package/lib/esm/geometry3d/GrowableBlockedArray.js.map +1 -1
  326. package/lib/esm/geometry3d/GrowableFloat64Array.js.map +1 -1
  327. package/lib/esm/geometry3d/GrowableXYArray.js.map +1 -1
  328. package/lib/esm/geometry3d/GrowableXYZArray.js.map +1 -1
  329. package/lib/esm/geometry3d/IndexedCollectionInterval.js.map +1 -1
  330. package/lib/esm/geometry3d/IndexedXYCollection.js.map +1 -1
  331. package/lib/esm/geometry3d/IndexedXYZCollection.js.map +1 -1
  332. package/lib/esm/geometry3d/LongitudeLatitudeAltitude.js.map +1 -1
  333. package/lib/esm/geometry3d/Matrix3d.js.map +1 -1
  334. package/lib/esm/geometry3d/OrderedRotationAngles.js.map +1 -1
  335. package/lib/esm/geometry3d/Plane3d.js.map +1 -1
  336. package/lib/esm/geometry3d/Plane3dByOriginAndUnitNormal.js.map +1 -1
  337. package/lib/esm/geometry3d/Plane3dByOriginAndVectors.js.map +1 -1
  338. package/lib/esm/geometry3d/Point2dArrayCarrier.js.map +1 -1
  339. package/lib/esm/geometry3d/Point2dVector2d.js.map +1 -1
  340. package/lib/esm/geometry3d/Point3dArrayCarrier.js.map +1 -1
  341. package/lib/esm/geometry3d/Point3dVector3d.js.map +1 -1
  342. package/lib/esm/geometry3d/PointHelpers.js.map +1 -1
  343. package/lib/esm/geometry3d/PointStreaming.js.map +1 -1
  344. package/lib/esm/geometry3d/PolygonOps.js.map +1 -1
  345. package/lib/esm/geometry3d/PolylineCompressionByEdgeOffset.js.map +1 -1
  346. package/lib/esm/geometry3d/PolylineOps.js.map +1 -1
  347. package/lib/esm/geometry3d/Range.js.map +1 -1
  348. package/lib/esm/geometry3d/Ray2d.js.map +1 -1
  349. package/lib/esm/geometry3d/Ray3d.js.map +1 -1
  350. package/lib/esm/geometry3d/ReusableObjectCache.js.map +1 -1
  351. package/lib/esm/geometry3d/Segment1d.js.map +1 -1
  352. package/lib/esm/geometry3d/SortablePolygon.js.map +1 -1
  353. package/lib/esm/geometry3d/Transform.js.map +1 -1
  354. package/lib/esm/geometry3d/UVSurfaceOps.js.map +1 -1
  355. package/lib/esm/geometry3d/XYZProps.js.map +1 -1
  356. package/lib/esm/geometry3d/YawPitchRollAngles.js.map +1 -1
  357. package/lib/esm/geometry4d/Map4d.js.map +1 -1
  358. package/lib/esm/geometry4d/Matrix4d.js.map +1 -1
  359. package/lib/esm/geometry4d/MomentData.js.map +1 -1
  360. package/lib/esm/geometry4d/PlaneByOriginAndVectors4d.js.map +1 -1
  361. package/lib/esm/geometry4d/Point4d.js.map +1 -1
  362. package/lib/esm/numerics/BandedSystem.js.map +1 -1
  363. package/lib/esm/numerics/BezierPolynomials.js.map +1 -1
  364. package/lib/esm/numerics/ClusterableArray.js.map +1 -1
  365. package/lib/esm/numerics/Complex.js.map +1 -1
  366. package/lib/esm/numerics/ConvexPolygon2d.js.map +1 -1
  367. package/lib/esm/numerics/Newton.js.map +1 -1
  368. package/lib/esm/numerics/PascalCoefficients.js.map +1 -1
  369. package/lib/esm/numerics/PolarData.js.map +1 -1
  370. package/lib/esm/numerics/Polynomials.js.map +1 -1
  371. package/lib/esm/numerics/Quadrature.js.map +1 -1
  372. package/lib/esm/numerics/Range1dArray.js.map +1 -1
  373. package/lib/esm/numerics/TriDiagonalSystem.js.map +1 -1
  374. package/lib/esm/numerics/UnionFind.js.map +1 -1
  375. package/lib/esm/numerics/UsageSums.js.map +1 -1
  376. package/lib/esm/polyface/AuxData.js.map +1 -1
  377. package/lib/esm/polyface/BoxTopology.js.map +1 -1
  378. package/lib/esm/polyface/FacetFaceData.js.map +1 -1
  379. package/lib/esm/polyface/FacetLocationDetail.js.map +1 -1
  380. package/lib/esm/polyface/FacetOrientation.js.map +1 -1
  381. package/lib/esm/polyface/GreedyTriangulationBetweenLineStrings.js.map +1 -1
  382. package/lib/esm/polyface/IndexedEdgeMatcher.js.map +1 -1
  383. package/lib/esm/polyface/IndexedPolyfaceVisitor.js.map +1 -1
  384. package/lib/esm/polyface/Polyface.js.map +1 -1
  385. package/lib/esm/polyface/PolyfaceBuilder.js.map +1 -1
  386. package/lib/esm/polyface/PolyfaceClip.js.map +1 -1
  387. package/lib/esm/polyface/PolyfaceData.js.map +1 -1
  388. package/lib/esm/polyface/PolyfaceQuery.js.map +1 -1
  389. package/lib/esm/polyface/RangeLengthData.js.map +1 -1
  390. package/lib/esm/polyface/TaggedNumericData.js.map +1 -1
  391. package/lib/esm/polyface/TriangleCandidate.js.map +1 -1
  392. package/lib/esm/polyface/multiclip/BuildAverageNormalsContext.js.map +1 -1
  393. package/lib/esm/polyface/multiclip/GriddedRaggedRange2dSet.js.map +1 -1
  394. package/lib/esm/polyface/multiclip/GriddedRaggedRange2dSetWithOverflow.js.map +1 -1
  395. package/lib/esm/polyface/multiclip/LinearSearchRange2dArray.js.map +1 -1
  396. package/lib/esm/polyface/multiclip/OffsetMeshContext.js.map +1 -1
  397. package/lib/esm/polyface/multiclip/Range2dSearchInterface.js.map +1 -1
  398. package/lib/esm/polyface/multiclip/RangeSearch.js.map +1 -1
  399. package/lib/esm/polyface/multiclip/SweepLineStringToFacetContext.js.map +1 -1
  400. package/lib/esm/polyface/multiclip/XYPointBuckets.js.map +1 -1
  401. package/lib/esm/serialization/BGFBAccessors.js.map +1 -1
  402. package/lib/esm/serialization/BGFBReader.js.map +1 -1
  403. package/lib/esm/serialization/BGFBWriter.js.map +1 -1
  404. package/lib/esm/serialization/BentleyGeometryFlatBuffer.js.map +1 -1
  405. package/lib/esm/serialization/DeepCompare.js.map +1 -1
  406. package/lib/esm/serialization/GeometrySamples.js.map +1 -1
  407. package/lib/esm/serialization/IModelJsonSchema.js.map +1 -1
  408. package/lib/esm/serialization/SerializationHelpers.js.map +1 -1
  409. package/lib/esm/solid/Box.js.map +1 -1
  410. package/lib/esm/solid/Cone.js.map +1 -1
  411. package/lib/esm/solid/LinearSweep.js.map +1 -1
  412. package/lib/esm/solid/RotationalSweep.js.map +1 -1
  413. package/lib/esm/solid/RuledSweep.js.map +1 -1
  414. package/lib/esm/solid/SolidPrimitive.js.map +1 -1
  415. package/lib/esm/solid/Sphere.js.map +1 -1
  416. package/lib/esm/solid/SweepContour.js.map +1 -1
  417. package/lib/esm/solid/TorusPipe.js.map +1 -1
  418. package/lib/esm/topology/ChainMerge.js.map +1 -1
  419. package/lib/esm/topology/Graph.d.ts +19 -9
  420. package/lib/esm/topology/Graph.d.ts.map +1 -1
  421. package/lib/esm/topology/Graph.js +19 -9
  422. package/lib/esm/topology/Graph.js.map +1 -1
  423. package/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js.map +1 -1
  424. package/lib/esm/topology/HalfEdgeGraphSearch.js.map +1 -1
  425. package/lib/esm/topology/HalfEdgeGraphSpineContext.js.map +1 -1
  426. package/lib/esm/topology/HalfEdgeGraphValidation.d.ts +23 -18
  427. package/lib/esm/topology/HalfEdgeGraphValidation.d.ts.map +1 -1
  428. package/lib/esm/topology/HalfEdgeGraphValidation.js +23 -18
  429. package/lib/esm/topology/HalfEdgeGraphValidation.js.map +1 -1
  430. package/lib/esm/topology/HalfEdgeMarkSet.js.map +1 -1
  431. package/lib/esm/topology/HalfEdgeNodeXYZUV.d.ts +17 -10
  432. package/lib/esm/topology/HalfEdgeNodeXYZUV.d.ts.map +1 -1
  433. package/lib/esm/topology/HalfEdgeNodeXYZUV.js +38 -17
  434. package/lib/esm/topology/HalfEdgeNodeXYZUV.js.map +1 -1
  435. package/lib/esm/topology/HalfEdgePointInGraphSearch.js.map +1 -1
  436. package/lib/esm/topology/HalfEdgePositionDetail.js.map +1 -1
  437. package/lib/esm/topology/HalfEdgePriorityQueue.js.map +1 -1
  438. package/lib/esm/topology/InsertAndRetriangulateContext.js.map +1 -1
  439. package/lib/esm/topology/MaskManager.js.map +1 -1
  440. package/lib/esm/topology/Merging.js.map +1 -1
  441. package/lib/esm/topology/RegularizeFace.js.map +1 -1
  442. package/lib/esm/topology/SignedDataSummary.js.map +1 -1
  443. package/lib/esm/topology/SpaceTriangulation.js.map +1 -1
  444. package/lib/esm/topology/Triangulation.js.map +1 -1
  445. package/lib/esm/topology/XYParitySearchContext.js.map +1 -1
  446. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"HalfEdgeGraphSearch.js","sourceRoot":"","sources":["../../../src/topology/HalfEdgeGraphSearch.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/** @packageDocumentation\r\n * @module Topology\r\n */\r\n\r\nimport { HalfEdge, HalfEdgeGraph, HalfEdgeMask, HalfEdgeToBooleanFunction, NodeToNumberFunction } from \"./Graph\";\r\nimport { SignedDataSummary } from \"./SignedDataSummary\";\r\nimport { XYParitySearchContext } from \"./XYParitySearchContext\";\r\n\r\n/**\r\n * Interface for an object that executes boolean tests on edges.\r\n */\r\nexport interface HalfEdgeTestObject {\r\n testEdge(h: HalfEdge): boolean;\r\n}\r\n/**\r\n */\r\nexport class HalfEdgeMaskTester {\r\n private _targetMask: HalfEdgeMask;\r\n private _targetValue: boolean;\r\n /**\r\n *\r\n * @param mask mask to test in `testEdge` function\r\n * @param targetValue value to match for true return\r\n */\r\n public constructor(mask: HalfEdgeMask, targetValue: boolean = true) {\r\n this._targetMask = mask;\r\n this._targetValue = targetValue;\r\n }\r\n /** Return true if the value of the targetMask matches the targetValue */\r\n public testEdge(edge: HalfEdge): boolean {\r\n return edge.isMaskSet(this._targetMask) === this._targetValue;\r\n }\r\n\r\n}\r\n// Search services for HalfEdgeGraph\r\nexport class HalfEdgeGraphSearch {\r\n\r\n /**\r\n * * for each node of face, set the mask push to allNodesStack\r\n * * push the faceSeed on onePerFaceStack[]\r\n */\r\n private static pushAndMaskAllNodesInFace(faceSeed: HalfEdge, mask: number, allNodeStack: HalfEdge[], onePerFaceStack: HalfEdge[]) {\r\n onePerFaceStack.push(faceSeed);\r\n faceSeed.collectAroundFace((node: HalfEdge) => {\r\n node.setMask(mask);\r\n allNodeStack.push(node);\r\n });\r\n }\r\n\r\n /**\r\n * Search an array of faceSeed nodes for the face with the most negative area.\r\n * @param oneCandidateNodePerFace array containing one node from each face to be considered.\r\n * @returns node on the minimum area face, or undefined if no such face (e.g., all faces have zero area).\r\n */\r\n public static findMinimumAreaFace(oneCandidateNodePerFace: HalfEdgeGraph | HalfEdge[], faceAreaFunction?: NodeToNumberFunction): HalfEdge | undefined {\r\n const summary = HalfEdgeGraphSearch.collectFaceAreaSummary(oneCandidateNodePerFace, false, faceAreaFunction);\r\n return summary.largestNegativeItem;\r\n }\r\n\r\n /**\r\n * static method for face area computation -- useful as function parameter in collect FaceAreaSummary.\r\n * * This simply calls `node.signedFaceArea ()`\r\n * @param node instance for signedFaceArea call.\r\n */\r\n public static signedFaceArea(node: HalfEdge): number { return node.signedFaceArea(); }\r\n /**\r\n *\r\n * Return a summary structure data about face (or other numeric quantity if the caller's areaFunction returns other value)\r\n * * The default areaFunction computes area of polygonal face.\r\n * * Callers with curved edge graphs must supply their own area function.\r\n * @param source graph or array of nodes to examine\r\n * @param collectAllNodes flag to pass to the SignedDataSummary constructor to control collection of nodes.\r\n * @param areaFunction function to all to obtain area (or other numeric value)\r\n */\r\n public static collectFaceAreaSummary(source: HalfEdgeGraph | HalfEdge[], collectAllNodes: boolean = false,\r\n areaFunction: NodeToNumberFunction = (node) => HalfEdgeGraphSearch.signedFaceArea(node)): SignedDataSummary<HalfEdge> {\r\n const result = new SignedDataSummary<HalfEdge>(collectAllNodes);\r\n let allFaces: HalfEdge[];\r\n\r\n if (source instanceof HalfEdgeGraph)\r\n allFaces = source.collectFaceLoops();\r\n else\r\n allFaces = source;\r\n\r\n for (const node of allFaces) {\r\n const area = areaFunction(node);\r\n result.announceItem(node, area);\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * * Test if the graph is triangulated.\r\n * * Return false if:\r\n * * Positive area face with more than 3 edges\r\n * * more than 1 negative area face with `allowMultipleNegativeAreaFaces` false\r\n * * 2-edge faces are ignored.\r\n */\r\n public static isTriangulatedCCW(source: HalfEdgeGraph | HalfEdge[], allowMultipleNegativeAreaFaces: boolean = true, numPositiveExceptionsAllowed = 0): boolean {\r\n let allFaces: HalfEdge[];\r\n\r\n if (source instanceof HalfEdgeGraph)\r\n allFaces = source.collectFaceLoops();\r\n else\r\n allFaces = source;\r\n let numNegative = 0;\r\n let numPositiveExceptions = 0;\r\n for (const node of allFaces) {\r\n const numEdges = node.countEdgesAroundFace();\r\n if (numEdges >= 3) {\r\n const area = node.signedFaceArea();\r\n if (area > 0) {\r\n if (numEdges > 3) {\r\n numPositiveExceptions++;\r\n if (numPositiveExceptions > numPositiveExceptionsAllowed)\r\n return false;\r\n }\r\n } else {\r\n numNegative++;\r\n if (numNegative > 1) {\r\n if (!allowMultipleNegativeAreaFaces)\r\n return false;\r\n }\r\n }\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Search to all accessible faces from given seed.\r\n * * The returned array contains one representative node in each face of the connected component.\r\n * * If (nonnull) parity mask is given, on return:\r\n * * It is entirely set or entirely clear around each face\r\n * * It is entirely set on all faces that are an even number of face-to-face steps away from the seed.\r\n * * It is entirely clear on all faces that are an odd number of face-to-face steps away from the seed.\r\n * @param seedEdge first edge to search.\r\n * @param visitMask mask applied to all faces as visited.\r\n * @param parityMask mask to apply (a) to first face, (b) to faces with alternating parity during the search.\r\n */\r\n private static parityFloodFromSeed(seedEdge: HalfEdge, visitMask: HalfEdgeMask, parityEdgeTester: HalfEdgeTestObject | undefined, parityMask: HalfEdgeMask): HalfEdge[] {\r\n const faces: HalfEdge[] = [];\r\n if (seedEdge.isMaskSet(visitMask)) return faces; // empty\r\n\r\n const allMasks = parityMask | visitMask;\r\n const stack: HalfEdge[] = [];\r\n // arbitrarily call the seed face exterior ... others will alternate as visited.\r\n HalfEdgeGraphSearch.pushAndMaskAllNodesInFace(seedEdge, allMasks, stack, faces); // Start with exterior as mask\r\n while (stack.length > 0) {\r\n const p = stack.pop()!;\r\n const mate = p.edgeMate;\r\n if (!mate)\r\n continue;\r\n if (!mate.isMaskSet(visitMask)) {\r\n let newState = p.isMaskSet(parityMask);\r\n if (!parityEdgeTester || parityEdgeTester.testEdge(p))\r\n newState = !newState;\r\n HalfEdgeGraphSearch.pushAndMaskAllNodesInFace(mate, newState ? allMasks : visitMask, stack, faces);\r\n }\r\n }\r\n return faces;\r\n }\r\n /**\r\n * * Search the given faces for the one with the minimum area.\r\n * * If the mask in that face is OFF, toggle it on (all half edges of) all the faces.\r\n * * In a properly merged planar subdivision there should be only one true negative area face per component.\r\n * @param graph parent graph\r\n * @param parityMask mask which was previously set with alternating parity, but with an arbitrary start face.\r\n * @param faces array of faces to search.\r\n */\r\n private static correctParityInSingleComponent(_graph: HalfEdgeGraph, mask: HalfEdgeMask, faces: HalfEdge[]) {\r\n const exteriorHalfEdge = HalfEdgeGraphSearch.findMinimumAreaFace(faces);\r\n if (!exteriorHalfEdge) {\r\n } else if (exteriorHalfEdge.isMaskSet(mask)) {\r\n // all should be well .. nothing to do.\r\n } else {\r\n // TOGGLE around the face (assuming all are consistent with the seed)\r\n for (const faceSeed of faces) {\r\n if (faceSeed.isMaskSet(mask)) {\r\n faceSeed.clearMaskAroundFace(mask);\r\n } else {\r\n faceSeed.setMaskAroundFace(mask);\r\n }\r\n }\r\n }\r\n }\r\n /** Apply correctParityInSingleComponent to each array in components. (Quick exit if mask in NULL_MASK) */\r\n private static correctParityInComponentArrays(graph: HalfEdgeGraph, mask: HalfEdgeMask, components: HalfEdge[][]) {\r\n if (mask === HalfEdgeMask.NULL_MASK)\r\n return;\r\n for (const facesInComponent of components)\r\n HalfEdgeGraphSearch.correctParityInSingleComponent(graph, mask, facesInComponent);\r\n }\r\n /**\r\n * Collect arrays gathering faces by connected component.\r\n * @param graph graph to inspect\r\n * @param parityEdgeTester (optional) function to test if an edge is a parity change (e.g., a boundary edge).\r\n * @param parityMask (optional, along with parityEdgeTester) mask to apply indicating parity. If this is Mask.NULL_MASK, there is no record of parity.\r\n */\r\n public static collectConnectedComponentsWithExteriorParityMasks(graph: HalfEdgeGraph, parityEdgeTester: HalfEdgeTestObject | undefined, parityMask: HalfEdgeMask = HalfEdgeMask.NULL_MASK): HalfEdge[][] {\r\n const components = [];\r\n const visitMask = HalfEdgeMask.VISITED;\r\n const allMasks = parityMask | visitMask;\r\n graph.clearMask(allMasks);\r\n for (const faceSeed of graph.allHalfEdges) {\r\n if (!faceSeed.isMaskSet(HalfEdgeMask.VISITED)) {\r\n const newFaces = HalfEdgeGraphSearch.parityFloodFromSeed(faceSeed, visitMask, parityEdgeTester, parityMask);\r\n components.push(newFaces);\r\n }\r\n }\r\n HalfEdgeGraphSearch.correctParityInComponentArrays(graph, parityMask, components);\r\n return components;\r\n }\r\n /**\r\n * Test if (x,y) is inside (1), on an edge (0) or outside (-1) a face.\r\n * @param seedNode any node on the face loop\r\n * @param x x coordinate of test point.\r\n * @param y y coordinate of test point.\r\n */\r\n public static pointInOrOnFaceXY(seedNode: HalfEdge, x: number, y: number): number | undefined {\r\n const context = new XYParitySearchContext(x, y);\r\n // walk around looking for an accepted node to start the search (seedNode is usually ok!)\r\n let nodeA = seedNode;\r\n let nodeB = seedNode.faceSuccessor;\r\n for (; ; nodeA = nodeB) {\r\n if (context.tryStartEdge(nodeA.x, nodeA.y, nodeB.x, nodeB.y))\r\n break;\r\n if (nodeB === seedNode) {\r\n // umm.. the face is all on the x axis?\r\n return context.classifyCounts();\r\n }\r\n nodeB = nodeA.faceSuccessor;\r\n }\r\n\r\n // nodeB is the real start node for search ... emit ends of each edge around the face,\r\n // stopping after emitting nodeB as an edge end.\r\n let node = nodeB.faceSuccessor;\r\n for (; ;) {\r\n if (!context.advance(node.x, node.y)) {\r\n return context.classifyCounts();\r\n }\r\n if (node === nodeB)\r\n break;\r\n node = node.faceSuccessor;\r\n }\r\n return context.classifyCounts();\r\n }\r\n /**\r\n * Announce nodes that are \"extended face boundary\" by conditions (usually mask of node and mate) in test functions.\r\n * * After each node, the next candidate in reached by looking \"around the head vertex loop\" for the next boundary.\r\n * * \"Around the vertex\" from nodeA means\r\n * * First look at nodeA.faceSuccessor;\r\n * * Then look at vertexPredecessor around that vertex loop.\r\n * * Each accepted node is passed to announceNode, and marked with the visit mask.\r\n * * The counter of the announceEdge function is zero for the first edge, then increases with each edge.\r\n * @param seed start node.\r\n * @param isBoundaryEdge\r\n * @param announceEdge\r\n */\r\n public static collectExtendedBoundaryLoopFromSeed(seed: HalfEdge, visitMask: HalfEdgeMask, isBoundaryEdge: HalfEdgeToBooleanFunction,\r\n announceEdge: (edge: HalfEdge, counter: number) => void) {\r\n let counter = 0;\r\n while (!seed.getMask(visitMask) && isBoundaryEdge(seed)) {\r\n announceEdge(seed, counter++);\r\n seed.setMask(visitMask);\r\n const vertexBase = seed.faceSuccessor;\r\n let candidateAroundVertex = vertexBase;\r\n for (; ;) {\r\n if (candidateAroundVertex.getMask(visitMask))\r\n return;\r\n if (isBoundaryEdge(candidateAroundVertex)) {\r\n seed = candidateAroundVertex;\r\n break;\r\n }\r\n candidateAroundVertex = candidateAroundVertex.vertexPredecessor;\r\n if (candidateAroundVertex === vertexBase)\r\n break;\r\n }\r\n }\r\n }\r\n /**\r\n * Collect arrays of nodes \"around the boundary\" of a graph with extraneous (non-boundary) edges.\r\n * * The \"boundary\" is nodes that do NOT have the exterior mask, but whose mates DO have the exterior mask.\r\n * * After each node, the next candidate in reached by looking \"around the head vertex loop\" for the next boundary.\r\n * * \"Around the vertex\" from nodeA means\r\n * * First look at nodeA.faceSuccessor;\r\n * * Then look at vertexPredecessor around that vertex loop.\r\n * * Each accepted node is passed to announceNode, and marked with the visit mask.\r\n * @param seed start node.\r\n * @param isBoundaryNode\r\n * @param announceNode\r\n */\r\n public static collectExtendedBoundaryLoopsInGraph(graph: HalfEdgeGraph, exteriorMask: HalfEdgeMask): HalfEdge[][] {\r\n const loops: HalfEdge[][] = [];\r\n const visitMask = graph.grabMask(true);\r\n const isBoundaryEdge = (edge: HalfEdge): boolean => {\r\n return edge.getMask(exteriorMask) === 0 && edge.edgeMate.getMask(exteriorMask) !== 0;\r\n };\r\n const announceEdgeInBoundary = (edge: HalfEdge, counter: number) => {\r\n if (counter === 0)\r\n loops.push([]);\r\n loops[loops.length - 1].push(edge);\r\n };\r\n for (const seed of graph.allHalfEdges) {\r\n this.collectExtendedBoundaryLoopFromSeed(seed, visitMask, isBoundaryEdge, announceEdgeInBoundary);\r\n }\r\n graph.dropMask(visitMask);\r\n return loops;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"HalfEdgeGraphSearch.js","sourceRoot":"","sources":["../../../src/topology/HalfEdgeGraphSearch.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\n/** @packageDocumentation\n * @module Topology\n */\n\nimport { HalfEdge, HalfEdgeGraph, HalfEdgeMask, HalfEdgeToBooleanFunction, NodeToNumberFunction } from \"./Graph\";\nimport { SignedDataSummary } from \"./SignedDataSummary\";\nimport { XYParitySearchContext } from \"./XYParitySearchContext\";\n\n/**\n * Interface for an object that executes boolean tests on edges.\n */\nexport interface HalfEdgeTestObject {\n testEdge(h: HalfEdge): boolean;\n}\n/**\n */\nexport class HalfEdgeMaskTester {\n private _targetMask: HalfEdgeMask;\n private _targetValue: boolean;\n /**\n *\n * @param mask mask to test in `testEdge` function\n * @param targetValue value to match for true return\n */\n public constructor(mask: HalfEdgeMask, targetValue: boolean = true) {\n this._targetMask = mask;\n this._targetValue = targetValue;\n }\n /** Return true if the value of the targetMask matches the targetValue */\n public testEdge(edge: HalfEdge): boolean {\n return edge.isMaskSet(this._targetMask) === this._targetValue;\n }\n\n}\n// Search services for HalfEdgeGraph\nexport class HalfEdgeGraphSearch {\n\n /**\n * * for each node of face, set the mask push to allNodesStack\n * * push the faceSeed on onePerFaceStack[]\n */\n private static pushAndMaskAllNodesInFace(faceSeed: HalfEdge, mask: number, allNodeStack: HalfEdge[], onePerFaceStack: HalfEdge[]) {\n onePerFaceStack.push(faceSeed);\n faceSeed.collectAroundFace((node: HalfEdge) => {\n node.setMask(mask);\n allNodeStack.push(node);\n });\n }\n\n /**\n * Search an array of faceSeed nodes for the face with the most negative area.\n * @param oneCandidateNodePerFace array containing one node from each face to be considered.\n * @returns node on the minimum area face, or undefined if no such face (e.g., all faces have zero area).\n */\n public static findMinimumAreaFace(oneCandidateNodePerFace: HalfEdgeGraph | HalfEdge[], faceAreaFunction?: NodeToNumberFunction): HalfEdge | undefined {\n const summary = HalfEdgeGraphSearch.collectFaceAreaSummary(oneCandidateNodePerFace, false, faceAreaFunction);\n return summary.largestNegativeItem;\n }\n\n /**\n * static method for face area computation -- useful as function parameter in collect FaceAreaSummary.\n * * This simply calls `node.signedFaceArea ()`\n * @param node instance for signedFaceArea call.\n */\n public static signedFaceArea(node: HalfEdge): number { return node.signedFaceArea(); }\n /**\n *\n * Return a summary structure data about face (or other numeric quantity if the caller's areaFunction returns other value)\n * * The default areaFunction computes area of polygonal face.\n * * Callers with curved edge graphs must supply their own area function.\n * @param source graph or array of nodes to examine\n * @param collectAllNodes flag to pass to the SignedDataSummary constructor to control collection of nodes.\n * @param areaFunction function to all to obtain area (or other numeric value)\n */\n public static collectFaceAreaSummary(source: HalfEdgeGraph | HalfEdge[], collectAllNodes: boolean = false,\n areaFunction: NodeToNumberFunction = (node) => HalfEdgeGraphSearch.signedFaceArea(node)): SignedDataSummary<HalfEdge> {\n const result = new SignedDataSummary<HalfEdge>(collectAllNodes);\n let allFaces: HalfEdge[];\n\n if (source instanceof HalfEdgeGraph)\n allFaces = source.collectFaceLoops();\n else\n allFaces = source;\n\n for (const node of allFaces) {\n const area = areaFunction(node);\n result.announceItem(node, area);\n }\n return result;\n }\n\n /**\n * * Test if the graph is triangulated.\n * * Return false if:\n * * Positive area face with more than 3 edges\n * * more than 1 negative area face with `allowMultipleNegativeAreaFaces` false\n * * 2-edge faces are ignored.\n */\n public static isTriangulatedCCW(source: HalfEdgeGraph | HalfEdge[], allowMultipleNegativeAreaFaces: boolean = true, numPositiveExceptionsAllowed = 0): boolean {\n let allFaces: HalfEdge[];\n\n if (source instanceof HalfEdgeGraph)\n allFaces = source.collectFaceLoops();\n else\n allFaces = source;\n let numNegative = 0;\n let numPositiveExceptions = 0;\n for (const node of allFaces) {\n const numEdges = node.countEdgesAroundFace();\n if (numEdges >= 3) {\n const area = node.signedFaceArea();\n if (area > 0) {\n if (numEdges > 3) {\n numPositiveExceptions++;\n if (numPositiveExceptions > numPositiveExceptionsAllowed)\n return false;\n }\n } else {\n numNegative++;\n if (numNegative > 1) {\n if (!allowMultipleNegativeAreaFaces)\n return false;\n }\n }\n }\n }\n return true;\n }\n\n /**\n * Search to all accessible faces from given seed.\n * * The returned array contains one representative node in each face of the connected component.\n * * If (nonnull) parity mask is given, on return:\n * * It is entirely set or entirely clear around each face\n * * It is entirely set on all faces that are an even number of face-to-face steps away from the seed.\n * * It is entirely clear on all faces that are an odd number of face-to-face steps away from the seed.\n * @param seedEdge first edge to search.\n * @param visitMask mask applied to all faces as visited.\n * @param parityMask mask to apply (a) to first face, (b) to faces with alternating parity during the search.\n */\n private static parityFloodFromSeed(seedEdge: HalfEdge, visitMask: HalfEdgeMask, parityEdgeTester: HalfEdgeTestObject | undefined, parityMask: HalfEdgeMask): HalfEdge[] {\n const faces: HalfEdge[] = [];\n if (seedEdge.isMaskSet(visitMask)) return faces; // empty\n\n const allMasks = parityMask | visitMask;\n const stack: HalfEdge[] = [];\n // arbitrarily call the seed face exterior ... others will alternate as visited.\n HalfEdgeGraphSearch.pushAndMaskAllNodesInFace(seedEdge, allMasks, stack, faces); // Start with exterior as mask\n while (stack.length > 0) {\n const p = stack.pop()!;\n const mate = p.edgeMate;\n if (!mate)\n continue;\n if (!mate.isMaskSet(visitMask)) {\n let newState = p.isMaskSet(parityMask);\n if (!parityEdgeTester || parityEdgeTester.testEdge(p))\n newState = !newState;\n HalfEdgeGraphSearch.pushAndMaskAllNodesInFace(mate, newState ? allMasks : visitMask, stack, faces);\n }\n }\n return faces;\n }\n /**\n * * Search the given faces for the one with the minimum area.\n * * If the mask in that face is OFF, toggle it on (all half edges of) all the faces.\n * * In a properly merged planar subdivision there should be only one true negative area face per component.\n * @param graph parent graph\n * @param parityMask mask which was previously set with alternating parity, but with an arbitrary start face.\n * @param faces array of faces to search.\n */\n private static correctParityInSingleComponent(_graph: HalfEdgeGraph, mask: HalfEdgeMask, faces: HalfEdge[]) {\n const exteriorHalfEdge = HalfEdgeGraphSearch.findMinimumAreaFace(faces);\n if (!exteriorHalfEdge) {\n } else if (exteriorHalfEdge.isMaskSet(mask)) {\n // all should be well .. nothing to do.\n } else {\n // TOGGLE around the face (assuming all are consistent with the seed)\n for (const faceSeed of faces) {\n if (faceSeed.isMaskSet(mask)) {\n faceSeed.clearMaskAroundFace(mask);\n } else {\n faceSeed.setMaskAroundFace(mask);\n }\n }\n }\n }\n /** Apply correctParityInSingleComponent to each array in components. (Quick exit if mask in NULL_MASK) */\n private static correctParityInComponentArrays(graph: HalfEdgeGraph, mask: HalfEdgeMask, components: HalfEdge[][]) {\n if (mask === HalfEdgeMask.NULL_MASK)\n return;\n for (const facesInComponent of components)\n HalfEdgeGraphSearch.correctParityInSingleComponent(graph, mask, facesInComponent);\n }\n /**\n * Collect arrays gathering faces by connected component.\n * @param graph graph to inspect\n * @param parityEdgeTester (optional) function to test if an edge is a parity change (e.g., a boundary edge).\n * @param parityMask (optional, along with parityEdgeTester) mask to apply indicating parity. If this is Mask.NULL_MASK, there is no record of parity.\n */\n public static collectConnectedComponentsWithExteriorParityMasks(graph: HalfEdgeGraph, parityEdgeTester: HalfEdgeTestObject | undefined, parityMask: HalfEdgeMask = HalfEdgeMask.NULL_MASK): HalfEdge[][] {\n const components = [];\n const visitMask = HalfEdgeMask.VISITED;\n const allMasks = parityMask | visitMask;\n graph.clearMask(allMasks);\n for (const faceSeed of graph.allHalfEdges) {\n if (!faceSeed.isMaskSet(HalfEdgeMask.VISITED)) {\n const newFaces = HalfEdgeGraphSearch.parityFloodFromSeed(faceSeed, visitMask, parityEdgeTester, parityMask);\n components.push(newFaces);\n }\n }\n HalfEdgeGraphSearch.correctParityInComponentArrays(graph, parityMask, components);\n return components;\n }\n /**\n * Test if (x,y) is inside (1), on an edge (0) or outside (-1) a face.\n * @param seedNode any node on the face loop\n * @param x x coordinate of test point.\n * @param y y coordinate of test point.\n */\n public static pointInOrOnFaceXY(seedNode: HalfEdge, x: number, y: number): number | undefined {\n const context = new XYParitySearchContext(x, y);\n // walk around looking for an accepted node to start the search (seedNode is usually ok!)\n let nodeA = seedNode;\n let nodeB = seedNode.faceSuccessor;\n for (; ; nodeA = nodeB) {\n if (context.tryStartEdge(nodeA.x, nodeA.y, nodeB.x, nodeB.y))\n break;\n if (nodeB === seedNode) {\n // umm.. the face is all on the x axis?\n return context.classifyCounts();\n }\n nodeB = nodeA.faceSuccessor;\n }\n\n // nodeB is the real start node for search ... emit ends of each edge around the face,\n // stopping after emitting nodeB as an edge end.\n let node = nodeB.faceSuccessor;\n for (; ;) {\n if (!context.advance(node.x, node.y)) {\n return context.classifyCounts();\n }\n if (node === nodeB)\n break;\n node = node.faceSuccessor;\n }\n return context.classifyCounts();\n }\n /**\n * Announce nodes that are \"extended face boundary\" by conditions (usually mask of node and mate) in test functions.\n * * After each node, the next candidate in reached by looking \"around the head vertex loop\" for the next boundary.\n * * \"Around the vertex\" from nodeA means\n * * First look at nodeA.faceSuccessor;\n * * Then look at vertexPredecessor around that vertex loop.\n * * Each accepted node is passed to announceNode, and marked with the visit mask.\n * * The counter of the announceEdge function is zero for the first edge, then increases with each edge.\n * @param seed start node.\n * @param isBoundaryEdge\n * @param announceEdge\n */\n public static collectExtendedBoundaryLoopFromSeed(seed: HalfEdge, visitMask: HalfEdgeMask, isBoundaryEdge: HalfEdgeToBooleanFunction,\n announceEdge: (edge: HalfEdge, counter: number) => void) {\n let counter = 0;\n while (!seed.getMask(visitMask) && isBoundaryEdge(seed)) {\n announceEdge(seed, counter++);\n seed.setMask(visitMask);\n const vertexBase = seed.faceSuccessor;\n let candidateAroundVertex = vertexBase;\n for (; ;) {\n if (candidateAroundVertex.getMask(visitMask))\n return;\n if (isBoundaryEdge(candidateAroundVertex)) {\n seed = candidateAroundVertex;\n break;\n }\n candidateAroundVertex = candidateAroundVertex.vertexPredecessor;\n if (candidateAroundVertex === vertexBase)\n break;\n }\n }\n }\n /**\n * Collect arrays of nodes \"around the boundary\" of a graph with extraneous (non-boundary) edges.\n * * The \"boundary\" is nodes that do NOT have the exterior mask, but whose mates DO have the exterior mask.\n * * After each node, the next candidate in reached by looking \"around the head vertex loop\" for the next boundary.\n * * \"Around the vertex\" from nodeA means\n * * First look at nodeA.faceSuccessor;\n * * Then look at vertexPredecessor around that vertex loop.\n * * Each accepted node is passed to announceNode, and marked with the visit mask.\n * @param seed start node.\n * @param isBoundaryNode\n * @param announceNode\n */\n public static collectExtendedBoundaryLoopsInGraph(graph: HalfEdgeGraph, exteriorMask: HalfEdgeMask): HalfEdge[][] {\n const loops: HalfEdge[][] = [];\n const visitMask = graph.grabMask(true);\n const isBoundaryEdge = (edge: HalfEdge): boolean => {\n return edge.getMask(exteriorMask) === 0 && edge.edgeMate.getMask(exteriorMask) !== 0;\n };\n const announceEdgeInBoundary = (edge: HalfEdge, counter: number) => {\n if (counter === 0)\n loops.push([]);\n loops[loops.length - 1].push(edge);\n };\n for (const seed of graph.allHalfEdges) {\n this.collectExtendedBoundaryLoopFromSeed(seed, visitMask, isBoundaryEdge, announceEdgeInBoundary);\n }\n graph.dropMask(visitMask);\n return loops;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"HalfEdgeGraphSpineContext.js","sourceRoot":"","sources":["../../../src/topology/HalfEdgeGraphSpineContext.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Topology\r\n */\r\nimport { Geometry } from \"../Geometry\";\r\nimport { HalfEdge, HalfEdgeGraph, HalfEdgeMask } from \"./Graph\";\r\nimport { Point3d, Vector3d } from \"../geometry3d/Point3dVector3d\";\r\nimport { HalfEdgeGraphMerge } from \"./Merging\";\r\nimport { Triangulator } from \"./Triangulation\";\r\nimport { RegularizationContext } from \"./RegularizeFace\";\r\nimport { HalfEdgeGraphSearch, HalfEdgeMaskTester } from \"./HalfEdgeGraphSearch\";\r\nimport { Angle } from \"../geometry3d/Angle\";\r\n// cSpell:disable\r\n// const sSpineRelTol = 1.0e-8;\r\n// const sSpineGraphAbsTol = 0.0;\r\n// const sSpineGraphRelTol = 1.0e-10;\r\n\r\nfunction createNPoints(n: number): Point3d[] {\r\n const points = [];\r\n for (let i = 0; i < n; i++)\r\n points.push(Point3d.create(0, 0, 0));\r\n return points;\r\n}\r\nfunction createNVectors(n: number): Vector3d[] {\r\n const points = [];\r\n for (let i = 0; i < n; i++)\r\n points.push(Vector3d.create(0, 0, 0));\r\n return points;\r\n}\r\n// Local struct to pair a graph node with a double as a sort key for std::sort\r\nclass NodeSortKey {\r\n private _a: number;\r\n private _node: HalfEdge;\r\n public get node() { return this._node; }\r\n\r\n public constructor(node: HalfEdge, b: number) {\r\n this._node = node;\r\n this._a = b;\r\n }\r\n public static compareForSort(dataA: NodeSortKey, dataB: NodeSortKey): number { return dataA._a - dataB._a; }\r\n}\r\n\r\n/**\r\n * Context manager to hold a vu graph and do spine operations\r\n *\r\n * Spine calculations determine both (a) a \"skeletal\" network of linework that follows the interior\r\n * path through within the boundaries, and (b) a block decomposition into quads and triangles.\r\n *\r\n * Usage pattern:\r\n * ```\r\n * const sc = new HalfEdgeGraphSpineContext();\r\n * // Data setup ....\r\n * foreach polygon or polyline\r\n * {\r\n * sc.InsertEdges (edgePoints, bClosed)\r\n * }\r\n * // Analysis steps ...\r\n * * bParity = true to treat the data as a \"polygon\". The interior is determined by parity rules\r\n * and the triangulation and spine are only constructed \"inside\"\r\n * * bParity = false if \"all\" spaces are to be triangulated and spined.\r\n * * minSplitRadians -- suggested value 0.3. If this value is large, it will encourage add internal\r\n * * edges from a vertex to an edge 'across' the polygon even if it creates small angles.\r\n * * minDiagonalAngle -- suggested value 1.0. If this value is large (up to about 1.5 as max) it favors\r\n * * using triangles to navigate turns. If it is small, it favors using skewed quadrilaterals.\r\n * sc.TriangulateForSpine (bParity, minSplitRadians)\r\n * sc.MarkBoxes (true, minDiagonalAngle);\r\n * edges = sc.GetSpineEdges ();\r\n * ```\r\n * @internal\r\n */\r\nexport class HalfEdgeGraphSpineContext {\r\n /** The Evolving graph */\r\n private _spineGraph: HalfEdgeGraph;\r\n /** mask marking edges that have been paired into quads */\r\n private _diagonalMask: HalfEdgeMask;\r\n private _boxMask: HalfEdgeMask;\r\n public get graph() { return this._spineGraph; }\r\n /**\r\n * Create a context with an empty graph.\r\n * * Reserve masks for specialized markup.\r\n */\r\n public constructor() {\r\n this._spineGraph = new HalfEdgeGraph();\r\n // vu_setTol (_spineGraph, sSpineGraphAbsTol, sSpineGraphRelTol);\r\n this._diagonalMask = this._spineGraph.grabMask();\r\n this._boxMask = this._spineGraph.grabMask();\r\n }\r\n\r\n /**\r\n * Release resources to the graph.\r\n */\r\n public teardown() {\r\n this._spineGraph.dropMask(this._diagonalMask);\r\n this._spineGraph.dropMask(this._boxMask);\r\n this._spineGraph.decommission();\r\n }\r\n\r\n // an edge (as new bvector<DPoint3d> at back, with cloned points>\r\n private addEdge(xyzOut: Point3d[][], xyzA: Point3d, xyzB: Point3d) {\r\n const newArray = [];\r\n newArray.push(xyzA.clone());\r\n newArray.push(xyzB.clone());\r\n xyzOut.push(newArray);\r\n }\r\n\r\n private getBoxCorners(diagonalNode: HalfEdge,\r\n nodes: HalfEdge[],\r\n points: Point3d[]): boolean {\r\n const diagonalMate = diagonalNode.edgeMate;\r\n nodes.length = 0;\r\n points.length = 0;\r\n if (!diagonalNode.getMask(HalfEdgeMask.BOUNDARY_EDGE)\r\n && diagonalNode.countEdgesAroundFace() === 3\r\n && diagonalMate.countEdgesAroundFace() === 3) {\r\n const nodeA = diagonalMate.faceSuccessor;\r\n nodes.push(nodeA);\r\n nodes.push(nodeA.faceSuccessor);\r\n const nodeB = diagonalNode.faceSuccessor;\r\n nodes.push(nodeB);\r\n nodes.push(nodeB.faceSuccessor);\r\n for (let i = 0; i < 4; i++)\r\n points.push(Point3d.create(nodes[i].x, nodes[i].y));\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n // Compute bisectors of the quad.\r\n // function key is the smaller absolute angle between the bisectors.\r\n // (pi/2 is max possible value).\r\n private diagonalKeyFunc(pDiagonalNode: HalfEdge): number {\r\n\r\n const nodes: HalfEdge[] = [];\r\n const points: Point3d[] = [];\r\n if (this.getBoxCorners(pDiagonalNode, nodes, points)) {\r\n const xyzA = points[0];\r\n const xyzB = points[1];\r\n const xyzC = points[2];\r\n const xyzD = points[3];\r\n const xyzAB = xyzA.interpolate(0.5, xyzB);\r\n const xyzBC = xyzB.interpolate(0.5, xyzC);\r\n const xyzCD = xyzC.interpolate(0.5, xyzD);\r\n const xyzDA = xyzD.interpolate(0.5, xyzA);\r\n\r\n const vectorAB = Vector3d.createStartEnd(xyzA, xyzB);\r\n const vectorBC = Vector3d.createStartEnd(xyzB, xyzC);\r\n const vectorCD = Vector3d.createStartEnd(xyzC, xyzD);\r\n const vectorDA = Vector3d.createStartEnd(xyzD, xyzA);\r\n\r\n const vectorABToCD = Vector3d.createStartEnd(xyzCD, xyzAB);\r\n const vectorBCToDA = Vector3d.createStartEnd(xyzDA, xyzBC);\r\n vectorABToCD.z = 0.0;\r\n vectorBCToDA.z = 0.0;\r\n const thetaAB = vectorABToCD.smallerUnorientedAngleTo(vectorAB).radians;\r\n const thetaBC = vectorBCToDA.smallerUnorientedAngleTo(vectorBC).radians;\r\n const thetaCD = vectorABToCD.smallerUnorientedAngleTo(vectorCD).radians;\r\n const thetaDA = vectorBCToDA.smallerUnorientedAngleTo(vectorDA).radians;\r\n\r\n const alpha = thetaAB < thetaCD ? thetaAB : thetaCD;\r\n const beta = thetaBC < thetaDA ? thetaBC : thetaDA;\r\n return alpha < beta ? alpha : beta;\r\n }\r\n\r\n return Number.NEGATIVE_INFINITY;\r\n }\r\n\r\n // Select a branch point in a triangle.\r\n // This may be the centroid or the midpoint of an edge joining midpoints of a pair of edges.\r\n private selectTriangleInteriorPoint(pXYZ: Point3d[]): Point3d {\r\n\r\n const xyz = createNPoints(6);\r\n const xyzMid = createNPoints(6); // Midpoints of each edge.\r\n const interiorCandidate = createNPoints(4); // for i in {012}, [i] is midpoint of midpoint[i+1] and midpoint[i+2].\r\n // [3] is centroid.\r\n const edgeVector = createNVectors(6);\r\n const centroid = Point3d.create();\r\n for (let i = 0; i < 3; i++) {\r\n xyz[i] = xyz[i + 3] = pXYZ[i];\r\n centroid.addInPlace(xyz[i]);\r\n }\r\n centroid.scaleInPlace(1.0 / 3.0);\r\n\r\n // Edge midpoints ...\r\n for (let i = 0; i < 3; i++) {\r\n xyzMid[i] = xyz[i].interpolate(0.5, xyz[i + 1]);\r\n xyzMid[i + 3] = xyzMid[i];\r\n edgeVector[i] = Vector3d.createStartEnd(xyz[i], xyz[i + 1]); // use wraparound\r\n edgeVector[i + 3] = edgeVector[i];\r\n }\r\n\r\n // Midpoints of midpoint-to-midpoint connections ..\r\n for (let i = 0; i < 3; i++) {\r\n const i1 = i + 1;\r\n const i2 = i + 2;\r\n interiorCandidate[i] = xyzMid[i1].interpolate(0.5, xyzMid[i2]);\r\n }\r\n\r\n interiorCandidate[3] = centroid;\r\n\r\n let bestAngle = Number.NEGATIVE_INFINITY;\r\n let bestIndex = -1;\r\n const theta: number[] = [0, 0, 0];\r\n let thetaMin;\r\n for (let k: number = 0; k < 4; k++) {\r\n // Measure angles from edge midpoints towards interior candidate.\r\n thetaMin = Number.POSITIVE_INFINITY;\r\n for (let i: number = 0; i < 3; i++) {\r\n const edgeToInterior = Vector3d.createStartEnd(xyzMid[i], interiorCandidate[k]);\r\n theta[i] = edgeVector[i].smallerUnorientedAngleTo(edgeToInterior).radians;\r\n if (theta[i] < thetaMin)\r\n thetaMin = theta[i];\r\n }\r\n if (thetaMin > bestAngle) {\r\n bestAngle = thetaMin;\r\n bestIndex = k;\r\n }\r\n }\r\n return interiorCandidate[bestIndex];\r\n }\r\n\r\n private markBox(pA: HalfEdge): void {\r\n\r\n const pB = pA.edgeMate;\r\n pA.setMask(this._diagonalMask);\r\n pB.setMask(this._diagonalMask);\r\n pA.setMaskAroundFace(this._boxMask);\r\n pB.setMaskAroundFace(this._boxMask);\r\n }\r\n\r\n private setSortedDiagonalMasks(minA: number): number {\r\n\r\n const candidates: NodeSortKey[] = [];\r\n let numDiagonal = 0;\r\n for (const node of this._spineGraph.allHalfEdges) {\r\n const b = this.diagonalKeyFunc(node);\r\n if (b > minA)\r\n candidates.push(new NodeSortKey(node, b));\r\n }\r\n\r\n candidates.sort((dataA, dataB) => NodeSortKey.compareForSort(dataA, dataB));\r\n\r\n let key;\r\n while (undefined !== (key = candidates.pop())) {\r\n const pA = key.node;\r\n const pB = pA.edgeMate;\r\n if (!pA.getMask(this._boxMask)\r\n && !pB.getMask(this._boxMask)) {\r\n this.markBox(pA);\r\n numDiagonal++;\r\n }\r\n }\r\n return numDiagonal;\r\n }\r\n\r\n /// <param name=\"xyzA\">Vertex whose angle is being split</param>\r\n private splitOK(xyzA: Point3d, xyzB: Point3d, xyzQ: Point3d, xyzC: Point3d, minAngle: number): boolean {\r\n\r\n const vectorAB = Vector3d.createStartEnd(xyzA, xyzB);\r\n const vectorAQ = Vector3d.createStartEnd(xyzA, xyzQ);\r\n const vectorAC = Vector3d.createStartEnd(xyzA, xyzC);\r\n const angleBAQ = vectorAB.angleToXY(vectorAQ).radians;\r\n const angleQAC = vectorAQ.angleToXY(vectorAC).radians;\r\n return Math.abs(angleBAQ) > minAngle && Math.abs(angleQAC) > minAngle;\r\n }\r\n\r\n // Search a triangulation for vertices which have\r\n // (a) pre-split angle greater than 90 degrees\r\n // (b) the opposite edge is a boundary.\r\n // (c) each post split angle is less than minSplitRadians\r\n // Drop a perpenedicular to that boundary.\r\n // return the number of edges added.\r\n private addPerpendicularsToBoundaries(minSplitRadians: number, minCandidateRadians: number): number {\r\n\r\n let numAdd = 0;\r\n for (const pA of this._spineGraph.allHalfEdges) {\r\n const pB = pA.faceSuccessor;\r\n const pC = pB.faceSuccessor;\r\n if (!pA.getMask(HalfEdgeMask.EXTERIOR)\r\n && !pA.getMask(HalfEdgeMask.BOUNDARY_EDGE) // ?? prevent deep recursion\r\n && !pC.getMask(HalfEdgeMask.BOUNDARY_EDGE) // ?? prevent deep recursion\r\n && pB.getMask(HalfEdgeMask.BOUNDARY_EDGE)\r\n && pC.faceSuccessor === pA\r\n ) {\r\n const vectorAB = pA.getVector2dAlongEdge();\r\n const vectorBC = pB.getVector2dAlongEdge();\r\n const vectorCA = pC.getVector2dAlongEdge();\r\n const candidateRadians = Math.PI - vectorCA.angleTo(vectorAB).radians;\r\n // const candidateDot = vectorCA.DotProduct (vectorAB);\r\n if (candidateRadians > minCandidateRadians) { // vectorCA.DotProduct (vectorAB) > 0.0)\r\n const bb = vectorBC.dotProduct(vectorBC);\r\n const ba = -vectorBC.dotProduct(vectorAB);\r\n const s = Geometry.conditionalDivideFraction(ba, bb);\r\n if (s !== undefined && s > 0.0 && s < 1.0) {\r\n const xyzA = pA.getPoint3d();\r\n const xyzB = pB.getPoint3d();\r\n const xyzC = pC.getPoint3d();\r\n const xyzE = xyzB.interpolate(s, xyzC);\r\n if (this.splitOK(xyzA, xyzB, xyzE, xyzC, minSplitRadians)) {\r\n const pE = this._spineGraph.splitEdgeAtFraction(pB, s);\r\n const pA1 = this._spineGraph.createEdgeHalfEdgeHalfEdge(pA, 0, pE, 0);\r\n pA1.setXYZFrom(pA);\r\n pE.setXYZAroundVertex(xyzE.x, xyzE.y, xyzE.z);\r\n numAdd++;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n return numAdd;\r\n }\r\n\r\n private getSpineEdgesInQuad(\r\n pFace: HalfEdge,\r\n xyzOut: Point3d[][],\r\n bIncludeInterior: boolean,\r\n // true to include the edge to boundary when the qued is a dead end.\r\n bIncludeFinal: boolean,\r\n // true to include the two adjacent edges to boundary if the quad is at a corner.\r\n bIncludeCornerSpokes: boolean): boolean {\r\n\r\n if (pFace.countEdgesAroundFace() !== 4)\r\n return false;\r\n const pNode: HalfEdge[] = [];\r\n const xyz = createNPoints(8);\r\n const midpoint = createNPoints(8);\r\n pNode[0] = pNode[4] = pFace;\r\n pNode[1] = pNode[5] = pNode[0].faceSuccessor;\r\n pNode[2] = pNode[6] = pNode[1].faceSuccessor;\r\n pNode[3] = pNode[7] = pNode[2].faceSuccessor;\r\n let numBoundary = 0;\r\n let numInterior = 0;\r\n const iBoundary: number[] = [];\r\n const iInterior: number[] = [];\r\n const bIsBoundary: boolean[] = [];\r\n const centroid = Point3d.create();\r\n for (let i: number = 0; i < 4; i++) {\r\n bIsBoundary[i] = 0 !== pNode[i].getMask(HalfEdgeMask.BOUNDARY_EDGE);\r\n if (pNode[i].getMask(HalfEdgeMask.BOUNDARY_EDGE))\r\n iBoundary[numBoundary++] = i;\r\n else\r\n iInterior[numInterior++] = i;\r\n xyz[i] = pNode[i].getPoint3d();\r\n xyz[i + 4] = xyz[i];\r\n centroid.addInPlace(xyz[i]);\r\n }\r\n for (let i: number = 0; i < 4; i++) {\r\n midpoint[i] = xyz[i].interpolate(0.5, xyz[i + 1]);\r\n midpoint[i + 4] = midpoint[i];\r\n }\r\n\r\n centroid.scaleInPlace(0.25);\r\n if (numBoundary === 0 || numBoundary === 1) {\r\n for (let i: number = 0; i < numInterior; i++)\r\n if (bIncludeInterior)\r\n this.addEdge(xyzOut, midpoint[iInterior[i]], centroid);\r\n } else if (numBoundary === 4) {\r\n for (let i: number = 0; i < numBoundary; i++)\r\n if (bIncludeFinal)\r\n this.addEdge(xyzOut, midpoint[i], centroid);\r\n } else if (numBoundary === 2) {\r\n if (iInterior[1] === iInterior[0] + 2) {\r\n // Spine enters one end, exits the other ..\r\n if (bIncludeInterior)\r\n this.addEdge(xyzOut, midpoint[iInterior[0]], midpoint[iInterior[1]]);\r\n } else {\r\n // Block sits as exterior corner. Let the two spines continue to their opposite faces ..\r\n for (let i: number = 0; i < 4; i++)\r\n if ((bIsBoundary[i] && bIncludeCornerSpokes)\r\n || (!bIsBoundary[i] && bIncludeInterior))\r\n this.addEdge(xyzOut, midpoint[i], centroid);\r\n }\r\n } else if (numBoundary === 3) {\r\n if (bIncludeInterior)\r\n this.addEdge(xyzOut, midpoint[iInterior[0]], centroid);\r\n if (bIncludeFinal)\r\n this.addEdge(xyzOut, centroid, midpoint[iInterior[0] + 2]);\r\n }\r\n return true;\r\n }\r\n\r\n private getSpineEdgesInTriangle(\r\n pFace: HalfEdge, xyzOut: Point3d[][],\r\n bIncludeInterior: boolean,\r\n bIncludeFinal: boolean): boolean {\r\n\r\n if (pFace.countEdgesAroundFace() !== 3)\r\n return false;\r\n let n = 0;\r\n const xyzMidpoint = createNPoints(6);\r\n const xyz = createNPoints(6);\r\n const xyzCentroid = Point3d.createZero();\r\n const isBoundary: boolean[] = [];\r\n let numBoundary = 0;\r\n let lastBoundary = -1;\r\n let lastInterior = -1;\r\n let currentEdge = pFace;\r\n do {\r\n xyz[n] = currentEdge.getPoint3d();\r\n xyzCentroid.addInPlace(xyz[n]);\r\n isBoundary[n] = false;\r\n if (currentEdge.getMask(HalfEdgeMask.BOUNDARY_EDGE)) {\r\n isBoundary[n] = true;\r\n numBoundary++;\r\n lastBoundary = n;\r\n } else {\r\n lastInterior = n;\r\n }\r\n xyz[n + 3] = xyz[n];\r\n isBoundary[n + 3] = isBoundary[n];\r\n n++;\r\n } while ((currentEdge = currentEdge.faceSuccessor) !== pFace);\r\n\r\n for (let i: number = 0; i < 3; i++) {\r\n xyzMidpoint[i] = xyz[i].interpolate(0.5, xyz[i + 1]);\r\n xyzMidpoint[i + 3] = xyzMidpoint[i];\r\n }\r\n\r\n xyzCentroid.scaleInPlace(1.0 / 3.0);\r\n\r\n if (numBoundary === 0) {\r\n // Interior branch\r\n const xyzInterior = this.selectTriangleInteriorPoint(xyz);\r\n if (bIncludeInterior) {\r\n this.addEdge(xyzOut, xyzMidpoint[0], xyzInterior);\r\n this.addEdge(xyzOut, xyzMidpoint[1], xyzInterior);\r\n this.addEdge(xyzOut, xyzMidpoint[2], xyzInterior);\r\n }\r\n } else if (numBoundary === 1) {\r\n if (bIncludeInterior)\r\n this.addEdge(xyzOut, xyzMidpoint[lastBoundary + 1], xyzMidpoint[lastBoundary + 2]);\r\n } else if (numBoundary === 2) {\r\n if (bIncludeFinal && lastInterior >= 0)\r\n this.addEdge(xyzOut, xyzMidpoint[lastInterior], xyz[lastInterior + 2]);\r\n } else if (numBoundary === 3) {\r\n const xyzInterior = this.selectTriangleInteriorPoint(xyz);\r\n if (bIncludeFinal) {\r\n this.addEdge(xyzOut, xyzMidpoint[0], xyzInterior);\r\n this.addEdge(xyzOut, xyzMidpoint[1], xyzInterior);\r\n this.addEdge(xyzOut, xyzMidpoint[2], xyzInterior);\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n /** Add a polyline to the graph.\r\n * * This may be called multiple times\r\n */\r\n public insertEdges(xyzIn: Point3d[], bClosed: boolean): void {\r\n let pPreviousB, pFirstA;\r\n for (let i: number = 1; i < xyzIn.length; i++) {\r\n const nodeA = this._spineGraph.createEdgeXYZXYZ(\r\n xyzIn[i - 1].x, xyzIn[i - 1].y, 0, 0,\r\n xyzIn[i].x, xyzIn[i].y, 0, 0);\r\n const nodeB = nodeA.faceSuccessor;\r\n nodeA.setMask(HalfEdgeMask.BOUNDARY_EDGE);\r\n nodeB.setMask(HalfEdgeMask.BOUNDARY_EDGE);\r\n if (pPreviousB === undefined) {\r\n pFirstA = nodeA;\r\n } else {\r\n HalfEdge.pinch(pPreviousB, nodeA);\r\n }\r\n pPreviousB = nodeB;\r\n }\r\n if (bClosed && pFirstA !== undefined && pPreviousB !== undefined)\r\n HalfEdge.pinch(pPreviousB, pFirstA);\r\n }\r\n /**\r\n * Look for trivial (2 edge) faces that have exteriorMask and non-masked on both sides.\r\n * * clear the mask\r\n * @param exteriorMask\r\n */\r\n private purgeNullFaces(exteriorMask: HalfEdgeMask) {\r\n for (const nodeA of this._spineGraph.allHalfEdges) {\r\n const nodeB = nodeA.faceSuccessor;\r\n const nodeC = nodeB.faceSuccessor;\r\n if (nodeB !== nodeA && nodeC === nodeA) {\r\n if (nodeA.getMask(exteriorMask) && nodeB.getMask(exteriorMask)) {\r\n const mateA = nodeA.edgeMate;\r\n const mateB = nodeB.edgeMate;\r\n if (!mateA.getMask(exteriorMask) && !mateB.getMask(exteriorMask)) {\r\n nodeA.clearMask(exteriorMask);\r\n nodeB.clearMask(exteriorMask);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n private static _regularize1 = true;\r\n private static _regularize2 = false;\r\n /**\r\n * Triangulate the graph for the edges that have been inserted.\r\n * @param applyParity if true ()\r\n * @param minSplitRadians smallest allowed angle in the split sector that is split.\r\n */\r\n public triangulateForSpine(applyParity: boolean = true, minSplitRadians: number = 0.3): void {\r\n\r\n const sMaxSplit = 20;\r\n const sMinCandidateRadians = 1.0;\r\n let numSplit = 0;\r\n HalfEdgeGraphMerge.splitIntersectingEdges(this.graph);\r\n HalfEdgeGraphMerge.clusterAndMergeXYTheta(this.graph);\r\n\r\n const context1 = new RegularizationContext(this.graph);\r\n context1.regularizeGraph(HalfEdgeGraphSpineContext._regularize1, false);\r\n const context2 = new RegularizationContext(this.graph);\r\n context2.regularizeGraph(false, HalfEdgeGraphSpineContext._regularize2);\r\n if (applyParity) {\r\n HalfEdgeGraphSearch.collectConnectedComponentsWithExteriorParityMasks(this.graph,\r\n new HalfEdgeMaskTester(HalfEdgeMask.BOUNDARY_EDGE), HalfEdgeMask.EXTERIOR);\r\n this.purgeNullFaces(HalfEdgeMask.EXTERIOR);\r\n }\r\n\r\n Triangulator.triangulateAllPositiveAreaFaces(this.graph);\r\n Triangulator.flipTriangles(this.graph);\r\n\r\n while (numSplit++ < sMaxSplit) {\r\n const numPerp = this.addPerpendicularsToBoundaries(minSplitRadians, sMinCandidateRadians);\r\n if (numPerp <= 0)\r\n break;\r\n Triangulator.flipTriangles(this.graph);\r\n }\r\n }\r\n\r\n // Find pseudo spine edges\r\n // Optionally include pure internal midline segments.\r\n // Optionally include midline segments into \"dead end\"\r\n // Optionally include adjacent spokes to corner.\r\n /**\r\n * Retrieve edges of the spine as arrays of points.\r\n * @param bIncludeInterior true to include fully internal segments\r\n * @param bIncludeFinal true to include segments that terminate at a boundary\r\n * @param bIncludeCornerSpokes\r\n * @return array of line data.\r\n */\r\n public getSpineEdges(bIncludeInterior: boolean = true, bIncludeFinal: boolean = true, bIncludeCornerSpokes: boolean = true): Point3d[][] {\r\n const xyzOut: Point3d[][] = [];\r\n this._spineGraph.announceFaceLoops(\r\n (_graph: HalfEdgeGraph, faceSeed: HalfEdge) => {\r\n if (!faceSeed.getMask(HalfEdgeMask.EXTERIOR)) {\r\n if (this.getSpineEdgesInTriangle(faceSeed, xyzOut, bIncludeInterior, bIncludeFinal)) {\r\n } else if (this.getSpineEdgesInQuad(faceSeed, xyzOut, bIncludeInterior, bIncludeFinal, bIncludeCornerSpokes)) {\r\n }\r\n }\r\n return true;\r\n });\r\n return xyzOut;\r\n }\r\n\r\n /**\r\n * Intermediate markup step to identify quads between corresponding boundary edges.\r\n * * search for and mark triangle edges that should be treated as diagonal of a quad\r\n * * Angle logic is:\r\n * * In a candidate quad (formed by joining triangles that share an edge)\r\n * * form segments between opposite edges of the quad.\r\n * * compute angles between these segments and the edges of their quads.\r\n * * if this angle is larger than minAngleRadians, accept this as a quad.\r\n * * recommended angle is between 15 and 5 degrees; 50 degrees is typical\r\n * @param bDeleteDiagonals if true, eliminate the diagonals.\r\n * @param minAngleRadians angle tolerance, as described above.\r\n */\r\n public consolidateTrianglesToQuads(bDeleteDiagonals: boolean, minAngle: Angle = Angle.createDegrees(50)): number {\r\n\r\n const numDiagonal = this.setSortedDiagonalMasks(minAngle.radians);\r\n if (bDeleteDiagonals && numDiagonal > 0) {\r\n this.graph.yankAndDeleteEdges(\r\n (node: HalfEdge) => node.getMask(this._diagonalMask));\r\n }\r\n return numDiagonal;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"HalfEdgeGraphSpineContext.js","sourceRoot":"","sources":["../../../src/topology/HalfEdgeGraphSpineContext.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Topology\n */\nimport { Geometry } from \"../Geometry\";\nimport { HalfEdge, HalfEdgeGraph, HalfEdgeMask } from \"./Graph\";\nimport { Point3d, Vector3d } from \"../geometry3d/Point3dVector3d\";\nimport { HalfEdgeGraphMerge } from \"./Merging\";\nimport { Triangulator } from \"./Triangulation\";\nimport { RegularizationContext } from \"./RegularizeFace\";\nimport { HalfEdgeGraphSearch, HalfEdgeMaskTester } from \"./HalfEdgeGraphSearch\";\nimport { Angle } from \"../geometry3d/Angle\";\n// cSpell:disable\n// const sSpineRelTol = 1.0e-8;\n// const sSpineGraphAbsTol = 0.0;\n// const sSpineGraphRelTol = 1.0e-10;\n\nfunction createNPoints(n: number): Point3d[] {\n const points = [];\n for (let i = 0; i < n; i++)\n points.push(Point3d.create(0, 0, 0));\n return points;\n}\nfunction createNVectors(n: number): Vector3d[] {\n const points = [];\n for (let i = 0; i < n; i++)\n points.push(Vector3d.create(0, 0, 0));\n return points;\n}\n// Local struct to pair a graph node with a double as a sort key for std::sort\nclass NodeSortKey {\n private _a: number;\n private _node: HalfEdge;\n public get node() { return this._node; }\n\n public constructor(node: HalfEdge, b: number) {\n this._node = node;\n this._a = b;\n }\n public static compareForSort(dataA: NodeSortKey, dataB: NodeSortKey): number { return dataA._a - dataB._a; }\n}\n\n/**\n * Context manager to hold a vu graph and do spine operations\n *\n * Spine calculations determine both (a) a \"skeletal\" network of linework that follows the interior\n * path through within the boundaries, and (b) a block decomposition into quads and triangles.\n *\n * Usage pattern:\n * ```\n * const sc = new HalfEdgeGraphSpineContext();\n * // Data setup ....\n * foreach polygon or polyline\n * {\n * sc.InsertEdges (edgePoints, bClosed)\n * }\n * // Analysis steps ...\n * * bParity = true to treat the data as a \"polygon\". The interior is determined by parity rules\n * and the triangulation and spine are only constructed \"inside\"\n * * bParity = false if \"all\" spaces are to be triangulated and spined.\n * * minSplitRadians -- suggested value 0.3. If this value is large, it will encourage add internal\n * * edges from a vertex to an edge 'across' the polygon even if it creates small angles.\n * * minDiagonalAngle -- suggested value 1.0. If this value is large (up to about 1.5 as max) it favors\n * * using triangles to navigate turns. If it is small, it favors using skewed quadrilaterals.\n * sc.TriangulateForSpine (bParity, minSplitRadians)\n * sc.MarkBoxes (true, minDiagonalAngle);\n * edges = sc.GetSpineEdges ();\n * ```\n * @internal\n */\nexport class HalfEdgeGraphSpineContext {\n /** The Evolving graph */\n private _spineGraph: HalfEdgeGraph;\n /** mask marking edges that have been paired into quads */\n private _diagonalMask: HalfEdgeMask;\n private _boxMask: HalfEdgeMask;\n public get graph() { return this._spineGraph; }\n /**\n * Create a context with an empty graph.\n * * Reserve masks for specialized markup.\n */\n public constructor() {\n this._spineGraph = new HalfEdgeGraph();\n // vu_setTol (_spineGraph, sSpineGraphAbsTol, sSpineGraphRelTol);\n this._diagonalMask = this._spineGraph.grabMask();\n this._boxMask = this._spineGraph.grabMask();\n }\n\n /**\n * Release resources to the graph.\n */\n public teardown() {\n this._spineGraph.dropMask(this._diagonalMask);\n this._spineGraph.dropMask(this._boxMask);\n this._spineGraph.decommission();\n }\n\n // an edge (as new bvector<DPoint3d> at back, with cloned points>\n private addEdge(xyzOut: Point3d[][], xyzA: Point3d, xyzB: Point3d) {\n const newArray = [];\n newArray.push(xyzA.clone());\n newArray.push(xyzB.clone());\n xyzOut.push(newArray);\n }\n\n private getBoxCorners(diagonalNode: HalfEdge,\n nodes: HalfEdge[],\n points: Point3d[]): boolean {\n const diagonalMate = diagonalNode.edgeMate;\n nodes.length = 0;\n points.length = 0;\n if (!diagonalNode.getMask(HalfEdgeMask.BOUNDARY_EDGE)\n && diagonalNode.countEdgesAroundFace() === 3\n && diagonalMate.countEdgesAroundFace() === 3) {\n const nodeA = diagonalMate.faceSuccessor;\n nodes.push(nodeA);\n nodes.push(nodeA.faceSuccessor);\n const nodeB = diagonalNode.faceSuccessor;\n nodes.push(nodeB);\n nodes.push(nodeB.faceSuccessor);\n for (let i = 0; i < 4; i++)\n points.push(Point3d.create(nodes[i].x, nodes[i].y));\n return true;\n }\n return false;\n }\n\n // Compute bisectors of the quad.\n // function key is the smaller absolute angle between the bisectors.\n // (pi/2 is max possible value).\n private diagonalKeyFunc(pDiagonalNode: HalfEdge): number {\n\n const nodes: HalfEdge[] = [];\n const points: Point3d[] = [];\n if (this.getBoxCorners(pDiagonalNode, nodes, points)) {\n const xyzA = points[0];\n const xyzB = points[1];\n const xyzC = points[2];\n const xyzD = points[3];\n const xyzAB = xyzA.interpolate(0.5, xyzB);\n const xyzBC = xyzB.interpolate(0.5, xyzC);\n const xyzCD = xyzC.interpolate(0.5, xyzD);\n const xyzDA = xyzD.interpolate(0.5, xyzA);\n\n const vectorAB = Vector3d.createStartEnd(xyzA, xyzB);\n const vectorBC = Vector3d.createStartEnd(xyzB, xyzC);\n const vectorCD = Vector3d.createStartEnd(xyzC, xyzD);\n const vectorDA = Vector3d.createStartEnd(xyzD, xyzA);\n\n const vectorABToCD = Vector3d.createStartEnd(xyzCD, xyzAB);\n const vectorBCToDA = Vector3d.createStartEnd(xyzDA, xyzBC);\n vectorABToCD.z = 0.0;\n vectorBCToDA.z = 0.0;\n const thetaAB = vectorABToCD.smallerUnorientedAngleTo(vectorAB).radians;\n const thetaBC = vectorBCToDA.smallerUnorientedAngleTo(vectorBC).radians;\n const thetaCD = vectorABToCD.smallerUnorientedAngleTo(vectorCD).radians;\n const thetaDA = vectorBCToDA.smallerUnorientedAngleTo(vectorDA).radians;\n\n const alpha = thetaAB < thetaCD ? thetaAB : thetaCD;\n const beta = thetaBC < thetaDA ? thetaBC : thetaDA;\n return alpha < beta ? alpha : beta;\n }\n\n return Number.NEGATIVE_INFINITY;\n }\n\n // Select a branch point in a triangle.\n // This may be the centroid or the midpoint of an edge joining midpoints of a pair of edges.\n private selectTriangleInteriorPoint(pXYZ: Point3d[]): Point3d {\n\n const xyz = createNPoints(6);\n const xyzMid = createNPoints(6); // Midpoints of each edge.\n const interiorCandidate = createNPoints(4); // for i in {012}, [i] is midpoint of midpoint[i+1] and midpoint[i+2].\n // [3] is centroid.\n const edgeVector = createNVectors(6);\n const centroid = Point3d.create();\n for (let i = 0; i < 3; i++) {\n xyz[i] = xyz[i + 3] = pXYZ[i];\n centroid.addInPlace(xyz[i]);\n }\n centroid.scaleInPlace(1.0 / 3.0);\n\n // Edge midpoints ...\n for (let i = 0; i < 3; i++) {\n xyzMid[i] = xyz[i].interpolate(0.5, xyz[i + 1]);\n xyzMid[i + 3] = xyzMid[i];\n edgeVector[i] = Vector3d.createStartEnd(xyz[i], xyz[i + 1]); // use wraparound\n edgeVector[i + 3] = edgeVector[i];\n }\n\n // Midpoints of midpoint-to-midpoint connections ..\n for (let i = 0; i < 3; i++) {\n const i1 = i + 1;\n const i2 = i + 2;\n interiorCandidate[i] = xyzMid[i1].interpolate(0.5, xyzMid[i2]);\n }\n\n interiorCandidate[3] = centroid;\n\n let bestAngle = Number.NEGATIVE_INFINITY;\n let bestIndex = -1;\n const theta: number[] = [0, 0, 0];\n let thetaMin;\n for (let k: number = 0; k < 4; k++) {\n // Measure angles from edge midpoints towards interior candidate.\n thetaMin = Number.POSITIVE_INFINITY;\n for (let i: number = 0; i < 3; i++) {\n const edgeToInterior = Vector3d.createStartEnd(xyzMid[i], interiorCandidate[k]);\n theta[i] = edgeVector[i].smallerUnorientedAngleTo(edgeToInterior).radians;\n if (theta[i] < thetaMin)\n thetaMin = theta[i];\n }\n if (thetaMin > bestAngle) {\n bestAngle = thetaMin;\n bestIndex = k;\n }\n }\n return interiorCandidate[bestIndex];\n }\n\n private markBox(pA: HalfEdge): void {\n\n const pB = pA.edgeMate;\n pA.setMask(this._diagonalMask);\n pB.setMask(this._diagonalMask);\n pA.setMaskAroundFace(this._boxMask);\n pB.setMaskAroundFace(this._boxMask);\n }\n\n private setSortedDiagonalMasks(minA: number): number {\n\n const candidates: NodeSortKey[] = [];\n let numDiagonal = 0;\n for (const node of this._spineGraph.allHalfEdges) {\n const b = this.diagonalKeyFunc(node);\n if (b > minA)\n candidates.push(new NodeSortKey(node, b));\n }\n\n candidates.sort((dataA, dataB) => NodeSortKey.compareForSort(dataA, dataB));\n\n let key;\n while (undefined !== (key = candidates.pop())) {\n const pA = key.node;\n const pB = pA.edgeMate;\n if (!pA.getMask(this._boxMask)\n && !pB.getMask(this._boxMask)) {\n this.markBox(pA);\n numDiagonal++;\n }\n }\n return numDiagonal;\n }\n\n /// <param name=\"xyzA\">Vertex whose angle is being split</param>\n private splitOK(xyzA: Point3d, xyzB: Point3d, xyzQ: Point3d, xyzC: Point3d, minAngle: number): boolean {\n\n const vectorAB = Vector3d.createStartEnd(xyzA, xyzB);\n const vectorAQ = Vector3d.createStartEnd(xyzA, xyzQ);\n const vectorAC = Vector3d.createStartEnd(xyzA, xyzC);\n const angleBAQ = vectorAB.angleToXY(vectorAQ).radians;\n const angleQAC = vectorAQ.angleToXY(vectorAC).radians;\n return Math.abs(angleBAQ) > minAngle && Math.abs(angleQAC) > minAngle;\n }\n\n // Search a triangulation for vertices which have\n // (a) pre-split angle greater than 90 degrees\n // (b) the opposite edge is a boundary.\n // (c) each post split angle is less than minSplitRadians\n // Drop a perpenedicular to that boundary.\n // return the number of edges added.\n private addPerpendicularsToBoundaries(minSplitRadians: number, minCandidateRadians: number): number {\n\n let numAdd = 0;\n for (const pA of this._spineGraph.allHalfEdges) {\n const pB = pA.faceSuccessor;\n const pC = pB.faceSuccessor;\n if (!pA.getMask(HalfEdgeMask.EXTERIOR)\n && !pA.getMask(HalfEdgeMask.BOUNDARY_EDGE) // ?? prevent deep recursion\n && !pC.getMask(HalfEdgeMask.BOUNDARY_EDGE) // ?? prevent deep recursion\n && pB.getMask(HalfEdgeMask.BOUNDARY_EDGE)\n && pC.faceSuccessor === pA\n ) {\n const vectorAB = pA.getVector2dAlongEdge();\n const vectorBC = pB.getVector2dAlongEdge();\n const vectorCA = pC.getVector2dAlongEdge();\n const candidateRadians = Math.PI - vectorCA.angleTo(vectorAB).radians;\n // const candidateDot = vectorCA.DotProduct (vectorAB);\n if (candidateRadians > minCandidateRadians) { // vectorCA.DotProduct (vectorAB) > 0.0)\n const bb = vectorBC.dotProduct(vectorBC);\n const ba = -vectorBC.dotProduct(vectorAB);\n const s = Geometry.conditionalDivideFraction(ba, bb);\n if (s !== undefined && s > 0.0 && s < 1.0) {\n const xyzA = pA.getPoint3d();\n const xyzB = pB.getPoint3d();\n const xyzC = pC.getPoint3d();\n const xyzE = xyzB.interpolate(s, xyzC);\n if (this.splitOK(xyzA, xyzB, xyzE, xyzC, minSplitRadians)) {\n const pE = this._spineGraph.splitEdgeAtFraction(pB, s);\n const pA1 = this._spineGraph.createEdgeHalfEdgeHalfEdge(pA, 0, pE, 0);\n pA1.setXYZFrom(pA);\n pE.setXYZAroundVertex(xyzE.x, xyzE.y, xyzE.z);\n numAdd++;\n }\n }\n }\n }\n }\n return numAdd;\n }\n\n private getSpineEdgesInQuad(\n pFace: HalfEdge,\n xyzOut: Point3d[][],\n bIncludeInterior: boolean,\n // true to include the edge to boundary when the qued is a dead end.\n bIncludeFinal: boolean,\n // true to include the two adjacent edges to boundary if the quad is at a corner.\n bIncludeCornerSpokes: boolean): boolean {\n\n if (pFace.countEdgesAroundFace() !== 4)\n return false;\n const pNode: HalfEdge[] = [];\n const xyz = createNPoints(8);\n const midpoint = createNPoints(8);\n pNode[0] = pNode[4] = pFace;\n pNode[1] = pNode[5] = pNode[0].faceSuccessor;\n pNode[2] = pNode[6] = pNode[1].faceSuccessor;\n pNode[3] = pNode[7] = pNode[2].faceSuccessor;\n let numBoundary = 0;\n let numInterior = 0;\n const iBoundary: number[] = [];\n const iInterior: number[] = [];\n const bIsBoundary: boolean[] = [];\n const centroid = Point3d.create();\n for (let i: number = 0; i < 4; i++) {\n bIsBoundary[i] = 0 !== pNode[i].getMask(HalfEdgeMask.BOUNDARY_EDGE);\n if (pNode[i].getMask(HalfEdgeMask.BOUNDARY_EDGE))\n iBoundary[numBoundary++] = i;\n else\n iInterior[numInterior++] = i;\n xyz[i] = pNode[i].getPoint3d();\n xyz[i + 4] = xyz[i];\n centroid.addInPlace(xyz[i]);\n }\n for (let i: number = 0; i < 4; i++) {\n midpoint[i] = xyz[i].interpolate(0.5, xyz[i + 1]);\n midpoint[i + 4] = midpoint[i];\n }\n\n centroid.scaleInPlace(0.25);\n if (numBoundary === 0 || numBoundary === 1) {\n for (let i: number = 0; i < numInterior; i++)\n if (bIncludeInterior)\n this.addEdge(xyzOut, midpoint[iInterior[i]], centroid);\n } else if (numBoundary === 4) {\n for (let i: number = 0; i < numBoundary; i++)\n if (bIncludeFinal)\n this.addEdge(xyzOut, midpoint[i], centroid);\n } else if (numBoundary === 2) {\n if (iInterior[1] === iInterior[0] + 2) {\n // Spine enters one end, exits the other ..\n if (bIncludeInterior)\n this.addEdge(xyzOut, midpoint[iInterior[0]], midpoint[iInterior[1]]);\n } else {\n // Block sits as exterior corner. Let the two spines continue to their opposite faces ..\n for (let i: number = 0; i < 4; i++)\n if ((bIsBoundary[i] && bIncludeCornerSpokes)\n || (!bIsBoundary[i] && bIncludeInterior))\n this.addEdge(xyzOut, midpoint[i], centroid);\n }\n } else if (numBoundary === 3) {\n if (bIncludeInterior)\n this.addEdge(xyzOut, midpoint[iInterior[0]], centroid);\n if (bIncludeFinal)\n this.addEdge(xyzOut, centroid, midpoint[iInterior[0] + 2]);\n }\n return true;\n }\n\n private getSpineEdgesInTriangle(\n pFace: HalfEdge, xyzOut: Point3d[][],\n bIncludeInterior: boolean,\n bIncludeFinal: boolean): boolean {\n\n if (pFace.countEdgesAroundFace() !== 3)\n return false;\n let n = 0;\n const xyzMidpoint = createNPoints(6);\n const xyz = createNPoints(6);\n const xyzCentroid = Point3d.createZero();\n const isBoundary: boolean[] = [];\n let numBoundary = 0;\n let lastBoundary = -1;\n let lastInterior = -1;\n let currentEdge = pFace;\n do {\n xyz[n] = currentEdge.getPoint3d();\n xyzCentroid.addInPlace(xyz[n]);\n isBoundary[n] = false;\n if (currentEdge.getMask(HalfEdgeMask.BOUNDARY_EDGE)) {\n isBoundary[n] = true;\n numBoundary++;\n lastBoundary = n;\n } else {\n lastInterior = n;\n }\n xyz[n + 3] = xyz[n];\n isBoundary[n + 3] = isBoundary[n];\n n++;\n } while ((currentEdge = currentEdge.faceSuccessor) !== pFace);\n\n for (let i: number = 0; i < 3; i++) {\n xyzMidpoint[i] = xyz[i].interpolate(0.5, xyz[i + 1]);\n xyzMidpoint[i + 3] = xyzMidpoint[i];\n }\n\n xyzCentroid.scaleInPlace(1.0 / 3.0);\n\n if (numBoundary === 0) {\n // Interior branch\n const xyzInterior = this.selectTriangleInteriorPoint(xyz);\n if (bIncludeInterior) {\n this.addEdge(xyzOut, xyzMidpoint[0], xyzInterior);\n this.addEdge(xyzOut, xyzMidpoint[1], xyzInterior);\n this.addEdge(xyzOut, xyzMidpoint[2], xyzInterior);\n }\n } else if (numBoundary === 1) {\n if (bIncludeInterior)\n this.addEdge(xyzOut, xyzMidpoint[lastBoundary + 1], xyzMidpoint[lastBoundary + 2]);\n } else if (numBoundary === 2) {\n if (bIncludeFinal && lastInterior >= 0)\n this.addEdge(xyzOut, xyzMidpoint[lastInterior], xyz[lastInterior + 2]);\n } else if (numBoundary === 3) {\n const xyzInterior = this.selectTriangleInteriorPoint(xyz);\n if (bIncludeFinal) {\n this.addEdge(xyzOut, xyzMidpoint[0], xyzInterior);\n this.addEdge(xyzOut, xyzMidpoint[1], xyzInterior);\n this.addEdge(xyzOut, xyzMidpoint[2], xyzInterior);\n }\n }\n return true;\n }\n\n /** Add a polyline to the graph.\n * * This may be called multiple times\n */\n public insertEdges(xyzIn: Point3d[], bClosed: boolean): void {\n let pPreviousB, pFirstA;\n for (let i: number = 1; i < xyzIn.length; i++) {\n const nodeA = this._spineGraph.createEdgeXYZXYZ(\n xyzIn[i - 1].x, xyzIn[i - 1].y, 0, 0,\n xyzIn[i].x, xyzIn[i].y, 0, 0);\n const nodeB = nodeA.faceSuccessor;\n nodeA.setMask(HalfEdgeMask.BOUNDARY_EDGE);\n nodeB.setMask(HalfEdgeMask.BOUNDARY_EDGE);\n if (pPreviousB === undefined) {\n pFirstA = nodeA;\n } else {\n HalfEdge.pinch(pPreviousB, nodeA);\n }\n pPreviousB = nodeB;\n }\n if (bClosed && pFirstA !== undefined && pPreviousB !== undefined)\n HalfEdge.pinch(pPreviousB, pFirstA);\n }\n /**\n * Look for trivial (2 edge) faces that have exteriorMask and non-masked on both sides.\n * * clear the mask\n * @param exteriorMask\n */\n private purgeNullFaces(exteriorMask: HalfEdgeMask) {\n for (const nodeA of this._spineGraph.allHalfEdges) {\n const nodeB = nodeA.faceSuccessor;\n const nodeC = nodeB.faceSuccessor;\n if (nodeB !== nodeA && nodeC === nodeA) {\n if (nodeA.getMask(exteriorMask) && nodeB.getMask(exteriorMask)) {\n const mateA = nodeA.edgeMate;\n const mateB = nodeB.edgeMate;\n if (!mateA.getMask(exteriorMask) && !mateB.getMask(exteriorMask)) {\n nodeA.clearMask(exteriorMask);\n nodeB.clearMask(exteriorMask);\n }\n }\n }\n }\n }\n private static _regularize1 = true;\n private static _regularize2 = false;\n /**\n * Triangulate the graph for the edges that have been inserted.\n * @param applyParity if true ()\n * @param minSplitRadians smallest allowed angle in the split sector that is split.\n */\n public triangulateForSpine(applyParity: boolean = true, minSplitRadians: number = 0.3): void {\n\n const sMaxSplit = 20;\n const sMinCandidateRadians = 1.0;\n let numSplit = 0;\n HalfEdgeGraphMerge.splitIntersectingEdges(this.graph);\n HalfEdgeGraphMerge.clusterAndMergeXYTheta(this.graph);\n\n const context1 = new RegularizationContext(this.graph);\n context1.regularizeGraph(HalfEdgeGraphSpineContext._regularize1, false);\n const context2 = new RegularizationContext(this.graph);\n context2.regularizeGraph(false, HalfEdgeGraphSpineContext._regularize2);\n if (applyParity) {\n HalfEdgeGraphSearch.collectConnectedComponentsWithExteriorParityMasks(this.graph,\n new HalfEdgeMaskTester(HalfEdgeMask.BOUNDARY_EDGE), HalfEdgeMask.EXTERIOR);\n this.purgeNullFaces(HalfEdgeMask.EXTERIOR);\n }\n\n Triangulator.triangulateAllPositiveAreaFaces(this.graph);\n Triangulator.flipTriangles(this.graph);\n\n while (numSplit++ < sMaxSplit) {\n const numPerp = this.addPerpendicularsToBoundaries(minSplitRadians, sMinCandidateRadians);\n if (numPerp <= 0)\n break;\n Triangulator.flipTriangles(this.graph);\n }\n }\n\n // Find pseudo spine edges\n // Optionally include pure internal midline segments.\n // Optionally include midline segments into \"dead end\"\n // Optionally include adjacent spokes to corner.\n /**\n * Retrieve edges of the spine as arrays of points.\n * @param bIncludeInterior true to include fully internal segments\n * @param bIncludeFinal true to include segments that terminate at a boundary\n * @param bIncludeCornerSpokes\n * @return array of line data.\n */\n public getSpineEdges(bIncludeInterior: boolean = true, bIncludeFinal: boolean = true, bIncludeCornerSpokes: boolean = true): Point3d[][] {\n const xyzOut: Point3d[][] = [];\n this._spineGraph.announceFaceLoops(\n (_graph: HalfEdgeGraph, faceSeed: HalfEdge) => {\n if (!faceSeed.getMask(HalfEdgeMask.EXTERIOR)) {\n if (this.getSpineEdgesInTriangle(faceSeed, xyzOut, bIncludeInterior, bIncludeFinal)) {\n } else if (this.getSpineEdgesInQuad(faceSeed, xyzOut, bIncludeInterior, bIncludeFinal, bIncludeCornerSpokes)) {\n }\n }\n return true;\n });\n return xyzOut;\n }\n\n /**\n * Intermediate markup step to identify quads between corresponding boundary edges.\n * * search for and mark triangle edges that should be treated as diagonal of a quad\n * * Angle logic is:\n * * In a candidate quad (formed by joining triangles that share an edge)\n * * form segments between opposite edges of the quad.\n * * compute angles between these segments and the edges of their quads.\n * * if this angle is larger than minAngleRadians, accept this as a quad.\n * * recommended angle is between 15 and 5 degrees; 50 degrees is typical\n * @param bDeleteDiagonals if true, eliminate the diagonals.\n * @param minAngleRadians angle tolerance, as described above.\n */\n public consolidateTrianglesToQuads(bDeleteDiagonals: boolean, minAngle: Angle = Angle.createDegrees(50)): number {\n\n const numDiagonal = this.setSortedDiagonalMasks(minAngle.radians);\n if (bDeleteDiagonals && numDiagonal > 0) {\n this.graph.yankAndDeleteEdges(\n (node: HalfEdge) => node.getMask(this._diagonalMask));\n }\n return numDiagonal;\n }\n}\n"]}
@@ -2,8 +2,9 @@
2
2
  * @module Topology
3
3
  */
4
4
  import { HalfEdge, HalfEdgeGraph, HalfEdgeMask } from "./Graph";
5
- /** HalfEdgePointerInspector has methods to check HalfEdge objects for pointer errors.
6
- * * For a one-step test of the whole graph,
5
+ /**
6
+ * HalfEdgePointerInspector has methods to check HalfEdge objects for pointer errors.
7
+ * * For a one-step test of the whole graph.
7
8
  */
8
9
  export declare class HalfEdgePointerInspector {
9
10
  numUndefinedEdgeMate: number;
@@ -13,39 +14,43 @@ export declare class HalfEdgePointerInspector {
13
14
  numMatePairError: number;
14
15
  numTested: number;
15
16
  numWithMatchedEdgeMate: number;
16
- /** Clear all counts */
17
+ /** Clear all counts. */
17
18
  clearCounts(): void;
18
- /** Inspect a single half edge. Increment counters according to the half edge's pointers. */
19
+ /** Inspect a single half edge. Increment counters according to the half edge's pointers. */
19
20
  inspectHalfEdge(he: HalfEdge): void;
20
- /** Return true if all pointer pairings are correct for a complete half edge graph:
21
+ /**
22
+ * Return true if all pointer pairings are correct for a closed half edge graph (with no boundary):
21
23
  * * For each he: `he.edgeMate.edgeMate === he`
22
- * * For each he: `he.faceSuccessor.facePredecessor !== he`
23
- * * For each he: `he.facePredecessor.faceSuccessor !== he`
24
+ * * For each he: `he.faceSuccessor.facePredecessor === he`
25
+ * * For each he: `he.facePredecessor.faceSuccessor === he`
24
26
  */
25
27
  get isValidClosedHalfEdgeGraph(): boolean;
26
- /** Return true if all counts are correct for a half edge graph that has complete pairings:
28
+ /**
29
+ * Return true if all pointer pairings are correct for a half edge graph with possible boundary:
27
30
  * * For each he: `he.edgeMate.edgeMate === he`
28
- * * For each he: `he.faceSuccessor.facePredecessor !== he`
29
- * * For each he: `he.facePredecessor.faceSuccessor !== he`
31
+ * * For each he: `he.faceSuccessor.facePredecessor === he`
32
+ * * For each he: `he.facePredecessor.faceSuccessor === he`
30
33
  */
31
34
  get isValidHalfEdgeGraphAllowRaggedBoundary(): boolean;
32
- /** inspect all half edges of graph.
33
- * All pointer counts are left in member vars for later inspection.
35
+ /**
36
+ * Inspect all half edges of graph.
37
+ * * All pointer counts are left in member vars for later inspection.
34
38
  */
35
39
  inspectHalfEdges(graph: HalfEdgeGraph): void;
36
- /** Inspect a graph's pointer properties.
37
- * @param expectAllMates [in] true for "complete" graph with
38
- * @returns true if all pointers are valid
40
+ /**
41
+ * Inspect a graph's pointer properties.
42
+ * @param expectAllMates true for "complete" graph.
43
+ * @returns true if all pointers are valid.
39
44
  */
40
45
  static inspectGraph(graph: HalfEdgeGraph, expectAllMates: boolean): boolean;
41
46
  }
42
- /** static methods to inspect mask consistency properties in HalfEdgeGraph. */
47
+ /** Static methods to inspect mask consistency properties in HalfEdgeGraph. */
43
48
  export declare class HalfEdgeMaskValidation {
44
49
  /**
45
50
  * Test if a mask is used consistently around faces.
46
- * * At the low level, there is no actual traversal around faces. It is only necessary to verify that the mask matches for each HalfEdge and its faceSuccessor.
51
+ * * At the low level, there is no actual traversal around faces. It is only necessary to verify that the mask
52
+ * matches for each HalfEdge and its faceSuccessor.
47
53
  * @returns Return true if mask is "all or nothing around all faces"
48
- *
49
54
  */
50
55
  static isMaskConsistentAroundAllFaces(graph: HalfEdgeGraph, mask: HalfEdgeMask): boolean;
51
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"HalfEdgeGraphValidation.d.ts","sourceRoot":"","sources":["../../../src/topology/HalfEdgeGraphValidation.ts"],"names":[],"mappings":"AAKA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGhE;;GAEG;AACH,qBAAa,wBAAwB;IAC5B,oBAAoB,EAAE,MAAM,CAAK;IACjC,cAAc,EAAE,MAAM,CAAK;IAC3B,cAAc,EAAE,MAAM,CAAK;IAC3B,YAAY,EAAE,MAAM,CAAK;IACzB,gBAAgB,EAAE,MAAM,CAAK;IAC7B,SAAS,EAAE,MAAM,CAAK;IACtB,sBAAsB,EAAE,MAAM,CAAK;IAC1C,uBAAuB;IAChB,WAAW;IASlB,8FAA8F;IACvF,eAAe,CAAC,EAAE,EAAE,QAAQ;IAYnC;;;;OAIG;IACH,IAAW,0BAA0B,IAAI,OAAO,CAM/C;IACD;;;;OAIG;IACH,IAAW,uCAAuC,IAAI,OAAO,CAM5D;IACD;;OAEG;IACI,gBAAgB,CAAC,KAAK,EAAE,aAAa;IAK5C;;;OAGG;WACW,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,OAAO,GAAG,OAAO;CAMnF;AACD,8EAA8E;AAC9E,qBAAa,sBAAsB;IACjC;;;;;OAKG;WACW,8BAA8B,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO;CAOhG"}
1
+ {"version":3,"file":"HalfEdgeGraphValidation.d.ts","sourceRoot":"","sources":["../../../src/topology/HalfEdgeGraphValidation.ts"],"names":[],"mappings":"AAKA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGhE;;;GAGG;AACH,qBAAa,wBAAwB;IAC5B,oBAAoB,EAAE,MAAM,CAAK;IACjC,cAAc,EAAE,MAAM,CAAK;IAC3B,cAAc,EAAE,MAAM,CAAK;IAC3B,YAAY,EAAE,MAAM,CAAK;IACzB,gBAAgB,EAAE,MAAM,CAAK;IAC7B,SAAS,EAAE,MAAM,CAAK;IACtB,sBAAsB,EAAE,MAAM,CAAK;IAC1C,wBAAwB;IACjB,WAAW;IASlB,4FAA4F;IACrF,eAAe,CAAC,EAAE,EAAE,QAAQ;IAmBnC;;;;;OAKG;IACH,IAAW,0BAA0B,IAAI,OAAO,CAM/C;IACD;;;;;OAKG;IACH,IAAW,uCAAuC,IAAI,OAAO,CAM5D;IACD;;;OAGG;IACI,gBAAgB,CAAC,KAAK,EAAE,aAAa;IAK5C;;;;OAIG;WACW,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,OAAO,GAAG,OAAO;CAOnF;AACD,8EAA8E;AAC9E,qBAAa,sBAAsB;IACjC;;;;;OAKG;WACW,8BAA8B,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO;CAOhG"}
@@ -3,8 +3,9 @@
3
3
  * See LICENSE.md in the project root for license terms and full copyright notice.
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  // Search services for HalfEdgeGraph
6
- /** HalfEdgePointerInspector has methods to check HalfEdge objects for pointer errors.
7
- * * For a one-step test of the whole graph,
6
+ /**
7
+ * HalfEdgePointerInspector has methods to check HalfEdge objects for pointer errors.
8
+ * * For a one-step test of the whole graph.
8
9
  */
9
10
  export class HalfEdgePointerInspector {
10
11
  constructor() {
@@ -16,7 +17,7 @@ export class HalfEdgePointerInspector {
16
17
  this.numTested = 0;
17
18
  this.numWithMatchedEdgeMate = 0;
18
19
  }
19
- /** Clear all counts */
20
+ /** Clear all counts. */
20
21
  clearCounts() {
21
22
  this.numUndefinedEdgeMate = 0;
22
23
  this.numUndefinedFP = 0;
@@ -26,7 +27,7 @@ export class HalfEdgePointerInspector {
26
27
  this.numWithMatchedEdgeMate = 0;
27
28
  this.numTested = 0;
28
29
  }
29
- /** Inspect a single half edge. Increment counters according to the half edge's pointers. */
30
+ /** Inspect a single half edge. Increment counters according to the half edge's pointers. */
30
31
  inspectHalfEdge(he) {
31
32
  this.numTested++;
32
33
  if (he.facePredecessor === undefined)
@@ -44,10 +45,11 @@ export class HalfEdgePointerInspector {
44
45
  else
45
46
  this.numMatePairError++;
46
47
  }
47
- /** Return true if all pointer pairings are correct for a complete half edge graph:
48
+ /**
49
+ * Return true if all pointer pairings are correct for a closed half edge graph (with no boundary):
48
50
  * * For each he: `he.edgeMate.edgeMate === he`
49
- * * For each he: `he.faceSuccessor.facePredecessor !== he`
50
- * * For each he: `he.facePredecessor.faceSuccessor !== he`
51
+ * * For each he: `he.faceSuccessor.facePredecessor === he`
52
+ * * For each he: `he.facePredecessor.faceSuccessor === he`
51
53
  */
52
54
  get isValidClosedHalfEdgeGraph() {
53
55
  return this.numWithMatchedEdgeMate === this.numTested
@@ -56,10 +58,11 @@ export class HalfEdgePointerInspector {
56
58
  && this.numFSFPError === 0
57
59
  && this.numMatePairError === 0;
58
60
  }
59
- /** Return true if all counts are correct for a half edge graph that has complete pairings:
61
+ /**
62
+ * Return true if all pointer pairings are correct for a half edge graph with possible boundary:
60
63
  * * For each he: `he.edgeMate.edgeMate === he`
61
- * * For each he: `he.faceSuccessor.facePredecessor !== he`
62
- * * For each he: `he.facePredecessor.faceSuccessor !== he`
64
+ * * For each he: `he.faceSuccessor.facePredecessor === he`
65
+ * * For each he: `he.facePredecessor.faceSuccessor === he`
63
66
  */
64
67
  get isValidHalfEdgeGraphAllowRaggedBoundary() {
65
68
  return this.numWithMatchedEdgeMate + this.numUndefinedEdgeMate === this.numTested
@@ -68,17 +71,19 @@ export class HalfEdgePointerInspector {
68
71
  && this.numFSFPError === 0
69
72
  && this.numMatePairError === 0;
70
73
  }
71
- /** inspect all half edges of graph.
72
- * All pointer counts are left in member vars for later inspection.
74
+ /**
75
+ * Inspect all half edges of graph.
76
+ * * All pointer counts are left in member vars for later inspection.
73
77
  */
74
78
  inspectHalfEdges(graph) {
75
79
  this.clearCounts();
76
80
  for (const he of graph.allHalfEdges)
77
81
  this.inspectHalfEdge(he);
78
82
  }
79
- /** Inspect a graph's pointer properties.
80
- * @param expectAllMates [in] true for "complete" graph with
81
- * @returns true if all pointers are valid
83
+ /**
84
+ * Inspect a graph's pointer properties.
85
+ * @param expectAllMates true for "complete" graph.
86
+ * @returns true if all pointers are valid.
82
87
  */
83
88
  static inspectGraph(graph, expectAllMates) {
84
89
  const inspector = new HalfEdgePointerInspector();
@@ -88,13 +93,13 @@ export class HalfEdgePointerInspector {
88
93
  return inspector.isValidHalfEdgeGraphAllowRaggedBoundary;
89
94
  }
90
95
  }
91
- /** static methods to inspect mask consistency properties in HalfEdgeGraph. */
96
+ /** Static methods to inspect mask consistency properties in HalfEdgeGraph. */
92
97
  export class HalfEdgeMaskValidation {
93
98
  /**
94
99
  * Test if a mask is used consistently around faces.
95
- * * At the low level, there is no actual traversal around faces. It is only necessary to verify that the mask matches for each HalfEdge and its faceSuccessor.
100
+ * * At the low level, there is no actual traversal around faces. It is only necessary to verify that the mask
101
+ * matches for each HalfEdge and its faceSuccessor.
96
102
  * @returns Return true if mask is "all or nothing around all faces"
97
- *
98
103
  */
99
104
  static isMaskConsistentAroundAllFaces(graph, mask) {
100
105
  for (const he of graph.allHalfEdges) {
@@ -1 +1 @@
1
- {"version":3,"file":"HalfEdgeGraphValidation.js","sourceRoot":"","sources":["../../../src/topology/HalfEdgeGraphValidation.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/** @packageDocumentation\r\n * @module Topology\r\n */\r\n// cspell:word FSFP\r\nimport { HalfEdge, HalfEdgeGraph, HalfEdgeMask } from \"./Graph\";\r\n\r\n// Search services for HalfEdgeGraph\r\n/** HalfEdgePointerInspector has methods to check HalfEdge objects for pointer errors.\r\n * * For a one-step test of the whole graph,\r\n */\r\nexport class HalfEdgePointerInspector {\r\n public numUndefinedEdgeMate: number = 0;\r\n public numUndefinedFS: number = 0;\r\n public numUndefinedFP: number = 0;\r\n public numFSFPError: number = 0;\r\n public numMatePairError: number = 0;\r\n public numTested: number = 0;\r\n public numWithMatchedEdgeMate: number = 0;\r\n /** Clear all counts */\r\n public clearCounts() {\r\n this.numUndefinedEdgeMate = 0;\r\n this.numUndefinedFP = 0;\r\n this.numUndefinedFS = 0;\r\n this.numFSFPError = 0;\r\n this.numMatePairError = 0;\r\n this.numWithMatchedEdgeMate = 0;\r\n this.numTested = 0;\r\n }\r\n /** Inspect a single half edge. Increment counters according to the half edge's pointers. */\r\n public inspectHalfEdge(he: HalfEdge) {\r\n this.numTested++;\r\n if (he.facePredecessor === undefined) this.numUndefinedFP++;\r\n else if (he.facePredecessor.faceSuccessor !== he) this.numFSFPError++;\r\n\r\n if (he.faceSuccessor === undefined) this.numUndefinedFS++;\r\n else if (he.faceSuccessor.facePredecessor !== he) this.numFSFPError++;\r\n\r\n if (he.edgeMate === undefined) this.numUndefinedEdgeMate++;\r\n else if (he.edgeMate.edgeMate === he) this.numWithMatchedEdgeMate++;\r\n else this.numMatePairError++;\r\n }\r\n /** Return true if all pointer pairings are correct for a complete half edge graph:\r\n * * For each he: `he.edgeMate.edgeMate === he`\r\n * * For each he: `he.faceSuccessor.facePredecessor !== he`\r\n * * For each he: `he.facePredecessor.faceSuccessor !== he`\r\n */\r\n public get isValidClosedHalfEdgeGraph(): boolean {\r\n return this.numWithMatchedEdgeMate === this.numTested\r\n && this.numUndefinedFS === 0\r\n && this.numUndefinedFP === 0\r\n && this.numFSFPError === 0\r\n && this.numMatePairError === 0;\r\n }\r\n /** Return true if all counts are correct for a half edge graph that has complete pairings:\r\n * * For each he: `he.edgeMate.edgeMate === he`\r\n * * For each he: `he.faceSuccessor.facePredecessor !== he`\r\n * * For each he: `he.facePredecessor.faceSuccessor !== he`\r\n */\r\n public get isValidHalfEdgeGraphAllowRaggedBoundary(): boolean {\r\n return this.numWithMatchedEdgeMate + this.numUndefinedEdgeMate === this.numTested\r\n && this.numUndefinedFS === 0\r\n && this.numUndefinedFP === 0\r\n && this.numFSFPError === 0\r\n && this.numMatePairError === 0;\r\n }\r\n /** inspect all half edges of graph.\r\n * All pointer counts are left in member vars for later inspection.\r\n */\r\n public inspectHalfEdges(graph: HalfEdgeGraph) {\r\n this.clearCounts();\r\n for (const he of graph.allHalfEdges) this.inspectHalfEdge(he);\r\n\r\n }\r\n /** Inspect a graph's pointer properties.\r\n * @param expectAllMates [in] true for \"complete\" graph with\r\n * @returns true if all pointers are valid\r\n */\r\n public static inspectGraph(graph: HalfEdgeGraph, expectAllMates: boolean): boolean {\r\n const inspector = new HalfEdgePointerInspector();\r\n inspector.inspectHalfEdges(graph);\r\n if (expectAllMates) return inspector.isValidClosedHalfEdgeGraph;\r\n return inspector.isValidHalfEdgeGraphAllowRaggedBoundary;\r\n }\r\n}\r\n/** static methods to inspect mask consistency properties in HalfEdgeGraph. */\r\nexport class HalfEdgeMaskValidation {\r\n /**\r\n * Test if a mask is used consistently around faces.\r\n * * At the low level, there is no actual traversal around faces. It is only necessary to verify that the mask matches for each HalfEdge and its faceSuccessor.\r\n * @returns Return true if mask is \"all or nothing around all faces\"\r\n *\r\n */\r\n public static isMaskConsistentAroundAllFaces(graph: HalfEdgeGraph, mask: HalfEdgeMask): boolean {\r\n for (const he of graph.allHalfEdges) {\r\n if (he.faceSuccessor.getMask(mask) !== he.getMask(mask))\r\n return false;\r\n }\r\n return true;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"HalfEdgeGraphValidation.js","sourceRoot":"","sources":["../../../src/topology/HalfEdgeGraphValidation.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\n/** @packageDocumentation\n * @module Topology\n */\n// cspell:word FSFP\nimport { HalfEdge, HalfEdgeGraph, HalfEdgeMask } from \"./Graph\";\n\n// Search services for HalfEdgeGraph\n/**\n * HalfEdgePointerInspector has methods to check HalfEdge objects for pointer errors.\n * * For a one-step test of the whole graph.\n */\nexport class HalfEdgePointerInspector {\n public numUndefinedEdgeMate: number = 0;\n public numUndefinedFS: number = 0;\n public numUndefinedFP: number = 0;\n public numFSFPError: number = 0;\n public numMatePairError: number = 0;\n public numTested: number = 0;\n public numWithMatchedEdgeMate: number = 0;\n /** Clear all counts. */\n public clearCounts() {\n this.numUndefinedEdgeMate = 0;\n this.numUndefinedFP = 0;\n this.numUndefinedFS = 0;\n this.numFSFPError = 0;\n this.numMatePairError = 0;\n this.numWithMatchedEdgeMate = 0;\n this.numTested = 0;\n }\n /** Inspect a single half edge. Increment counters according to the half edge's pointers. */\n public inspectHalfEdge(he: HalfEdge) {\n this.numTested++;\n if (he.facePredecessor === undefined)\n this.numUndefinedFP++;\n else if (he.facePredecessor.faceSuccessor !== he)\n this.numFSFPError++;\n\n if (he.faceSuccessor === undefined)\n this.numUndefinedFS++;\n else if (he.faceSuccessor.facePredecessor !== he)\n this.numFSFPError++;\n\n if (he.edgeMate === undefined)\n this.numUndefinedEdgeMate++;\n else if (he.edgeMate.edgeMate === he)\n this.numWithMatchedEdgeMate++;\n else\n this.numMatePairError++;\n }\n /**\n * Return true if all pointer pairings are correct for a closed half edge graph (with no boundary):\n * * For each he: `he.edgeMate.edgeMate === he`\n * * For each he: `he.faceSuccessor.facePredecessor === he`\n * * For each he: `he.facePredecessor.faceSuccessor === he`\n */\n public get isValidClosedHalfEdgeGraph(): boolean {\n return this.numWithMatchedEdgeMate === this.numTested\n && this.numUndefinedFS === 0\n && this.numUndefinedFP === 0\n && this.numFSFPError === 0\n && this.numMatePairError === 0;\n }\n /**\n * Return true if all pointer pairings are correct for a half edge graph with possible boundary:\n * * For each he: `he.edgeMate.edgeMate === he`\n * * For each he: `he.faceSuccessor.facePredecessor === he`\n * * For each he: `he.facePredecessor.faceSuccessor === he`\n */\n public get isValidHalfEdgeGraphAllowRaggedBoundary(): boolean {\n return this.numWithMatchedEdgeMate + this.numUndefinedEdgeMate === this.numTested\n && this.numUndefinedFS === 0\n && this.numUndefinedFP === 0\n && this.numFSFPError === 0\n && this.numMatePairError === 0;\n }\n /**\n * Inspect all half edges of graph.\n * * All pointer counts are left in member vars for later inspection.\n */\n public inspectHalfEdges(graph: HalfEdgeGraph) {\n this.clearCounts();\n for (const he of graph.allHalfEdges)\n this.inspectHalfEdge(he);\n }\n /**\n * Inspect a graph's pointer properties.\n * @param expectAllMates true for \"complete\" graph.\n * @returns true if all pointers are valid.\n */\n public static inspectGraph(graph: HalfEdgeGraph, expectAllMates: boolean): boolean {\n const inspector = new HalfEdgePointerInspector();\n inspector.inspectHalfEdges(graph);\n if (expectAllMates)\n return inspector.isValidClosedHalfEdgeGraph;\n return inspector.isValidHalfEdgeGraphAllowRaggedBoundary;\n }\n}\n/** Static methods to inspect mask consistency properties in HalfEdgeGraph. */\nexport class HalfEdgeMaskValidation {\n /**\n * Test if a mask is used consistently around faces.\n * * At the low level, there is no actual traversal around faces. It is only necessary to verify that the mask\n * matches for each HalfEdge and its faceSuccessor.\n * @returns Return true if mask is \"all or nothing around all faces\"\n */\n public static isMaskConsistentAroundAllFaces(graph: HalfEdgeGraph, mask: HalfEdgeMask): boolean {\n for (const he of graph.allHalfEdges) {\n if (he.faceSuccessor.getMask(mask) !== he.getMask(mask))\n return false;\n }\n return true;\n }\n}\n"]}