@itwin/core-geometry 4.9.0-dev.9 → 4.10.0-dev.1

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 (336) hide show
  1. package/CHANGELOG.md +26 -1
  2. package/lib/cjs/Geometry.d.ts +57 -46
  3. package/lib/cjs/Geometry.d.ts.map +1 -1
  4. package/lib/cjs/Geometry.js +73 -53
  5. package/lib/cjs/Geometry.js.map +1 -1
  6. package/lib/cjs/curve/Arc3d.d.ts +141 -38
  7. package/lib/cjs/curve/Arc3d.d.ts.map +1 -1
  8. package/lib/cjs/curve/Arc3d.js +219 -31
  9. package/lib/cjs/curve/Arc3d.js.map +1 -1
  10. package/lib/cjs/curve/CurveChainWithDistanceIndex.d.ts +11 -6
  11. package/lib/cjs/curve/CurveChainWithDistanceIndex.d.ts.map +1 -1
  12. package/lib/cjs/curve/CurveChainWithDistanceIndex.js +12 -10
  13. package/lib/cjs/curve/CurveChainWithDistanceIndex.js.map +1 -1
  14. package/lib/cjs/curve/CurveCollection.d.ts +2 -1
  15. package/lib/cjs/curve/CurveCollection.d.ts.map +1 -1
  16. package/lib/cjs/curve/CurveCollection.js +2 -1
  17. package/lib/cjs/curve/CurveCollection.js.map +1 -1
  18. package/lib/cjs/curve/CurveCurve.d.ts +11 -9
  19. package/lib/cjs/curve/CurveCurve.d.ts.map +1 -1
  20. package/lib/cjs/curve/CurveCurve.js +11 -9
  21. package/lib/cjs/curve/CurveCurve.js.map +1 -1
  22. package/lib/cjs/curve/CurveFactory.d.ts +4 -3
  23. package/lib/cjs/curve/CurveFactory.d.ts.map +1 -1
  24. package/lib/cjs/curve/CurveFactory.js +4 -3
  25. package/lib/cjs/curve/CurveFactory.js.map +1 -1
  26. package/lib/cjs/curve/CurveLocationDetail.d.ts +19 -1
  27. package/lib/cjs/curve/CurveLocationDetail.d.ts.map +1 -1
  28. package/lib/cjs/curve/CurveLocationDetail.js +39 -0
  29. package/lib/cjs/curve/CurveLocationDetail.js.map +1 -1
  30. package/lib/cjs/curve/CurveOps.d.ts +4 -4
  31. package/lib/cjs/curve/CurveOps.d.ts.map +1 -1
  32. package/lib/cjs/curve/CurveOps.js +6 -6
  33. package/lib/cjs/curve/CurveOps.js.map +1 -1
  34. package/lib/cjs/curve/CurvePrimitive.d.ts +1 -1
  35. package/lib/cjs/curve/CurvePrimitive.js.map +1 -1
  36. package/lib/cjs/curve/LineString3d.d.ts +7 -5
  37. package/lib/cjs/curve/LineString3d.d.ts.map +1 -1
  38. package/lib/cjs/curve/LineString3d.js +8 -6
  39. package/lib/cjs/curve/LineString3d.js.map +1 -1
  40. package/lib/cjs/curve/Loop.d.ts.map +1 -1
  41. package/lib/cjs/curve/Loop.js +6 -6
  42. package/lib/cjs/curve/Loop.js.map +1 -1
  43. package/lib/cjs/curve/OffsetOptions.d.ts +1 -1
  44. package/lib/cjs/curve/OffsetOptions.js +1 -1
  45. package/lib/cjs/curve/OffsetOptions.js.map +1 -1
  46. package/lib/cjs/curve/Path.d.ts.map +1 -1
  47. package/lib/cjs/curve/Path.js +5 -6
  48. package/lib/cjs/curve/Path.js.map +1 -1
  49. package/lib/cjs/curve/Query/ConsolidateAdjacentPrimitivesContext.d.ts.map +1 -1
  50. package/lib/cjs/curve/Query/ConsolidateAdjacentPrimitivesContext.js +3 -4
  51. package/lib/cjs/curve/Query/ConsolidateAdjacentPrimitivesContext.js.map +1 -1
  52. package/lib/cjs/curve/Query/CylindricalRange.js.map +1 -1
  53. package/lib/cjs/curve/RegionOps.d.ts +4 -3
  54. package/lib/cjs/curve/RegionOps.d.ts.map +1 -1
  55. package/lib/cjs/curve/RegionOps.js +4 -3
  56. package/lib/cjs/curve/RegionOps.js.map +1 -1
  57. package/lib/cjs/curve/internalContexts/CurveCurveCloseApproachXY.d.ts +23 -7
  58. package/lib/cjs/curve/internalContexts/CurveCurveCloseApproachXY.d.ts.map +1 -1
  59. package/lib/cjs/curve/internalContexts/CurveCurveCloseApproachXY.js +43 -35
  60. package/lib/cjs/curve/internalContexts/CurveCurveCloseApproachXY.js.map +1 -1
  61. package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.d.ts +22 -8
  62. package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.d.ts.map +1 -1
  63. package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.js +127 -52
  64. package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -1
  65. package/lib/cjs/curve/internalContexts/EllipticalArcApproximationContext.d.ts +211 -0
  66. package/lib/cjs/curve/internalContexts/EllipticalArcApproximationContext.d.ts.map +1 -0
  67. package/lib/cjs/curve/internalContexts/EllipticalArcApproximationContext.js +1000 -0
  68. package/lib/cjs/curve/internalContexts/EllipticalArcApproximationContext.js.map +1 -0
  69. package/lib/cjs/curve/internalContexts/MultiChainCollector.d.ts +11 -8
  70. package/lib/cjs/curve/internalContexts/MultiChainCollector.d.ts.map +1 -1
  71. package/lib/cjs/curve/internalContexts/MultiChainCollector.js +7 -4
  72. package/lib/cjs/curve/internalContexts/MultiChainCollector.js.map +1 -1
  73. package/lib/cjs/geometry3d/Angle.d.ts +18 -5
  74. package/lib/cjs/geometry3d/Angle.d.ts.map +1 -1
  75. package/lib/cjs/geometry3d/Angle.js +23 -7
  76. package/lib/cjs/geometry3d/Angle.js.map +1 -1
  77. package/lib/cjs/geometry3d/AngleSweep.d.ts +14 -1
  78. package/lib/cjs/geometry3d/AngleSweep.d.ts.map +1 -1
  79. package/lib/cjs/geometry3d/AngleSweep.js +47 -12
  80. package/lib/cjs/geometry3d/AngleSweep.js.map +1 -1
  81. package/lib/cjs/geometry3d/FrameBuilder.d.ts +2 -1
  82. package/lib/cjs/geometry3d/FrameBuilder.d.ts.map +1 -1
  83. package/lib/cjs/geometry3d/FrameBuilder.js +12 -10
  84. package/lib/cjs/geometry3d/FrameBuilder.js.map +1 -1
  85. package/lib/cjs/geometry3d/GeometryHandler.d.ts.map +1 -1
  86. package/lib/cjs/geometry3d/GeometryHandler.js +1 -7
  87. package/lib/cjs/geometry3d/GeometryHandler.js.map +1 -1
  88. package/lib/cjs/geometry3d/Matrix3d.d.ts +6 -4
  89. package/lib/cjs/geometry3d/Matrix3d.d.ts.map +1 -1
  90. package/lib/cjs/geometry3d/Matrix3d.js +6 -4
  91. package/lib/cjs/geometry3d/Matrix3d.js.map +1 -1
  92. package/lib/cjs/geometry3d/Point3dVector3d.d.ts +5 -5
  93. package/lib/cjs/geometry3d/Point3dVector3d.d.ts.map +1 -1
  94. package/lib/cjs/geometry3d/Point3dVector3d.js +5 -5
  95. package/lib/cjs/geometry3d/Point3dVector3d.js.map +1 -1
  96. package/lib/cjs/geometry3d/PointHelpers.d.ts +6 -5
  97. package/lib/cjs/geometry3d/PointHelpers.d.ts.map +1 -1
  98. package/lib/cjs/geometry3d/PointHelpers.js +11 -10
  99. package/lib/cjs/geometry3d/PointHelpers.js.map +1 -1
  100. package/lib/cjs/geometry3d/PolygonOps.d.ts +4 -4
  101. package/lib/cjs/geometry3d/PolygonOps.d.ts.map +1 -1
  102. package/lib/cjs/geometry3d/PolygonOps.js +7 -11
  103. package/lib/cjs/geometry3d/PolygonOps.js.map +1 -1
  104. package/lib/cjs/geometry3d/PolylineCompressionByEdgeOffset.d.ts +1 -1
  105. package/lib/cjs/geometry3d/PolylineCompressionByEdgeOffset.d.ts.map +1 -1
  106. package/lib/cjs/geometry3d/PolylineCompressionByEdgeOffset.js +3 -3
  107. package/lib/cjs/geometry3d/PolylineCompressionByEdgeOffset.js.map +1 -1
  108. package/lib/cjs/geometry3d/Range.d.ts +6 -1
  109. package/lib/cjs/geometry3d/Range.d.ts.map +1 -1
  110. package/lib/cjs/geometry3d/Range.js +9 -3
  111. package/lib/cjs/geometry3d/Range.js.map +1 -1
  112. package/lib/cjs/geometry3d/Ray3d.d.ts +1 -1
  113. package/lib/cjs/geometry3d/Ray3d.d.ts.map +1 -1
  114. package/lib/cjs/geometry3d/Ray3d.js.map +1 -1
  115. package/lib/cjs/geometry3d/Transform.d.ts +1 -1
  116. package/lib/cjs/geometry3d/Transform.js +1 -1
  117. package/lib/cjs/geometry3d/Transform.js.map +1 -1
  118. package/lib/cjs/numerics/Newton.d.ts +3 -3
  119. package/lib/cjs/numerics/Newton.d.ts.map +1 -1
  120. package/lib/cjs/numerics/Newton.js +14 -16
  121. package/lib/cjs/numerics/Newton.js.map +1 -1
  122. package/lib/cjs/numerics/Polynomials.d.ts +2 -2
  123. package/lib/cjs/numerics/Polynomials.js +2 -2
  124. package/lib/cjs/numerics/Polynomials.js.map +1 -1
  125. package/lib/cjs/polyface/PolyfaceBuilder.d.ts +7 -4
  126. package/lib/cjs/polyface/PolyfaceBuilder.d.ts.map +1 -1
  127. package/lib/cjs/polyface/PolyfaceBuilder.js +11 -6
  128. package/lib/cjs/polyface/PolyfaceBuilder.js.map +1 -1
  129. package/lib/cjs/polyface/PolyfaceClip.d.ts +13 -10
  130. package/lib/cjs/polyface/PolyfaceClip.d.ts.map +1 -1
  131. package/lib/cjs/polyface/PolyfaceClip.js +17 -14
  132. package/lib/cjs/polyface/PolyfaceClip.js.map +1 -1
  133. package/lib/cjs/polyface/PolyfaceQuery.d.ts +11 -14
  134. package/lib/cjs/polyface/PolyfaceQuery.d.ts.map +1 -1
  135. package/lib/cjs/polyface/PolyfaceQuery.js +59 -52
  136. package/lib/cjs/polyface/PolyfaceQuery.js.map +1 -1
  137. package/lib/cjs/serialization/BGFBReader.js.map +1 -1
  138. package/lib/cjs/serialization/BGFBWriter.js +2 -2
  139. package/lib/cjs/serialization/BGFBWriter.js.map +1 -1
  140. package/lib/cjs/serialization/GeometrySamples.js.map +1 -1
  141. package/lib/cjs/solid/SweepContour.d.ts.map +1 -1
  142. package/lib/cjs/solid/SweepContour.js +0 -4
  143. package/lib/cjs/solid/SweepContour.js.map +1 -1
  144. package/lib/cjs/topology/Graph.d.ts +1 -1
  145. package/lib/cjs/topology/Graph.js +2 -2
  146. package/lib/cjs/topology/Graph.js.map +1 -1
  147. package/lib/cjs/topology/HalfEdgeNodeXYZUV.d.ts +1 -1
  148. package/lib/cjs/topology/HalfEdgeNodeXYZUV.js +1 -1
  149. package/lib/cjs/topology/HalfEdgeNodeXYZUV.js.map +1 -1
  150. package/lib/cjs/topology/HalfEdgePointInGraphSearch.d.ts +57 -15
  151. package/lib/cjs/topology/HalfEdgePointInGraphSearch.d.ts.map +1 -1
  152. package/lib/cjs/topology/HalfEdgePointInGraphSearch.js +168 -127
  153. package/lib/cjs/topology/HalfEdgePointInGraphSearch.js.map +1 -1
  154. package/lib/cjs/topology/HalfEdgePositionDetail.d.ts +35 -35
  155. package/lib/cjs/topology/HalfEdgePositionDetail.d.ts.map +1 -1
  156. package/lib/cjs/topology/HalfEdgePositionDetail.js +63 -41
  157. package/lib/cjs/topology/HalfEdgePositionDetail.js.map +1 -1
  158. package/lib/cjs/topology/InsertAndRetriangulateContext.d.ts +64 -12
  159. package/lib/cjs/topology/InsertAndRetriangulateContext.d.ts.map +1 -1
  160. package/lib/cjs/topology/InsertAndRetriangulateContext.js +174 -75
  161. package/lib/cjs/topology/InsertAndRetriangulateContext.js.map +1 -1
  162. package/lib/cjs/topology/Merging.d.ts +2 -2
  163. package/lib/cjs/topology/Merging.js +2 -2
  164. package/lib/cjs/topology/Merging.js.map +1 -1
  165. package/lib/cjs/topology/Triangulation.d.ts +16 -10
  166. package/lib/cjs/topology/Triangulation.d.ts.map +1 -1
  167. package/lib/cjs/topology/Triangulation.js +23 -30
  168. package/lib/cjs/topology/Triangulation.js.map +1 -1
  169. package/lib/esm/Geometry.d.ts +57 -46
  170. package/lib/esm/Geometry.d.ts.map +1 -1
  171. package/lib/esm/Geometry.js +73 -53
  172. package/lib/esm/Geometry.js.map +1 -1
  173. package/lib/esm/curve/Arc3d.d.ts +141 -38
  174. package/lib/esm/curve/Arc3d.d.ts.map +1 -1
  175. package/lib/esm/curve/Arc3d.js +217 -30
  176. package/lib/esm/curve/Arc3d.js.map +1 -1
  177. package/lib/esm/curve/CurveChainWithDistanceIndex.d.ts +11 -6
  178. package/lib/esm/curve/CurveChainWithDistanceIndex.d.ts.map +1 -1
  179. package/lib/esm/curve/CurveChainWithDistanceIndex.js +12 -10
  180. package/lib/esm/curve/CurveChainWithDistanceIndex.js.map +1 -1
  181. package/lib/esm/curve/CurveCollection.d.ts +2 -1
  182. package/lib/esm/curve/CurveCollection.d.ts.map +1 -1
  183. package/lib/esm/curve/CurveCollection.js +2 -1
  184. package/lib/esm/curve/CurveCollection.js.map +1 -1
  185. package/lib/esm/curve/CurveCurve.d.ts +11 -9
  186. package/lib/esm/curve/CurveCurve.d.ts.map +1 -1
  187. package/lib/esm/curve/CurveCurve.js +11 -9
  188. package/lib/esm/curve/CurveCurve.js.map +1 -1
  189. package/lib/esm/curve/CurveFactory.d.ts +4 -3
  190. package/lib/esm/curve/CurveFactory.d.ts.map +1 -1
  191. package/lib/esm/curve/CurveFactory.js +4 -3
  192. package/lib/esm/curve/CurveFactory.js.map +1 -1
  193. package/lib/esm/curve/CurveLocationDetail.d.ts +19 -1
  194. package/lib/esm/curve/CurveLocationDetail.d.ts.map +1 -1
  195. package/lib/esm/curve/CurveLocationDetail.js +39 -0
  196. package/lib/esm/curve/CurveLocationDetail.js.map +1 -1
  197. package/lib/esm/curve/CurveOps.d.ts +4 -4
  198. package/lib/esm/curve/CurveOps.d.ts.map +1 -1
  199. package/lib/esm/curve/CurveOps.js +6 -6
  200. package/lib/esm/curve/CurveOps.js.map +1 -1
  201. package/lib/esm/curve/CurvePrimitive.d.ts +1 -1
  202. package/lib/esm/curve/CurvePrimitive.js.map +1 -1
  203. package/lib/esm/curve/LineString3d.d.ts +7 -5
  204. package/lib/esm/curve/LineString3d.d.ts.map +1 -1
  205. package/lib/esm/curve/LineString3d.js +8 -6
  206. package/lib/esm/curve/LineString3d.js.map +1 -1
  207. package/lib/esm/curve/Loop.d.ts.map +1 -1
  208. package/lib/esm/curve/Loop.js +6 -6
  209. package/lib/esm/curve/Loop.js.map +1 -1
  210. package/lib/esm/curve/OffsetOptions.d.ts +1 -1
  211. package/lib/esm/curve/OffsetOptions.js +1 -1
  212. package/lib/esm/curve/OffsetOptions.js.map +1 -1
  213. package/lib/esm/curve/Path.d.ts.map +1 -1
  214. package/lib/esm/curve/Path.js +5 -6
  215. package/lib/esm/curve/Path.js.map +1 -1
  216. package/lib/esm/curve/Query/ConsolidateAdjacentPrimitivesContext.d.ts.map +1 -1
  217. package/lib/esm/curve/Query/ConsolidateAdjacentPrimitivesContext.js +3 -4
  218. package/lib/esm/curve/Query/ConsolidateAdjacentPrimitivesContext.js.map +1 -1
  219. package/lib/esm/curve/Query/CylindricalRange.js.map +1 -1
  220. package/lib/esm/curve/RegionOps.d.ts +4 -3
  221. package/lib/esm/curve/RegionOps.d.ts.map +1 -1
  222. package/lib/esm/curve/RegionOps.js +4 -3
  223. package/lib/esm/curve/RegionOps.js.map +1 -1
  224. package/lib/esm/curve/internalContexts/CurveCurveCloseApproachXY.d.ts +23 -7
  225. package/lib/esm/curve/internalContexts/CurveCurveCloseApproachXY.d.ts.map +1 -1
  226. package/lib/esm/curve/internalContexts/CurveCurveCloseApproachXY.js +43 -35
  227. package/lib/esm/curve/internalContexts/CurveCurveCloseApproachXY.js.map +1 -1
  228. package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.d.ts +22 -8
  229. package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.d.ts.map +1 -1
  230. package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.js +127 -52
  231. package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -1
  232. package/lib/esm/curve/internalContexts/EllipticalArcApproximationContext.d.ts +211 -0
  233. package/lib/esm/curve/internalContexts/EllipticalArcApproximationContext.d.ts.map +1 -0
  234. package/lib/esm/curve/internalContexts/EllipticalArcApproximationContext.js +995 -0
  235. package/lib/esm/curve/internalContexts/EllipticalArcApproximationContext.js.map +1 -0
  236. package/lib/esm/curve/internalContexts/MultiChainCollector.d.ts +11 -8
  237. package/lib/esm/curve/internalContexts/MultiChainCollector.d.ts.map +1 -1
  238. package/lib/esm/curve/internalContexts/MultiChainCollector.js +7 -4
  239. package/lib/esm/curve/internalContexts/MultiChainCollector.js.map +1 -1
  240. package/lib/esm/geometry3d/Angle.d.ts +18 -5
  241. package/lib/esm/geometry3d/Angle.d.ts.map +1 -1
  242. package/lib/esm/geometry3d/Angle.js +23 -7
  243. package/lib/esm/geometry3d/Angle.js.map +1 -1
  244. package/lib/esm/geometry3d/AngleSweep.d.ts +14 -1
  245. package/lib/esm/geometry3d/AngleSweep.d.ts.map +1 -1
  246. package/lib/esm/geometry3d/AngleSweep.js +47 -12
  247. package/lib/esm/geometry3d/AngleSweep.js.map +1 -1
  248. package/lib/esm/geometry3d/FrameBuilder.d.ts +2 -1
  249. package/lib/esm/geometry3d/FrameBuilder.d.ts.map +1 -1
  250. package/lib/esm/geometry3d/FrameBuilder.js +12 -10
  251. package/lib/esm/geometry3d/FrameBuilder.js.map +1 -1
  252. package/lib/esm/geometry3d/GeometryHandler.d.ts.map +1 -1
  253. package/lib/esm/geometry3d/GeometryHandler.js +1 -7
  254. package/lib/esm/geometry3d/GeometryHandler.js.map +1 -1
  255. package/lib/esm/geometry3d/Matrix3d.d.ts +6 -4
  256. package/lib/esm/geometry3d/Matrix3d.d.ts.map +1 -1
  257. package/lib/esm/geometry3d/Matrix3d.js +6 -4
  258. package/lib/esm/geometry3d/Matrix3d.js.map +1 -1
  259. package/lib/esm/geometry3d/Point3dVector3d.d.ts +5 -5
  260. package/lib/esm/geometry3d/Point3dVector3d.d.ts.map +1 -1
  261. package/lib/esm/geometry3d/Point3dVector3d.js +5 -5
  262. package/lib/esm/geometry3d/Point3dVector3d.js.map +1 -1
  263. package/lib/esm/geometry3d/PointHelpers.d.ts +6 -5
  264. package/lib/esm/geometry3d/PointHelpers.d.ts.map +1 -1
  265. package/lib/esm/geometry3d/PointHelpers.js +11 -10
  266. package/lib/esm/geometry3d/PointHelpers.js.map +1 -1
  267. package/lib/esm/geometry3d/PolygonOps.d.ts +4 -4
  268. package/lib/esm/geometry3d/PolygonOps.d.ts.map +1 -1
  269. package/lib/esm/geometry3d/PolygonOps.js +7 -11
  270. package/lib/esm/geometry3d/PolygonOps.js.map +1 -1
  271. package/lib/esm/geometry3d/PolylineCompressionByEdgeOffset.d.ts +1 -1
  272. package/lib/esm/geometry3d/PolylineCompressionByEdgeOffset.d.ts.map +1 -1
  273. package/lib/esm/geometry3d/PolylineCompressionByEdgeOffset.js +3 -3
  274. package/lib/esm/geometry3d/PolylineCompressionByEdgeOffset.js.map +1 -1
  275. package/lib/esm/geometry3d/Range.d.ts +6 -1
  276. package/lib/esm/geometry3d/Range.d.ts.map +1 -1
  277. package/lib/esm/geometry3d/Range.js +9 -3
  278. package/lib/esm/geometry3d/Range.js.map +1 -1
  279. package/lib/esm/geometry3d/Ray3d.d.ts +1 -1
  280. package/lib/esm/geometry3d/Ray3d.d.ts.map +1 -1
  281. package/lib/esm/geometry3d/Ray3d.js.map +1 -1
  282. package/lib/esm/geometry3d/Transform.d.ts +1 -1
  283. package/lib/esm/geometry3d/Transform.js +1 -1
  284. package/lib/esm/geometry3d/Transform.js.map +1 -1
  285. package/lib/esm/numerics/Newton.d.ts +3 -3
  286. package/lib/esm/numerics/Newton.d.ts.map +1 -1
  287. package/lib/esm/numerics/Newton.js +14 -16
  288. package/lib/esm/numerics/Newton.js.map +1 -1
  289. package/lib/esm/numerics/Polynomials.d.ts +2 -2
  290. package/lib/esm/numerics/Polynomials.js +2 -2
  291. package/lib/esm/numerics/Polynomials.js.map +1 -1
  292. package/lib/esm/polyface/PolyfaceBuilder.d.ts +7 -4
  293. package/lib/esm/polyface/PolyfaceBuilder.d.ts.map +1 -1
  294. package/lib/esm/polyface/PolyfaceBuilder.js +11 -6
  295. package/lib/esm/polyface/PolyfaceBuilder.js.map +1 -1
  296. package/lib/esm/polyface/PolyfaceClip.d.ts +13 -10
  297. package/lib/esm/polyface/PolyfaceClip.d.ts.map +1 -1
  298. package/lib/esm/polyface/PolyfaceClip.js +17 -14
  299. package/lib/esm/polyface/PolyfaceClip.js.map +1 -1
  300. package/lib/esm/polyface/PolyfaceQuery.d.ts +11 -14
  301. package/lib/esm/polyface/PolyfaceQuery.d.ts.map +1 -1
  302. package/lib/esm/polyface/PolyfaceQuery.js +59 -52
  303. package/lib/esm/polyface/PolyfaceQuery.js.map +1 -1
  304. package/lib/esm/serialization/BGFBReader.js.map +1 -1
  305. package/lib/esm/serialization/BGFBWriter.js +2 -2
  306. package/lib/esm/serialization/BGFBWriter.js.map +1 -1
  307. package/lib/esm/serialization/GeometrySamples.js.map +1 -1
  308. package/lib/esm/solid/SweepContour.d.ts.map +1 -1
  309. package/lib/esm/solid/SweepContour.js +0 -4
  310. package/lib/esm/solid/SweepContour.js.map +1 -1
  311. package/lib/esm/topology/Graph.d.ts +1 -1
  312. package/lib/esm/topology/Graph.js +2 -2
  313. package/lib/esm/topology/Graph.js.map +1 -1
  314. package/lib/esm/topology/HalfEdgeNodeXYZUV.d.ts +1 -1
  315. package/lib/esm/topology/HalfEdgeNodeXYZUV.js +1 -1
  316. package/lib/esm/topology/HalfEdgeNodeXYZUV.js.map +1 -1
  317. package/lib/esm/topology/HalfEdgePointInGraphSearch.d.ts +57 -15
  318. package/lib/esm/topology/HalfEdgePointInGraphSearch.d.ts.map +1 -1
  319. package/lib/esm/topology/HalfEdgePointInGraphSearch.js +168 -127
  320. package/lib/esm/topology/HalfEdgePointInGraphSearch.js.map +1 -1
  321. package/lib/esm/topology/HalfEdgePositionDetail.d.ts +35 -35
  322. package/lib/esm/topology/HalfEdgePositionDetail.d.ts.map +1 -1
  323. package/lib/esm/topology/HalfEdgePositionDetail.js +63 -41
  324. package/lib/esm/topology/HalfEdgePositionDetail.js.map +1 -1
  325. package/lib/esm/topology/InsertAndRetriangulateContext.d.ts +64 -12
  326. package/lib/esm/topology/InsertAndRetriangulateContext.d.ts.map +1 -1
  327. package/lib/esm/topology/InsertAndRetriangulateContext.js +173 -74
  328. package/lib/esm/topology/InsertAndRetriangulateContext.js.map +1 -1
  329. package/lib/esm/topology/Merging.d.ts +2 -2
  330. package/lib/esm/topology/Merging.js +2 -2
  331. package/lib/esm/topology/Merging.js.map +1 -1
  332. package/lib/esm/topology/Triangulation.d.ts +16 -10
  333. package/lib/esm/topology/Triangulation.d.ts.map +1 -1
  334. package/lib/esm/topology/Triangulation.js +24 -31
  335. package/lib/esm/topology/Triangulation.js.map +1 -1
  336. package/package.json +3 -3
@@ -2,32 +2,74 @@ import { Point3d } from "../geometry3d/Point3dVector3d";
2
2
  import { Ray3d } from "../geometry3d/Ray3d";
3
3
  import { HalfEdge } from "./Graph";
4
4
  import { HalfEdgePositionDetail } from "./HalfEdgePositionDetail";
5
+ /**
6
+ * Return code from [PointSearchContext.reAimAroundFace]
7
+ * @internal
8
+ */
5
9
  export declare enum RayClassification {
6
- RC_NoHits = 0,
7
- RC_TargetOnVertex = 1,
8
- RC_TargetOnEdge = 2,
9
- RC_Bracket = 3,
10
- RC_TargetBefore = 4,
11
- RC_TargetAfter = 5
10
+ NoHits = 0,
11
+ TargetOnVertex = 1,
12
+ TargetOnEdge = 2,
13
+ Bracket = 3,
14
+ TargetBefore = 4,
15
+ TargetAfter = 5
12
16
  }
17
+ /**
18
+ * Context for searching for the location of an xy-point in a graph.
19
+ * * Assumptions: interior faces of the graph are convex, no edge has length less than `tol`.
20
+ * @internal
21
+ */
13
22
  export declare class PointSearchContext {
14
23
  private _tol;
15
24
  private constructor();
16
25
  static create(tol?: number): PointSearchContext;
17
26
  private panic;
27
+ /**
28
+ * Reposition `edgeHit` to an adjacent face or vertex, or another position on the edge, that is closer to the
29
+ * target point.
30
+ * @param edgeHit start position on a graph edge, updated and returned.
31
+ * @param ray the ray to the target point. Origin is assumed to lie on the edge.
32
+ * @param targetDistance distance along the ray to the target point.
33
+ * @return detail closer to the target point.
34
+ */
18
35
  reAimFromEdge(edgeHit: HalfEdgePositionDetail, ray: Ray3d, targetDistance: number): HalfEdgePositionDetail;
19
- reAimFromVertex(searchBase: HalfEdgePositionDetail, ray: Ray3d, targetDistance: number): HalfEdgePositionDetail;
20
- reAimAroundFace(faceNode: HalfEdge, ray: Ray3d, targetDistance: number, // !< distance to target point
21
- lastBefore: HalfEdgePositionDetail, // CALLER CREATED -- reset as first hit on negative side of ray.
22
- firstAfter: HalfEdgePositionDetail): RayClassification;
23
36
  /**
24
- * Set (replace contents) ray with
25
- * * `origin` at start
26
- * * `direction` is unit vector from start towards target
27
- * * `a` is distance from start to target.
37
+ * Reposition `vertexHit` to an adjacent face, edge, or vertex hit that is closer to the target point.
38
+ * @param vertexHit start position at a graph vertex, updated and returned.
39
+ * @param ray the ray to the target point, assumed to start exactly at the vertex.
40
+ * @param targetDistance distance along the ray to the target point.
41
+ * @return detail closer to the target point.
42
+ */
43
+ reAimFromVertex(vertexHit: HalfEdgePositionDetail, ray: Ray3d, targetDistance: number): HalfEdgePositionDetail;
44
+ /**
45
+ * Visit all edges around the face, updating `lastBefore` and `firstAfter` to ray-edge intersections that
46
+ * lie directly before and/or after the target point on the ray, if at all.
47
+ * @param faceNode starting node on a graph face.
48
+ * @param ray the ray to the target point.
49
+ * @param targetDistance distance along the ray to the target point.
50
+ * @param lastBefore the detail to reset as the last hit on the ray before the target point (CALLER CREATED).
51
+ * @param firstAfter the detail to reset as the first hit on the ray after the target point (CALLER CREATED).
52
+ * @returns summary of the updated details:
53
+ * * [[RayClassification.TargetOnVertex]] - target lies at a vertex of the face (details are identical).
54
+ * * [[RayClassification.TargetOnEdge]] - target lies on an edge of the face (details are identical).
55
+ * * [[RayClassification.TargetBefore]] - target lies before the face; the ray intersects the face beyond
56
+ * the target point.
57
+ * * [[RayClassification.TargetAfter]] - target lies after the face; the ray intersects the face before
58
+ * the target point.
59
+ * * [[RayClassification.Bracket]] - target lies between intersections of the ray and the face; if the face
60
+ * is convex, this means the target lies inside the face.
61
+ * * [[RayClassification.NoHits]] - the face does not intersect the ray.
62
+ */
63
+ reAimAroundFace(faceNode: HalfEdge, ray: Ray3d, targetDistance: number, lastBefore: HalfEdgePositionDetail, firstAfter: HalfEdgePositionDetail): RayClassification;
64
+ /**
65
+ * Initialize the input ray for topology search:
66
+ * * `origin` is at `start`
67
+ * * `direction` is the unit xy-vector from `start` towards `target`
68
+ * * `a` is the xy-distance from `start` to `target`
28
69
  * @param start existing position
29
70
  * @param target target xy coordinates
30
- * @param ray ray to update
71
+ * @param ray updated in place
72
+ * @returns false if target is reached.
31
73
  */
32
74
  setSearchRay(start: HalfEdgePositionDetail, target: Point3d, ray: Ray3d): boolean;
33
75
  }
@@ -1 +1 @@
1
- {"version":3,"file":"HalfEdgePointInGraphSearch.d.ts","sourceRoot":"","sources":["../../../src/topology/HalfEdgePointInGraphSearch.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,OAAO,EAAY,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,oBAAY,iBAAiB;IAC3B,SAAS,IAAA;IACT,iBAAiB,IAAA;IACjB,eAAe,IAAA;IACf,UAAU,IAAA;IACV,eAAe,IAAA;IACf,cAAc,IAAA;CACf;AAGD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO;WAGO,MAAM,CAAC,GAAG,GAAE,MAAqC;IAG/D,OAAO,CAAC,KAAK;IAKN,aAAa,CAClB,OAAO,EAAE,sBAAsB,EAC/B,GAAG,EAAE,KAAK,EACV,cAAc,EAAE,MAAM,GAAG,sBAAsB;IAgE1C,eAAe,CACpB,UAAU,EAAE,sBAAsB,EAClC,GAAG,EAAE,KAAK,EACV,cAAc,EAAE,MAAM,GAAG,sBAAsB;IAyD1C,eAAe,CACpB,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,KAAK,EACV,cAAc,EAAE,MAAM,EAAG,8BAA8B;IACvD,UAAU,EAAE,sBAAsB,EAAI,gEAAgE;IACtG,UAAU,EAAE,sBAAsB,GAAG,iBAAiB;IAoExD;;;;;;;;OAQG;IACI,YAAY,CAAC,KAAK,EAAE,sBAAsB,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,GAAG,OAAO;CASzF"}
1
+ {"version":3,"file":"HalfEdgePointInGraphSearch.d.ts","sourceRoot":"","sources":["../../../src/topology/HalfEdgePointInGraphSearch.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,OAAO,EAAY,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAgB,MAAM,SAAS,CAAC;AAEjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAIlE;;;GAGG;AACH,oBAAY,iBAAiB;IAC3B,MAAM,IAAA;IACN,cAAc,IAAA;IACd,YAAY,IAAA;IACZ,OAAO,IAAA;IACP,YAAY,IAAA;IACZ,WAAW,IAAA;CACZ;AAED;;;;GAIG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO;WAGO,MAAM,CAAC,GAAG,GAAE,MAAqC;IAG/D,OAAO,CAAC,KAAK;IAab;;;;;;;OAOG;IACI,aAAa,CAClB,OAAO,EAAE,sBAAsB,EAAE,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,GAClE,sBAAsB;IAsDzB;;;;;;OAMG;IACI,eAAe,CACpB,SAAS,EAAE,sBAAsB,EAAE,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,GACpE,sBAAsB;IA0DzB;;;;;;;;;;;;;;;;;;OAkBG;IACI,eAAe,CACpB,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,KAAK,EACV,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,sBAAsB,EAClC,UAAU,EAAE,sBAAsB,GACjC,iBAAiB;IA0DpB;;;;;;;;;OASG;IACI,YAAY,CAAC,KAAK,EAAE,sBAAsB,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,GAAG,OAAO;CAWzF"}
@@ -8,21 +8,31 @@ exports.PointSearchContext = exports.RayClassification = void 0;
8
8
  /** @packageDocumentation
9
9
  * @module Topology
10
10
  */
11
+ const core_bentley_1 = require("@itwin/core-bentley");
11
12
  const Geometry_1 = require("../Geometry");
12
13
  const Point3dVector3d_1 = require("../geometry3d/Point3dVector3d");
14
+ const Graph_1 = require("./Graph");
13
15
  const HalfEdgeNodeXYZUV_1 = require("./HalfEdgeNodeXYZUV");
14
16
  const HalfEdgePositionDetail_1 = require("./HalfEdgePositionDetail");
15
- /* eslint-disable @typescript-eslint/naming-convention */
17
+ // cspell:word Chebyshev
18
+ /**
19
+ * Return code from [PointSearchContext.reAimAroundFace]
20
+ * @internal
21
+ */
16
22
  var RayClassification;
17
23
  (function (RayClassification) {
18
- RayClassification[RayClassification["RC_NoHits"] = 0] = "RC_NoHits";
19
- RayClassification[RayClassification["RC_TargetOnVertex"] = 1] = "RC_TargetOnVertex";
20
- RayClassification[RayClassification["RC_TargetOnEdge"] = 2] = "RC_TargetOnEdge";
21
- RayClassification[RayClassification["RC_Bracket"] = 3] = "RC_Bracket";
22
- RayClassification[RayClassification["RC_TargetBefore"] = 4] = "RC_TargetBefore";
23
- RayClassification[RayClassification["RC_TargetAfter"] = 5] = "RC_TargetAfter";
24
+ RayClassification[RayClassification["NoHits"] = 0] = "NoHits";
25
+ RayClassification[RayClassification["TargetOnVertex"] = 1] = "TargetOnVertex";
26
+ RayClassification[RayClassification["TargetOnEdge"] = 2] = "TargetOnEdge";
27
+ RayClassification[RayClassification["Bracket"] = 3] = "Bracket";
28
+ RayClassification[RayClassification["TargetBefore"] = 4] = "TargetBefore";
29
+ RayClassification[RayClassification["TargetAfter"] = 5] = "TargetAfter";
24
30
  })(RayClassification || (exports.RayClassification = RayClassification = {}));
25
- /* eslint-enable @typescript-eslint/naming-convention */
31
+ /**
32
+ * Context for searching for the location of an xy-point in a graph.
33
+ * * Assumptions: interior faces of the graph are convex, no edge has length less than `tol`.
34
+ * @internal
35
+ */
26
36
  class PointSearchContext {
27
37
  constructor(tol) {
28
38
  this._tol = tol;
@@ -31,10 +41,26 @@ class PointSearchContext {
31
41
  return new PointSearchContext(tol);
32
42
  }
33
43
  panic() {
44
+ // A note on "unexpectedly" found in comments in this file:
45
+ // Though this class assumes all edges of the graph have length at least tolerance, the tests below account for
46
+ // edges with smaller length. This is because we are using two different metrics: Euclidean for distinguishing
47
+ // points matching user expectation, and Chebyshev, aka "max component", for efficiently testing ray-sector
48
+ // inclusion in the reAimXXX methods. In particular, epsilon-balls in the former metric are smaller than in the
49
+ // latter. Thus an edge can be inserted into the graph with Euclidean length (barely) greater than epsilon, but
50
+ // the edge's parallel and perpendicular components with respect to a ray can have Euclidean length *less* than
51
+ // epsilon, yielding a Chebyshev edge length less than epsilon. This discrepancy requires careful analysis below,
52
+ // and if this method is invoked, it is probably because we've missed a case where a dot/cross product lies just
53
+ // beyond the tolerance.
34
54
  return HalfEdgePositionDetail_1.HalfEdgePositionDetail.create();
35
55
  }
36
- // From given edge start point
37
- // The edgeHit is reused as the result.
56
+ /**
57
+ * Reposition `edgeHit` to an adjacent face or vertex, or another position on the edge, that is closer to the
58
+ * target point.
59
+ * @param edgeHit start position on a graph edge, updated and returned.
60
+ * @param ray the ray to the target point. Origin is assumed to lie on the edge.
61
+ * @param targetDistance distance along the ray to the target point.
62
+ * @return detail closer to the target point.
63
+ */
38
64
  reAimFromEdge(edgeHit, ray, targetDistance) {
39
65
  const nodeA = edgeHit.node;
40
66
  const dataA = HalfEdgeNodeXYZUV_1.NodeXYZUV.createNodeAndRayOrigin(nodeA, ray);
@@ -42,8 +68,7 @@ class PointSearchContext {
42
68
  const sideA = -dataA.classifyV(0.0, this._tol);
43
69
  const sideB = -dataB.classifyV(0.0, this._tol);
44
70
  let result;
45
- if (sideA * sideB < 0) {
46
- // Simple crossing -- just aim into a face
71
+ if (sideA * sideB < 0) { // simple crossing; just aim into a face
47
72
  if (sideA > 0) {
48
73
  result = edgeHit.resetAsFace(dataA.node);
49
74
  }
@@ -52,126 +77,150 @@ class PointSearchContext {
52
77
  }
53
78
  }
54
79
  else if (sideA === 0 || sideB === 0) {
55
- // The usual case is both 0 i.e. ray is clearly along the edge.
56
80
  const alongA = dataA.classifyU(targetDistance, this._tol);
57
81
  const alongB = dataB.classifyU(targetDistance, this._tol);
58
- if (alongA === 0 && sideA === 0) {
82
+ if (sideA === 0 && alongA === 0) { // hit start vertex
59
83
  result = edgeHit.resetAsVertex(dataA.node);
60
84
  result.setITag(1);
61
85
  }
62
- else if (alongB === 0 && sideB === 0) {
86
+ else if (sideB === 0 && alongB === 0) { // hit end vertex
63
87
  result = edgeHit.resetAsVertex(dataB.node);
64
88
  result.setITag(1);
65
89
  }
66
- else if (alongA * alongB < 0) {
67
- // target is within edge
68
- // (.. This is written for the case where both sideA and sideB are zero.
69
- // If only one is zero, this computes a close edge point but the strong "on" conclusion might be wrong)
70
- const edgeFraction = (targetDistance - dataA.u) / (dataB.u - dataA.u);
71
- result = edgeHit.resetAtEdgeAndFraction(dataA.node, edgeFraction);
72
- result.setITag(1);
73
- }
74
- else if (alongA < 0 && alongB < 0) {
75
- // target is beyond the edge -- move towards it.
76
- if (dataA.u > dataB.u)
77
- result = edgeHit.resetAsVertex(dataA.node);
78
- else
79
- result = edgeHit.resetAsVertex(dataB.node);
80
- }
81
- else {
82
- // This shouldn't happen -- maybe as if the initial edge point was not within the edge???
83
- if (Math.abs(dataA.u) < this._tol
84
- && Math.abs(dataA.v) < this._tol) {
85
- result = edgeHit.resetAsVertex(dataA.node); // , dataA);
90
+ else if (sideA === 0 && sideB === 0) { // ray is clearly along the edge
91
+ if (alongA * alongB < 0) { // target is within edge
92
+ const edgeFraction = (targetDistance - dataA.u) / (dataB.u - dataA.u);
93
+ result = edgeHit.resetAtEdgeAndFraction(dataA.node, edgeFraction);
94
+ result.setITag(1);
86
95
  }
87
- else if (Math.abs(dataB.u) < this._tol
88
- && Math.abs(dataB.v) < this._tol) {
89
- result = edgeHit.resetAsVertex(dataB.node);
96
+ else if (alongA < 0 && alongB < 0) { // target is beyond the edge; move towards it
97
+ if (dataA.u > dataB.u)
98
+ result = edgeHit.resetAsVertex(dataA.node);
99
+ else
100
+ result = edgeHit.resetAsVertex(dataB.node);
90
101
  }
91
- else {
102
+ else { // both vertices lie on the ray before or after the target; shouldn't happen for edgeHit between nodes
92
103
  edgeHit.resetAsUnknown();
93
104
  result = this.panic();
94
105
  }
95
106
  }
107
+ else if (sideA === 0) { // ray near start vertex but NOT parallel to the edge
108
+ if (0 === dataA.classifyU(0.0, this._tol))
109
+ result = edgeHit.resetAsVertex(dataA.node);
110
+ else
111
+ result = edgeHit.resetAsFace(sideB > 0 ? dataB.node : dataA.node);
112
+ }
113
+ else { // ray near end vertex but NOT parallel to the edge
114
+ (0, core_bentley_1.assert)(sideB === 0);
115
+ if (0 === dataB.classifyU(0.0, this._tol))
116
+ result = edgeHit.resetAsVertex(dataB.node);
117
+ else
118
+ result = edgeHit.resetAsFace(sideA > 0 ? dataA.node : dataB.node);
119
+ }
96
120
  }
97
- else {
98
- // Both vertices are to same side of the line. This can't happen for edge point between nodes.
121
+ else { // both vertices are to same side of the ray; shouldn't happen for edgeHit between nodes
99
122
  edgeHit.resetAsUnknown();
100
123
  result = this.panic();
101
124
  }
102
125
  return result;
103
126
  }
104
- // From given edge start point, pick vertex or edge side for proceeding along ray.
105
- // RAY IS ASSUMED TO START AT THE VERTEX PRECISELY !!!!
106
- reAimFromVertex(searchBase, ray, targetDistance) {
107
- const vertexNode = searchBase.node;
108
- let result;
127
+ /**
128
+ * Reposition `vertexHit` to an adjacent face, edge, or vertex hit that is closer to the target point.
129
+ * @param vertexHit start position at a graph vertex, updated and returned.
130
+ * @param ray the ray to the target point, assumed to start exactly at the vertex.
131
+ * @param targetDistance distance along the ray to the target point.
132
+ * @return detail closer to the target point.
133
+ */
134
+ reAimFromVertex(vertexHit, ray, targetDistance) {
135
+ (0, core_bentley_1.assert)(ray.origin.isExactEqual(vertexHit));
136
+ const vertexNode = vertexHit.node;
109
137
  let outboundEdge = vertexNode;
138
+ // lambda to handle the case where the target definitively lies in the same direction as outboundEdge
139
+ const advancePositionAlongOutboundEdge = (rayParam) => {
140
+ if (Math.abs(rayParam - targetDistance) <= this._tol) { // direct hit at far end of outBoundEdge
141
+ vertexHit.resetAsVertex(outboundEdge.faceSuccessor).setITag(1);
142
+ }
143
+ else if (rayParam > targetDistance) { // direct hit within outBoundEdge
144
+ vertexHit.resetAtEdgeAndFraction(outboundEdge, targetDistance / rayParam);
145
+ }
146
+ else if (rayParam > this._tol) { // far end of outBoundEdge is closer to target
147
+ vertexHit.resetAsVertex(outboundEdge.faceSuccessor);
148
+ }
149
+ else {
150
+ return false;
151
+ }
152
+ return true;
153
+ };
110
154
  do {
111
- // DPoint3d xyzBase;
112
- // vu_getDPoint3d(& xyzBase, outboundEdge);
155
+ // examine the sector at the outboundEdge node; if ray lies in this sector, return updated detail
113
156
  const data0 = HalfEdgeNodeXYZUV_1.NodeXYZUV.createNodeAndRayOrigin(outboundEdge.faceSuccessor, ray);
114
157
  const data1 = HalfEdgeNodeXYZUV_1.NodeXYZUV.createNodeAndRayOrigin(outboundEdge.facePredecessor, ray);
158
+ // u0 is the length of projection of faceSuccessor to the ray and v0 is the length of projection of
159
+ // faceSuccessor to the ray perp line (90 degrees CCW). Similarly for u1 and v1 with facePredecessor.
115
160
  const u0 = data0.u;
116
- // double u1 = data1.GetU ();
161
+ const u1 = data1.u;
117
162
  const v0 = data0.v;
118
163
  const v1 = data1.v;
119
- if (Math.abs(v0) < this._tol) {
120
- if (Math.abs(u0 - targetDistance) < this._tol) {
121
- // Direct hit at far end
122
- result = searchBase.resetAsVertex(data0.node);
123
- result.setITag(1);
124
- return result;
125
- }
126
- else if (u0 > targetDistance) {
127
- // Direct hig within edge
128
- const edgeFraction = targetDistance / u0;
129
- result = searchBase.resetAtEdgeAndFraction(outboundEdge, edgeFraction);
130
- return result;
131
- }
132
- else if (Math.abs(u0) <= this._tol) {
133
- // Unexpected direct hit on the base of the search, but call it a hit....
134
- result = searchBase.resetAsVertex(outboundEdge);
135
- result.setITag(1);
136
- return result;
137
- }
138
- else if (u0 > this._tol) {
139
- // Advance to vertex ...
140
- // double edgeFraction = targetDistance / u0;
141
- result = searchBase.resetAsVertex(data0.node);
142
- return result;
143
- }
144
- else {
145
- // Search direction is exactly opposite this edge.
146
- // See if the other side of the sector is turned even beyond that ...
147
- if (v1 > this._tol) {
148
- result = searchBase.resetAsFace(outboundEdge, outboundEdge);
149
- return result;
150
- }
164
+ // examine dot and cross of ray with both edges defining this sector to see if ray lies between them
165
+ if (Math.abs(v0) <= this._tol) { // ray parallel to outBoundEdge
166
+ if (advancePositionAlongOutboundEdge(u0))
167
+ return vertexHit;
168
+ if (Math.abs(u0) <= this._tol) { // edge is unexpectedly* small
169
+ if (v0 <= 0 && v1 > this._tol && (u0 >= 0 || (u0 < 0 && u1 > this._tol)))
170
+ return vertexHit.resetAsFace(outboundEdge, outboundEdge);
151
171
  }
172
+ // The only remaining case is u0 < -this._tol: ray points opposite outBoundEdge.
173
+ // By our convexity assumption, the only way that ray lies in this sector is if the lookBack
174
+ // vector points in the same direction as ray, but this would be handled in the next sector.
152
175
  }
153
176
  else if (v0 < -this._tol) {
154
- if (v1 > this._tol) {
155
- // The usual simple entry into an angle < 180
156
- result = searchBase.resetAsFace(outboundEdge, outboundEdge);
157
- return result;
177
+ if (v1 > this._tol) // ray definitely lies in this sector
178
+ return vertexHit.resetAsFace(outboundEdge, outboundEdge);
179
+ if (v1 >= -this._tol) { // ray and lookBack vector are parallel
180
+ // handle special cases not handled in the next sector
181
+ if (Math.abs(u1) <= this._tol) { // lookBack vector is unexpectedly* small...
182
+ if (v1 > 0 && (u1 >= 0 || (u0 > this._tol && u1 < 0))) // ...and ray is in this sector
183
+ return vertexHit.resetAsFace(outboundEdge, outboundEdge);
184
+ }
185
+ else if (u0 > this._tol && u1 < 0) { // ray and lookBack point in opposite directions
186
+ return vertexHit.resetAsVertex(outboundEdge.faceSuccessor); // far end is closer to target
187
+ }
158
188
  }
189
+ // The only remaining case is v1 < -this._tol: ray definitely lies outside this sector.
159
190
  }
160
- // NEEDS WORK: angle >= 180 cases !!!!
191
+ // Proceed to the next sector around this vertex. We even examine the (concave) exterior sector at a boundary
192
+ // vertex in order to handle the case where the target lies in the direction of an exterior outboundEdge.
161
193
  outboundEdge = outboundEdge.vertexSuccessor;
162
194
  } while (outboundEdge !== vertexNode);
163
195
  return this.panic();
164
196
  }
165
- // Visit all edges around face.
166
- // reset lastBefore and firstAfter describing progress towards target distance on ray.
167
- reAimAroundFace(faceNode, ray, targetDistance, // !< distance to target point
168
- lastBefore, // CALLER CREATED -- reset as first hit on negative side of ray.
169
- firstAfter) {
197
+ /**
198
+ * Visit all edges around the face, updating `lastBefore` and `firstAfter` to ray-edge intersections that
199
+ * lie directly before and/or after the target point on the ray, if at all.
200
+ * @param faceNode starting node on a graph face.
201
+ * @param ray the ray to the target point.
202
+ * @param targetDistance distance along the ray to the target point.
203
+ * @param lastBefore the detail to reset as the last hit on the ray before the target point (CALLER CREATED).
204
+ * @param firstAfter the detail to reset as the first hit on the ray after the target point (CALLER CREATED).
205
+ * @returns summary of the updated details:
206
+ * * [[RayClassification.TargetOnVertex]] - target lies at a vertex of the face (details are identical).
207
+ * * [[RayClassification.TargetOnEdge]] - target lies on an edge of the face (details are identical).
208
+ * * [[RayClassification.TargetBefore]] - target lies before the face; the ray intersects the face beyond
209
+ * the target point.
210
+ * * [[RayClassification.TargetAfter]] - target lies after the face; the ray intersects the face before
211
+ * the target point.
212
+ * * [[RayClassification.Bracket]] - target lies between intersections of the ray and the face; if the face
213
+ * is convex, this means the target lies inside the face.
214
+ * * [[RayClassification.NoHits]] - the face does not intersect the ray.
215
+ */
216
+ reAimAroundFace(faceNode, ray, targetDistance, lastBefore, firstAfter) {
217
+ (0, core_bentley_1.assert)(!faceNode.isMaskSet(Graph_1.HalfEdgeMask.EXTERIOR));
170
218
  lastBefore.resetAsUndefinedWithTag(-Number.MAX_VALUE);
171
219
  firstAfter.resetAsUndefinedWithTag(Number.MAX_VALUE);
172
220
  const data0 = HalfEdgeNodeXYZUV_1.NodeXYZUV.createNodeAndRayOrigin(faceNode, ray);
173
221
  let data1;
174
222
  let node0 = faceNode;
223
+ // find the intersection of the ray with each edge of the face to classify the ray hit
175
224
  do {
176
225
  const node1 = node0.faceSuccessor;
177
226
  data1 = HalfEdgeNodeXYZUV_1.NodeXYZUV.createNodeAndRayOrigin(node1, ray, data1);
@@ -179,78 +228,70 @@ class PointSearchContext {
179
228
  const u1 = data1.u;
180
229
  const v0 = data0.v;
181
230
  const v1 = data1.v;
182
- if (Math.abs(v1) < this._tol) {
183
- // Vertex hit ...
231
+ if (Math.abs(v1) < this._tol) { // ray parallel to edge
184
232
  const vertexHit = HalfEdgePositionDetail_1.HalfEdgePositionDetail.createVertex(node1);
185
233
  vertexHit.setDTag(u1);
186
234
  if (Math.abs(u1 - targetDistance) < this._tol) {
187
235
  firstAfter.setFrom(vertexHit);
188
236
  lastBefore.setFrom(vertexHit);
189
- return RayClassification.RC_TargetOnVertex;
237
+ return RayClassification.TargetOnVertex;
190
238
  }
191
239
  if (u1 > targetDistance && u1 < firstAfter.getDTag())
192
240
  firstAfter.setFrom(vertexHit);
193
241
  if (u1 < targetDistance && u1 > lastBefore.getDTag())
194
242
  lastBefore.setFrom(vertexHit);
195
243
  }
196
- else if (v0 * v1 < 0.0) {
197
- // Edge Crossing ...
244
+ else if (v0 * v1 < 0.0) { // ray crosses edge
198
245
  const edgeFraction = -v0 / (v1 - v0);
199
- const uEdge = Geometry_1.Geometry.interpolate(u0, edgeFraction, u1);
246
+ const rayFraction = Geometry_1.Geometry.interpolate(u0, edgeFraction, u1);
200
247
  const edgeHit = HalfEdgePositionDetail_1.HalfEdgePositionDetail.createEdgeAtFraction(data0.node, edgeFraction);
201
- edgeHit.setDTag(uEdge);
202
- if (Math.abs(uEdge - targetDistance) <= this._tol) {
248
+ edgeHit.setDTag(rayFraction);
249
+ if (Math.abs(rayFraction - targetDistance) <= this._tol) {
203
250
  firstAfter.setFrom(edgeHit);
204
251
  lastBefore.setFrom(edgeHit);
205
- return RayClassification.RC_TargetOnEdge;
252
+ return RayClassification.TargetOnEdge;
206
253
  }
207
- if (uEdge > targetDistance && uEdge < firstAfter.getDTag()) {
254
+ if (rayFraction > targetDistance && rayFraction < firstAfter.getDTag())
208
255
  firstAfter.setFrom(edgeHit);
209
- firstAfter.setITag(v0 > 0.0 ? -1 : 1);
210
- }
211
- if (uEdge < targetDistance && uEdge > lastBefore.getDTag()) {
256
+ if (rayFraction < targetDistance && rayFraction > lastBefore.getDTag())
212
257
  lastBefore.setFrom(edgeHit);
213
- lastBefore.setDTag(uEdge);
214
- }
215
258
  }
216
259
  data0.setFrom(data1);
217
260
  node0 = node0.faceSuccessor;
218
261
  } while (node0 !== faceNode);
219
- // Returned to start node !!!
220
- const afterTag = firstAfter.getITag();
262
+ // returned to start node
221
263
  firstAfter.setITag(0);
222
264
  lastBefore.setITag(0);
223
265
  if (lastBefore.isUnclassified) {
224
266
  if (firstAfter.isUnclassified)
225
- return RayClassification.RC_NoHits;
226
- return RayClassification.RC_TargetBefore;
227
- }
228
- if (firstAfter.isUnclassified
229
- || (firstAfter.isEdge && afterTag && afterTag < 0)) {
230
- return RayClassification.RC_TargetAfter;
231
- }
232
- else {
233
- return RayClassification.RC_Bracket;
267
+ return RayClassification.NoHits;
268
+ return RayClassification.TargetBefore;
234
269
  }
270
+ if (firstAfter.isUnclassified)
271
+ return RayClassification.TargetAfter;
272
+ else
273
+ return RayClassification.Bracket; // face is locally convex; target lies inside this face
235
274
  }
236
- // Return false if target is reached !!!!
237
275
  /**
238
- * Set (replace contents) ray with
239
- * * `origin` at start
240
- * * `direction` is unit vector from start towards target
241
- * * `a` is distance from start to target.
276
+ * Initialize the input ray for topology search:
277
+ * * `origin` is at `start`
278
+ * * `direction` is the unit xy-vector from `start` towards `target`
279
+ * * `a` is the xy-distance from `start` to `target`
242
280
  * @param start existing position
243
281
  * @param target target xy coordinates
244
- * @param ray ray to update
282
+ * @param ray updated in place
283
+ * @returns false if target is reached.
245
284
  */
246
285
  setSearchRay(start, target, ray) {
247
286
  ray.origin.setFromPoint3d(start);
248
287
  Point3dVector3d_1.Vector3d.createStartEnd(ray.origin, target, ray.direction);
249
288
  ray.direction.z = 0.0;
250
- const distanceToTarget = ray.direction.magnitudeXY();
251
- ray.a = ray.direction.magnitude();
252
- ray.direction.scaleInPlace(1 / ray.a);
253
- return distanceToTarget >= this._tol;
289
+ const distanceToTargetXY = ray.direction.magnitudeXY();
290
+ if (distanceToTargetXY < this._tol)
291
+ return false; // no searching necessary, we are already at the target point
292
+ ray.a = distanceToTargetXY;
293
+ ray.direction.scaleInPlace(1 / distanceToTargetXY);
294
+ return true;
254
295
  }
255
296
  }
256
297
  exports.PointSearchContext = PointSearchContext;
@@ -1 +1 @@
1
- {"version":3,"file":"HalfEdgePointInGraphSearch.js","sourceRoot":"","sources":["../../../src/topology/HalfEdgePointInGraphSearch.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 { Geometry } from \"../Geometry\";\r\nimport { Point3d, Vector3d } from \"../geometry3d/Point3dVector3d\";\r\nimport { Ray3d } from \"../geometry3d/Ray3d\";\r\nimport { HalfEdge } from \"./Graph\";\r\nimport { NodeXYZUV } from \"./HalfEdgeNodeXYZUV\";\r\nimport { HalfEdgePositionDetail } from \"./HalfEdgePositionDetail\";\r\n\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nexport enum RayClassification {\r\n RC_NoHits,\r\n RC_TargetOnVertex,\r\n RC_TargetOnEdge,\r\n RC_Bracket,\r\n RC_TargetBefore,\r\n RC_TargetAfter,\r\n}\r\n/* eslint-enable @typescript-eslint/naming-convention */\r\n\r\nexport class PointSearchContext {\r\n private _tol: number;\r\n private constructor(tol: number) {\r\n this._tol = tol;\r\n }\r\n public static create(tol: number = Geometry.smallMetricDistance) {\r\n return new PointSearchContext(tol);\r\n }\r\n private panic(): HalfEdgePositionDetail {\r\n return HalfEdgePositionDetail.create();\r\n }\r\n // From given edge start point\r\n // The edgeHit is reused as the result.\r\n public reAimFromEdge(\r\n edgeHit: HalfEdgePositionDetail,\r\n ray: Ray3d,\r\n targetDistance: number): HalfEdgePositionDetail {\r\n const nodeA = edgeHit.node!;\r\n const dataA = NodeXYZUV.createNodeAndRayOrigin(nodeA, ray);\r\n const dataB = NodeXYZUV.createNodeAndRayOrigin(nodeA.edgeMate, ray);\r\n const sideA = -dataA.classifyV(0.0, this._tol);\r\n const sideB = -dataB.classifyV(0.0, this._tol);\r\n let result;\r\n if (sideA * sideB < 0) {\r\n // Simple crossing -- just aim into a face\r\n if (sideA > 0) {\r\n result = edgeHit.resetAsFace(dataA.node);\r\n } else {\r\n result = edgeHit.resetAsFace(dataB.node);\r\n }\r\n } else if (sideA === 0 || sideB === 0) {\r\n // The usual case is both 0 i.e. ray is clearly along the edge.\r\n\r\n const alongA = dataA.classifyU(targetDistance, this._tol);\r\n const alongB = dataB.classifyU(targetDistance, this._tol);\r\n if (alongA === 0 && sideA === 0) {\r\n result = edgeHit.resetAsVertex(dataA.node);\r\n result.setITag(1);\r\n } else if (alongB === 0 && sideB === 0) {\r\n result = edgeHit.resetAsVertex(dataB.node);\r\n result.setITag(1);\r\n } else if (alongA * alongB < 0) {\r\n // target is within edge\r\n // (.. This is written for the case where both sideA and sideB are zero.\r\n // If only one is zero, this computes a close edge point but the strong \"on\" conclusion might be wrong)\r\n\r\n const edgeFraction = (targetDistance - dataA.u) / (dataB.u - dataA.u);\r\n result = edgeHit.resetAtEdgeAndFraction(dataA.node, edgeFraction);\r\n result.setITag(1);\r\n } else if (alongA < 0 && alongB < 0) {\r\n // target is beyond the edge -- move towards it.\r\n if (dataA.u > dataB.u)\r\n result = edgeHit.resetAsVertex(dataA.node);\r\n else\r\n result = edgeHit.resetAsVertex(dataB.node);\r\n } else {\r\n // This shouldn't happen -- maybe as if the initial edge point was not within the edge???\r\n if (Math.abs(dataA.u) < this._tol\r\n && Math.abs(dataA.v) < this._tol\r\n ) {\r\n result = edgeHit.resetAsVertex(dataA.node); // , dataA);\r\n } else if (Math.abs(dataB.u) < this._tol\r\n && Math.abs(dataB.v) < this._tol\r\n ) {\r\n result = edgeHit.resetAsVertex(dataB.node);\r\n } else {\r\n edgeHit.resetAsUnknown();\r\n result = this.panic();\r\n }\r\n }\r\n } else {\r\n // Both vertices are to same side of the line. This can't happen for edge point between nodes.\r\n edgeHit.resetAsUnknown();\r\n result = this.panic();\r\n }\r\n return result;\r\n }\r\n\r\n // From given edge start point, pick vertex or edge side for proceeding along ray.\r\n // RAY IS ASSUMED TO START AT THE VERTEX PRECISELY !!!!\r\n public reAimFromVertex(\r\n searchBase: HalfEdgePositionDetail,\r\n ray: Ray3d,\r\n targetDistance: number): HalfEdgePositionDetail {\r\n const vertexNode = searchBase.node;\r\n let result;\r\n let outboundEdge = vertexNode!;\r\n do {\r\n // DPoint3d xyzBase;\r\n // vu_getDPoint3d(& xyzBase, outboundEdge);\r\n const data0 = NodeXYZUV.createNodeAndRayOrigin(outboundEdge.faceSuccessor, ray);\r\n const data1 = NodeXYZUV.createNodeAndRayOrigin(outboundEdge.facePredecessor, ray);\r\n const u0 = data0.u;\r\n // double u1 = data1.GetU ();\r\n const v0 = data0.v;\r\n const v1 = data1.v;\r\n if (Math.abs(v0) < this._tol) {\r\n if (Math.abs(u0 - targetDistance) < this._tol) {\r\n // Direct hit at far end\r\n result = searchBase.resetAsVertex(data0.node);\r\n result.setITag(1);\r\n return result;\r\n } else if (u0 > targetDistance) {\r\n // Direct hig within edge\r\n const edgeFraction = targetDistance / u0;\r\n result = searchBase.resetAtEdgeAndFraction(outboundEdge, edgeFraction);\r\n return result;\r\n } else if (Math.abs(u0) <= this._tol) {\r\n // Unexpected direct hit on the base of the search, but call it a hit....\r\n result = searchBase.resetAsVertex(outboundEdge);\r\n result.setITag(1);\r\n return result;\r\n } else if (u0 > this._tol) {\r\n // Advance to vertex ...\r\n // double edgeFraction = targetDistance / u0;\r\n result = searchBase.resetAsVertex(data0.node);\r\n return result;\r\n } else {\r\n // Search direction is exactly opposite this edge.\r\n // See if the other side of the sector is turned even beyond that ...\r\n if (v1 > this._tol) {\r\n result = searchBase.resetAsFace(outboundEdge, outboundEdge);\r\n return result;\r\n }\r\n }\r\n } else if (v0 < -this._tol) {\r\n if (v1 > this._tol) {\r\n // The usual simple entry into an angle < 180\r\n result = searchBase.resetAsFace(outboundEdge, outboundEdge);\r\n return result;\r\n }\r\n }\r\n // NEEDS WORK: angle >= 180 cases !!!!\r\n outboundEdge = outboundEdge.vertexSuccessor;\r\n } while (outboundEdge !== vertexNode);\r\n return this.panic();\r\n }\r\n\r\n // Visit all edges around face.\r\n // reset lastBefore and firstAfter describing progress towards target distance on ray.\r\n public reAimAroundFace(\r\n faceNode: HalfEdge,\r\n ray: Ray3d,\r\n targetDistance: number, // !< distance to target point\r\n lastBefore: HalfEdgePositionDetail, // CALLER CREATED -- reset as first hit on negative side of ray.\r\n firstAfter: HalfEdgePositionDetail): RayClassification { // ! CALLER CREATED -- reset as first hit on positive side of ray.\r\n\r\n lastBefore.resetAsUndefinedWithTag(-Number.MAX_VALUE);\r\n firstAfter.resetAsUndefinedWithTag(Number.MAX_VALUE);\r\n const data0 = NodeXYZUV.createNodeAndRayOrigin(faceNode, ray);\r\n let data1;\r\n let node0 = faceNode;\r\n do {\r\n const node1 = node0.faceSuccessor;\r\n data1 = NodeXYZUV.createNodeAndRayOrigin(node1, ray, data1);\r\n const u0 = data0.u;\r\n const u1 = data1.u;\r\n const v0 = data0.v;\r\n const v1 = data1.v;\r\n if (Math.abs(v1) < this._tol) {\r\n // Vertex hit ...\r\n const vertexHit = HalfEdgePositionDetail.createVertex(node1);\r\n vertexHit.setDTag(u1);\r\n if (Math.abs(u1 - targetDistance) < this._tol) {\r\n firstAfter.setFrom(vertexHit);\r\n lastBefore.setFrom(vertexHit);\r\n return RayClassification.RC_TargetOnVertex;\r\n }\r\n if (u1 > targetDistance && u1 < firstAfter.getDTag()!)\r\n firstAfter.setFrom(vertexHit);\r\n if (u1 < targetDistance && u1 > lastBefore.getDTag()!)\r\n lastBefore.setFrom(vertexHit);\r\n } else if (v0 * v1 < 0.0) {\r\n // Edge Crossing ...\r\n const edgeFraction = - v0 / (v1 - v0);\r\n const uEdge = Geometry.interpolate(u0, edgeFraction, u1);\r\n const edgeHit = HalfEdgePositionDetail.createEdgeAtFraction(data0.node, edgeFraction);\r\n edgeHit.setDTag(uEdge);\r\n if (Math.abs(uEdge - targetDistance) <= this._tol) {\r\n firstAfter.setFrom(edgeHit);\r\n lastBefore.setFrom(edgeHit);\r\n return RayClassification.RC_TargetOnEdge;\r\n }\r\n if (uEdge > targetDistance && uEdge < firstAfter.getDTag()!) {\r\n firstAfter.setFrom(edgeHit);\r\n firstAfter.setITag(v0 > 0.0 ? -1 : 1);\r\n }\r\n if (uEdge < targetDistance && uEdge > lastBefore.getDTag()!) {\r\n lastBefore.setFrom(edgeHit);\r\n lastBefore.setDTag(uEdge);\r\n }\r\n }\r\n data0.setFrom(data1);\r\n node0 = node0.faceSuccessor;\r\n } while (node0 !== faceNode);\r\n// Returned to start node !!!\r\n const afterTag = firstAfter.getITag();\r\n firstAfter.setITag(0);\r\n lastBefore.setITag(0);\r\n if (lastBefore.isUnclassified) {\r\n if (firstAfter.isUnclassified)\r\n return RayClassification.RC_NoHits;\r\n return RayClassification.RC_TargetBefore;\r\n }\r\n if (firstAfter.isUnclassified\r\n || (firstAfter.isEdge && afterTag && afterTag < 0)) {\r\n return RayClassification.RC_TargetAfter;\r\n } else {\r\n return RayClassification.RC_Bracket;\r\n }\r\n }\r\n\r\n // Return false if target is reached !!!!\r\n /**\r\n * Set (replace contents) ray with\r\n * * `origin` at start\r\n * * `direction` is unit vector from start towards target\r\n * * `a` is distance from start to target.\r\n * @param start existing position\r\n * @param target target xy coordinates\r\n * @param ray ray to update\r\n */\r\n public setSearchRay(start: HalfEdgePositionDetail, target: Point3d, ray: Ray3d): boolean {\r\n ray.origin.setFromPoint3d(start);\r\n Vector3d.createStartEnd(ray.origin, target, ray.direction);\r\n ray.direction.z = 0.0;\r\n const distanceToTarget = ray.direction.magnitudeXY();\r\n ray.a = ray.direction.magnitude();\r\n ray.direction.scaleInPlace(1 / ray.a);\r\n return distanceToTarget >= this._tol;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"HalfEdgePointInGraphSearch.js","sourceRoot":"","sources":["../../../src/topology/HalfEdgePointInGraphSearch.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 { assert } from \"@itwin/core-bentley\";\r\nimport { Geometry } from \"../Geometry\";\r\nimport { Point3d, Vector3d } from \"../geometry3d/Point3dVector3d\";\r\nimport { Ray3d } from \"../geometry3d/Ray3d\";\r\nimport { HalfEdge, HalfEdgeMask } from \"./Graph\";\r\nimport { NodeXYZUV } from \"./HalfEdgeNodeXYZUV\";\r\nimport { HalfEdgePositionDetail } from \"./HalfEdgePositionDetail\";\r\n\r\n// cspell:word Chebyshev\r\n\r\n/**\r\n * Return code from [PointSearchContext.reAimAroundFace]\r\n * @internal\r\n */\r\nexport enum RayClassification {\r\n NoHits,\r\n TargetOnVertex,\r\n TargetOnEdge,\r\n Bracket,\r\n TargetBefore,\r\n TargetAfter,\r\n}\r\n\r\n/**\r\n * Context for searching for the location of an xy-point in a graph.\r\n * * Assumptions: interior faces of the graph are convex, no edge has length less than `tol`.\r\n * @internal\r\n */\r\nexport class PointSearchContext {\r\n private _tol: number;\r\n private constructor(tol: number) {\r\n this._tol = tol;\r\n }\r\n public static create(tol: number = Geometry.smallMetricDistance) {\r\n return new PointSearchContext(tol);\r\n }\r\n private panic(): HalfEdgePositionDetail {\r\n // A note on \"unexpectedly\" found in comments in this file:\r\n // Though this class assumes all edges of the graph have length at least tolerance, the tests below account for\r\n // edges with smaller length. This is because we are using two different metrics: Euclidean for distinguishing\r\n // points matching user expectation, and Chebyshev, aka \"max component\", for efficiently testing ray-sector\r\n // inclusion in the reAimXXX methods. In particular, epsilon-balls in the former metric are smaller than in the\r\n // latter. Thus an edge can be inserted into the graph with Euclidean length (barely) greater than epsilon, but\r\n // the edge's parallel and perpendicular components with respect to a ray can have Euclidean length *less* than\r\n // epsilon, yielding a Chebyshev edge length less than epsilon. This discrepancy requires careful analysis below,\r\n // and if this method is invoked, it is probably because we've missed a case where a dot/cross product lies just\r\n // beyond the tolerance.\r\n return HalfEdgePositionDetail.create();\r\n }\r\n /**\r\n * Reposition `edgeHit` to an adjacent face or vertex, or another position on the edge, that is closer to the\r\n * target point.\r\n * @param edgeHit start position on a graph edge, updated and returned.\r\n * @param ray the ray to the target point. Origin is assumed to lie on the edge.\r\n * @param targetDistance distance along the ray to the target point.\r\n * @return detail closer to the target point.\r\n */\r\n public reAimFromEdge(\r\n edgeHit: HalfEdgePositionDetail, ray: Ray3d, targetDistance: number,\r\n ): HalfEdgePositionDetail {\r\n const nodeA = edgeHit.node!;\r\n const dataA = NodeXYZUV.createNodeAndRayOrigin(nodeA, ray);\r\n const dataB = NodeXYZUV.createNodeAndRayOrigin(nodeA.edgeMate, ray);\r\n const sideA = -dataA.classifyV(0.0, this._tol);\r\n const sideB = -dataB.classifyV(0.0, this._tol);\r\n let result;\r\n if (sideA * sideB < 0) { // simple crossing; just aim into a face\r\n if (sideA > 0) {\r\n result = edgeHit.resetAsFace(dataA.node);\r\n } else {\r\n result = edgeHit.resetAsFace(dataB.node);\r\n }\r\n } else if (sideA === 0 || sideB === 0) {\r\n const alongA = dataA.classifyU(targetDistance, this._tol);\r\n const alongB = dataB.classifyU(targetDistance, this._tol);\r\n if (sideA === 0 && alongA === 0) { // hit start vertex\r\n result = edgeHit.resetAsVertex(dataA.node);\r\n result.setITag(1);\r\n } else if (sideB === 0 && alongB === 0) { // hit end vertex\r\n result = edgeHit.resetAsVertex(dataB.node);\r\n result.setITag(1);\r\n } else if (sideA === 0 && sideB === 0) { // ray is clearly along the edge\r\n if (alongA * alongB < 0) { // target is within edge\r\n const edgeFraction = (targetDistance - dataA.u) / (dataB.u - dataA.u);\r\n result = edgeHit.resetAtEdgeAndFraction(dataA.node, edgeFraction);\r\n result.setITag(1);\r\n } else if (alongA < 0 && alongB < 0) { // target is beyond the edge; move towards it\r\n if (dataA.u > dataB.u)\r\n result = edgeHit.resetAsVertex(dataA.node);\r\n else\r\n result = edgeHit.resetAsVertex(dataB.node);\r\n } else { // both vertices lie on the ray before or after the target; shouldn't happen for edgeHit between nodes\r\n edgeHit.resetAsUnknown();\r\n result = this.panic();\r\n }\r\n } else if (sideA === 0) { // ray near start vertex but NOT parallel to the edge\r\n if (0 === dataA.classifyU(0.0, this._tol))\r\n result = edgeHit.resetAsVertex(dataA.node);\r\n else\r\n result = edgeHit.resetAsFace(sideB > 0 ? dataB.node : dataA.node);\r\n } else { // ray near end vertex but NOT parallel to the edge\r\n assert(sideB === 0);\r\n if (0 === dataB.classifyU(0.0, this._tol))\r\n result = edgeHit.resetAsVertex(dataB.node);\r\n else\r\n result = edgeHit.resetAsFace(sideA > 0 ? dataA.node : dataB.node);\r\n }\r\n } else { // both vertices are to same side of the ray; shouldn't happen for edgeHit between nodes\r\n edgeHit.resetAsUnknown();\r\n result = this.panic();\r\n }\r\n return result;\r\n }\r\n /**\r\n * Reposition `vertexHit` to an adjacent face, edge, or vertex hit that is closer to the target point.\r\n * @param vertexHit start position at a graph vertex, updated and returned.\r\n * @param ray the ray to the target point, assumed to start exactly at the vertex.\r\n * @param targetDistance distance along the ray to the target point.\r\n * @return detail closer to the target point.\r\n */\r\n public reAimFromVertex(\r\n vertexHit: HalfEdgePositionDetail, ray: Ray3d, targetDistance: number,\r\n ): HalfEdgePositionDetail {\r\n assert(ray.origin.isExactEqual(vertexHit));\r\n const vertexNode = vertexHit.node;\r\n let outboundEdge = vertexNode!;\r\n // lambda to handle the case where the target definitively lies in the same direction as outboundEdge\r\n const advancePositionAlongOutboundEdge = (rayParam: number): boolean => {\r\n if (Math.abs(rayParam - targetDistance) <= this._tol) { // direct hit at far end of outBoundEdge\r\n vertexHit.resetAsVertex(outboundEdge.faceSuccessor).setITag(1);\r\n } else if (rayParam > targetDistance) { // direct hit within outBoundEdge\r\n vertexHit.resetAtEdgeAndFraction(outboundEdge, targetDistance / rayParam);\r\n } else if (rayParam > this._tol) { // far end of outBoundEdge is closer to target\r\n vertexHit.resetAsVertex(outboundEdge.faceSuccessor);\r\n } else {\r\n return false;\r\n }\r\n return true;\r\n };\r\n do {\r\n // examine the sector at the outboundEdge node; if ray lies in this sector, return updated detail\r\n const data0 = NodeXYZUV.createNodeAndRayOrigin(outboundEdge.faceSuccessor, ray);\r\n const data1 = NodeXYZUV.createNodeAndRayOrigin(outboundEdge.facePredecessor, ray);\r\n // u0 is the length of projection of faceSuccessor to the ray and v0 is the length of projection of\r\n // faceSuccessor to the ray perp line (90 degrees CCW). Similarly for u1 and v1 with facePredecessor.\r\n const u0 = data0.u;\r\n const u1 = data1.u;\r\n const v0 = data0.v;\r\n const v1 = data1.v;\r\n // examine dot and cross of ray with both edges defining this sector to see if ray lies between them\r\n if (Math.abs(v0) <= this._tol) { // ray parallel to outBoundEdge\r\n if (advancePositionAlongOutboundEdge(u0))\r\n return vertexHit;\r\n if (Math.abs(u0) <= this._tol) { // edge is unexpectedly* small\r\n if (v0 <= 0 && v1 > this._tol && (u0 >= 0 || (u0 < 0 && u1 > this._tol)))\r\n return vertexHit.resetAsFace(outboundEdge, outboundEdge);\r\n }\r\n // The only remaining case is u0 < -this._tol: ray points opposite outBoundEdge.\r\n // By our convexity assumption, the only way that ray lies in this sector is if the lookBack\r\n // vector points in the same direction as ray, but this would be handled in the next sector.\r\n } else if (v0 < -this._tol) {\r\n if (v1 > this._tol) // ray definitely lies in this sector\r\n return vertexHit.resetAsFace(outboundEdge, outboundEdge);\r\n if (v1 >= -this._tol) { // ray and lookBack vector are parallel\r\n // handle special cases not handled in the next sector\r\n if (Math.abs(u1) <= this._tol) { // lookBack vector is unexpectedly* small...\r\n if (v1 > 0 && (u1 >= 0 || (u0 > this._tol && u1 < 0))) // ...and ray is in this sector\r\n return vertexHit.resetAsFace(outboundEdge, outboundEdge);\r\n } else if (u0 > this._tol && u1 < 0) { // ray and lookBack point in opposite directions\r\n return vertexHit.resetAsVertex(outboundEdge.faceSuccessor); // far end is closer to target\r\n }\r\n }\r\n // The only remaining case is v1 < -this._tol: ray definitely lies outside this sector.\r\n }\r\n // Proceed to the next sector around this vertex. We even examine the (concave) exterior sector at a boundary\r\n // vertex in order to handle the case where the target lies in the direction of an exterior outboundEdge.\r\n outboundEdge = outboundEdge.vertexSuccessor;\r\n } while (outboundEdge !== vertexNode);\r\n return this.panic();\r\n }\r\n /**\r\n * Visit all edges around the face, updating `lastBefore` and `firstAfter` to ray-edge intersections that\r\n * lie directly before and/or after the target point on the ray, if at all.\r\n * @param faceNode starting node on a graph face.\r\n * @param ray the ray to the target point.\r\n * @param targetDistance distance along the ray to the target point.\r\n * @param lastBefore the detail to reset as the last hit on the ray before the target point (CALLER CREATED).\r\n * @param firstAfter the detail to reset as the first hit on the ray after the target point (CALLER CREATED).\r\n * @returns summary of the updated details:\r\n * * [[RayClassification.TargetOnVertex]] - target lies at a vertex of the face (details are identical).\r\n * * [[RayClassification.TargetOnEdge]] - target lies on an edge of the face (details are identical).\r\n * * [[RayClassification.TargetBefore]] - target lies before the face; the ray intersects the face beyond\r\n * the target point.\r\n * * [[RayClassification.TargetAfter]] - target lies after the face; the ray intersects the face before\r\n * the target point.\r\n * * [[RayClassification.Bracket]] - target lies between intersections of the ray and the face; if the face\r\n * is convex, this means the target lies inside the face.\r\n * * [[RayClassification.NoHits]] - the face does not intersect the ray.\r\n */\r\n public reAimAroundFace(\r\n faceNode: HalfEdge,\r\n ray: Ray3d,\r\n targetDistance: number,\r\n lastBefore: HalfEdgePositionDetail,\r\n firstAfter: HalfEdgePositionDetail,\r\n ): RayClassification {\r\n assert(!faceNode.isMaskSet(HalfEdgeMask.EXTERIOR));\r\n lastBefore.resetAsUndefinedWithTag(-Number.MAX_VALUE);\r\n firstAfter.resetAsUndefinedWithTag(Number.MAX_VALUE);\r\n const data0 = NodeXYZUV.createNodeAndRayOrigin(faceNode, ray);\r\n let data1;\r\n let node0 = faceNode;\r\n // find the intersection of the ray with each edge of the face to classify the ray hit\r\n do {\r\n const node1 = node0.faceSuccessor;\r\n data1 = NodeXYZUV.createNodeAndRayOrigin(node1, ray, data1);\r\n const u0 = data0.u;\r\n const u1 = data1.u;\r\n const v0 = data0.v;\r\n const v1 = data1.v;\r\n if (Math.abs(v1) < this._tol) { // ray parallel to edge\r\n const vertexHit = HalfEdgePositionDetail.createVertex(node1);\r\n vertexHit.setDTag(u1);\r\n if (Math.abs(u1 - targetDistance) < this._tol) {\r\n firstAfter.setFrom(vertexHit);\r\n lastBefore.setFrom(vertexHit);\r\n return RayClassification.TargetOnVertex;\r\n }\r\n if (u1 > targetDistance && u1 < firstAfter.getDTag()!)\r\n firstAfter.setFrom(vertexHit);\r\n if (u1 < targetDistance && u1 > lastBefore.getDTag()!)\r\n lastBefore.setFrom(vertexHit);\r\n } else if (v0 * v1 < 0.0) { // ray crosses edge\r\n const edgeFraction = -v0 / (v1 - v0);\r\n const rayFraction = Geometry.interpolate(u0, edgeFraction, u1);\r\n const edgeHit = HalfEdgePositionDetail.createEdgeAtFraction(data0.node, edgeFraction);\r\n edgeHit.setDTag(rayFraction);\r\n if (Math.abs(rayFraction - targetDistance) <= this._tol) {\r\n firstAfter.setFrom(edgeHit);\r\n lastBefore.setFrom(edgeHit);\r\n return RayClassification.TargetOnEdge;\r\n }\r\n if (rayFraction > targetDistance && rayFraction < firstAfter.getDTag()!)\r\n firstAfter.setFrom(edgeHit);\r\n if (rayFraction < targetDistance && rayFraction > lastBefore.getDTag()!)\r\n lastBefore.setFrom(edgeHit);\r\n }\r\n data0.setFrom(data1);\r\n node0 = node0.faceSuccessor;\r\n } while (node0 !== faceNode);\r\n // returned to start node\r\n firstAfter.setITag(0);\r\n lastBefore.setITag(0);\r\n if (lastBefore.isUnclassified) {\r\n if (firstAfter.isUnclassified)\r\n return RayClassification.NoHits;\r\n return RayClassification.TargetBefore;\r\n }\r\n if (firstAfter.isUnclassified)\r\n return RayClassification.TargetAfter;\r\n else\r\n return RayClassification.Bracket; // face is locally convex; target lies inside this face\r\n }\r\n /**\r\n * Initialize the input ray for topology search:\r\n * * `origin` is at `start`\r\n * * `direction` is the unit xy-vector from `start` towards `target`\r\n * * `a` is the xy-distance from `start` to `target`\r\n * @param start existing position\r\n * @param target target xy coordinates\r\n * @param ray updated in place\r\n * @returns false if target is reached.\r\n */\r\n public setSearchRay(start: HalfEdgePositionDetail, target: Point3d, ray: Ray3d): boolean {\r\n ray.origin.setFromPoint3d(start);\r\n Vector3d.createStartEnd(ray.origin, target, ray.direction);\r\n ray.direction.z = 0.0;\r\n const distanceToTargetXY = ray.direction.magnitudeXY();\r\n if (distanceToTargetXY < this._tol)\r\n return false; // no searching necessary, we are already at the target point\r\n ray.a = distanceToTargetXY;\r\n ray.direction.scaleInPlace(1 / distanceToTargetXY);\r\n return true;\r\n }\r\n}\r\n"]}