@itwin/core-geometry 4.0.0-dev.4 → 4.0.0-dev.40

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 (344) hide show
  1. package/CHANGELOG.md +17 -3
  2. package/lib/cjs/Geometry.d.ts +56 -16
  3. package/lib/cjs/Geometry.d.ts.map +1 -1
  4. package/lib/cjs/Geometry.js +87 -30
  5. package/lib/cjs/Geometry.js.map +1 -1
  6. package/lib/cjs/bspline/BSplineCurveOps.js +4 -5
  7. package/lib/cjs/bspline/BSplineCurveOps.js.map +1 -1
  8. package/lib/cjs/bspline/InterpolationCurve3d.js +7 -10
  9. package/lib/cjs/bspline/InterpolationCurve3d.js.map +1 -1
  10. package/lib/cjs/clipping/ClipPrimitive.js +2 -2
  11. package/lib/cjs/clipping/ClipPrimitive.js.map +1 -1
  12. package/lib/cjs/clipping/ClipUtils.js +4 -4
  13. package/lib/cjs/clipping/ClipUtils.js.map +1 -1
  14. package/lib/cjs/clipping/internalContexts/LineStringOffsetClipperContext.js +2 -2
  15. package/lib/cjs/clipping/internalContexts/LineStringOffsetClipperContext.js.map +1 -1
  16. package/lib/cjs/curve/CurveChainWithDistanceIndex.d.ts.map +1 -1
  17. package/lib/cjs/curve/CurveChainWithDistanceIndex.js +20 -13
  18. package/lib/cjs/curve/CurveChainWithDistanceIndex.js.map +1 -1
  19. package/lib/cjs/curve/CurveCollection.js +1 -1
  20. package/lib/cjs/curve/CurveCollection.js.map +1 -1
  21. package/lib/cjs/curve/CurveCurve.d.ts +11 -8
  22. package/lib/cjs/curve/CurveCurve.d.ts.map +1 -1
  23. package/lib/cjs/curve/CurveCurve.js +16 -12
  24. package/lib/cjs/curve/CurveCurve.js.map +1 -1
  25. package/lib/cjs/curve/CurveCurveIntersectXY.d.ts +5 -1
  26. package/lib/cjs/curve/CurveCurveIntersectXY.d.ts.map +1 -1
  27. package/lib/cjs/curve/CurveCurveIntersectXY.js +11 -10
  28. package/lib/cjs/curve/CurveCurveIntersectXY.js.map +1 -1
  29. package/lib/cjs/curve/Loop.d.ts +2 -2
  30. package/lib/cjs/curve/Loop.d.ts.map +1 -1
  31. package/lib/cjs/curve/Loop.js +6 -0
  32. package/lib/cjs/curve/Loop.js.map +1 -1
  33. package/lib/cjs/curve/RegionOps.d.ts +10 -10
  34. package/lib/cjs/curve/RegionOps.d.ts.map +1 -1
  35. package/lib/cjs/curve/RegionOps.js +11 -11
  36. package/lib/cjs/curve/RegionOps.js.map +1 -1
  37. package/lib/cjs/curve/RegionOpsClassificationSweeps.d.ts +2 -1
  38. package/lib/cjs/curve/RegionOpsClassificationSweeps.d.ts.map +1 -1
  39. package/lib/cjs/curve/RegionOpsClassificationSweeps.js +5 -2
  40. package/lib/cjs/curve/RegionOpsClassificationSweeps.js.map +1 -1
  41. package/lib/cjs/curve/StrokeOptions.js +1 -2
  42. package/lib/cjs/curve/StrokeOptions.js.map +1 -1
  43. package/lib/cjs/curve/spiral/DirectSpiral3d.js +1 -2
  44. package/lib/cjs/curve/spiral/DirectSpiral3d.js.map +1 -1
  45. package/lib/cjs/curve/spiral/IntegratedSpiral3d.js +1 -2
  46. package/lib/cjs/curve/spiral/IntegratedSpiral3d.js.map +1 -1
  47. package/lib/cjs/geometry3d/Angle.d.ts +19 -0
  48. package/lib/cjs/geometry3d/Angle.d.ts.map +1 -1
  49. package/lib/cjs/geometry3d/Angle.js +39 -0
  50. package/lib/cjs/geometry3d/Angle.js.map +1 -1
  51. package/lib/cjs/geometry3d/AngleSweep.d.ts +1 -0
  52. package/lib/cjs/geometry3d/AngleSweep.d.ts.map +1 -1
  53. package/lib/cjs/geometry3d/AngleSweep.js +1 -0
  54. package/lib/cjs/geometry3d/AngleSweep.js.map +1 -1
  55. package/lib/cjs/geometry3d/BarycentricTriangle.d.ts +195 -8
  56. package/lib/cjs/geometry3d/BarycentricTriangle.d.ts.map +1 -1
  57. package/lib/cjs/geometry3d/BarycentricTriangle.js +459 -11
  58. package/lib/cjs/geometry3d/BarycentricTriangle.js.map +1 -1
  59. package/lib/cjs/geometry3d/CoincidentGeometryOps.d.ts +1 -0
  60. package/lib/cjs/geometry3d/CoincidentGeometryOps.d.ts.map +1 -1
  61. package/lib/cjs/geometry3d/CoincidentGeometryOps.js +3 -0
  62. package/lib/cjs/geometry3d/CoincidentGeometryOps.js.map +1 -1
  63. package/lib/cjs/geometry3d/GrowableFloat64Array.js +2 -2
  64. package/lib/cjs/geometry3d/GrowableFloat64Array.js.map +1 -1
  65. package/lib/cjs/geometry3d/GrowableXYArray.d.ts +1 -1
  66. package/lib/cjs/geometry3d/GrowableXYArray.d.ts.map +1 -1
  67. package/lib/cjs/geometry3d/GrowableXYArray.js +2 -2
  68. package/lib/cjs/geometry3d/GrowableXYArray.js.map +1 -1
  69. package/lib/cjs/geometry3d/GrowableXYZArray.js +1 -1
  70. package/lib/cjs/geometry3d/GrowableXYZArray.js.map +1 -1
  71. package/lib/cjs/geometry3d/IndexedXYCollection.d.ts +22 -7
  72. package/lib/cjs/geometry3d/IndexedXYCollection.d.ts.map +1 -1
  73. package/lib/cjs/geometry3d/IndexedXYCollection.js +41 -5
  74. package/lib/cjs/geometry3d/IndexedXYCollection.js.map +1 -1
  75. package/lib/cjs/geometry3d/IndexedXYZCollection.d.ts +58 -4
  76. package/lib/cjs/geometry3d/IndexedXYZCollection.d.ts.map +1 -1
  77. package/lib/cjs/geometry3d/IndexedXYZCollection.js +102 -4
  78. package/lib/cjs/geometry3d/IndexedXYZCollection.js.map +1 -1
  79. package/lib/cjs/geometry3d/Matrix3d.d.ts +479 -265
  80. package/lib/cjs/geometry3d/Matrix3d.d.ts.map +1 -1
  81. package/lib/cjs/geometry3d/Matrix3d.js +996 -784
  82. package/lib/cjs/geometry3d/Matrix3d.js.map +1 -1
  83. package/lib/cjs/geometry3d/OrderedRotationAngles.d.ts +1 -0
  84. package/lib/cjs/geometry3d/OrderedRotationAngles.d.ts.map +1 -1
  85. package/lib/cjs/geometry3d/OrderedRotationAngles.js +1 -0
  86. package/lib/cjs/geometry3d/OrderedRotationAngles.js.map +1 -1
  87. package/lib/cjs/geometry3d/Point2dArrayCarrier.d.ts +10 -0
  88. package/lib/cjs/geometry3d/Point2dArrayCarrier.d.ts.map +1 -1
  89. package/lib/cjs/geometry3d/Point2dArrayCarrier.js +14 -0
  90. package/lib/cjs/geometry3d/Point2dArrayCarrier.js.map +1 -1
  91. package/lib/cjs/geometry3d/Point2dVector2d.js +4 -6
  92. package/lib/cjs/geometry3d/Point2dVector2d.js.map +1 -1
  93. package/lib/cjs/geometry3d/Point3dArrayCarrier.d.ts +0 -6
  94. package/lib/cjs/geometry3d/Point3dArrayCarrier.d.ts.map +1 -1
  95. package/lib/cjs/geometry3d/Point3dArrayCarrier.js +0 -6
  96. package/lib/cjs/geometry3d/Point3dArrayCarrier.js.map +1 -1
  97. package/lib/cjs/geometry3d/Point3dVector3d.d.ts +57 -57
  98. package/lib/cjs/geometry3d/Point3dVector3d.d.ts.map +1 -1
  99. package/lib/cjs/geometry3d/Point3dVector3d.js +63 -65
  100. package/lib/cjs/geometry3d/Point3dVector3d.js.map +1 -1
  101. package/lib/cjs/geometry3d/PointHelpers.d.ts +14 -1
  102. package/lib/cjs/geometry3d/PointHelpers.d.ts.map +1 -1
  103. package/lib/cjs/geometry3d/PointHelpers.js +33 -1
  104. package/lib/cjs/geometry3d/PointHelpers.js.map +1 -1
  105. package/lib/cjs/geometry3d/PolygonOps.d.ts +127 -19
  106. package/lib/cjs/geometry3d/PolygonOps.d.ts.map +1 -1
  107. package/lib/cjs/geometry3d/PolygonOps.js +420 -22
  108. package/lib/cjs/geometry3d/PolygonOps.js.map +1 -1
  109. package/lib/cjs/geometry3d/Ray3d.js +1 -1
  110. package/lib/cjs/geometry3d/Ray3d.js.map +1 -1
  111. package/lib/cjs/geometry3d/Segment1d.d.ts +1 -1
  112. package/lib/cjs/geometry3d/Segment1d.js +1 -1
  113. package/lib/cjs/geometry3d/Segment1d.js.map +1 -1
  114. package/lib/cjs/numerics/Polynomials.d.ts +12 -0
  115. package/lib/cjs/numerics/Polynomials.d.ts.map +1 -1
  116. package/lib/cjs/numerics/Polynomials.js +14 -0
  117. package/lib/cjs/numerics/Polynomials.js.map +1 -1
  118. package/lib/cjs/polyface/AuxData.js +1 -1
  119. package/lib/cjs/polyface/AuxData.js.map +1 -1
  120. package/lib/cjs/polyface/FacetLocationDetail.d.ts +264 -0
  121. package/lib/cjs/polyface/FacetLocationDetail.d.ts.map +1 -0
  122. package/lib/cjs/polyface/FacetLocationDetail.js +376 -0
  123. package/lib/cjs/polyface/FacetLocationDetail.js.map +1 -0
  124. package/lib/cjs/polyface/IndexedPolyfaceVisitor.d.ts +2 -5
  125. package/lib/cjs/polyface/IndexedPolyfaceVisitor.d.ts.map +1 -1
  126. package/lib/cjs/polyface/IndexedPolyfaceVisitor.js +5 -2
  127. package/lib/cjs/polyface/IndexedPolyfaceVisitor.js.map +1 -1
  128. package/lib/cjs/polyface/PolyfaceBuilder.d.ts +24 -14
  129. package/lib/cjs/polyface/PolyfaceBuilder.d.ts.map +1 -1
  130. package/lib/cjs/polyface/PolyfaceBuilder.js +74 -23
  131. package/lib/cjs/polyface/PolyfaceBuilder.js.map +1 -1
  132. package/lib/cjs/polyface/PolyfaceClip.js +6 -7
  133. package/lib/cjs/polyface/PolyfaceClip.js.map +1 -1
  134. package/lib/cjs/polyface/PolyfaceData.d.ts +1 -1
  135. package/lib/cjs/polyface/PolyfaceData.d.ts.map +1 -1
  136. package/lib/cjs/polyface/PolyfaceData.js.map +1 -1
  137. package/lib/cjs/polyface/PolyfaceQuery.d.ts +76 -1
  138. package/lib/cjs/polyface/PolyfaceQuery.d.ts.map +1 -1
  139. package/lib/cjs/polyface/PolyfaceQuery.js +123 -3
  140. package/lib/cjs/polyface/PolyfaceQuery.js.map +1 -1
  141. package/lib/cjs/polyface/multiclip/OffsetMeshContext.d.ts +202 -0
  142. package/lib/cjs/polyface/multiclip/OffsetMeshContext.d.ts.map +1 -0
  143. package/lib/cjs/polyface/multiclip/OffsetMeshContext.js +1038 -0
  144. package/lib/cjs/polyface/multiclip/OffsetMeshContext.js.map +1 -0
  145. package/lib/cjs/serialization/BGFBReader.js +4 -4
  146. package/lib/cjs/serialization/BGFBReader.js.map +1 -1
  147. package/lib/cjs/serialization/GeometrySamples.d.ts +8 -6
  148. package/lib/cjs/serialization/GeometrySamples.d.ts.map +1 -1
  149. package/lib/cjs/serialization/GeometrySamples.js +26 -19
  150. package/lib/cjs/serialization/GeometrySamples.js.map +1 -1
  151. package/lib/cjs/serialization/IModelJsonSchema.js +1 -2
  152. package/lib/cjs/serialization/IModelJsonSchema.js.map +1 -1
  153. package/lib/cjs/solid/Sphere.d.ts +5 -5
  154. package/lib/cjs/solid/Sphere.js +5 -5
  155. package/lib/cjs/solid/Sphere.js.map +1 -1
  156. package/lib/cjs/solid/SweepContour.d.ts.map +1 -1
  157. package/lib/cjs/solid/SweepContour.js +8 -1
  158. package/lib/cjs/solid/SweepContour.js.map +1 -1
  159. package/lib/cjs/topology/Graph.d.ts +113 -7
  160. package/lib/cjs/topology/Graph.d.ts.map +1 -1
  161. package/lib/cjs/topology/Graph.js +185 -7
  162. package/lib/cjs/topology/Graph.js.map +1 -1
  163. package/lib/cjs/topology/HalfEdgeGraphFromIndexedLoopsContext.d.ts +38 -0
  164. package/lib/cjs/topology/HalfEdgeGraphFromIndexedLoopsContext.d.ts.map +1 -0
  165. package/lib/cjs/topology/HalfEdgeGraphFromIndexedLoopsContext.js +82 -0
  166. package/lib/cjs/topology/HalfEdgeGraphFromIndexedLoopsContext.js.map +1 -0
  167. package/lib/cjs/topology/HalfEdgeGraphSearch.d.ts +2 -1
  168. package/lib/cjs/topology/HalfEdgeGraphSearch.d.ts.map +1 -1
  169. package/lib/cjs/topology/HalfEdgeGraphSearch.js +1 -0
  170. package/lib/cjs/topology/HalfEdgeGraphSearch.js.map +1 -1
  171. package/lib/cjs/topology/Triangulation.js +1 -1
  172. package/lib/cjs/topology/Triangulation.js.map +1 -1
  173. package/lib/esm/Geometry.d.ts +56 -16
  174. package/lib/esm/Geometry.d.ts.map +1 -1
  175. package/lib/esm/Geometry.js +86 -29
  176. package/lib/esm/Geometry.js.map +1 -1
  177. package/lib/esm/bspline/BSplineCurveOps.js +4 -5
  178. package/lib/esm/bspline/BSplineCurveOps.js.map +1 -1
  179. package/lib/esm/bspline/InterpolationCurve3d.js +7 -10
  180. package/lib/esm/bspline/InterpolationCurve3d.js.map +1 -1
  181. package/lib/esm/clipping/ClipPrimitive.js +2 -2
  182. package/lib/esm/clipping/ClipPrimitive.js.map +1 -1
  183. package/lib/esm/clipping/ClipUtils.js +4 -4
  184. package/lib/esm/clipping/ClipUtils.js.map +1 -1
  185. package/lib/esm/clipping/internalContexts/LineStringOffsetClipperContext.js +2 -2
  186. package/lib/esm/clipping/internalContexts/LineStringOffsetClipperContext.js.map +1 -1
  187. package/lib/esm/curve/CurveChainWithDistanceIndex.d.ts.map +1 -1
  188. package/lib/esm/curve/CurveChainWithDistanceIndex.js +21 -14
  189. package/lib/esm/curve/CurveChainWithDistanceIndex.js.map +1 -1
  190. package/lib/esm/curve/CurveCollection.js +1 -1
  191. package/lib/esm/curve/CurveCollection.js.map +1 -1
  192. package/lib/esm/curve/CurveCurve.d.ts +11 -8
  193. package/lib/esm/curve/CurveCurve.d.ts.map +1 -1
  194. package/lib/esm/curve/CurveCurve.js +16 -12
  195. package/lib/esm/curve/CurveCurve.js.map +1 -1
  196. package/lib/esm/curve/CurveCurveIntersectXY.d.ts +5 -1
  197. package/lib/esm/curve/CurveCurveIntersectXY.d.ts.map +1 -1
  198. package/lib/esm/curve/CurveCurveIntersectXY.js +11 -10
  199. package/lib/esm/curve/CurveCurveIntersectXY.js.map +1 -1
  200. package/lib/esm/curve/Loop.d.ts +2 -2
  201. package/lib/esm/curve/Loop.d.ts.map +1 -1
  202. package/lib/esm/curve/Loop.js +6 -0
  203. package/lib/esm/curve/Loop.js.map +1 -1
  204. package/lib/esm/curve/RegionOps.d.ts +10 -10
  205. package/lib/esm/curve/RegionOps.d.ts.map +1 -1
  206. package/lib/esm/curve/RegionOps.js +11 -11
  207. package/lib/esm/curve/RegionOps.js.map +1 -1
  208. package/lib/esm/curve/RegionOpsClassificationSweeps.d.ts +2 -1
  209. package/lib/esm/curve/RegionOpsClassificationSweeps.d.ts.map +1 -1
  210. package/lib/esm/curve/RegionOpsClassificationSweeps.js +5 -2
  211. package/lib/esm/curve/RegionOpsClassificationSweeps.js.map +1 -1
  212. package/lib/esm/curve/StrokeOptions.js +1 -2
  213. package/lib/esm/curve/StrokeOptions.js.map +1 -1
  214. package/lib/esm/curve/spiral/DirectSpiral3d.js +1 -2
  215. package/lib/esm/curve/spiral/DirectSpiral3d.js.map +1 -1
  216. package/lib/esm/curve/spiral/IntegratedSpiral3d.js +1 -2
  217. package/lib/esm/curve/spiral/IntegratedSpiral3d.js.map +1 -1
  218. package/lib/esm/geometry3d/Angle.d.ts +19 -0
  219. package/lib/esm/geometry3d/Angle.d.ts.map +1 -1
  220. package/lib/esm/geometry3d/Angle.js +39 -0
  221. package/lib/esm/geometry3d/Angle.js.map +1 -1
  222. package/lib/esm/geometry3d/AngleSweep.d.ts +1 -0
  223. package/lib/esm/geometry3d/AngleSweep.d.ts.map +1 -1
  224. package/lib/esm/geometry3d/AngleSweep.js +1 -0
  225. package/lib/esm/geometry3d/AngleSweep.js.map +1 -1
  226. package/lib/esm/geometry3d/BarycentricTriangle.d.ts +195 -8
  227. package/lib/esm/geometry3d/BarycentricTriangle.d.ts.map +1 -1
  228. package/lib/esm/geometry3d/BarycentricTriangle.js +459 -12
  229. package/lib/esm/geometry3d/BarycentricTriangle.js.map +1 -1
  230. package/lib/esm/geometry3d/CoincidentGeometryOps.d.ts +1 -0
  231. package/lib/esm/geometry3d/CoincidentGeometryOps.d.ts.map +1 -1
  232. package/lib/esm/geometry3d/CoincidentGeometryOps.js +3 -0
  233. package/lib/esm/geometry3d/CoincidentGeometryOps.js.map +1 -1
  234. package/lib/esm/geometry3d/GrowableFloat64Array.js +2 -2
  235. package/lib/esm/geometry3d/GrowableFloat64Array.js.map +1 -1
  236. package/lib/esm/geometry3d/GrowableXYArray.d.ts +1 -1
  237. package/lib/esm/geometry3d/GrowableXYArray.d.ts.map +1 -1
  238. package/lib/esm/geometry3d/GrowableXYArray.js +2 -2
  239. package/lib/esm/geometry3d/GrowableXYArray.js.map +1 -1
  240. package/lib/esm/geometry3d/GrowableXYZArray.js +1 -1
  241. package/lib/esm/geometry3d/GrowableXYZArray.js.map +1 -1
  242. package/lib/esm/geometry3d/IndexedXYCollection.d.ts +22 -7
  243. package/lib/esm/geometry3d/IndexedXYCollection.d.ts.map +1 -1
  244. package/lib/esm/geometry3d/IndexedXYCollection.js +41 -5
  245. package/lib/esm/geometry3d/IndexedXYCollection.js.map +1 -1
  246. package/lib/esm/geometry3d/IndexedXYZCollection.d.ts +58 -4
  247. package/lib/esm/geometry3d/IndexedXYZCollection.d.ts.map +1 -1
  248. package/lib/esm/geometry3d/IndexedXYZCollection.js +103 -5
  249. package/lib/esm/geometry3d/IndexedXYZCollection.js.map +1 -1
  250. package/lib/esm/geometry3d/Matrix3d.d.ts +479 -265
  251. package/lib/esm/geometry3d/Matrix3d.d.ts.map +1 -1
  252. package/lib/esm/geometry3d/Matrix3d.js +996 -784
  253. package/lib/esm/geometry3d/Matrix3d.js.map +1 -1
  254. package/lib/esm/geometry3d/OrderedRotationAngles.d.ts +1 -0
  255. package/lib/esm/geometry3d/OrderedRotationAngles.d.ts.map +1 -1
  256. package/lib/esm/geometry3d/OrderedRotationAngles.js +1 -0
  257. package/lib/esm/geometry3d/OrderedRotationAngles.js.map +1 -1
  258. package/lib/esm/geometry3d/Point2dArrayCarrier.d.ts +10 -0
  259. package/lib/esm/geometry3d/Point2dArrayCarrier.d.ts.map +1 -1
  260. package/lib/esm/geometry3d/Point2dArrayCarrier.js +14 -0
  261. package/lib/esm/geometry3d/Point2dArrayCarrier.js.map +1 -1
  262. package/lib/esm/geometry3d/Point2dVector2d.js +4 -6
  263. package/lib/esm/geometry3d/Point2dVector2d.js.map +1 -1
  264. package/lib/esm/geometry3d/Point3dArrayCarrier.d.ts +0 -6
  265. package/lib/esm/geometry3d/Point3dArrayCarrier.d.ts.map +1 -1
  266. package/lib/esm/geometry3d/Point3dArrayCarrier.js +0 -6
  267. package/lib/esm/geometry3d/Point3dArrayCarrier.js.map +1 -1
  268. package/lib/esm/geometry3d/Point3dVector3d.d.ts +57 -57
  269. package/lib/esm/geometry3d/Point3dVector3d.d.ts.map +1 -1
  270. package/lib/esm/geometry3d/Point3dVector3d.js +63 -65
  271. package/lib/esm/geometry3d/Point3dVector3d.js.map +1 -1
  272. package/lib/esm/geometry3d/PointHelpers.d.ts +14 -1
  273. package/lib/esm/geometry3d/PointHelpers.d.ts.map +1 -1
  274. package/lib/esm/geometry3d/PointHelpers.js +33 -1
  275. package/lib/esm/geometry3d/PointHelpers.js.map +1 -1
  276. package/lib/esm/geometry3d/PolygonOps.d.ts +127 -19
  277. package/lib/esm/geometry3d/PolygonOps.d.ts.map +1 -1
  278. package/lib/esm/geometry3d/PolygonOps.js +419 -22
  279. package/lib/esm/geometry3d/PolygonOps.js.map +1 -1
  280. package/lib/esm/geometry3d/Ray3d.js +1 -1
  281. package/lib/esm/geometry3d/Ray3d.js.map +1 -1
  282. package/lib/esm/geometry3d/Segment1d.d.ts +1 -1
  283. package/lib/esm/geometry3d/Segment1d.js +1 -1
  284. package/lib/esm/geometry3d/Segment1d.js.map +1 -1
  285. package/lib/esm/numerics/Polynomials.d.ts +12 -0
  286. package/lib/esm/numerics/Polynomials.d.ts.map +1 -1
  287. package/lib/esm/numerics/Polynomials.js +14 -0
  288. package/lib/esm/numerics/Polynomials.js.map +1 -1
  289. package/lib/esm/polyface/AuxData.js +1 -1
  290. package/lib/esm/polyface/AuxData.js.map +1 -1
  291. package/lib/esm/polyface/FacetLocationDetail.d.ts +264 -0
  292. package/lib/esm/polyface/FacetLocationDetail.d.ts.map +1 -0
  293. package/lib/esm/polyface/FacetLocationDetail.js +369 -0
  294. package/lib/esm/polyface/FacetLocationDetail.js.map +1 -0
  295. package/lib/esm/polyface/IndexedPolyfaceVisitor.d.ts +2 -5
  296. package/lib/esm/polyface/IndexedPolyfaceVisitor.d.ts.map +1 -1
  297. package/lib/esm/polyface/IndexedPolyfaceVisitor.js +5 -2
  298. package/lib/esm/polyface/IndexedPolyfaceVisitor.js.map +1 -1
  299. package/lib/esm/polyface/PolyfaceBuilder.d.ts +24 -14
  300. package/lib/esm/polyface/PolyfaceBuilder.d.ts.map +1 -1
  301. package/lib/esm/polyface/PolyfaceBuilder.js +74 -23
  302. package/lib/esm/polyface/PolyfaceBuilder.js.map +1 -1
  303. package/lib/esm/polyface/PolyfaceClip.js +6 -7
  304. package/lib/esm/polyface/PolyfaceClip.js.map +1 -1
  305. package/lib/esm/polyface/PolyfaceData.d.ts +1 -1
  306. package/lib/esm/polyface/PolyfaceData.d.ts.map +1 -1
  307. package/lib/esm/polyface/PolyfaceData.js.map +1 -1
  308. package/lib/esm/polyface/PolyfaceQuery.d.ts +76 -1
  309. package/lib/esm/polyface/PolyfaceQuery.d.ts.map +1 -1
  310. package/lib/esm/polyface/PolyfaceQuery.js +121 -2
  311. package/lib/esm/polyface/PolyfaceQuery.js.map +1 -1
  312. package/lib/esm/polyface/multiclip/OffsetMeshContext.d.ts +202 -0
  313. package/lib/esm/polyface/multiclip/OffsetMeshContext.d.ts.map +1 -0
  314. package/lib/esm/polyface/multiclip/OffsetMeshContext.js +1032 -0
  315. package/lib/esm/polyface/multiclip/OffsetMeshContext.js.map +1 -0
  316. package/lib/esm/serialization/BGFBReader.js +4 -4
  317. package/lib/esm/serialization/BGFBReader.js.map +1 -1
  318. package/lib/esm/serialization/GeometrySamples.d.ts +8 -6
  319. package/lib/esm/serialization/GeometrySamples.d.ts.map +1 -1
  320. package/lib/esm/serialization/GeometrySamples.js +26 -19
  321. package/lib/esm/serialization/GeometrySamples.js.map +1 -1
  322. package/lib/esm/serialization/IModelJsonSchema.js +1 -2
  323. package/lib/esm/serialization/IModelJsonSchema.js.map +1 -1
  324. package/lib/esm/solid/Sphere.d.ts +5 -5
  325. package/lib/esm/solid/Sphere.js +5 -5
  326. package/lib/esm/solid/Sphere.js.map +1 -1
  327. package/lib/esm/solid/SweepContour.d.ts.map +1 -1
  328. package/lib/esm/solid/SweepContour.js +8 -1
  329. package/lib/esm/solid/SweepContour.js.map +1 -1
  330. package/lib/esm/topology/Graph.d.ts +113 -7
  331. package/lib/esm/topology/Graph.d.ts.map +1 -1
  332. package/lib/esm/topology/Graph.js +185 -7
  333. package/lib/esm/topology/Graph.js.map +1 -1
  334. package/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.d.ts +38 -0
  335. package/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.d.ts.map +1 -0
  336. package/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js +78 -0
  337. package/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js.map +1 -0
  338. package/lib/esm/topology/HalfEdgeGraphSearch.d.ts +2 -1
  339. package/lib/esm/topology/HalfEdgeGraphSearch.d.ts.map +1 -1
  340. package/lib/esm/topology/HalfEdgeGraphSearch.js +1 -0
  341. package/lib/esm/topology/HalfEdgeGraphSearch.js.map +1 -1
  342. package/lib/esm/topology/Triangulation.js +1 -1
  343. package/lib/esm/topology/Triangulation.js.map +1 -1
  344. package/package.json +5 -5
@@ -45,6 +45,7 @@ class HalfEdgeGraphSearch {
45
45
  /**
46
46
  * Search an array of faceSeed nodes for the face with the most negative area.
47
47
  * @param oneCandidateNodePerFace array containing one node from each face to be considered.
48
+ * @returns node on the minimum area face, or undefined if no such face (e.g., all faces have zero area).
48
49
  */
49
50
  static findMinimumAreaFace(oneCandidateNodePerFace, faceAreaFunction) {
50
51
  const summary = HalfEdgeGraphSearch.collectFaceAreaSummary(oneCandidateNodePerFace, false, faceAreaFunction);
@@ -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 */\r\n public static findMinimumAreaFace(oneCandidateNodePerFace: HalfEdgeGraph | HalfEdge[],\r\n faceAreaFunction?: NodeToNumberFunction): HalfEdge {\r\n const summary = HalfEdgeGraphSearch.collectFaceAreaSummary(oneCandidateNodePerFace, false, faceAreaFunction);\r\n return summary.largestNegativeItem!;\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 = HalfEdgeGraphSearch.signedFaceArea): 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":["/*---------------------------------------------------------------------------------------------\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 = HalfEdgeGraphSearch.signedFaceArea): 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"]}
@@ -469,7 +469,7 @@ class Triangulator {
469
469
  ear.clearMaskAroundFace(Graph_1.HalfEdgeMask.TRIANGULATED_FACE);
470
470
  // iterate through ears, slicing them one by one
471
471
  while (!ear.isMaskSet(Graph_1.HalfEdgeMask.TRIANGULATED_FACE)) {
472
- pred = ear === null || ear === void 0 ? void 0 : ear.facePredecessor;
472
+ pred = ear?.facePredecessor;
473
473
  next = ear.faceSuccessor;
474
474
  next2 = next.faceSuccessor;
475
475
  if (next === ear || next2 === ear)
@@ -1 +1 @@
1
- {"version":3,"file":"Triangulation.js","sourceRoot":"","sources":["../../../src/topology/Triangulation.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 { ClipUtilities } from \"../clipping/ClipUtils\";\r\nimport { Geometry } from \"../Geometry\";\r\nimport { GrowableXYZArray } from \"../geometry3d/GrowableXYZArray\";\r\nimport { IndexedXYZCollection } from \"../geometry3d/IndexedXYZCollection\";\r\nimport { Plane3dByOriginAndUnitNormal } from \"../geometry3d/Plane3dByOriginAndUnitNormal\";\r\nimport { Point3d } from \"../geometry3d/Point3dVector3d\";\r\nimport { Point3dArray } from \"../geometry3d/PointHelpers\";\r\nimport { PointStreamXYZXYZHandlerBase, VariantPointDataStream } from \"../geometry3d/PointStreaming\";\r\nimport { Range1d, Range2d } from \"../geometry3d/Range\";\r\nimport { XAndY, XYAndZ } from \"../geometry3d/XYZProps\";\r\nimport { HalfEdge, HalfEdgeGraph, HalfEdgeMask } from \"./Graph\";\r\nimport { MarkedEdgeSet } from \"./HalfEdgeMarkSet\";\r\nimport { InsertAndRetriangulateContext } from \"./InsertAndRetriangulateContext\";\r\n\r\n/**\r\n * type for use as signature for xyz data of a single linestring appearing in a parameter list.\r\n * @public\r\n */\r\nexport type LineStringDataVariant = IndexedXYZCollection | XYAndZ[] | XAndY[] | number[][];\r\n\r\n/**\r\n * type for use as signature for multiple xyz data of multiple linestrings appearing in a parameter list.\r\n * @public\r\n */\r\nexport type MultiLineStringDataVariant = LineStringDataVariant | LineStringDataVariant[];\r\n\r\n/**\r\n * (static) methods for triangulating polygons\r\n * * @internal\r\n */\r\nexport class Triangulator {\r\n\r\n /** Given the six nodes that make up two bordering triangles, \"pinch\" and relocate the nodes to flip them\r\n * * The shared edge mates are c and e.\r\n * * (abc) are a triangle in CCW order\r\n * * (dfe) are a triangle in CCW order. (!! node dfe instead of def.)\r\n */\r\n private static flipEdgeBetweenTriangles(a: HalfEdge, b: HalfEdge, c: HalfEdge, d: HalfEdge, e: HalfEdge, f: HalfEdge) {\r\n // Reassign all of the pointers\r\n HalfEdge.pinch(a, e);\r\n HalfEdge.pinch(c, d);\r\n HalfEdge.pinch(f, c);\r\n HalfEdge.pinch(e, b);\r\n\r\n // Move alpha and beta into the xy coordinates of their predecessors\r\n e.x = b.x;\r\n e.y = b.y;\r\n e.z = b.z;\r\n e.i = b.i;\r\n c.i = f.i;\r\n c.x = f.x;\r\n c.y = f.y;\r\n c.z = f.z;\r\n }\r\n /**\r\n * * nodeA is a given node\r\n * * nodeA1 is its nodeA.faceSuccessor\r\n * * nodeA2 is nodeA1.faceSuccessor, i.e. 3rd node of triangle A\r\n * * nodeB is nodeA.edgeMate, i.e. a node in the \"other\" triangle at nodeA's edge\r\n * * nodeB1 is nodeB.faceSuccessor\r\n * * nodeB2 is nodeB1.faceSuccessor, i.e the 3rd node of triangle B\r\n * Construct (as simple doubles, to avoid object creation) xy vectors from:\r\n * * (ux,uy): nodeA to nodeA1, i.e. the shared edge\r\n * * (vx,vy): nodeA to nodeA2,\r\n * * (wx,wy): nodeA to nodeB2\r\n * * this determinant is positive if nodeA is \"in the circle\" of nodeB2, nodeA1, nodeA2\r\n * * Return true if clearly positive\r\n * * Return false if clearly negative or almost zero.\r\n * @param nodeA node on the diagonal edge of candidate for edge flip.\r\n */\r\n public static computeInCircleDeterminantIsStrongPositive(nodeA: HalfEdge): boolean {\r\n // Assume triangle A1,A2,B2 is ccw.\r\n // Shift the triangle to the origin (by negated A coords).\r\n // The Delaunay condition is computed by projecting the origin and the shifted triangle\r\n // points up to the paraboloid z = x*x + y*y. Due to the radially symmetric convexity of\r\n // this surface and the ccw orientation of this triangle, \"A is inside triangle A1,A2,B2\"\r\n // is equivalent to \"the volume of the parallelepiped formed by the projected points is\r\n // negative, as computed by the triple product.\"\r\n const nodeA1 = nodeA.faceSuccessor;\r\n const nodeA2 = nodeA1.faceSuccessor;\r\n if (nodeA2.faceSuccessor !== nodeA)\r\n return false;\r\n const nodeB = nodeA.edgeMate;\r\n const nodeB1 = nodeB.faceSuccessor;\r\n const nodeB2 = nodeB1.faceSuccessor;\r\n if (nodeB2.faceSuccessor !== nodeB)\r\n return false;\r\n const ux = nodeA1.x - nodeA.x;\r\n const uy = nodeA1.y - nodeA.y;\r\n const vx = nodeA2.x - nodeA.x;\r\n const vy = nodeA2.y - nodeA.y;\r\n if (Geometry.crossProductXYXY(ux, uy, vx, vy) < 0)\r\n return false;\r\n // we assume identical coordinates in pairs (nodeA, nodeB1) and (nodeA1, nodeB)\r\n const wx = nodeB2.x - nodeA.x;\r\n const wy = nodeB2.y - nodeA.y;\r\n const tx = wx * wx + wy * wy;\r\n const ty = vx * vx + vy * vy;\r\n const tz = ux * ux + uy * uy;\r\n const q = Geometry.tripleProduct(\r\n wx, wy, tx,\r\n vx, vy, ty,\r\n ux, uy, tz);\r\n if (q < 0)\r\n return false;\r\n const denom = Math.abs(wx * vy * tz) + Math.abs(wy * ty * ux) + Math.abs(tx * vx * uy)\r\n + Math.abs(wx * ty * uy) + Math.abs(wy * vx * tz) + Math.abs(tx * vy * ux);\r\n return q > 1.0e-12 * denom;\r\n }\r\n\r\n /**\r\n * * Visit each node of the graph array\r\n * * If a flip would be possible, test the results of flipping using incircle condition\r\n * * If revealed to be an improvement, conduct the flip, mark involved nodes as unvisited, and repeat until all nodes are visited\r\n */\r\n public static flipTriangles(graph: HalfEdgeGraph): number {\r\n const edgeSet = MarkedEdgeSet.create(graph)!;\r\n for (const node of graph.allHalfEdges)\r\n edgeSet.addToSet(node);\r\n const numFlip = this.flipTrianglesInEdgeSet(graph, edgeSet);\r\n edgeSet.teardown();\r\n return numFlip;\r\n }\r\n\r\n /**\r\n * * Visit each node of the graph array\r\n * * If a flip would be possible, test the results of flipping using incircle condition\r\n * * If revealed to be an improvement, conduct the flip, mark involved nodes as unvisited, and repeat until all nodes are visited\r\n */\r\n public static flipTrianglesInEdgeSet(graph: HalfEdgeGraph, edgeSet: MarkedEdgeSet): number {\r\n const barrierMasks = HalfEdgeMask.EXTERIOR | HalfEdgeMask.PRIMARY_EDGE | HalfEdgeMask.BOUNDARY_EDGE;\r\n\r\n const nodeArray = graph.allHalfEdges;\r\n const maxTest = 10.0 * nodeArray.length;\r\n let numFlip = 0;\r\n let numOK = 0;\r\n let node;\r\n while (undefined !== (node = edgeSet.chooseAndRemoveAny())) {\r\n\r\n if (node.isMaskSet(barrierMasks)) // Flip not allowed\r\n continue;\r\n\r\n if (Triangulator.computeInCircleDeterminantIsStrongPositive(node)) {\r\n // Flip the triangles\r\n Triangulator.flipEdgeBetweenTriangles(node.edgeMate.faceSuccessor, node.edgeMate.facePredecessor, node.edgeMate, node.faceSuccessor, node, node.facePredecessor);\r\n // keep looking at the 2 faces\r\n edgeSet.addAroundFace(node);\r\n edgeSet.addAroundFace(node.edgeMate);\r\n numFlip++;\r\n } else {\r\n numOK++;\r\n }\r\n if (numFlip + numOK > maxTest)\r\n break;\r\n }\r\n return numFlip;\r\n }\r\n\r\n /** Create a graph with a triangulation points.\r\n * * The outer limit of the graph is the convex hull of the points.\r\n * * The outside loop is marked `HalfEdgeMask.EXTERIOR`\r\n */\r\n public static createTriangulatedGraphFromPoints(points: Point3d[]): HalfEdgeGraph | undefined {\r\n if (points.length < 3)\r\n return undefined;\r\n const hull: Point3d[] = [];\r\n const interior: Point3d[] = [];\r\n Point3dArray.computeConvexHullXY(points, hull, interior, true);\r\n const graph = new HalfEdgeGraph();\r\n const context = InsertAndRetriangulateContext.create(graph);\r\n Triangulator.createFaceLoopFromCoordinates(graph, hull, true, true);\r\n // HalfEdgeGraphMerge.clusterAndMergeXYTheta(graph);\r\n let numInsert = 0;\r\n for (const p of interior) {\r\n context.insertAndRetriangulate(p, true);\r\n numInsert++;\r\n if (numInsert > 16) {\r\n /*\r\n context.reset();\r\n Triangulator.flipTriangles(context.graph);\r\n // console.log (\" intermediate flips \" + numFlip);\r\n */\r\n numInsert = 0;\r\n }\r\n }\r\n /*\r\n // final touchup for aspect ratio flip\r\n for (let i = 0; i < 15; i++) {\r\n const numFlip = Triangulator.flipTriangles(graph);\r\n if (numFlip === 0)\r\n break;\r\n }\r\n */\r\n return graph;\r\n }\r\n /**\r\n * * Only one outer loop permitted.\r\n * * Largest area loop is assumed outer.\r\n * @param loops an array of loops as GrowableXYZArray or XAndY[]\r\n * @returns triangulated graph, or undefined if bad data.\r\n */\r\n public static createTriangulatedGraphFromLoops(loops: GrowableXYZArray[] | XAndY[][]): HalfEdgeGraph | undefined {\r\n if (loops.length < 1)\r\n return undefined;\r\n const mask = HalfEdgeMask.BOUNDARY_EDGE | HalfEdgeMask.PRIMARY_EDGE;\r\n const graph = new HalfEdgeGraph();\r\n const holeSeeds: HalfEdge[] = [];\r\n let maxArea = -10000.0;\r\n let maxAreaIndex = -1;\r\n // collect all the loops with pointers to the positive (inside)\r\n // remember which one has largest area.\r\n for (let i = 0; i < loops.length; i++) {\r\n let seed = Triangulator.directCreateFaceLoopFromCoordinates(graph, loops[i]);\r\n if (seed) {\r\n seed = seed.faceSuccessor; // directCreate returns tail\r\n const mate = seed.vertexSuccessor;\r\n seed.setMaskAroundFace(mask);\r\n mate.setMaskAroundFace(mask);\r\n const signedFaceArea = seed.signedFaceArea();\r\n const area = Math.abs(signedFaceArea);\r\n holeSeeds.push(signedFaceArea >= 0 ? seed : mate);\r\n if (i === 0 || area > maxArea) {\r\n maxArea = area;\r\n maxAreaIndex = i;\r\n }\r\n }\r\n }\r\n if (holeSeeds.length === 0)\r\n return undefined;\r\n // extract the max area seed ...\r\n const maxAreaFace = holeSeeds[maxAreaIndex];\r\n holeSeeds[maxAreaIndex] = holeSeeds[holeSeeds.length - 1];\r\n holeSeeds.pop();\r\n maxAreaFace.vertexSuccessor.setMaskAroundFace(HalfEdgeMask.EXTERIOR);\r\n // The hole seeds all have inside nodes. Set mask there and jump to outside.\r\n for (let i = 0; i < holeSeeds.length; i++) {\r\n const seed = holeSeeds[i];\r\n seed.setMaskAroundFace(HalfEdgeMask.EXTERIOR);\r\n holeSeeds[i] = this.getLeftmost(seed.vertexSuccessor);\r\n }\r\n\r\n const startingNode = Triangulator.spliceLeftMostNodesOfHoles(graph, maxAreaFace, holeSeeds);\r\n if (startingNode) {\r\n if (Triangulator.triangulateSingleFace(graph, startingNode))\r\n return graph;\r\n }\r\n return undefined;\r\n }\r\n /**\r\n * Triangulate all positive area faces of a graph.\r\n */\r\n public static triangulateAllPositiveAreaFaces(graph: HalfEdgeGraph): boolean {\r\n const seeds = graph.collectFaceLoops();\r\n let numFail = 0;\r\n for (const face of seeds) {\r\n if (face.countEdgesAroundFace() > 3) {\r\n const area = face.signedFaceArea();\r\n if (area > 0.0)\r\n if (!Triangulator.triangulateSingleFace(graph, face))\r\n numFail++;\r\n }\r\n }\r\n return numFail === 0;\r\n }\r\n\r\n /**\r\n * Triangulate the polygon made up of by a series of points.\r\n * * The loop may be either CCW or CW -- CCW order will be used for triangles.\r\n * * To triangulate a polygon with holes, use createTriangulatedGraphFromLoops\r\n */\r\n public static createTriangulatedGraphFromSingleLoop(data: XAndY[] | GrowableXYZArray): HalfEdgeGraph | undefined {\r\n const graph = new HalfEdgeGraph();\r\n const startingNode = Triangulator.createFaceLoopFromCoordinates(graph, data, true, true);\r\n\r\n if (!startingNode || graph.countNodes() < 6) return graph;\r\n\r\n if (Triangulator.triangulateSingleFace(graph, startingNode)) {\r\n Triangulator.flipTriangles(graph);\r\n return graph;\r\n }\r\n return undefined;\r\n }\r\n\r\n /**\r\n * cautiously split the edge starting at baseNode.\r\n * * If baseNode is null, create a trivial loop with the single vertex at xy\r\n * * if xy is distinct from the coordinates at both baseNode and its successor, insert xy as a new node within that edge.\r\n * * also include z coordinate if present.\r\n */\r\n private static interiorEdgeSplit(graph: HalfEdgeGraph, baseNode: HalfEdge | undefined, xy: XAndY | number[]): HalfEdge | undefined {\r\n let x = 0, y = 0, z = 0;\r\n if (Array.isArray(xy)) {\r\n x = xy[0];\r\n y = xy[1];\r\n z = xy.length > 2 ? xy[3] : 0.0;\r\n } else {\r\n const q = xy as any;\r\n if (q.hasOwnProperty(\"x\")) x = q.x;\r\n if (q.hasOwnProperty(\"y\")) y = q.y;\r\n if (q.hasOwnProperty(\"z\")) z = q.z;\r\n }\r\n if (!baseNode)\r\n return graph.splitEdge(baseNode, x, y, z);\r\n if (Triangulator.isAlmostEqualXAndYXY(baseNode, x, y))\r\n return baseNode;\r\n if (Triangulator.isAlmostEqualXAndYXY(baseNode.faceSuccessor, x, y))\r\n return baseNode;\r\n return graph.splitEdge(baseNode, x, y, z);\r\n }\r\n /** Create a loop from coordinates.\r\n * * Return a pointer to any node on the loop.\r\n * * no masking or other markup is applied.\r\n */\r\n public static directCreateFaceLoopFromCoordinates(graph: HalfEdgeGraph, data: LineStringDataVariant): HalfEdge | undefined {\r\n // Add the starting nodes as the boundary, and apply initial masks to the primary edge and exteriors\r\n let baseNode: HalfEdge | undefined;\r\n if (data instanceof IndexedXYZCollection) {\r\n const xyz = Point3d.create();\r\n for (let i = 0; i < data.length; i++) {\r\n data.getPoint3dAtCheckedPointIndex(i, xyz);\r\n baseNode = Triangulator.interiorEdgeSplit(graph, baseNode, xyz);\r\n }\r\n } else {\r\n for (const xy of data) {\r\n baseNode = Triangulator.interiorEdgeSplit(graph, baseNode, xy);\r\n }\r\n }\r\n return baseNode;\r\n }\r\n\r\n /** Create chains from coordinates.\r\n * * Return array of pointers to base node of the chains.\r\n * * no masking or other markup is applied.\r\n * @param graph New edges are built in this graph\r\n * @param data coordinate data\r\n * @param id id to attach to (both side of all) edges\r\n */\r\n public static directCreateChainsFromCoordinates(graph: HalfEdgeGraph, data: MultiLineStringDataVariant, id: number = 0): HalfEdge[] {\r\n // Add the starting nodes as the boundary, and apply initial masks to the primary edge and exteriors\r\n const assembler = new AssembleXYZXYZChains(graph, id);\r\n VariantPointDataStream.streamXYZ(data, assembler);\r\n return assembler.claimSeeds();\r\n }\r\n\r\n /**\r\n * @param graph the containing graph\r\n * @param base The last node of a newly created loop. (i.e. its `faceSuccessor` has the start xy)\r\n * @param returnPositiveAreaLoop if true, return the start node on the side with positive area. otherwise return the left side as given.\r\n * @param maskForBothSides mask to apply on both sides.\r\n * @param maskForOtherSide mask to apply to the \"other\" side of the loop.\r\n * @return the loop's start node or its vertex successor, chosen to be the positive or negative loop per request.\r\n */\r\n private static maskAndOrientNewFaceLoop(_graph: HalfEdgeGraph, base: HalfEdge | undefined, returnPositiveAreaLoop: boolean,\r\n maskForBothSides: HalfEdgeMask,\r\n maskForOtherSide: HalfEdgeMask): HalfEdge | undefined {\r\n // base is the final coordinates\r\n if (base) {\r\n base = base.faceSuccessor; // because typical construction process leaves the \"live\" edge at the end of the loop.\r\n const area = base.signedFaceArea();\r\n const mate = base.edgeMate;\r\n if (maskForBothSides !== HalfEdgeMask.NULL_MASK) {\r\n base.setMaskAroundFace(maskForBothSides);\r\n mate.setMaskAroundFace(maskForBothSides);\r\n }\r\n\r\n let preferredNode = base;\r\n if (returnPositiveAreaLoop && (area < 0))\r\n preferredNode = mate;\r\n const otherNode = preferredNode.vertexSuccessor;\r\n\r\n if (maskForOtherSide !== HalfEdgeMask.NULL_MASK)\r\n otherNode.setMaskAroundFace(maskForOtherSide);\r\n return preferredNode;\r\n }\r\n return undefined;\r\n }\r\n /**\r\n * create a circular doubly linked list of internal and external nodes from polygon points in the specified winding order\r\n * * This applies the masks used by typical applications:\r\n * * HalfEdgeMask.BOUNDARY on both sides\r\n * * HalfEdgeMask.PRIMARY_EDGE on both sides.\r\n * * Use `createFaceLoopFromCoordinatesAndMasks` for detail control of masks.\r\n */\r\n public static createFaceLoopFromCoordinates(graph: HalfEdgeGraph, data: LineStringDataVariant, returnPositiveAreaLoop: boolean, markExterior: boolean): HalfEdge | undefined {\r\n const base = Triangulator.directCreateFaceLoopFromCoordinates(graph, data);\r\n return Triangulator.maskAndOrientNewFaceLoop(graph, base, returnPositiveAreaLoop,\r\n HalfEdgeMask.BOUNDARY_EDGE | HalfEdgeMask.PRIMARY_EDGE,\r\n markExterior ? HalfEdgeMask.EXTERIOR : HalfEdgeMask.NULL_MASK);\r\n }\r\n\r\n /**\r\n * create a circular doubly linked list of internal and external nodes from polygon points.\r\n * * Optionally jump to the \"other\" side so the returned loop has positive area\r\n * @param graph graph to receive the new edges\r\n * @param data array with x,y coordinates\r\n * @param returnPositiveAreaLoop if false, return an edge proceeding around the loop in the order given. If true, compute the loop area and flip return the side with positive area.\r\n * @param maskForBothSides mask to apply on both sides.\r\n * @param maskForOtherSide mask to apply on the \"other\" side from the returned loop.\r\n */\r\n public static createFaceLoopFromCoordinatesAndMasks(graph: HalfEdgeGraph, data: LineStringDataVariant, returnPositiveAreaLoop: boolean,\r\n maskForBothSides: HalfEdgeMask,\r\n maskForOtherSide: HalfEdgeMask): HalfEdge | undefined {\r\n const base = Triangulator.directCreateFaceLoopFromCoordinates(graph, data);\r\n return Triangulator.maskAndOrientNewFaceLoop(graph, base, returnPositiveAreaLoop, maskForBothSides, maskForOtherSide);\r\n }\r\n\r\n /** Cut off an ear, forming a new face loop of nodes\r\n * @param ear the vertex being cut off.\r\n * * Form two new nodes, alpha and beta, which have the coordinates one step away from the ear vertex.\r\n * * Reassigns the pointers such that beta is left behind with the new face created\r\n * * Reassigns the pointers such that alpha becomes the resulting missing node from the remaining polygon\r\n * * Reassigns prevZ and nextZ pointers\r\n */\r\n private static joinNeighborsOfEar(graph: HalfEdgeGraph, ear: HalfEdge) {\r\n const alpha = graph.createEdgeXYZXYZ(\r\n ear.facePredecessor.x, ear.facePredecessor.y, ear.facePredecessor.z, ear.facePredecessor.i,\r\n ear.faceSuccessor.x, ear.faceSuccessor.y, ear.faceSuccessor.z, ear.faceSuccessor.i);\r\n const beta = alpha.edgeMate;\r\n\r\n // Add two nodes alpha and beta and reassign pointers (also mark triangle nodes as part of triangle)\r\n HalfEdge.pinch(ear.faceSuccessor, beta);\r\n HalfEdge.pinch(ear.facePredecessor, alpha);\r\n ear.setMaskAroundFace(HalfEdgeMask.TRIANGULATED_FACE);\r\n }\r\n private static isInteriorTriangle(a: HalfEdge) {\r\n if (!a.isMaskSet(HalfEdgeMask.TRIANGULATED_FACE) || a.isMaskSet(HalfEdgeMask.EXTERIOR))\r\n return false;\r\n const b = a.faceSuccessor;\r\n if (!b.isMaskSet(HalfEdgeMask.TRIANGULATED_FACE) || b.isMaskSet(HalfEdgeMask.EXTERIOR))\r\n return false;\r\n const c = b.faceSuccessor;\r\n if (!c.isMaskSet(HalfEdgeMask.TRIANGULATED_FACE) || c.isMaskSet(HalfEdgeMask.EXTERIOR))\r\n return false;\r\n return c.faceSuccessor === a;\r\n }\r\n\r\n /**\r\n * Perform 0, 1, or more edge flips to improve aspect ratio just behind an ear that was just cut.\r\n * @param ear the triangle corner which just served as the ear node.\r\n * @returns the node at the back corner after flipping.\"appropriately positioned\" node for the usual advance to ear.faceSuccessor.edgeMate.faceSuccessor.\r\n */\r\n private static doPostCutFlips(ear: HalfEdge) {\r\n // B is the ear -- inside a (probably newly created) triangle ABC\r\n // CA is the recently added cut edge.\r\n // AB is the candidate to be flipped.\r\n // triangle B1 A1 D is on the other side of AB\r\n // The condition for flipping is:\r\n // ! both triangles must be TRIANGULATED_NODE_MASK\r\n // ! incircle condition flags D as in the circle of ABC\r\n // after flip, node A moves to the vertex of D, and is the effective \"ear\", with the cap edge C A1\r\n // after flip, consider the A1 D (whose nodes are A1 and flipped A!!!)\r\n //\r\n // * *\r\n // . C0| . / |\r\n // . | . C0 /B1|\r\n // . | . /v |\r\n // . ^| . / |\r\n // . A0 ----> B0| . / ^|\r\n // *=======================* --> * A1 / B0*\r\n // \\ A1 <---- B1/ \\ / /\r\n // \\ / \\ / /\r\n // \\ / \\ ^/ D1/\r\n // \\ D1 / \\A0/ /\r\n // * *\r\n let b0 = ear;\r\n let a0 = b0.facePredecessor;\r\n let b1 = a0.edgeMate;\r\n while (Triangulator.isInteriorTriangle(a0) && Triangulator.isInteriorTriangle(b1)) {\r\n const detA = Triangulator.computeInCircleDeterminantIsStrongPositive(a0);\r\n if (!detA)\r\n break;\r\n // Flip the triangles\r\n const a1 = b1.faceSuccessor;\r\n Triangulator.flipEdgeBetweenTriangles(a1, a1.faceSuccessor, a1.facePredecessor, b0, b0.facePredecessor, b0.faceSuccessor);\r\n b0 = a0;\r\n a0 = b0.facePredecessor;\r\n b1 = a0.edgeMate;\r\n }\r\n return b0;\r\n }\r\n\r\n /**\r\n * main ear slicing loop which triangulates a polygon (given as a linked list)\r\n * While there still exists ear nodes that have not yet been triangulated...\r\n *\r\n * * Check if the ear is hashed, and can easily be split off. If so, \"join\" that ear.\r\n * * If not hashed, move on to a separate ear.\r\n * * If no ears are currently hashed, attempt to cure self intersections or split the polygon into two before continuing\r\n */\r\n private static triangulateSingleFace(graph: HalfEdgeGraph, ear?: HalfEdge): boolean {\r\n if (!ear) {\r\n Triangulator.setDebugGraph(graph);\r\n return false;\r\n }\r\n\r\n let next;\r\n let next2;\r\n let pred;\r\n let maxCandidate = ear.countEdgesAroundFace();\r\n let numCandidate = 0;\r\n ear.clearMaskAroundFace(HalfEdgeMask.TRIANGULATED_FACE);\r\n // iterate through ears, slicing them one by one\r\n while (!ear.isMaskSet(HalfEdgeMask.TRIANGULATED_FACE)) {\r\n pred = ear?.facePredecessor;\r\n next = ear.faceSuccessor;\r\n next2 = next.faceSuccessor;\r\n if (next === ear || next2 === ear)\r\n return true;\r\n if (next2.faceSuccessor === ear) {\r\n // if triangle, mask it so that its edges can potentially be flipped by doPostCutFlips()\r\n ear.setMaskAroundFace(HalfEdgeMask.TRIANGULATED_FACE);\r\n return true;\r\n }\r\n // earcut does not support self intersections.\r\n // BUT .. maybe if we watch from the simplest case of next2 returning to pred it will catch some . . .\r\n // (no need to do flips -- we know it's already a triangle)\r\n // EDL Sept 2021 NO... coordinate test is fooled into early exit when large outer triangle has\r\n // edges going in from pred.\r\n // Hence add the around vertex test. But this is possibly vulnerable to a variant false positive ..\r\n if (Geometry.isAlmostEqualXAndY(next2, pred) && !next2.findAroundVertex (pred)) {\r\n HalfEdge.pinch(pred, next2);\r\n ear.setMaskAroundFace(HalfEdgeMask.TRIANGULATED_FACE);\r\n ear = next2;\r\n continue;\r\n }\r\n if (++numCandidate > maxCandidate) {\r\n Triangulator.setDebugGraph(graph);\r\n return false;\r\n }\r\n if (Triangulator.isEar(ear)) {\r\n maxCandidate--;\r\n numCandidate = 0;\r\n\r\n // skipping the next vertices leads to less sliver triangles\r\n\r\n // If we already have a separated triangle, do not join\r\n if (ear.faceSuccessor.faceSuccessor !== ear.facePredecessor) {\r\n Triangulator.joinNeighborsOfEar(graph, ear);\r\n ear = Triangulator.doPostCutFlips(ear);\r\n ear = ear.faceSuccessor.edgeMate.faceSuccessor;\r\n // another step? Nate's 2017 code went one more.\r\n } else {\r\n ear.setMaskAroundFace(HalfEdgeMask.TRIANGULATED_FACE);\r\n ear = next.faceSuccessor;\r\n }\r\n continue;\r\n }\r\n ear = next;\r\n }\r\n return true; // um .. I'm not sure what this state is.\r\n }\r\n /** @internal */\r\n private static sDebugGraph: HalfEdgeGraph | undefined;\r\n /** @internal */\r\n private static sEnableDebugGraphCapture = false;\r\n\r\n /**\r\n * * returns the (possibly undefined) debug graph.\r\n * * sets the debug graph to undefined.\r\n * * disables subsequent saving.\r\n * @internal */\r\n public static claimDebugGraph(): HalfEdgeGraph | undefined {\r\n const g = Triangulator.sDebugGraph;\r\n Triangulator.sDebugGraph = undefined;\r\n Triangulator.sEnableDebugGraphCapture = false;\r\n return g;\r\n }\r\n /** Call (from within the triangulator) to announce a graph to be saved for debug.\r\n * * If debug graph capture is not enabled, do nothing.\r\n * * If debug graph capture is enabled, save this graph.\r\n * * This is called by internal steps at point of failure to preserve the failing graph for unit test examination.\r\n * @internal */\r\n public static setDebugGraph(graph: HalfEdgeGraph | undefined) { if (Triangulator.sEnableDebugGraphCapture) Triangulator.sDebugGraph = graph; }\r\n /**\r\n * * Clear the debug graph\r\n * * Set capture enabled to indicated value.\r\n * * Intended use:\r\n * * By default \"enabled\" is false so there is no activity in the debug graph.\r\n * * A unit test which needs to see graph after failure calls clearAndEnableDebugGraphCapture (true)\r\n * * run the triangulation step\r\n * * call claimDebugGraph.\r\n * * claimDebugGraph reverts everything to default no-capture state.\r\n * @internal */\r\n public static clearAndEnableDebugGraphCapture(value: boolean) {\r\n Triangulator.sEnableDebugGraphCapture = value;\r\n Triangulator.sDebugGraph = undefined;\r\n }\r\n\r\n // for reuse over all calls to isEar ....\r\n private static _edgeInterval = Range1d.createNull();\r\n private static _earRange = Range2d.createNull();\r\n private static _edgeRange = Range2d.createNull();\r\n private static _planes: Plane3dByOriginAndUnitNormal[] = [\r\n Plane3dByOriginAndUnitNormal.createXYPlane(),\r\n Plane3dByOriginAndUnitNormal.createXYPlane(),\r\n Plane3dByOriginAndUnitNormal.createXYPlane(),\r\n ];\r\n /** Check whether a polygon node forms a valid ear with adjacent nodes */\r\n private static isEar(ear: HalfEdge) {\r\n const a = ear.facePredecessor;\r\n const b = ear;\r\n const c = ear.faceSuccessor;\r\n const area = Triangulator.signedTolerancedCCWTriangleArea(a, b, c);\r\n if (area <= 0)\r\n return false; // reflex, can't be an ear\r\n const planes = this._planes;\r\n if (!Plane3dByOriginAndUnitNormal.createOriginAndTargetXY(a, b, planes[0])\r\n || !Plane3dByOriginAndUnitNormal.createOriginAndTargetXY(b, c, planes[1])\r\n || !Plane3dByOriginAndUnitNormal.createOriginAndTargetXY(c, a, planes[2]))\r\n return false;\r\n\r\n // now make sure we don't have other points inside the potential ear, or edges crossing.\r\n const earRange = this._earRange;\r\n const edgeRange = this._edgeRange;\r\n const edgeInterval = this._edgeInterval;\r\n Range2d.createXYXYXY(a.x, a.y, b.x, b.y, c.x, c.y, earRange);\r\n earRange.expandInPlace(Geometry.smallMetricDistance);\r\n let p = c;\r\n const zeroPlus = 1.0e-8;\r\n const zeroMinus = -zeroPlus;\r\n const onePlus = 1.0 + zeroPlus;\r\n const oneMinus = 1.0 - zeroPlus;\r\n const clipTolerance = 1.0e-10 * area;\r\n while (p !== a) {\r\n const q = p.faceSuccessor;\r\n Range2d.createXYXY(p.x, p.y, q.x, q.y, edgeRange);\r\n if (earRange.intersectsRange(edgeRange)) {\r\n // Does pq impinge on the triangle?\r\n Range1d.createXX(zeroMinus, onePlus, edgeInterval);\r\n ClipUtilities.clipSegmentBelowPlanesXY(planes, p, q, edgeInterval, clipTolerance);\r\n if (!edgeInterval.isNull) {\r\n const mate = p.edgeMate;\r\n if (mate === a || mate === b) {\r\n // this is the back side of a bridge edge\r\n } else if (edgeInterval.low > oneMinus) {\r\n // the endpoint (q) just touches ... if it is at one of the vertex loops it's ok ...\r\n if (!a.findAroundVertex(q)\r\n && !b.findAroundVertex(q)\r\n && !c.findAroundVertex(q))\r\n return false;\r\n } else if (edgeInterval.high < zeroPlus) {\r\n // the start (p) just touches ... if it is at one of the vertex loops it's ok ...\r\n if (!a.findAroundVertex(p)\r\n && !b.findAroundVertex(p)\r\n && !c.findAroundVertex(p))\r\n return false;\r\n } else {\r\n // significant internal intersection -- this edge really intrudes on the into the triangle\r\n return false;\r\n }\r\n }\r\n }\r\n p = p.faceSuccessor;\r\n }\r\n return true;\r\n }\r\n /** link holeLoopNodes[1], holeLoopNodes[2] etc into the outer loop, producing a single-ring polygon without holes\r\n *\r\n */\r\n private static spliceLeftMostNodesOfHoles(graph: HalfEdgeGraph, outerNode: HalfEdge, leftMostHoleLoopNode: HalfEdge[]): HalfEdge | undefined {\r\n\r\n leftMostHoleLoopNode.sort(Triangulator.compareX);\r\n let numFail = 0;\r\n // process holes from left to right\r\n for (const holeStart of leftMostHoleLoopNode) {\r\n if (!Triangulator.eliminateHole(graph, holeStart, outerNode))\r\n numFail++;\r\n }\r\n\r\n return numFail === 0 ? outerNode : undefined;\r\n }\r\n /** For use in sorting -- return (signed) difference (a.x - b.x) */\r\n private static compareX(a: HalfEdge, b: HalfEdge) {\r\n return a.x - b.x;\r\n }\r\n\r\n /** find a bridge between vertices that connects hole with an outer ring and and link it */\r\n private static eliminateHole(graph: HalfEdgeGraph, hole: HalfEdge, outerNode: HalfEdge): boolean {\r\n const outerNodeA = Triangulator.findHoleBridge(hole, outerNode);\r\n if (outerNodeA) {\r\n return Triangulator.splitFace(graph, outerNodeA, hole) !== undefined;\r\n }\r\n return false;\r\n }\r\n // cspell:word Eberly\r\n /**\r\n * David Eberly algorithm for finding a bridge between hole and outer polygon:\r\n * https://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf\r\n */\r\n private static findHoleBridge(hole: HalfEdge, outerNode?: HalfEdge): HalfEdge | undefined {\r\n let p = outerNode;\r\n\r\n if (!p)\r\n return undefined;\r\n\r\n const hx = hole.x;\r\n const hy = hole.y;\r\n let qx = -Infinity;\r\n let m;\r\n\r\n // find a segment intersected by a ray from the hole's leftmost point to the left;\r\n // segment's endpoint with lesser x will be potential connection point\r\n do {\r\n if (hy <= p.y && hy >= p.faceSuccessor.y && p.faceSuccessor.y !== p.y) {\r\n const x = p.x + (hy - p.y) * (p.faceSuccessor.x - p.x) / (p.faceSuccessor.y - p.y);\r\n if (x <= hx && x > qx) {\r\n qx = x;\r\n if (x === hx) {\r\n if (hy === p.y) return p;\r\n if (hy === p.faceSuccessor.y) return p.faceSuccessor;\r\n }\r\n m = p.x < p.faceSuccessor.x ? p : p.faceSuccessor;\r\n }\r\n }\r\n p = p.faceSuccessor;\r\n } while (p !== outerNode);\r\n\r\n if (!m) return undefined;\r\n\r\n if (hx === qx) return m.facePredecessor; // hole touches outer segment; pick lower endpoint\r\n\r\n // look for points inside the triangle of hole point, segment intersection and endpoint;\r\n // if there are no points found, we have a valid connection;\r\n // otherwise choose the point of the minimum angle with the ray as connection point\r\n\r\n const stop = m;\r\n const mx = m.x;\r\n const my = m.y;\r\n let tanMin = Infinity;\r\n let tan;\r\n\r\n p = m.faceSuccessor;\r\n\r\n while (p !== stop) {\r\n if (hx >= p.x && p.x >= mx && hx !== p.x &&\r\n Triangulator.pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {\r\n\r\n tan = Math.abs(hy - p.y) / (hx - p.x); // tangential\r\n\r\n if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && Triangulator.locallyInside(p, hole)) {\r\n m = p;\r\n tanMin = tan;\r\n }\r\n }\r\n\r\n p = p.faceSuccessor;\r\n }\r\n\r\n return m;\r\n }\r\n\r\n // find the leftmost node of a polygon ring\r\n private static getLeftmost(start: HalfEdge) {\r\n let p = start;\r\n let leftmost = start;\r\n do {\r\n if (p.x < leftmost.x) leftmost = p;\r\n p = p.faceSuccessor;\r\n } while (p !== start);\r\n\r\n return leftmost;\r\n }\r\n\r\n /** check if a point lies within a convex triangle.\r\n * i.e. areas of 3 triangles with an edge of abc and p all have zero or positive area. (abp, bcp, cap)\r\n */\r\n private static pointInTriangle(ax: number, ay: number, bx: number, by: number, cx: number, cy: number, px: number, py: number) {\r\n return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&\r\n (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&\r\n (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;\r\n }\r\n private static nodeInTriangle(a: HalfEdge, b: HalfEdge, c: HalfEdge, p: HalfEdge) {\r\n return Triangulator.signedTolerancedCCWTriangleArea(a, b, p) > 0\r\n && Triangulator.signedTolerancedCCWTriangleArea(b, c, p) > 0.0\r\n && Triangulator.signedTolerancedCCWTriangleArea(c, a, p) > 0.0;\r\n }\r\n /** signed area of a triangle\r\n * EDL 2/21 This is negative of usual CCW area. Beware in callers !!!\r\n * (This originates in classic earcut code.)\r\n */\r\n private static signedCWTriangleArea(p: HalfEdge, q: HalfEdge, r: HalfEdge) {\r\n return 0.5 * ((q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y));\r\n }\r\n\r\n /** signed area of a triangle, with small positive corrected to zero by relTol\r\n */\r\n private static signedTolerancedCCWTriangleArea(p: HalfEdge, q: HalfEdge, r: HalfEdge, relTol: number = 1.0e-12) {\r\n const ux = q.x - p.x;\r\n const uy = q.y - p.y;\r\n const vx = r.x - p.x;\r\n const vy = r.y - p.y;\r\n const area = 0.5 * (ux * vy - uy * vx);\r\n if (area < 0.0)\r\n return area;\r\n const uu = ux * ux + uy * uy;\r\n const vv = vx * vx + vy * vy;\r\n if (area < relTol * (uu + vv))\r\n return 0.0;\r\n return area;\r\n }\r\n\r\n /** check if two points are equal */\r\n private static isAlmostEqualXAndYXY(p1: XAndY, x: number, y: number) {\r\n return Geometry.isAlmostEqualNumber(p1.x, x) && Geometry.isAlmostEqualNumber(p1.y, y);\r\n }\r\n\r\n /** check if a b is inside the sector around a */\r\n private static locallyInside(a: HalfEdge, b: HalfEdge) {\r\n return Triangulator.signedCWTriangleArea(a.facePredecessor, a, a.faceSuccessor) < 0 ?\r\n Triangulator.signedCWTriangleArea(a, b, a.faceSuccessor) >= 0 && Triangulator.signedCWTriangleArea(a, a.facePredecessor, b) >= 0 :\r\n Triangulator.signedCWTriangleArea(a, b, a.facePredecessor) < 0 || Triangulator.signedCWTriangleArea(a, a.faceSuccessor, b) < 0;\r\n }\r\n\r\n /**\r\n * link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;\r\n * if one belongs to the outer ring and another to a hole, it merges it into a single ring\r\n * * Returns the base of the new edge at the \"a\" end.\r\n * * \"a\" and \"b\" still represent the same physical pieces of edges\r\n * @returns Returns the (base of) the new half edge, at the \"a\" end.\r\n */\r\n private static splitFace(graph: HalfEdgeGraph, a: HalfEdge, b: HalfEdge): HalfEdge | undefined {\r\n if (HalfEdge.isNodeVisibleInSector(a, b) && HalfEdge.isNodeVisibleInSector(b, a)) {\r\n const a2 = graph.createEdgeXYZXYZ(a.x, a.y, a.z, a.i, b.x, b.y, b.z, b.i);\r\n const b2 = a2.faceSuccessor;\r\n HalfEdge.pinch(a, a2);\r\n HalfEdge.pinch(b, b2);\r\n return a2;\r\n }\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Triangulate a single face with (linear time) logic applicable only if the lowNode is the lowest node.\r\n * @returns false if any monotonicity condition is violated.\r\n */\r\n public static triangulateSingleMonotoneFace(graph: HalfEdgeGraph, start: HalfEdge): boolean {\r\n let left = start.facePredecessor;\r\n let right = start.faceSuccessor;\r\n // P0, P1, P2 are successive edges along evolving chain\r\n let upperSideOfNewEdge;\r\n while (left !== right\r\n && right !== start\r\n && right.faceSuccessor !== left) {\r\n /** These should not happen if face is monotone . .. */\r\n if (HalfEdge.crossProductXYAlongChain(left, start, right) <= 0)\r\n return false;\r\n if (!start.belowYX(left))\r\n return false;\r\n if (!start.belowYX(right))\r\n return false;\r\n if (left.belowYX(right)) {\r\n /* Triangulate to all left side edges that\r\n are below right */\r\n\r\n /* Phase 1: move upward, adding back edges\r\n when prior nodes are visible. */\r\n let P0 = left;\r\n let P1 = start;\r\n let P2 = right;\r\n /* Invariant: the path from P0 back to P1 is concave.\r\n Each loop pass moves P0 up the left side, filling in\r\n edges as needed. The right side edge\r\n (following start) is never altered.\r\n */\r\n while (P0 !== P2 && P0.belowYX(right)) {\r\n while (P2 !== right\r\n && P2 !== P0\r\n && P2 !== P1\r\n && HalfEdge.crossProductXYAlongChain(P0, P1, P2) > 0) {\r\n upperSideOfNewEdge = Triangulator.splitFace(graph, P0, P2);\r\n if (upperSideOfNewEdge === undefined)\r\n return false;\r\n P0 = upperSideOfNewEdge;\r\n P1 = P0.faceSuccessor;\r\n P2 = P1.faceSuccessor;\r\n }\r\n P2 = P1;\r\n P1 = P0;\r\n P0 = P0.facePredecessor;\r\n }\r\n /* Phase 2: Fan out edges from right to the\r\n left side. P0.P1.P2 describes a pair of\r\n adjacent edges at the bottom. */\r\n left = P1;\r\n P2 = right;\r\n P1 = P2.facePredecessor;\r\n P0 = P1.facePredecessor;\r\n while (P2.faceSuccessor !== P0 && P0 !== left) {\r\n upperSideOfNewEdge = Triangulator.splitFace(graph, P0, P2);\r\n if (upperSideOfNewEdge === undefined)\r\n return false;\r\n P1 = upperSideOfNewEdge;\r\n P0 = P1.facePredecessor;\r\n }\r\n /* Finish off with the last stroke from the\r\n left node to the right, except when already\r\n topped out */\r\n if (P2.faceSuccessor !== P0) {\r\n upperSideOfNewEdge = Triangulator.splitFace(graph, P0, P2);\r\n if (upperSideOfNewEdge === undefined)\r\n return false;\r\n P0 = upperSideOfNewEdge;\r\n }\r\n start = P0;\r\n right = start.faceSuccessor;\r\n left = start.facePredecessor;\r\n\r\n } else {\r\n /* Triangulate to all right side edges that\r\n are below left */\r\n\r\n /* Phase 1: move upward, adding back edges\r\n when prior nodes are visible. */\r\n let P0 = left;\r\n let P1 = start;\r\n let P2 = right;\r\n /* Invariant: the path up to P1 is concave.\r\n Each loop pass advances P1, filling in\r\n edges as needed. Note that the\r\n start edge may get hidden, so the\r\n bottom node must be referenced as\r\n left.faceSuccessor rather than as start.\r\n */\r\n while (P0 !== P2 && P2.belowYX(left)) {\r\n while (P0 !== left\r\n && P2 !== P0\r\n && P2 !== P1\r\n && HalfEdge.crossProductXYAlongChain(P0, P1, P2) > 0) {\r\n upperSideOfNewEdge = Triangulator.splitFace(graph, P0, P2);\r\n if (upperSideOfNewEdge === undefined)\r\n return false;\r\n\r\n P0 = upperSideOfNewEdge.facePredecessor;\r\n P1 = upperSideOfNewEdge;\r\n }\r\n P0 = P1;\r\n P1 = P2;\r\n P2 = P2.faceSuccessor;\r\n }\r\n /* Phase 2: Fan out edges from left to the\r\n right side. P0.P1.P2 describes a pair of\r\n adjacent edges at the bottom. */\r\n right = P1;\r\n P0 = left;\r\n P1 = P0.faceSuccessor;\r\n P2 = P1.faceSuccessor;\r\n while (P2.faceSuccessor !== P0 && P2 !== right) {\r\n upperSideOfNewEdge = Triangulator.splitFace(graph, P0, P2);\r\n if (upperSideOfNewEdge === undefined)\r\n return false;\r\n P0 = upperSideOfNewEdge;\r\n // P1 = P2; // original code (ported from native) carefully maintained P1..P2 relationship. But code analyzer says P1 is not used again. So skip it.\r\n P2 = P2.faceSuccessor;\r\n }\r\n /* Finish off with the last stroke from the\r\n left node to the right, except when already\r\n topped out */\r\n if (P2.faceSuccessor !== P0) {\r\n const newEdge = Triangulator.splitFace(graph, P0, P2);\r\n if (newEdge === undefined)\r\n return false;\r\n }\r\n start = right;\r\n right = start.faceSuccessor;\r\n left = start.facePredecessor;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n}\r\n\r\n/**\r\n * Internal class for assembling chains\r\n * @internal\r\n */\r\nclass AssembleXYZXYZChains extends PointStreamXYZXYZHandlerBase {\r\n // Add the starting nodes as the boundary, and apply initial masks to the primary edge and exteriors\r\n private _seeds?: HalfEdge[];\r\n private _baseNode: HalfEdge | undefined;\r\n private _nodeB: HalfEdge | undefined;\r\n private _nodeC: HalfEdge | undefined;\r\n private _graph: HalfEdgeGraph;\r\n private _id: any;\r\n public constructor(graph: HalfEdgeGraph, id: any) {\r\n super();\r\n this._graph = graph;\r\n this._id = id;\r\n }\r\n public override startChain(chainData: MultiLineStringDataVariant, isLeaf: boolean): void {\r\n super.startChain(chainData, isLeaf);\r\n this._baseNode = undefined;\r\n this._nodeB = undefined;\r\n }\r\n public override handleXYZXYZ(x0: number, y0: number, z0: number, x1: number, y1: number, z1: number) {\r\n this._nodeC = this._graph.createEdgeXYZXYZ(x0, y0, z0, this._id, x1, y1, z1, this._id);\r\n if (this._baseNode === undefined) {\r\n this._baseNode = this._nodeC;\r\n this._nodeB = this._baseNode.faceSuccessor;\r\n } else {\r\n HalfEdge.pinch(this._nodeB!, this._nodeC);\r\n this._nodeB = this._nodeC.faceSuccessor;\r\n }\r\n }\r\n public override endChain(chainData: MultiLineStringDataVariant, isLeaf: boolean): void {\r\n super.endChain(chainData, isLeaf);\r\n if (this._baseNode !== undefined) {\r\n if (this._seeds === undefined)\r\n this._seeds = [];\r\n this._seeds.push(this._baseNode);\r\n }\r\n this._baseNode = undefined;\r\n this._nodeB = undefined;\r\n this._nodeC = undefined;\r\n }\r\n public claimSeeds(): HalfEdge[] {\r\n if (this._seeds === undefined)\r\n return [];\r\n return this._seeds;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"Triangulation.js","sourceRoot":"","sources":["../../../src/topology/Triangulation.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 { ClipUtilities } from \"../clipping/ClipUtils\";\r\nimport { Geometry } from \"../Geometry\";\r\nimport { GrowableXYZArray } from \"../geometry3d/GrowableXYZArray\";\r\nimport { IndexedXYZCollection } from \"../geometry3d/IndexedXYZCollection\";\r\nimport { Plane3dByOriginAndUnitNormal } from \"../geometry3d/Plane3dByOriginAndUnitNormal\";\r\nimport { Point3d } from \"../geometry3d/Point3dVector3d\";\r\nimport { Point3dArray } from \"../geometry3d/PointHelpers\";\r\nimport { PointStreamXYZXYZHandlerBase, VariantPointDataStream } from \"../geometry3d/PointStreaming\";\r\nimport { Range1d, Range2d } from \"../geometry3d/Range\";\r\nimport { XAndY, XYAndZ } from \"../geometry3d/XYZProps\";\r\nimport { HalfEdge, HalfEdgeGraph, HalfEdgeMask } from \"./Graph\";\r\nimport { MarkedEdgeSet } from \"./HalfEdgeMarkSet\";\r\nimport { InsertAndRetriangulateContext } from \"./InsertAndRetriangulateContext\";\r\n\r\n/**\r\n * type for use as signature for xyz data of a single linestring appearing in a parameter list.\r\n * @public\r\n */\r\nexport type LineStringDataVariant = IndexedXYZCollection | XYAndZ[] | XAndY[] | number[][];\r\n\r\n/**\r\n * type for use as signature for multiple xyz data of multiple linestrings appearing in a parameter list.\r\n * @public\r\n */\r\nexport type MultiLineStringDataVariant = LineStringDataVariant | LineStringDataVariant[];\r\n\r\n/**\r\n * (static) methods for triangulating polygons\r\n * * @internal\r\n */\r\nexport class Triangulator {\r\n\r\n /** Given the six nodes that make up two bordering triangles, \"pinch\" and relocate the nodes to flip them\r\n * * The shared edge mates are c and e.\r\n * * (abc) are a triangle in CCW order\r\n * * (dfe) are a triangle in CCW order. (!! node dfe instead of def.)\r\n */\r\n private static flipEdgeBetweenTriangles(a: HalfEdge, b: HalfEdge, c: HalfEdge, d: HalfEdge, e: HalfEdge, f: HalfEdge) {\r\n // Reassign all of the pointers\r\n HalfEdge.pinch(a, e);\r\n HalfEdge.pinch(c, d);\r\n HalfEdge.pinch(f, c);\r\n HalfEdge.pinch(e, b);\r\n\r\n // Move alpha and beta into the xy coordinates of their predecessors\r\n e.x = b.x;\r\n e.y = b.y;\r\n e.z = b.z;\r\n e.i = b.i;\r\n c.i = f.i;\r\n c.x = f.x;\r\n c.y = f.y;\r\n c.z = f.z;\r\n }\r\n /**\r\n * * nodeA is a given node\r\n * * nodeA1 is its nodeA.faceSuccessor\r\n * * nodeA2 is nodeA1.faceSuccessor, i.e. 3rd node of triangle A\r\n * * nodeB is nodeA.edgeMate, i.e. a node in the \"other\" triangle at nodeA's edge\r\n * * nodeB1 is nodeB.faceSuccessor\r\n * * nodeB2 is nodeB1.faceSuccessor, i.e the 3rd node of triangle B\r\n * Construct (as simple doubles, to avoid object creation) xy vectors from:\r\n * * (ux,uy): nodeA to nodeA1, i.e. the shared edge\r\n * * (vx,vy): nodeA to nodeA2,\r\n * * (wx,wy): nodeA to nodeB2\r\n * * this determinant is positive if nodeA is \"in the circle\" of nodeB2, nodeA1, nodeA2\r\n * * Return true if clearly positive\r\n * * Return false if clearly negative or almost zero.\r\n * @param nodeA node on the diagonal edge of candidate for edge flip.\r\n */\r\n public static computeInCircleDeterminantIsStrongPositive(nodeA: HalfEdge): boolean {\r\n // Assume triangle A1,A2,B2 is ccw.\r\n // Shift the triangle to the origin (by negated A coords).\r\n // The Delaunay condition is computed by projecting the origin and the shifted triangle\r\n // points up to the paraboloid z = x*x + y*y. Due to the radially symmetric convexity of\r\n // this surface and the ccw orientation of this triangle, \"A is inside triangle A1,A2,B2\"\r\n // is equivalent to \"the volume of the parallelepiped formed by the projected points is\r\n // negative, as computed by the triple product.\"\r\n const nodeA1 = nodeA.faceSuccessor;\r\n const nodeA2 = nodeA1.faceSuccessor;\r\n if (nodeA2.faceSuccessor !== nodeA)\r\n return false;\r\n const nodeB = nodeA.edgeMate;\r\n const nodeB1 = nodeB.faceSuccessor;\r\n const nodeB2 = nodeB1.faceSuccessor;\r\n if (nodeB2.faceSuccessor !== nodeB)\r\n return false;\r\n const ux = nodeA1.x - nodeA.x;\r\n const uy = nodeA1.y - nodeA.y;\r\n const vx = nodeA2.x - nodeA.x;\r\n const vy = nodeA2.y - nodeA.y;\r\n if (Geometry.crossProductXYXY(ux, uy, vx, vy) < 0)\r\n return false;\r\n // we assume identical coordinates in pairs (nodeA, nodeB1) and (nodeA1, nodeB)\r\n const wx = nodeB2.x - nodeA.x;\r\n const wy = nodeB2.y - nodeA.y;\r\n const tx = wx * wx + wy * wy;\r\n const ty = vx * vx + vy * vy;\r\n const tz = ux * ux + uy * uy;\r\n const q = Geometry.tripleProduct(\r\n wx, wy, tx,\r\n vx, vy, ty,\r\n ux, uy, tz);\r\n if (q < 0)\r\n return false;\r\n const denom = Math.abs(wx * vy * tz) + Math.abs(wy * ty * ux) + Math.abs(tx * vx * uy)\r\n + Math.abs(wx * ty * uy) + Math.abs(wy * vx * tz) + Math.abs(tx * vy * ux);\r\n return q > 1.0e-12 * denom;\r\n }\r\n\r\n /**\r\n * * Visit each node of the graph array\r\n * * If a flip would be possible, test the results of flipping using incircle condition\r\n * * If revealed to be an improvement, conduct the flip, mark involved nodes as unvisited, and repeat until all nodes are visited\r\n */\r\n public static flipTriangles(graph: HalfEdgeGraph): number {\r\n const edgeSet = MarkedEdgeSet.create(graph)!;\r\n for (const node of graph.allHalfEdges)\r\n edgeSet.addToSet(node);\r\n const numFlip = this.flipTrianglesInEdgeSet(graph, edgeSet);\r\n edgeSet.teardown();\r\n return numFlip;\r\n }\r\n\r\n /**\r\n * * Visit each node of the graph array\r\n * * If a flip would be possible, test the results of flipping using incircle condition\r\n * * If revealed to be an improvement, conduct the flip, mark involved nodes as unvisited, and repeat until all nodes are visited\r\n */\r\n public static flipTrianglesInEdgeSet(graph: HalfEdgeGraph, edgeSet: MarkedEdgeSet): number {\r\n const barrierMasks = HalfEdgeMask.EXTERIOR | HalfEdgeMask.PRIMARY_EDGE | HalfEdgeMask.BOUNDARY_EDGE;\r\n\r\n const nodeArray = graph.allHalfEdges;\r\n const maxTest = 10.0 * nodeArray.length;\r\n let numFlip = 0;\r\n let numOK = 0;\r\n let node;\r\n while (undefined !== (node = edgeSet.chooseAndRemoveAny())) {\r\n\r\n if (node.isMaskSet(barrierMasks)) // Flip not allowed\r\n continue;\r\n\r\n if (Triangulator.computeInCircleDeterminantIsStrongPositive(node)) {\r\n // Flip the triangles\r\n Triangulator.flipEdgeBetweenTriangles(node.edgeMate.faceSuccessor, node.edgeMate.facePredecessor, node.edgeMate, node.faceSuccessor, node, node.facePredecessor);\r\n // keep looking at the 2 faces\r\n edgeSet.addAroundFace(node);\r\n edgeSet.addAroundFace(node.edgeMate);\r\n numFlip++;\r\n } else {\r\n numOK++;\r\n }\r\n if (numFlip + numOK > maxTest)\r\n break;\r\n }\r\n return numFlip;\r\n }\r\n\r\n /** Create a graph with a triangulation points.\r\n * * The outer limit of the graph is the convex hull of the points.\r\n * * The outside loop is marked `HalfEdgeMask.EXTERIOR`\r\n */\r\n public static createTriangulatedGraphFromPoints(points: Point3d[]): HalfEdgeGraph | undefined {\r\n if (points.length < 3)\r\n return undefined;\r\n const hull: Point3d[] = [];\r\n const interior: Point3d[] = [];\r\n Point3dArray.computeConvexHullXY(points, hull, interior, true);\r\n const graph = new HalfEdgeGraph();\r\n const context = InsertAndRetriangulateContext.create(graph);\r\n Triangulator.createFaceLoopFromCoordinates(graph, hull, true, true);\r\n // HalfEdgeGraphMerge.clusterAndMergeXYTheta(graph);\r\n let numInsert = 0;\r\n for (const p of interior) {\r\n context.insertAndRetriangulate(p, true);\r\n numInsert++;\r\n if (numInsert > 16) {\r\n /*\r\n context.reset();\r\n Triangulator.flipTriangles(context.graph);\r\n // console.log (\" intermediate flips \" + numFlip);\r\n */\r\n numInsert = 0;\r\n }\r\n }\r\n /*\r\n // final touchup for aspect ratio flip\r\n for (let i = 0; i < 15; i++) {\r\n const numFlip = Triangulator.flipTriangles(graph);\r\n if (numFlip === 0)\r\n break;\r\n }\r\n */\r\n return graph;\r\n }\r\n /**\r\n * * Only one outer loop permitted.\r\n * * Largest area loop is assumed outer.\r\n * @param loops an array of loops as GrowableXYZArray or XAndY[]\r\n * @returns triangulated graph, or undefined if bad data.\r\n */\r\n public static createTriangulatedGraphFromLoops(loops: GrowableXYZArray[] | XAndY[][]): HalfEdgeGraph | undefined {\r\n if (loops.length < 1)\r\n return undefined;\r\n const mask = HalfEdgeMask.BOUNDARY_EDGE | HalfEdgeMask.PRIMARY_EDGE;\r\n const graph = new HalfEdgeGraph();\r\n const holeSeeds: HalfEdge[] = [];\r\n let maxArea = -10000.0;\r\n let maxAreaIndex = -1;\r\n // collect all the loops with pointers to the positive (inside)\r\n // remember which one has largest area.\r\n for (let i = 0; i < loops.length; i++) {\r\n let seed = Triangulator.directCreateFaceLoopFromCoordinates(graph, loops[i]);\r\n if (seed) {\r\n seed = seed.faceSuccessor; // directCreate returns tail\r\n const mate = seed.vertexSuccessor;\r\n seed.setMaskAroundFace(mask);\r\n mate.setMaskAroundFace(mask);\r\n const signedFaceArea = seed.signedFaceArea();\r\n const area = Math.abs(signedFaceArea);\r\n holeSeeds.push(signedFaceArea >= 0 ? seed : mate);\r\n if (i === 0 || area > maxArea) {\r\n maxArea = area;\r\n maxAreaIndex = i;\r\n }\r\n }\r\n }\r\n if (holeSeeds.length === 0)\r\n return undefined;\r\n // extract the max area seed ...\r\n const maxAreaFace = holeSeeds[maxAreaIndex];\r\n holeSeeds[maxAreaIndex] = holeSeeds[holeSeeds.length - 1];\r\n holeSeeds.pop();\r\n maxAreaFace.vertexSuccessor.setMaskAroundFace(HalfEdgeMask.EXTERIOR);\r\n // The hole seeds all have inside nodes. Set mask there and jump to outside.\r\n for (let i = 0; i < holeSeeds.length; i++) {\r\n const seed = holeSeeds[i];\r\n seed.setMaskAroundFace(HalfEdgeMask.EXTERIOR);\r\n holeSeeds[i] = this.getLeftmost(seed.vertexSuccessor);\r\n }\r\n\r\n const startingNode = Triangulator.spliceLeftMostNodesOfHoles(graph, maxAreaFace, holeSeeds);\r\n if (startingNode) {\r\n if (Triangulator.triangulateSingleFace(graph, startingNode))\r\n return graph;\r\n }\r\n return undefined;\r\n }\r\n /**\r\n * Triangulate all positive area faces of a graph.\r\n */\r\n public static triangulateAllPositiveAreaFaces(graph: HalfEdgeGraph): boolean {\r\n const seeds = graph.collectFaceLoops();\r\n let numFail = 0;\r\n for (const face of seeds) {\r\n if (face.countEdgesAroundFace() > 3) {\r\n const area = face.signedFaceArea();\r\n if (area > 0.0)\r\n if (!Triangulator.triangulateSingleFace(graph, face))\r\n numFail++;\r\n }\r\n }\r\n return numFail === 0;\r\n }\r\n\r\n /**\r\n * Triangulate the polygon made up of by a series of points.\r\n * * The loop may be either CCW or CW -- CCW order will be used for triangles.\r\n * * To triangulate a polygon with holes, use createTriangulatedGraphFromLoops\r\n */\r\n public static createTriangulatedGraphFromSingleLoop(data: XAndY[] | GrowableXYZArray): HalfEdgeGraph | undefined {\r\n const graph = new HalfEdgeGraph();\r\n const startingNode = Triangulator.createFaceLoopFromCoordinates(graph, data, true, true);\r\n\r\n if (!startingNode || graph.countNodes() < 6) return graph;\r\n\r\n if (Triangulator.triangulateSingleFace(graph, startingNode)) {\r\n Triangulator.flipTriangles(graph);\r\n return graph;\r\n }\r\n return undefined;\r\n }\r\n\r\n /**\r\n * cautiously split the edge starting at baseNode.\r\n * * If baseNode is null, create a trivial loop with the single vertex at xy\r\n * * if xy is distinct from the coordinates at both baseNode and its successor, insert xy as a new node within that edge.\r\n * * also include z coordinate if present.\r\n */\r\n private static interiorEdgeSplit(graph: HalfEdgeGraph, baseNode: HalfEdge | undefined, xy: XAndY | number[]): HalfEdge | undefined {\r\n let x = 0, y = 0, z = 0;\r\n if (Array.isArray(xy)) {\r\n x = xy[0];\r\n y = xy[1];\r\n z = xy.length > 2 ? xy[3] : 0.0;\r\n } else {\r\n const q = xy as any;\r\n if (q.hasOwnProperty(\"x\")) x = q.x;\r\n if (q.hasOwnProperty(\"y\")) y = q.y;\r\n if (q.hasOwnProperty(\"z\")) z = q.z;\r\n }\r\n if (!baseNode)\r\n return graph.splitEdge(baseNode, x, y, z);\r\n if (Triangulator.isAlmostEqualXAndYXY(baseNode, x, y))\r\n return baseNode;\r\n if (Triangulator.isAlmostEqualXAndYXY(baseNode.faceSuccessor, x, y))\r\n return baseNode;\r\n return graph.splitEdge(baseNode, x, y, z);\r\n }\r\n /** Create a loop from coordinates.\r\n * * Return a pointer to any node on the loop.\r\n * * no masking or other markup is applied.\r\n */\r\n public static directCreateFaceLoopFromCoordinates(graph: HalfEdgeGraph, data: LineStringDataVariant): HalfEdge | undefined {\r\n // Add the starting nodes as the boundary, and apply initial masks to the primary edge and exteriors\r\n let baseNode: HalfEdge | undefined;\r\n if (data instanceof IndexedXYZCollection) {\r\n const xyz = Point3d.create();\r\n for (let i = 0; i < data.length; i++) {\r\n data.getPoint3dAtCheckedPointIndex(i, xyz);\r\n baseNode = Triangulator.interiorEdgeSplit(graph, baseNode, xyz);\r\n }\r\n } else {\r\n for (const xy of data) {\r\n baseNode = Triangulator.interiorEdgeSplit(graph, baseNode, xy);\r\n }\r\n }\r\n return baseNode;\r\n }\r\n\r\n /** Create chains from coordinates.\r\n * * Return array of pointers to base node of the chains.\r\n * * no masking or other markup is applied.\r\n * @param graph New edges are built in this graph\r\n * @param data coordinate data\r\n * @param id id to attach to (both side of all) edges\r\n */\r\n public static directCreateChainsFromCoordinates(graph: HalfEdgeGraph, data: MultiLineStringDataVariant, id: number = 0): HalfEdge[] {\r\n // Add the starting nodes as the boundary, and apply initial masks to the primary edge and exteriors\r\n const assembler = new AssembleXYZXYZChains(graph, id);\r\n VariantPointDataStream.streamXYZ(data, assembler);\r\n return assembler.claimSeeds();\r\n }\r\n\r\n /**\r\n * @param graph the containing graph\r\n * @param base The last node of a newly created loop. (i.e. its `faceSuccessor` has the start xy)\r\n * @param returnPositiveAreaLoop if true, return the start node on the side with positive area. otherwise return the left side as given.\r\n * @param maskForBothSides mask to apply on both sides.\r\n * @param maskForOtherSide mask to apply to the \"other\" side of the loop.\r\n * @return the loop's start node or its vertex successor, chosen to be the positive or negative loop per request.\r\n */\r\n private static maskAndOrientNewFaceLoop(_graph: HalfEdgeGraph, base: HalfEdge | undefined, returnPositiveAreaLoop: boolean,\r\n maskForBothSides: HalfEdgeMask,\r\n maskForOtherSide: HalfEdgeMask): HalfEdge | undefined {\r\n // base is the final coordinates\r\n if (base) {\r\n base = base.faceSuccessor; // because typical construction process leaves the \"live\" edge at the end of the loop.\r\n const area = base.signedFaceArea();\r\n const mate = base.edgeMate;\r\n if (maskForBothSides !== HalfEdgeMask.NULL_MASK) {\r\n base.setMaskAroundFace(maskForBothSides);\r\n mate.setMaskAroundFace(maskForBothSides);\r\n }\r\n\r\n let preferredNode = base;\r\n if (returnPositiveAreaLoop && (area < 0))\r\n preferredNode = mate;\r\n const otherNode = preferredNode.vertexSuccessor;\r\n\r\n if (maskForOtherSide !== HalfEdgeMask.NULL_MASK)\r\n otherNode.setMaskAroundFace(maskForOtherSide);\r\n return preferredNode;\r\n }\r\n return undefined;\r\n }\r\n /**\r\n * create a circular doubly linked list of internal and external nodes from polygon points in the specified winding order\r\n * * This applies the masks used by typical applications:\r\n * * HalfEdgeMask.BOUNDARY on both sides\r\n * * HalfEdgeMask.PRIMARY_EDGE on both sides.\r\n * * Use `createFaceLoopFromCoordinatesAndMasks` for detail control of masks.\r\n */\r\n public static createFaceLoopFromCoordinates(graph: HalfEdgeGraph, data: LineStringDataVariant, returnPositiveAreaLoop: boolean, markExterior: boolean): HalfEdge | undefined {\r\n const base = Triangulator.directCreateFaceLoopFromCoordinates(graph, data);\r\n return Triangulator.maskAndOrientNewFaceLoop(graph, base, returnPositiveAreaLoop,\r\n HalfEdgeMask.BOUNDARY_EDGE | HalfEdgeMask.PRIMARY_EDGE,\r\n markExterior ? HalfEdgeMask.EXTERIOR : HalfEdgeMask.NULL_MASK);\r\n }\r\n\r\n /**\r\n * create a circular doubly linked list of internal and external nodes from polygon points.\r\n * * Optionally jump to the \"other\" side so the returned loop has positive area\r\n * @param graph graph to receive the new edges\r\n * @param data array with x,y coordinates\r\n * @param returnPositiveAreaLoop if false, return an edge proceeding around the loop in the order given. If true, compute the loop area and flip return the side with positive area.\r\n * @param maskForBothSides mask to apply on both sides.\r\n * @param maskForOtherSide mask to apply on the \"other\" side from the returned loop.\r\n */\r\n public static createFaceLoopFromCoordinatesAndMasks(graph: HalfEdgeGraph, data: LineStringDataVariant, returnPositiveAreaLoop: boolean,\r\n maskForBothSides: HalfEdgeMask,\r\n maskForOtherSide: HalfEdgeMask): HalfEdge | undefined {\r\n const base = Triangulator.directCreateFaceLoopFromCoordinates(graph, data);\r\n return Triangulator.maskAndOrientNewFaceLoop(graph, base, returnPositiveAreaLoop, maskForBothSides, maskForOtherSide);\r\n }\r\n\r\n /** Cut off an ear, forming a new face loop of nodes\r\n * @param ear the vertex being cut off.\r\n * * Form two new nodes, alpha and beta, which have the coordinates one step away from the ear vertex.\r\n * * Reassigns the pointers such that beta is left behind with the new face created\r\n * * Reassigns the pointers such that alpha becomes the resulting missing node from the remaining polygon\r\n * * Reassigns prevZ and nextZ pointers\r\n */\r\n private static joinNeighborsOfEar(graph: HalfEdgeGraph, ear: HalfEdge) {\r\n const alpha = graph.createEdgeXYZXYZ(\r\n ear.facePredecessor.x, ear.facePredecessor.y, ear.facePredecessor.z, ear.facePredecessor.i,\r\n ear.faceSuccessor.x, ear.faceSuccessor.y, ear.faceSuccessor.z, ear.faceSuccessor.i);\r\n const beta = alpha.edgeMate;\r\n\r\n // Add two nodes alpha and beta and reassign pointers (also mark triangle nodes as part of triangle)\r\n HalfEdge.pinch(ear.faceSuccessor, beta);\r\n HalfEdge.pinch(ear.facePredecessor, alpha);\r\n ear.setMaskAroundFace(HalfEdgeMask.TRIANGULATED_FACE);\r\n }\r\n private static isInteriorTriangle(a: HalfEdge) {\r\n if (!a.isMaskSet(HalfEdgeMask.TRIANGULATED_FACE) || a.isMaskSet(HalfEdgeMask.EXTERIOR))\r\n return false;\r\n const b = a.faceSuccessor;\r\n if (!b.isMaskSet(HalfEdgeMask.TRIANGULATED_FACE) || b.isMaskSet(HalfEdgeMask.EXTERIOR))\r\n return false;\r\n const c = b.faceSuccessor;\r\n if (!c.isMaskSet(HalfEdgeMask.TRIANGULATED_FACE) || c.isMaskSet(HalfEdgeMask.EXTERIOR))\r\n return false;\r\n return c.faceSuccessor === a;\r\n }\r\n\r\n /**\r\n * Perform 0, 1, or more edge flips to improve aspect ratio just behind an ear that was just cut.\r\n * @param ear the triangle corner which just served as the ear node.\r\n * @returns the node at the back corner after flipping.\"appropriately positioned\" node for the usual advance to ear.faceSuccessor.edgeMate.faceSuccessor.\r\n */\r\n private static doPostCutFlips(ear: HalfEdge) {\r\n // B is the ear -- inside a (probably newly created) triangle ABC\r\n // CA is the recently added cut edge.\r\n // AB is the candidate to be flipped.\r\n // triangle B1 A1 D is on the other side of AB\r\n // The condition for flipping is:\r\n // ! both triangles must be TRIANGULATED_NODE_MASK\r\n // ! incircle condition flags D as in the circle of ABC\r\n // after flip, node A moves to the vertex of D, and is the effective \"ear\", with the cap edge C A1\r\n // after flip, consider the A1 D (whose nodes are A1 and flipped A!!!)\r\n //\r\n // * *\r\n // . C0| . / |\r\n // . | . C0 /B1|\r\n // . | . /v |\r\n // . ^| . / |\r\n // . A0 ----> B0| . / ^|\r\n // *=======================* --> * A1 / B0*\r\n // \\ A1 <---- B1/ \\ / /\r\n // \\ / \\ / /\r\n // \\ / \\ ^/ D1/\r\n // \\ D1 / \\A0/ /\r\n // * *\r\n let b0 = ear;\r\n let a0 = b0.facePredecessor;\r\n let b1 = a0.edgeMate;\r\n while (Triangulator.isInteriorTriangle(a0) && Triangulator.isInteriorTriangle(b1)) {\r\n const detA = Triangulator.computeInCircleDeterminantIsStrongPositive(a0);\r\n if (!detA)\r\n break;\r\n // Flip the triangles\r\n const a1 = b1.faceSuccessor;\r\n Triangulator.flipEdgeBetweenTriangles(a1, a1.faceSuccessor, a1.facePredecessor, b0, b0.facePredecessor, b0.faceSuccessor);\r\n b0 = a0;\r\n a0 = b0.facePredecessor;\r\n b1 = a0.edgeMate;\r\n }\r\n return b0;\r\n }\r\n\r\n /**\r\n * main ear slicing loop which triangulates a polygon (given as a linked list)\r\n * While there still exists ear nodes that have not yet been triangulated...\r\n *\r\n * * Check if the ear is hashed, and can easily be split off. If so, \"join\" that ear.\r\n * * If not hashed, move on to a separate ear.\r\n * * If no ears are currently hashed, attempt to cure self intersections or split the polygon into two before continuing\r\n */\r\n private static triangulateSingleFace(graph: HalfEdgeGraph, ear?: HalfEdge): boolean {\r\n if (!ear) {\r\n Triangulator.setDebugGraph(graph);\r\n return false;\r\n }\r\n\r\n let next;\r\n let next2;\r\n let pred;\r\n let maxCandidate = ear.countEdgesAroundFace();\r\n let numCandidate = 0;\r\n ear.clearMaskAroundFace(HalfEdgeMask.TRIANGULATED_FACE);\r\n // iterate through ears, slicing them one by one\r\n while (!ear.isMaskSet(HalfEdgeMask.TRIANGULATED_FACE)) {\r\n pred = ear?.facePredecessor;\r\n next = ear.faceSuccessor;\r\n next2 = next.faceSuccessor;\r\n if (next === ear || next2 === ear)\r\n return true;\r\n if (next2.faceSuccessor === ear) {\r\n // if triangle, mask it so that its edges can potentially be flipped by doPostCutFlips()\r\n ear.setMaskAroundFace(HalfEdgeMask.TRIANGULATED_FACE);\r\n return true;\r\n }\r\n // earcut does not support self intersections.\r\n // BUT .. maybe if we watch from the simplest case of next2 returning to pred it will catch some . . .\r\n // (no need to do flips -- we know it's already a triangle)\r\n // EDL Sept 2021 NO... coordinate test is fooled into early exit when large outer triangle has\r\n // edges going in from pred.\r\n // Hence add the around vertex test. But this is possibly vulnerable to a variant false positive ..\r\n if (Geometry.isAlmostEqualXAndY(next2, pred) && !next2.findAroundVertex (pred)) {\r\n HalfEdge.pinch(pred, next2);\r\n ear.setMaskAroundFace(HalfEdgeMask.TRIANGULATED_FACE);\r\n ear = next2;\r\n continue;\r\n }\r\n if (++numCandidate > maxCandidate) {\r\n Triangulator.setDebugGraph(graph);\r\n return false;\r\n }\r\n if (Triangulator.isEar(ear)) {\r\n maxCandidate--;\r\n numCandidate = 0;\r\n\r\n // skipping the next vertices leads to less sliver triangles\r\n\r\n // If we already have a separated triangle, do not join\r\n if (ear.faceSuccessor.faceSuccessor !== ear.facePredecessor) {\r\n Triangulator.joinNeighborsOfEar(graph, ear);\r\n ear = Triangulator.doPostCutFlips(ear);\r\n ear = ear.faceSuccessor.edgeMate.faceSuccessor;\r\n // another step? Nate's 2017 code went one more.\r\n } else {\r\n ear.setMaskAroundFace(HalfEdgeMask.TRIANGULATED_FACE);\r\n ear = next.faceSuccessor;\r\n }\r\n continue;\r\n }\r\n ear = next;\r\n }\r\n return true; // um .. I'm not sure what this state is.\r\n }\r\n /** @internal */\r\n private static sDebugGraph: HalfEdgeGraph | undefined;\r\n /** @internal */\r\n private static sEnableDebugGraphCapture = false;\r\n\r\n /**\r\n * * returns the (possibly undefined) debug graph.\r\n * * sets the debug graph to undefined.\r\n * * disables subsequent saving.\r\n * @internal */\r\n public static claimDebugGraph(): HalfEdgeGraph | undefined {\r\n const g = Triangulator.sDebugGraph;\r\n Triangulator.sDebugGraph = undefined;\r\n Triangulator.sEnableDebugGraphCapture = false;\r\n return g;\r\n }\r\n /** Call (from within the triangulator) to announce a graph to be saved for debug.\r\n * * If debug graph capture is not enabled, do nothing.\r\n * * If debug graph capture is enabled, save this graph.\r\n * * This is called by internal steps at point of failure to preserve the failing graph for unit test examination.\r\n * @internal */\r\n public static setDebugGraph(graph: HalfEdgeGraph | undefined) { if (Triangulator.sEnableDebugGraphCapture) Triangulator.sDebugGraph = graph; }\r\n /**\r\n * * Clear the debug graph\r\n * * Set capture enabled to indicated value.\r\n * * Intended use:\r\n * * By default \"enabled\" is false so there is no activity in the debug graph.\r\n * * A unit test which needs to see graph after failure calls clearAndEnableDebugGraphCapture (true)\r\n * * run the triangulation step\r\n * * call claimDebugGraph.\r\n * * claimDebugGraph reverts everything to default no-capture state.\r\n * @internal */\r\n public static clearAndEnableDebugGraphCapture(value: boolean) {\r\n Triangulator.sEnableDebugGraphCapture = value;\r\n Triangulator.sDebugGraph = undefined;\r\n }\r\n\r\n // for reuse over all calls to isEar ....\r\n private static _edgeInterval = Range1d.createNull();\r\n private static _earRange = Range2d.createNull();\r\n private static _edgeRange = Range2d.createNull();\r\n private static _planes: Plane3dByOriginAndUnitNormal[] = [\r\n Plane3dByOriginAndUnitNormal.createXYPlane(),\r\n Plane3dByOriginAndUnitNormal.createXYPlane(),\r\n Plane3dByOriginAndUnitNormal.createXYPlane(),\r\n ];\r\n /** Check whether a polygon node forms a valid ear with adjacent nodes */\r\n private static isEar(ear: HalfEdge) {\r\n const a = ear.facePredecessor;\r\n const b = ear;\r\n const c = ear.faceSuccessor;\r\n const area = Triangulator.signedTolerancedCCWTriangleArea(a, b, c);\r\n if (area <= 0)\r\n return false; // reflex, can't be an ear\r\n const planes = this._planes;\r\n if (!Plane3dByOriginAndUnitNormal.createOriginAndTargetXY(a, b, planes[0])\r\n || !Plane3dByOriginAndUnitNormal.createOriginAndTargetXY(b, c, planes[1])\r\n || !Plane3dByOriginAndUnitNormal.createOriginAndTargetXY(c, a, planes[2]))\r\n return false;\r\n\r\n // now make sure we don't have other points inside the potential ear, or edges crossing.\r\n const earRange = this._earRange;\r\n const edgeRange = this._edgeRange;\r\n const edgeInterval = this._edgeInterval;\r\n Range2d.createXYXYXY(a.x, a.y, b.x, b.y, c.x, c.y, earRange);\r\n earRange.expandInPlace(Geometry.smallMetricDistance);\r\n let p = c;\r\n const zeroPlus = 1.0e-8;\r\n const zeroMinus = -zeroPlus;\r\n const onePlus = 1.0 + zeroPlus;\r\n const oneMinus = 1.0 - zeroPlus;\r\n const clipTolerance = 1.0e-10 * area;\r\n while (p !== a) {\r\n const q = p.faceSuccessor;\r\n Range2d.createXYXY(p.x, p.y, q.x, q.y, edgeRange);\r\n if (earRange.intersectsRange(edgeRange)) {\r\n // Does pq impinge on the triangle?\r\n Range1d.createXX(zeroMinus, onePlus, edgeInterval);\r\n ClipUtilities.clipSegmentBelowPlanesXY(planes, p, q, edgeInterval, clipTolerance);\r\n if (!edgeInterval.isNull) {\r\n const mate = p.edgeMate;\r\n if (mate === a || mate === b) {\r\n // this is the back side of a bridge edge\r\n } else if (edgeInterval.low > oneMinus) {\r\n // the endpoint (q) just touches ... if it is at one of the vertex loops it's ok ...\r\n if (!a.findAroundVertex(q)\r\n && !b.findAroundVertex(q)\r\n && !c.findAroundVertex(q))\r\n return false;\r\n } else if (edgeInterval.high < zeroPlus) {\r\n // the start (p) just touches ... if it is at one of the vertex loops it's ok ...\r\n if (!a.findAroundVertex(p)\r\n && !b.findAroundVertex(p)\r\n && !c.findAroundVertex(p))\r\n return false;\r\n } else {\r\n // significant internal intersection -- this edge really intrudes on the into the triangle\r\n return false;\r\n }\r\n }\r\n }\r\n p = p.faceSuccessor;\r\n }\r\n return true;\r\n }\r\n /** link holeLoopNodes[1], holeLoopNodes[2] etc into the outer loop, producing a single-ring polygon without holes\r\n *\r\n */\r\n private static spliceLeftMostNodesOfHoles(graph: HalfEdgeGraph, outerNode: HalfEdge, leftMostHoleLoopNode: HalfEdge[]): HalfEdge | undefined {\r\n\r\n leftMostHoleLoopNode.sort(Triangulator.compareX);\r\n let numFail = 0;\r\n // process holes from left to right\r\n for (const holeStart of leftMostHoleLoopNode) {\r\n if (!Triangulator.eliminateHole(graph, holeStart, outerNode))\r\n numFail++;\r\n }\r\n\r\n return numFail === 0 ? outerNode : undefined;\r\n }\r\n /** For use in sorting -- return (signed) difference (a.x - b.x) */\r\n private static compareX(a: HalfEdge, b: HalfEdge) {\r\n return a.x - b.x;\r\n }\r\n\r\n /** find a bridge between vertices that connects hole with an outer ring and and link it */\r\n private static eliminateHole(graph: HalfEdgeGraph, hole: HalfEdge, outerNode: HalfEdge): boolean {\r\n const outerNodeA = Triangulator.findHoleBridge(hole, outerNode);\r\n if (outerNodeA) {\r\n return Triangulator.splitFace(graph, outerNodeA, hole) !== undefined;\r\n }\r\n return false;\r\n }\r\n // cspell:word Eberly\r\n /**\r\n * David Eberly algorithm for finding a bridge between hole and outer polygon:\r\n * https://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf\r\n */\r\n private static findHoleBridge(hole: HalfEdge, outerNode?: HalfEdge): HalfEdge | undefined {\r\n let p = outerNode;\r\n\r\n if (!p)\r\n return undefined;\r\n\r\n const hx = hole.x;\r\n const hy = hole.y;\r\n let qx = -Infinity;\r\n let m;\r\n\r\n // find a segment intersected by a ray from the hole's leftmost point to the left;\r\n // segment's endpoint with lesser x will be potential connection point\r\n do {\r\n if (hy <= p.y && hy >= p.faceSuccessor.y && p.faceSuccessor.y !== p.y) {\r\n const x = p.x + (hy - p.y) * (p.faceSuccessor.x - p.x) / (p.faceSuccessor.y - p.y);\r\n if (x <= hx && x > qx) {\r\n qx = x;\r\n if (x === hx) {\r\n if (hy === p.y) return p;\r\n if (hy === p.faceSuccessor.y) return p.faceSuccessor;\r\n }\r\n m = p.x < p.faceSuccessor.x ? p : p.faceSuccessor;\r\n }\r\n }\r\n p = p.faceSuccessor;\r\n } while (p !== outerNode);\r\n\r\n if (!m) return undefined;\r\n\r\n if (hx === qx) return m.facePredecessor; // hole touches outer segment; pick lower endpoint\r\n\r\n // look for points inside the triangle of hole point, segment intersection and endpoint;\r\n // if there are no points found, we have a valid connection;\r\n // otherwise choose the point of the minimum angle with the ray as connection point\r\n\r\n const stop = m;\r\n const mx = m.x;\r\n const my = m.y;\r\n let tanMin = Infinity;\r\n let tan;\r\n\r\n p = m.faceSuccessor;\r\n\r\n while (p !== stop) {\r\n if (hx >= p.x && p.x >= mx && hx !== p.x &&\r\n Triangulator.pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {\r\n\r\n tan = Math.abs(hy - p.y) / (hx - p.x); // tangential\r\n\r\n if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && Triangulator.locallyInside(p, hole)) {\r\n m = p;\r\n tanMin = tan;\r\n }\r\n }\r\n\r\n p = p.faceSuccessor;\r\n }\r\n\r\n return m;\r\n }\r\n\r\n // find the leftmost node of a polygon ring\r\n private static getLeftmost(start: HalfEdge) {\r\n let p = start;\r\n let leftmost = start;\r\n do {\r\n if (p.x < leftmost.x) leftmost = p;\r\n p = p.faceSuccessor;\r\n } while (p !== start);\r\n\r\n return leftmost;\r\n }\r\n\r\n /** check if a point lies within a convex triangle.\r\n * i.e. areas of 3 triangles with an edge of abc and p all have zero or positive area. (abp, bcp, cap)\r\n */\r\n private static pointInTriangle(ax: number, ay: number, bx: number, by: number, cx: number, cy: number, px: number, py: number) {\r\n return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&\r\n (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&\r\n (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;\r\n }\r\n private static nodeInTriangle(a: HalfEdge, b: HalfEdge, c: HalfEdge, p: HalfEdge) {\r\n return Triangulator.signedTolerancedCCWTriangleArea(a, b, p) > 0\r\n && Triangulator.signedTolerancedCCWTriangleArea(b, c, p) > 0.0\r\n && Triangulator.signedTolerancedCCWTriangleArea(c, a, p) > 0.0;\r\n }\r\n /** signed area of a triangle\r\n * EDL 2/21 This is negative of usual CCW area. Beware in callers !!!\r\n * (This originates in classic earcut code.)\r\n */\r\n private static signedCWTriangleArea(p: HalfEdge, q: HalfEdge, r: HalfEdge) {\r\n return 0.5 * ((q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y));\r\n }\r\n\r\n /** signed area of a triangle, with small positive corrected to zero by relTol\r\n */\r\n private static signedTolerancedCCWTriangleArea(p: HalfEdge, q: HalfEdge, r: HalfEdge, relTol: number = 1.0e-12) {\r\n const ux = q.x - p.x;\r\n const uy = q.y - p.y;\r\n const vx = r.x - p.x;\r\n const vy = r.y - p.y;\r\n const area = 0.5 * (ux * vy - uy * vx);\r\n if (area < 0.0)\r\n return area;\r\n const uu = ux * ux + uy * uy;\r\n const vv = vx * vx + vy * vy;\r\n if (area < relTol * (uu + vv))\r\n return 0.0;\r\n return area;\r\n }\r\n\r\n /** check if two points are equal */\r\n private static isAlmostEqualXAndYXY(p1: XAndY, x: number, y: number) {\r\n return Geometry.isAlmostEqualNumber(p1.x, x) && Geometry.isAlmostEqualNumber(p1.y, y);\r\n }\r\n\r\n /** check if a b is inside the sector around a */\r\n private static locallyInside(a: HalfEdge, b: HalfEdge) {\r\n return Triangulator.signedCWTriangleArea(a.facePredecessor, a, a.faceSuccessor) < 0 ?\r\n Triangulator.signedCWTriangleArea(a, b, a.faceSuccessor) >= 0 && Triangulator.signedCWTriangleArea(a, a.facePredecessor, b) >= 0 :\r\n Triangulator.signedCWTriangleArea(a, b, a.facePredecessor) < 0 || Triangulator.signedCWTriangleArea(a, a.faceSuccessor, b) < 0;\r\n }\r\n\r\n /**\r\n * link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;\r\n * if one belongs to the outer ring and another to a hole, it merges it into a single ring\r\n * * Returns the base of the new edge at the \"a\" end.\r\n * * \"a\" and \"b\" still represent the same physical pieces of edges\r\n * @returns Returns the (base of) the new half edge, at the \"a\" end.\r\n */\r\n private static splitFace(graph: HalfEdgeGraph, a: HalfEdge, b: HalfEdge): HalfEdge | undefined {\r\n if (HalfEdge.isNodeVisibleInSector(a, b) && HalfEdge.isNodeVisibleInSector(b, a)) {\r\n const a2 = graph.createEdgeXYZXYZ(a.x, a.y, a.z, a.i, b.x, b.y, b.z, b.i);\r\n const b2 = a2.faceSuccessor;\r\n HalfEdge.pinch(a, a2);\r\n HalfEdge.pinch(b, b2);\r\n return a2;\r\n }\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Triangulate a single face with (linear time) logic applicable only if the lowNode is the lowest node.\r\n * @returns false if any monotonicity condition is violated.\r\n */\r\n public static triangulateSingleMonotoneFace(graph: HalfEdgeGraph, start: HalfEdge): boolean {\r\n let left = start.facePredecessor;\r\n let right = start.faceSuccessor;\r\n // P0, P1, P2 are successive edges along evolving chain\r\n let upperSideOfNewEdge;\r\n while (left !== right\r\n && right !== start\r\n && right.faceSuccessor !== left) {\r\n /** These should not happen if face is monotone . .. */\r\n if (HalfEdge.crossProductXYAlongChain(left, start, right) <= 0)\r\n return false;\r\n if (!start.belowYX(left))\r\n return false;\r\n if (!start.belowYX(right))\r\n return false;\r\n if (left.belowYX(right)) {\r\n /* Triangulate to all left side edges that\r\n are below right */\r\n\r\n /* Phase 1: move upward, adding back edges\r\n when prior nodes are visible. */\r\n let P0 = left;\r\n let P1 = start;\r\n let P2 = right;\r\n /* Invariant: the path from P0 back to P1 is concave.\r\n Each loop pass moves P0 up the left side, filling in\r\n edges as needed. The right side edge\r\n (following start) is never altered.\r\n */\r\n while (P0 !== P2 && P0.belowYX(right)) {\r\n while (P2 !== right\r\n && P2 !== P0\r\n && P2 !== P1\r\n && HalfEdge.crossProductXYAlongChain(P0, P1, P2) > 0) {\r\n upperSideOfNewEdge = Triangulator.splitFace(graph, P0, P2);\r\n if (upperSideOfNewEdge === undefined)\r\n return false;\r\n P0 = upperSideOfNewEdge;\r\n P1 = P0.faceSuccessor;\r\n P2 = P1.faceSuccessor;\r\n }\r\n P2 = P1;\r\n P1 = P0;\r\n P0 = P0.facePredecessor;\r\n }\r\n /* Phase 2: Fan out edges from right to the\r\n left side. P0.P1.P2 describes a pair of\r\n adjacent edges at the bottom. */\r\n left = P1;\r\n P2 = right;\r\n P1 = P2.facePredecessor;\r\n P0 = P1.facePredecessor;\r\n while (P2.faceSuccessor !== P0 && P0 !== left) {\r\n upperSideOfNewEdge = Triangulator.splitFace(graph, P0, P2);\r\n if (upperSideOfNewEdge === undefined)\r\n return false;\r\n P1 = upperSideOfNewEdge;\r\n P0 = P1.facePredecessor;\r\n }\r\n /* Finish off with the last stroke from the\r\n left node to the right, except when already\r\n topped out */\r\n if (P2.faceSuccessor !== P0) {\r\n upperSideOfNewEdge = Triangulator.splitFace(graph, P0, P2);\r\n if (upperSideOfNewEdge === undefined)\r\n return false;\r\n P0 = upperSideOfNewEdge;\r\n }\r\n start = P0;\r\n right = start.faceSuccessor;\r\n left = start.facePredecessor;\r\n\r\n } else {\r\n /* Triangulate to all right side edges that\r\n are below left */\r\n\r\n /* Phase 1: move upward, adding back edges\r\n when prior nodes are visible. */\r\n let P0 = left;\r\n let P1 = start;\r\n let P2 = right;\r\n /* Invariant: the path up to P1 is concave.\r\n Each loop pass advances P1, filling in\r\n edges as needed. Note that the\r\n start edge may get hidden, so the\r\n bottom node must be referenced as\r\n left.faceSuccessor rather than as start.\r\n */\r\n while (P0 !== P2 && P2.belowYX(left)) {\r\n while (P0 !== left\r\n && P2 !== P0\r\n && P2 !== P1\r\n && HalfEdge.crossProductXYAlongChain(P0, P1, P2) > 0) {\r\n upperSideOfNewEdge = Triangulator.splitFace(graph, P0, P2);\r\n if (upperSideOfNewEdge === undefined)\r\n return false;\r\n\r\n P0 = upperSideOfNewEdge.facePredecessor;\r\n P1 = upperSideOfNewEdge;\r\n }\r\n P0 = P1;\r\n P1 = P2;\r\n P2 = P2.faceSuccessor;\r\n }\r\n /* Phase 2: Fan out edges from left to the\r\n right side. P0.P1.P2 describes a pair of\r\n adjacent edges at the bottom. */\r\n right = P1;\r\n P0 = left;\r\n P1 = P0.faceSuccessor;\r\n P2 = P1.faceSuccessor;\r\n while (P2.faceSuccessor !== P0 && P2 !== right) {\r\n upperSideOfNewEdge = Triangulator.splitFace(graph, P0, P2);\r\n if (upperSideOfNewEdge === undefined)\r\n return false;\r\n P0 = upperSideOfNewEdge;\r\n // P1 = P2; // original code (ported from native) carefully maintained P1..P2 relationship. But code analyzer says P1 is not used again. So skip it.\r\n P2 = P2.faceSuccessor;\r\n }\r\n /* Finish off with the last stroke from the\r\n left node to the right, except when already\r\n topped out */\r\n if (P2.faceSuccessor !== P0) {\r\n const newEdge = Triangulator.splitFace(graph, P0, P2);\r\n if (newEdge === undefined)\r\n return false;\r\n }\r\n start = right;\r\n right = start.faceSuccessor;\r\n left = start.facePredecessor;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n}\r\n\r\n/**\r\n * Internal class for assembling chains\r\n * @internal\r\n */\r\nclass AssembleXYZXYZChains extends PointStreamXYZXYZHandlerBase {\r\n // Add the starting nodes as the boundary, and apply initial masks to the primary edge and exteriors\r\n private _seeds?: HalfEdge[];\r\n private _baseNode: HalfEdge | undefined;\r\n private _nodeB: HalfEdge | undefined;\r\n private _nodeC: HalfEdge | undefined;\r\n private _graph: HalfEdgeGraph;\r\n private _id: any;\r\n public constructor(graph: HalfEdgeGraph, id: any) {\r\n super();\r\n this._graph = graph;\r\n this._id = id;\r\n }\r\n public override startChain(chainData: MultiLineStringDataVariant, isLeaf: boolean): void {\r\n super.startChain(chainData, isLeaf);\r\n this._baseNode = undefined;\r\n this._nodeB = undefined;\r\n }\r\n public override handleXYZXYZ(x0: number, y0: number, z0: number, x1: number, y1: number, z1: number) {\r\n this._nodeC = this._graph.createEdgeXYZXYZ(x0, y0, z0, this._id, x1, y1, z1, this._id);\r\n if (this._baseNode === undefined) {\r\n this._baseNode = this._nodeC;\r\n this._nodeB = this._baseNode.faceSuccessor;\r\n } else {\r\n HalfEdge.pinch(this._nodeB!, this._nodeC);\r\n this._nodeB = this._nodeC.faceSuccessor;\r\n }\r\n }\r\n public override endChain(chainData: MultiLineStringDataVariant, isLeaf: boolean): void {\r\n super.endChain(chainData, isLeaf);\r\n if (this._baseNode !== undefined) {\r\n if (this._seeds === undefined)\r\n this._seeds = [];\r\n this._seeds.push(this._baseNode);\r\n }\r\n this._baseNode = undefined;\r\n this._nodeB = undefined;\r\n this._nodeC = undefined;\r\n }\r\n public claimSeeds(): HalfEdge[] {\r\n if (this._seeds === undefined)\r\n return [];\r\n return this._seeds;\r\n }\r\n}\r\n"]}
@@ -6,8 +6,8 @@ import { Point2d, Vector2d, XY } from "./geometry3d/Point2dVector2d";
6
6
  import { Point3d, Vector3d, XYZ } from "./geometry3d/Point3dVector3d";
7
7
  import { XAndY } from "./geometry3d/XYZProps";
8
8
  import { Point4d } from "./geometry4d/Point4d";
9
- /** Enumeration of the 6 possible orderings of XYZ axis order
10
- *
9
+ /**
10
+ * Enumeration of the 6 possible orderings of XYZ axis order
11
11
  * * **Note:** There are 3 axis order with right hand system (XYZ = 0, YZX = 1, ZXY = 2) and 3 axis order with
12
12
  * left hand system (XZY = 4, YXZ = 5, ZYX = 6). Note that AxisOrder is encoding the handedness as well. Cross
13
13
  * product of the i_th axis in an ordering (i=0,1,2), with the i+1_th in that ordering, will produce the i+2_th
@@ -28,7 +28,8 @@ export declare enum AxisOrder {
28
28
  /** Left handed system, Z then Y then X */
29
29
  ZYX = 6
30
30
  }
31
- /** Enumeration of numeric indices of 3 axes AxisIndex.X, AxisIndex.Y, AxisIndex.Z
31
+ /**
32
+ * Enumeration of numeric indices of 3 axes AxisIndex.X, AxisIndex.Y, AxisIndex.Z
32
33
  * @public
33
34
  */
34
35
  export declare enum AxisIndex {
@@ -125,6 +126,29 @@ export interface PlaneAltitudeEvaluator {
125
126
  /** x part of normal vector */
126
127
  normalZ(): number;
127
128
  }
129
+ /** Enumeration of possible locations of a point in the plane of a polygon.
130
+ * @public
131
+ */
132
+ export declare enum PolygonLocation {
133
+ /** No location specified. */
134
+ Unknown = 0,
135
+ /** Point is at a vertex. */
136
+ OnPolygonVertex = 1,
137
+ /** Point is on an edge (but not a vertex). */
138
+ OnPolygonEdgeInterior = 2,
139
+ /** Point is strictly inside the polygon with unknown projection. */
140
+ InsidePolygon = 3,
141
+ /** Point is strictly inside the polygon and projects to a vertex. */
142
+ InsidePolygonProjectsToVertex = 4,
143
+ /** Point is strictly inside the polygon and projects to an edge (but not a vertex). */
144
+ InsidePolygonProjectsToEdgeInterior = 5,
145
+ /** Point is strictly outside the polygon with unknown projection. */
146
+ OutsidePolygon = 6,
147
+ /** Point is strictly outside the polygon and projects to a vertex. */
148
+ OutsidePolygonProjectsToVertex = 7,
149
+ /** Point is strictly outside the polygon and projects to an edge (but not a vertex). */
150
+ OutsidePolygonProjectsToEdgeInterior = 8
151
+ }
128
152
  /**
129
153
  * Interface for `toJSON` and `setFromJSON` methods
130
154
  * @public
@@ -223,7 +247,10 @@ export declare class Geometry {
223
247
  * @param a denominator of division
224
248
  */
225
249
  static inverseMetricDistanceSquared(a: number): number | undefined;
226
- /** Boolean test for metric coordinate near-equality */
250
+ /**
251
+ * Boolean test for metric coordinate near-equality (i.e., if x and y are almost equal). If tolerance is not passed,
252
+ * `Geometry.smallMetricDistance` is used as tolerance.
253
+ */
227
254
  static isSameCoordinate(x: number, y: number, tol?: number): boolean;
228
255
  /** Boolean test for metric coordinate near-equality, with toleranceFactor applied to the usual smallMetricDistance */
229
256
  static isSameCoordinateWithToleranceFactor(x: number, y: number, toleranceFactor: number): boolean;
@@ -292,9 +319,9 @@ export declare class Geometry {
292
319
  * */
293
320
  static cyclic3dAxis(axis: number): number;
294
321
  /** Return the AxisOrder for which axisIndex is the first named axis.
295
- * * `axisIndex===0`returns AxisOrder.XYZ
296
- * * `axisIndex===1`returns AxisOrder.YZX
297
- * * `axisIndex===2`returns AxisOrder.ZXY
322
+ * * `axisIndex === 0` returns `AxisOrder.XYZ`
323
+ * * `axisIndex === 1` returns `AxisOrder.YZX`
324
+ * * `axisIndex === 2` returns `AxisOrder.ZXY`
298
325
  */
299
326
  static axisIndexToRightHandedAxisOrder(axisIndex: AxisIndex): AxisOrder;
300
327
  /** Return the largest absolute distance from a to either of b0 or b1 */
@@ -305,7 +332,8 @@ export declare class Geometry {
305
332
  static maxAbsXY(x: number, y: number): number;
306
333
  /** Return the largest signed value among a, b, c */
307
334
  static maxXYZ(a: number, b: number, c: number): number;
308
- /** Examine the value (particularly sign) of x.
335
+ /**
336
+ * Examine the value (particularly sign) of x.
309
337
  * * If x is negative, return outNegative.
310
338
  * * If x is true zero, return outZero
311
339
  * * If x is positive, return outPositive
@@ -431,12 +459,28 @@ export declare class Geometry {
431
459
  static modulo(a: number, period: number): number;
432
460
  /** return 0 if the value is undefined, 1 if defined. */
433
461
  static defined01(value: any): number;
434
- /** normally, return numerator/denominator.
435
- * but if the ratio would exceed Geometry.largeFractionResult, return undefined.
462
+ /**
463
+ * Return `numerator` divided by `denominator`, or `undefined`.
464
+ * @param numerator the numerator
465
+ * @param denominator the denominator
466
+ * @returns return `numerator/denominator` but if the ratio would exceed `Geometry.largeFractionResult`,
467
+ * return `undefined`.
436
468
  */
437
469
  static conditionalDivideFraction(numerator: number, denominator: number): number | undefined;
438
- /** normally, return numerator/denominator.
439
- * but if the ratio would exceed Geometry.largestResult, return undefined.
470
+ /**
471
+ * Return `numerator` divided by `denominator`.
472
+ * @param numerator the numerator
473
+ * @param denominator the denominator
474
+ * @returns return `numerator/denominator` but if the ratio would exceed `Geometry.largeFractionResult`,
475
+ * return `defaultResult`.
476
+ */
477
+ static safeDivideFraction(numerator: number, denominator: number, defaultResult: number): number;
478
+ /**
479
+ * Return `numerator` divided by `denominator` (with a given `largestResult`), or `undefined`.
480
+ * @param numerator the numerator
481
+ * @param denominator the denominator
482
+ * @param largestResult the ratio threshold.
483
+ * @returns return `numerator/denominator` but if the ratio would exceed `largestResult`, return `undefined`.
440
484
  */
441
485
  static conditionalDivideCoordinate(numerator: number, denominator: number, largestResult?: number): number | undefined;
442
486
  /** return the 0, 1, or 2 pairs of (c,s) values that solve
@@ -444,10 +488,6 @@ export declare class Geometry {
444
488
  * with the constraint {c*c+s*s = 1}
445
489
  */
446
490
  static solveTrigForm(constCoff: number, cosCoff: number, sinCoff: number): Vector2d[] | undefined;
447
- /** normally, return the number result of conditionalDivideFraction.
448
- * but if conditionalDivideFraction fails return specified default number.
449
- */
450
- static safeDivideFraction(numerator: number, denominator: number, defaultResult: number): number;
451
491
  /** For a line f(x) whose function values at x0 and x1 are f0 and f1, return the x value at which f(x)=fTarget; */
452
492
  static inverseInterpolate(x0: number, f0: number, x1: number, f1: number, targetF?: number, defaultResult?: number): number | undefined;
453
493
  /** For a line f(x) whose function values at x=0 and x=1 are f0 and f1, return the x value at which f(x)=fTarget; */