@itwin/rpcinterface-full-stack-tests 5.9.0-dev.7 → 5.9.0-dev.9

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.
@@ -72327,6 +72327,7 @@ __webpack_require__.r(__webpack_exports__);
72327
72327
  /* harmony export */ CloudSqliteError: () => (/* binding */ CloudSqliteError),
72328
72328
  /* harmony export */ EditTxnError: () => (/* binding */ EditTxnError),
72329
72329
  /* harmony export */ ITwinSettingsError: () => (/* binding */ ITwinSettingsError),
72330
+ /* harmony export */ ServerBasedLocksError: () => (/* binding */ ServerBasedLocksError),
72330
72331
  /* harmony export */ SqliteError: () => (/* binding */ SqliteError),
72331
72332
  /* harmony export */ ViewStoreError: () => (/* binding */ ViewStoreError),
72332
72333
  /* harmony export */ WorkspaceError: () => (/* binding */ WorkspaceError)
@@ -72449,6 +72450,24 @@ var EditTxnError;
72449
72450
  }
72450
72451
  EditTxnError.isError = isError;
72451
72452
  })(EditTxnError || (EditTxnError = {}));
72453
+ /** Errors originating from the server-based implementation of the [LockControl]($backend) interface.
72454
+ * @beta
72455
+ */
72456
+ var ServerBasedLocksError;
72457
+ (function (ServerBasedLocksError) {
72458
+ /** the ITwinError scope for `ServerBasedLocksError`s. */
72459
+ ServerBasedLocksError.scope = "itwin-ServerBasedLocks";
72460
+ /** Instantiate and throw a ServerBasedLocksError */
72461
+ function throwError(key, message) {
72462
+ _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.ITwinError.throwError({ iTwinErrorId: { scope: ServerBasedLocksError.scope, key }, message });
72463
+ }
72464
+ ServerBasedLocksError.throwError = throwError;
72465
+ /** Determine whether an error object is a ServerBasedLocksError */
72466
+ function isError(error, key) {
72467
+ return _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.ITwinError.isError(error, ServerBasedLocksError.scope, key);
72468
+ }
72469
+ ServerBasedLocksError.isError = isError;
72470
+ })(ServerBasedLocksError || (ServerBasedLocksError = {}));
72452
72471
 
72453
72472
 
72454
72473
  /***/ }),
@@ -82335,6 +82354,7 @@ __webpack_require__.r(__webpack_exports__);
82335
82354
  /* harmony export */ Run: () => (/* reexport safe */ _annotation_TextBlock__WEBPACK_IMPORTED_MODULE_3__.Run),
82336
82355
  /* harmony export */ SchemaState: () => (/* reexport safe */ _BriefcaseTypes__WEBPACK_IMPORTED_MODULE_13__.SchemaState),
82337
82356
  /* harmony export */ SectionType: () => (/* reexport safe */ _ElementProps__WEBPACK_IMPORTED_MODULE_32__.SectionType),
82357
+ /* harmony export */ ServerBasedLocksError: () => (/* reexport safe */ _ITwinCoreErrors__WEBPACK_IMPORTED_MODULE_73__.ServerBasedLocksError),
82338
82358
  /* harmony export */ ServerError: () => (/* reexport safe */ _IModelError__WEBPACK_IMPORTED_MODULE_71__.ServerError),
82339
82359
  /* harmony export */ ServerTimeoutError: () => (/* reexport safe */ _IModelError__WEBPACK_IMPORTED_MODULE_71__.ServerTimeoutError),
82340
82360
  /* harmony export */ SilhouetteEdgeArgs: () => (/* reexport safe */ _internal_cross_package__WEBPACK_IMPORTED_MODULE_164__.SilhouetteEdgeArgs),
@@ -119671,6 +119691,23 @@ class BriefcaseTxns extends BriefcaseNotificationHandler {
119671
119691
  async reverseSingleTxn() {
119672
119692
  return this.reverseTxns(1);
119673
119693
  }
119694
+ /** Reverse (undo) the most recent operation to this briefcase in the current session. By default, this method also
119695
+ * abandons the locks that were acquired for that operation.
119696
+ * @beta
119697
+ * @note This method will also abandon locks associated with any later, reversed Txns, if they have not
119698
+ * already been abandoned. For example, if a call to [[reverseTxns]] reverses Txn 2 without abandoning
119699
+ * its locks, and then this method is called to reverse Txn 1, it will abandon the locks associated
119700
+ * with _both_ Txn 1 and Txn 2.
119701
+ * @note If there are any outstanding uncommitted changes, they are reversed.
119702
+ * @note The term "operation" is used rather than Txn, since multiple Txns can be grouped together via [TxnManager.beginMultiTxnOperation]($backend). So,
119703
+ * even though this method reverses only one operation, multiple Txns may be reversed if they were grouped together when they were made.
119704
+ * @note If there are no reversible operations, this method does nothing and returns Success.
119705
+ * @param args Optional arguments to control the behavior of the reverse operation, such as whether to retain locks.
119706
+ * @returns A Promise that resolves to success if the transactions were reversed, or rejects with an IModelError otherwise.
119707
+ */
119708
+ async reverseSingleTxnAsync(args) {
119709
+ await this.reverseTxnsAsync(1, args);
119710
+ }
119674
119711
  /** Reverse (undo) the most recent operation(s) to the briefcase in the current session.
119675
119712
  * @param numOperations the number of operations to reverse. If this is greater than 1, the entire set of operations will
119676
119713
  * be reinstated together when/if [[reinstateTxn]] is called.
@@ -119682,6 +119719,26 @@ class BriefcaseTxns extends BriefcaseNotificationHandler {
119682
119719
  async reverseTxns(numOperations) {
119683
119720
  return _IpcApp__WEBPACK_IMPORTED_MODULE_3__.IpcApp.appFunctionIpc.reverseTxns(this._iModel.key, numOperations);
119684
119721
  }
119722
+ /** Reverse (undo) the most recent operation(s) to the briefcase in the current session. By default, this method also
119723
+ * abandons the locks that were acquired for those operations.
119724
+ * @beta
119725
+ * @note This method will also abandon locks associated with any later, reversed Txns, if they have not
119726
+ * already been abandoned. For example, if a call to [[reverseTxns]] reverses Txn 2 without abandoning
119727
+ * its locks, and then this method is called to reverse Txn 1, it will abandon the locks associated
119728
+ * with _both_ Txn 1 and Txn 2.
119729
+ * @note If you do not want to abandon any locks, set [ReverseTxnArgs.retainLocks]($common) to true.
119730
+ * @note If there are any outstanding uncommitted changes, they are reversed.
119731
+ * @note The term "operation" is used rather than Txn, since multiple Txns can be grouped together via [[beginMultiTxnOperation]]. So,
119732
+ * even if numOperations is 1, multiple Txns may be reversed if they were grouped together when they were made.
119733
+ * @note If numOperations is too large only the operations are reversible are reversed.
119734
+ * @param numOperations the number of operations to reverse. If this is greater than 1, the entire set of operations will
119735
+ * be reinstated together when/if ReinstateTxn is called.
119736
+ * @param args Optional arguments to control the behavior of the reverse operation, such as whether to retain locks.
119737
+ * @returns A Promise that resolves to success if the transactions were reversed, or rejects with an IModelError otherwise.
119738
+ */
119739
+ async reverseTxnsAsync(numOperations, args) {
119740
+ return _IpcApp__WEBPACK_IMPORTED_MODULE_3__.IpcApp.appFunctionIpc.reverseTxnsAsync(this._iModel.key, numOperations, args);
119741
+ }
119685
119742
  /** Reverse (undo) all changes back to the beginning of the session.
119686
119743
  * @see [[reinstateTxn]] to redo changes.
119687
119744
  * @see [[reverseSingleTxn]] to undo only the most recent operation.
@@ -119690,6 +119747,21 @@ class BriefcaseTxns extends BriefcaseNotificationHandler {
119690
119747
  async reverseAll() {
119691
119748
  return _IpcApp__WEBPACK_IMPORTED_MODULE_3__.IpcApp.appFunctionIpc.reverseAllTxn(this._iModel.key);
119692
119749
  }
119750
+ /** Reverse (undo) all operations back to the beginning of the session. By default, this method also
119751
+ * abandons the locks that were acquired for those operations.
119752
+ * @beta
119753
+ * @note This method will also abandon locks associated with any later, reversed Txns, if they have not
119754
+ * already been abandoned. For example, if a call to [[reverseTxns]] reverses Txn 2 without abandoning
119755
+ * its locks, and then this method is called to reverse Txn 1, it will abandon the locks associated
119756
+ * with _both_ Txn 1 and Txn 2.
119757
+ * @note If there are any outstanding uncommitted changes, they are reversed.
119758
+ * @note If there are no reversible operations, this method does nothing and returns Success.
119759
+ * @param args Optional arguments to control the behavior of the reverse operation, such as whether to retain locks.
119760
+ * @returns A Promise that resolves to success if the transactions were reversed, or rejects with an IModelError otherwise.
119761
+ */
119762
+ async reverseAllTxnsAsync(args) {
119763
+ return _IpcApp__WEBPACK_IMPORTED_MODULE_3__.IpcApp.appFunctionIpc.reverseAllTxnsAsync(this._iModel.key, args);
119764
+ }
119693
119765
  /** Reinstate (redo) the most recently reversed transaction. Since at any time multiple transactions can be reversed, it
119694
119766
  * may take multiple calls to this method to reinstate all reversed operations.
119695
119767
  * @returns Success if a reversed transaction was reinstated, error status otherwise.
@@ -119700,6 +119772,19 @@ class BriefcaseTxns extends BriefcaseNotificationHandler {
119700
119772
  async reinstateTxn() {
119701
119773
  return _IpcApp__WEBPACK_IMPORTED_MODULE_3__.IpcApp.appFunctionIpc.reinstateTxn(this._iModel.key);
119702
119774
  }
119775
+ /** Reinstate (redo) the most recently reversed transaction. Since at any time multiple transactions can be reversed, it
119776
+ * may take multiple calls to this method to reinstate all reversed operations. This method also
119777
+ * re-acquires the locks that were abandoned when those operations were reversed.
119778
+ * @beta
119779
+ * @param args Optional arguments to control the behavior of the reinstate operation.
119780
+ * @returns Success if a reversed transaction was reinstated, error status otherwise.
119781
+ * @note If there are any outstanding uncommitted changes, they are canceled before the Txn is reinstated.
119782
+ * @see [[isRedoPossible]] to determine if any reinstatable operations exist.
119783
+ * @see [[reverseSingleTxn]] or [[reverseAll]] to undo changes.
119784
+ */
119785
+ async reinstateTxnAsync(args) {
119786
+ return _IpcApp__WEBPACK_IMPORTED_MODULE_3__.IpcApp.appFunctionIpc.reinstateTxnAsync(this._iModel.key, args);
119787
+ }
119703
119788
  /** Restart the current TxnManager session. This causes all Txns in the current session to no longer be undoable (as if the file was closed
119704
119789
  * and reopened.)
119705
119790
  * @note This can be quite disconcerting to the user expecting to be able to undo previously made changes. It should only be used
@@ -220725,7 +220810,7 @@ class ToolAdmin {
220725
220810
  const imodel = _IModelApp__WEBPACK_IMPORTED_MODULE_5__.IModelApp.viewManager.selectedView?.view.iModel;
220726
220811
  if (undefined === imodel || imodel.isReadonly || !imodel.isBriefcaseConnection())
220727
220812
  return false;
220728
- return (_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.IModelStatus.Success === await imodel.txns.reverseSingleTxn() ? true : false);
220813
+ return imodel.txns.reverseSingleTxnAsync().then(() => true).catch(() => false);
220729
220814
  }
220730
220815
  /** Called to redo previous data button for primitive tools or undo last write operation. */
220731
220816
  async doRedoOperation() {
@@ -220738,7 +220823,7 @@ class ToolAdmin {
220738
220823
  const imodel = _IModelApp__WEBPACK_IMPORTED_MODULE_5__.IModelApp.viewManager.selectedView?.view.iModel;
220739
220824
  if (undefined === imodel || imodel.isReadonly || !imodel.isBriefcaseConnection())
220740
220825
  return false;
220741
- return (_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.IModelStatus.Success === await imodel.txns.reinstateTxn() ? true : false);
220826
+ return imodel.txns.reinstateTxnAsync().then(() => true).catch(() => false);
220742
220827
  }
220743
220828
  onActiveToolChanged(tool, start) {
220744
220829
  this.clearMotionPromises();
@@ -225697,18 +225782,18 @@ __webpack_require__.r(__webpack_exports__);
225697
225782
  */
225698
225783
  var AxisOrder;
225699
225784
  (function (AxisOrder) {
225700
- /** Right handed system, X then Y then Z */
225785
+ /** Right-handed system, X then Y then Z. */
225701
225786
  // eslint-disable-next-line @typescript-eslint/no-shadow
225702
225787
  AxisOrder[AxisOrder["XYZ"] = 0] = "XYZ";
225703
- /** Right handed system, Y then Z then X */
225788
+ /** Right-handed system, Y then Z then X. */
225704
225789
  AxisOrder[AxisOrder["YZX"] = 1] = "YZX";
225705
- /** Right handed system, Z then X then Y */
225790
+ /** Right-handed system, Z then X then Y. */
225706
225791
  AxisOrder[AxisOrder["ZXY"] = 2] = "ZXY";
225707
- /** Left handed system, X then Z then Y */
225792
+ /** Left-handed system, X then Z then Y. For a right-handed alternative, swap the first two axes and use `AxisOrder.ZXY`. */
225708
225793
  AxisOrder[AxisOrder["XZY"] = 4] = "XZY";
225709
- /** Left handed system, Y then X then Z */
225794
+ /** Left-handed system, Y then X then Z. For a right-handed alternative, swap the first two axes and use `AxisOrder.XYZ`.*/
225710
225795
  AxisOrder[AxisOrder["YXZ"] = 5] = "YXZ";
225711
- /** Left handed system, Z then Y then X */
225796
+ /** Left-handed system, Z then Y then X. For a right-handed alternative, swap the first two axes and use `AxisOrder.YZX`.*/
225712
225797
  AxisOrder[AxisOrder["ZYX"] = 6] = "ZYX";
225713
225798
  })(AxisOrder || (AxisOrder = {}));
225714
225799
  /**
@@ -225808,6 +225893,8 @@ class Geometry {
225808
225893
  static smallAngleSeconds = 2e-7;
225809
225894
  /** Numeric value that may be considered zero for fractions between 0 and 1. */
225810
225895
  static smallFraction = 1.0e-10;
225896
+ /** Relative fraction tolerance for Newton iterations. */
225897
+ static smallNewtonStep = 1.0e-11;
225811
225898
  /** Tight tolerance near machine precision (unitless). Useful for snapping values, e.g., to 0 or 1. */
225812
225899
  static smallFloatingPoint = 1.0e-15;
225813
225900
  /** Radians value for full circle 2PI radians minus [[smallAngleRadians]]. */
@@ -238486,6 +238573,7 @@ __webpack_require__.r(__webpack_exports__);
238486
238573
  /* harmony export */ TriangularFacetLocationDetail: () => (/* reexport safe */ _polyface_FacetLocationDetail__WEBPACK_IMPORTED_MODULE_115__.TriangularFacetLocationDetail),
238487
238574
  /* harmony export */ UVSelect: () => (/* reexport safe */ _bspline_BSplineSurface__WEBPACK_IMPORTED_MODULE_108__.UVSelect),
238488
238575
  /* harmony export */ UVSurfaceOps: () => (/* reexport safe */ _geometry3d_UVSurfaceOps__WEBPACK_IMPORTED_MODULE_34__.UVSurfaceOps),
238576
+ /* harmony export */ UniformStrokeCollector: () => (/* reexport safe */ _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODULE_8__.UniformStrokeCollector),
238489
238577
  /* harmony export */ UnionOfConvexClipPlaneSets: () => (/* reexport safe */ _clipping_UnionOfConvexClipPlaneSets__WEBPACK_IMPORTED_MODULE_42__.UnionOfConvexClipPlaneSets),
238490
238578
  /* harmony export */ UnionRegion: () => (/* reexport safe */ _curve_UnionRegion__WEBPACK_IMPORTED_MODULE_88__.UnionRegion),
238491
238579
  /* harmony export */ UnivariateBezier: () => (/* reexport safe */ _numerics_BezierPolynomials__WEBPACK_IMPORTED_MODULE_52__.UnivariateBezier),
@@ -239579,6 +239667,17 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
239579
239667
  startPoint(result) {
239580
239668
  return this.fractionToPoint(0.0, result);
239581
239669
  }
239670
+ /**
239671
+ * Whether the start and end points are defined and within tolerance.
239672
+ * * Does not check for degeneracy.
239673
+ * @param tolerance optional distance tolerance (default is [[Geometry.smallMetricDistance]])
239674
+ * @param xyOnly if true, ignore z coordinate (default is `false`)
239675
+ */
239676
+ isPhysicallyClosedCurve(tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_6__.Geometry.smallMetricDistance, xyOnly = false) {
239677
+ if (this.sweep.isFullCircle)
239678
+ return true;
239679
+ return super.isPhysicallyClosedCurve(tolerance, xyOnly);
239680
+ }
239582
239681
  /**
239583
239682
  * Return the end point of the arc.
239584
239683
  * @param result optional preallocated result.
@@ -241774,32 +241873,42 @@ class CurveChainWithDistanceIndex extends _curve_CurvePrimitive__WEBPACK_IMPORTE
241774
241873
  }
241775
241874
  return undefined;
241776
241875
  }
241876
+ /**
241877
+ * Given a parent chain, convert the corresponding child detail in the specified pair.
241878
+ * * Converted details refer to the chain's global parameterization instead of the child's.
241879
+ * * It is assumed that `pair.detailA.curve` is a child of chainA (similarly for chainB).
241880
+ * @param pair detail pair to convert in place
241881
+ * @param chainA convert pair.detailA to the global parameterization of chainA
241882
+ * @param chainB convert pair.detailB to the global parameterization of chainB
241883
+ * @return the converted pair
241884
+ */
241885
+ static convertChildDetailToChainDetailSingle(pair, chainA, chainB) {
241886
+ if (chainA) {
241887
+ const chainDetail = chainA.computeChainDetail(pair.detailA);
241888
+ if (chainDetail)
241889
+ pair.detailA = chainDetail;
241890
+ }
241891
+ if (chainB) {
241892
+ const chainDetail = chainB.computeChainDetail(pair.detailB);
241893
+ if (chainDetail)
241894
+ pair.detailB = chainDetail;
241895
+ }
241896
+ return pair;
241897
+ }
241777
241898
  /**
241778
241899
  * Given a parent chain, convert the corresponding child details in the specified pairs.
241779
241900
  * * Converted details refer to the chain's global parameterization instead of the child's.
241780
241901
  * * It is assumed that for all i >= index0, `pairs[i].detailA.curve` is a child of chainA (similarly for chainB).
241781
- * @param pairs array to mutate
241902
+ * @param pairs array of pairs to convert in place
241782
241903
  * @param index0 convert details of pairs in the tail of the array, starting at index0
241783
241904
  * @param chainA convert each specified detailA to the global parameterization of chainA
241784
241905
  * @param chainB convert each specified detailB to the global parameterization of chainB
241785
241906
  * @param compressAdjacent whether to remove adjacent duplicate pairs after conversion
241786
241907
  * @return the converted array
241787
- * @internal
241788
241908
  */
241789
241909
  static convertChildDetailToChainDetail(pairs, index0, chainA, chainB, compressAdjacent) {
241790
- for (let i = index0; i < pairs.length; ++i) {
241791
- const childDetailPair = pairs[i];
241792
- if (chainA) {
241793
- const chainDetail = chainA.computeChainDetail(childDetailPair.detailA);
241794
- if (chainDetail)
241795
- childDetailPair.detailA = chainDetail;
241796
- }
241797
- if (chainB) {
241798
- const chainDetail = chainB.computeChainDetail(childDetailPair.detailB);
241799
- if (chainDetail)
241800
- childDetailPair.detailB = chainDetail;
241801
- }
241802
- }
241910
+ for (let i = index0; i < pairs.length; ++i)
241911
+ pairs[i] = this.convertChildDetailToChainDetailSingle(pairs[i], chainA, chainB);
241803
241912
  if (compressAdjacent)
241804
241913
  pairs = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetailPair.removeAdjacentDuplicates(pairs, index0);
241805
241914
  return pairs;
@@ -242068,25 +242177,34 @@ class CurveCollection extends _GeometryQuery__WEBPACK_IMPORTED_MODULE_1__.Geomet
242068
242177
  return this.isAnyRegionType;
242069
242178
  }
242070
242179
  /**
242071
- * Return true for a `Path`, i.e. a chain of curves joined head-to-tail
242072
- * @see isPath
242180
+ * Return true for a `Path`, i.e. a chain of curves joined head-to-tail.
242181
+ * * This is NOT a test for (lack of) physical closure.
242182
+ * @see [[isPath]], [[CurveChain.isPhysicallyClosedCurve]]
242073
242183
  */
242074
242184
  get isOpenPath() {
242075
242185
  return this.dgnBoundaryType() === 1;
242076
242186
  }
242077
- /** Type guard for Path */
242187
+ /**
242188
+ * Type guard for Path.
242189
+ * * This is NOT a test for (lack of) physical closure.
242190
+ * @see [[CurveChain.isPhysicallyClosedCurve]]
242191
+ */
242078
242192
  isPath() {
242079
242193
  return this.isOpenPath;
242080
242194
  }
242081
242195
  /**
242082
242196
  * Return true for a single-loop planar region type, i.e. `Loop`.
242083
- * * This is NOT a test for physical closure of a `Path`.
242084
- * @see isLoop
242197
+ * * This is NOT a test for physical closure.
242198
+ * @see [[isLoop]], [[CurveChain.isPhysicallyClosedCurve]]
242085
242199
  */
242086
242200
  get isClosedPath() {
242087
242201
  return this.dgnBoundaryType() === 2;
242088
242202
  }
242089
- /** Type guard for Loop */
242203
+ /**
242204
+ * Type guard for Loop.
242205
+ * * This is NOT a test for physical closure.
242206
+ * @see [[CurveChain.isPhysicallyClosedCurve]]
242207
+ */
242090
242208
  isLoop() {
242091
242209
  return this.isClosedPath;
242092
242210
  }
@@ -242506,7 +242624,7 @@ class CurveCurve {
242506
242624
  * * If more than one approach is returned, one of them is the closest approach.
242507
242625
  * * If an input curve is a `CurveCollection`, then close approaches are computed to each `CurvePrimitive` child.
242508
242626
  * This can lead to many returned pairs, especially when both inputs are `CurveCollection`s. If an input curve is
242509
- * an `AnyRegion` then close approaches are computed only to the boundary curves, not to the interior.
242627
+ * an `AnyRegion`, then close approaches are computed only to the defining curves, not to the area they enclose.
242510
242628
  * @param curveA first curve
242511
242629
  * @param curveB second curve
242512
242630
  * @param maxDistance maximum xy-distance to consider between the curves.
@@ -242539,6 +242657,7 @@ class CurveCurve {
242539
242657
  let iMin = 0;
242540
242658
  let minDistXY = 2 * maxDistance;
242541
242659
  for (let i = 0; i < closeApproaches.length; ++i) {
242660
+ // TODO: this distance should already be in detail.a. Verify this, then just use it instead of recomputing below.
242542
242661
  const distXY = closeApproaches[i].detailA.point.distanceXY(closeApproaches[i].detailB.point);
242543
242662
  if (distXY < minDistXY) {
242544
242663
  iMin = i;
@@ -243618,8 +243737,9 @@ __webpack_require__.r(__webpack_exports__);
243618
243737
  /* harmony export */ CurveLocationDetailPair: () => (/* binding */ CurveLocationDetailPair),
243619
243738
  /* harmony export */ CurveSearchStatus: () => (/* binding */ CurveSearchStatus)
243620
243739
  /* harmony export */ });
243621
- /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
243622
- /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
243740
+ /* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
243741
+ /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
243742
+ /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
243623
243743
  /*---------------------------------------------------------------------------------------------
243624
243744
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
243625
243745
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -243629,6 +243749,7 @@ __webpack_require__.r(__webpack_exports__);
243629
243749
  */
243630
243750
 
243631
243751
 
243752
+
243632
243753
  /**
243633
243754
  * An enumeration of special conditions being described by a CurveLocationDetail.
243634
243755
  * @public
@@ -243709,9 +243830,9 @@ class CurveLocationDetail {
243709
243830
  pointQ;
243710
243831
  /** Constructor */
243711
243832
  constructor() {
243712
- this.pointQ = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.createZero();
243833
+ this.pointQ = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.createZero();
243713
243834
  this.fraction = 0;
243714
- this.point = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.createZero();
243835
+ this.point = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.createZero();
243715
243836
  this.a = 0.0;
243716
243837
  }
243717
243838
  /** Set the (optional) intervalRole field. */
@@ -243858,7 +243979,7 @@ class CurveLocationDetail {
243858
243979
  static createConditionalMoveSignedDistance(allowExtension, curve, startFraction, endFraction, requestedSignedDistance, result) {
243859
243980
  let a = requestedSignedDistance;
243860
243981
  let status = CurveSearchStatus.success;
243861
- if (!allowExtension && !_Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isIn01(endFraction)) {
243982
+ if (!allowExtension && !_Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.isIn01(endFraction)) {
243862
243983
  // cap the movement at the endpoint
243863
243984
  if (endFraction < 0.0) {
243864
243985
  a = -curve.curveLengthBetweenFractions(startFraction, 0.0);
@@ -243969,7 +244090,7 @@ class CurveLocationDetail {
243969
244090
  inverseInterpolateFraction(f, defaultFraction = 0) {
243970
244091
  if (this.fraction1 === undefined)
243971
244092
  return defaultFraction;
243972
- const a = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.inverseInterpolate01(this.fraction, this.fraction1, f);
244093
+ const a = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.inverseInterpolate01(this.fraction, this.fraction1, f);
243973
244094
  if (a === undefined)
243974
244095
  return defaultFraction;
243975
244096
  return a;
@@ -243992,7 +244113,7 @@ class CurveLocationDetail {
243992
244113
  * @param fractionTol optional relative tolerance for comparing fractions with [[Geometry.isAlmostEqualNumber]].
243993
244114
  */
243994
244115
  isSameCurveAndFraction(other, fractionTol) {
243995
- return this.curve === other.curve && _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isAlmostEqualNumber(this.fraction, other.fraction, fractionTol);
244116
+ return this.curve === other.curve && _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.isAlmostEqualNumber(this.fraction, other.fraction, fractionTol);
243996
244117
  }
243997
244118
  /**
243998
244119
  * Transform the detail in place.
@@ -244128,6 +244249,64 @@ class CurveLocationDetailPair {
244128
244249
  tryTransformInPlace(transform) {
244129
244250
  return this.detailA.tryTransformInPlace(transform) && this.detailB.tryTransformInPlace(transform);
244130
244251
  }
244252
+ /**
244253
+ * Return a pair comparator useful for sorting an array of detail pairs by their fractions.
244254
+ * * Comparison assumes detailA curves are the same and detailB curves are the same.
244255
+ * * Comparison checks for equality of pair fractions, then of pair points, then sorts by detailA.fraction, then detailB.fraction.
244256
+ * @param fractionTol tolerance for comparing fractions. Default value [[Geometry.smallFraction]].
244257
+ * @param pointTol tolerance for comparing points, used if fractions are distinct. Default value [[Geometry.smallMetricDistance]].
244258
+ * @param xyOnly whether to perform point comparisons in xy only. Default is false (compare 3D points).
244259
+ * @param equateClosedCurveFractions whether to equate fractions 0 and 1 for physically closed curves. Default is false.
244260
+ */
244261
+ static comparePairsByFractions(fractionTol = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallFraction, pointTol = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallMetricDistance, xyOnly = false, equateClosedCurveFractions = false) {
244262
+ return (p0, p1) => {
244263
+ (0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.assert)(() => p0.detailA.curve === p1.detailA.curve && p0.detailB.curve === p1.detailB.curve, "pairs are compatible");
244264
+ const curveA = p0.detailA.curve;
244265
+ const curveB = p0.detailB.curve;
244266
+ let fraction0A = p0.detailA.fraction;
244267
+ let fraction0B = p0.detailB.fraction;
244268
+ let fraction1A = p1.detailA.fraction;
244269
+ let fraction1B = p1.detailB.fraction;
244270
+ if (equateClosedCurveFractions) {
244271
+ if (curveA?.isPhysicallyClosedCurve(pointTol, xyOnly)) {
244272
+ if (_Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.isAlmostEqualEitherNumber(p0.detailA.fraction, 0, 1, fractionTol))
244273
+ fraction0A = 0;
244274
+ if (_Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.isAlmostEqualEitherNumber(p1.detailA.fraction, 0, 1, fractionTol))
244275
+ fraction1A = 0;
244276
+ }
244277
+ if (curveB?.isPhysicallyClosedCurve(pointTol, xyOnly)) {
244278
+ if (_Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.isAlmostEqualEitherNumber(p0.detailB.fraction, 0, 1, fractionTol))
244279
+ fraction0B = 0;
244280
+ if (_Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.isAlmostEqualEitherNumber(p1.detailB.fraction, 0, 1, fractionTol))
244281
+ fraction1B = 0;
244282
+ }
244283
+ }
244284
+ const sameFractionsA = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.isAlmostEqualNumber(fraction0A, fraction1A, fractionTol);
244285
+ if (sameFractionsA && _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.isAlmostEqualNumber(fraction0B, fraction1B, fractionTol))
244286
+ return 0;
244287
+ const samePointsA = xyOnly ? p0.detailA.point.isAlmostEqualXY(p1.detailA.point, pointTol) : p0.detailA.point.isAlmostEqual(p1.detailA.point, pointTol);
244288
+ if (samePointsA && (xyOnly ? p0.detailB.point.isAlmostEqualXY(p1.detailB.point, pointTol) : p0.detailB.point.isAlmostEqual(p1.detailB.point, pointTol)))
244289
+ return 0;
244290
+ return sameFractionsA ? fraction0B - fraction1B : fraction0A - fraction1A;
244291
+ };
244292
+ }
244293
+ /**
244294
+ * Return a pair comparator useful for sorting an array of detail pairs by their points.
244295
+ * * Comparison sorts the points lexicographically, `detailA.point` first, then `detailB.point`.
244296
+ * @param pointTol tolerance for comparing points. Default value [[Geometry.smallMetricDistance]].
244297
+ * @param xyOnly whether to perform point comparisons in xy only. Default is false (compare 3D points).
244298
+ */
244299
+ static comparePairsByPoints(pointTol = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallMetricDistance, xyOnly = false) {
244300
+ return (p0, p1) => {
244301
+ const comparePoints = xyOnly ? _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.compareXY(pointTol) : _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.compareXYZ(pointTol);
244302
+ const compareA = comparePoints(p0.detailA.point, p1.detailA.point);
244303
+ const compareB = comparePoints(p0.detailB.point, p1.detailB.point);
244304
+ const samePointsA = compareA === 0;
244305
+ if (samePointsA && compareB === 0)
244306
+ return 0;
244307
+ return samePointsA ? compareB : compareA;
244308
+ };
244309
+ }
244131
244310
  }
244132
244311
  /**
244133
244312
  * Data bundle for a pair of arrays of CurveLocationDetail structures.
@@ -245081,11 +245260,11 @@ class CurvePrimitive extends _GeometryQuery__WEBPACK_IMPORTED_MODULE_1__.Geometr
245081
245260
  }
245082
245261
  /**
245083
245262
  * Attach StrokeCountMap structure to this primitive (and recursively to any children)
245084
- * * Base class implementation (here) gets the simple count from computeStrokeCountForOptions and attaches it.
245085
- * * LineString3d, arc3d, BezierCurve3d, BezierCurve3dH accept that default.
245086
- * * Subdivided primitives (linestring, bspline curve) implement themselves and attach a StrokeCountMap containing the
245263
+ * * Base class implementation (here) gets the simple count from [[computeStrokeCountForOptions]] and attaches it.
245264
+ * * [[LineString3d]], [[Arc3d]], [[BezierCurve3d]], [[BezierCurve3dH]] accept that default.
245265
+ * * Subdivided primitives ([[LineString3d]], [[BSplineCurve3d]]) implement themselves and attach a StrokeCountMap containing the
245087
245266
  * total count, and also containing an array of StrokeCountMap per component.
245088
- * * For CurvePrimitiveWithDistanceIndex, the top level gets (only) a total count, and each child gets
245267
+ * * For [[CurveChainWithDistanceIndex]], the top level gets (only) a total count, and each child gets
245089
245268
  * its own StrokeCountMap with appropriate structure.
245090
245269
  * @param options StrokeOptions that determine count
245091
245270
  * @param parentStrokeMap optional map from parent. Its count, curveLength, and a1 values are increased with count
@@ -245099,11 +245278,11 @@ class CurvePrimitive extends _GeometryQuery__WEBPACK_IMPORTED_MODULE_1__.Geometr
245099
245278
  }
245100
245279
  /**
245101
245280
  * Evaluate strokes at fractions indicated in a StrokeCountMap.
245102
- * * Base class implementation (here) gets the simple count from computeStrokeCountForOptions and strokes at
245281
+ * * Base class implementation (here) gets the simple count from [[computeStrokeCountForOptions]] and strokes at
245103
245282
  * uniform fractions.
245104
- * * LineString3d, arc3d, BezierCurve3d, BezierCurve3dH accept that default.
245105
- * * Subdivided primitives (linestring, bspline curve) implement themselves and evaluate within components.
245106
- * * CurvePrimitiveWithDistanceIndex recurses to its children.
245283
+ * * [[LineString3d]], [[Arc3d]], [[BezierCurve3d]], [[BezierCurve3dH]] accept that default.
245284
+ * * Subdivided primitives ([[LineString3d]], [[BSplineCurve3d]]) implement themselves and evaluate within components.
245285
+ * * [[CurveChainWithDistanceIndex]] recurses to its children.
245107
245286
  * * if packedFraction and packedDerivative arrays are present in the LineString3d, fill them.
245108
245287
  * @param map = stroke count data.
245109
245288
  * @param linestring = receiver linestring.
@@ -245134,7 +245313,7 @@ class CurvePrimitive extends _GeometryQuery__WEBPACK_IMPORTED_MODULE_1__.Geometr
245134
245313
  * Return an array containing only the curve primitives.
245135
245314
  * * This DEFAULT implementation simply pushes `this` to the collectorArray.
245136
245315
  * @param collectorArray array to receive primitives (pushed -- the array is not cleared)
245137
- * @param smallestPossiblePrimitives if true, a [[CurvePrimitiveWithDistanceIndex]] recurses on its (otherwise hidden)
245316
+ * @param smallestPossiblePrimitives if true, a [[CurveChainWithDistanceIndex]] recurses on its (otherwise hidden)
245138
245317
  * children. If false, it returns only itself.
245139
245318
  * @param explodeLinestrings if true, push a [[LineSegment3d]] for each segment of a [[LineString3d]]. If false,
245140
245319
  * push only the [[LineString3d]].
@@ -245147,8 +245326,9 @@ class CurvePrimitive extends _GeometryQuery__WEBPACK_IMPORTED_MODULE_1__.Geometr
245147
245326
  * * This DEFAULT implementation captures the optional collector and calls [[collectCurvePrimitivesGo]].
245148
245327
  * @param collectorArray optional array to receive primitives. If present, new primitives are ADDED (without
245149
245328
  * clearing the array.)
245150
- * @param smallestPossiblePrimitives if false, CurvePrimitiveWithDistanceIndex returns only itself. If true,
245151
- * it recurses to its (otherwise hidden) children.
245329
+ * @param smallestPossiblePrimitives if false (default), a [[CurveChainWithDistanceIndex]] returns only itself;
245330
+ * otherwise, it recurses to its (otherwise hidden) children.
245331
+ * @param explodeLinestrings whether to return [[LineSegment3d]]s for a [[LineString3d]] (default false).
245152
245332
  */
245153
245333
  collectCurvePrimitives(collectorArray, smallestPossiblePrimitives = false, explodeLinestrings = false) {
245154
245334
  const results = collectorArray === undefined ? [] : collectorArray;
@@ -250283,9 +250463,9 @@ __webpack_require__.r(__webpack_exports__);
250283
250463
  /* harmony import */ var _geometry3d_IndexedXYZCollection__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../geometry3d/IndexedXYZCollection */ "../../core/geometry/lib/esm/geometry3d/IndexedXYZCollection.js");
250284
250464
  /* harmony import */ var _geometry3d_Point3dArrayCarrier__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ../geometry3d/Point3dArrayCarrier */ "../../core/geometry/lib/esm/geometry3d/Point3dArrayCarrier.js");
250285
250465
  /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
250286
- /* harmony import */ var _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ../geometry3d/PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
250466
+ /* harmony import */ var _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ../geometry3d/PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
250287
250467
  /* harmony import */ var _geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ../geometry3d/PolylineCompressionByEdgeOffset */ "../../core/geometry/lib/esm/geometry3d/PolylineCompressionByEdgeOffset.js");
250288
- /* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
250468
+ /* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
250289
250469
  /* harmony import */ var _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../geometry3d/Ray3d */ "../../core/geometry/lib/esm/geometry3d/Ray3d.js");
250290
250470
  /* harmony import */ var _geometry3d_SortablePolygon__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ../geometry3d/SortablePolygon */ "../../core/geometry/lib/esm/geometry3d/SortablePolygon.js");
250291
250471
  /* harmony import */ var _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ../geometry3d/Transform */ "../../core/geometry/lib/esm/geometry3d/Transform.js");
@@ -250293,18 +250473,19 @@ __webpack_require__.r(__webpack_exports__);
250293
250473
  /* harmony import */ var _polyface_PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../polyface/PolyfaceBuilder */ "../../core/geometry/lib/esm/polyface/PolyfaceBuilder.js");
250294
250474
  /* harmony import */ var _topology_Graph__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../topology/Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
250295
250475
  /* harmony import */ var _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../topology/HalfEdgeGraphSearch */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphSearch.js");
250296
- /* harmony import */ var _topology_Merging__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ../topology/Merging */ "../../core/geometry/lib/esm/topology/Merging.js");
250476
+ /* harmony import */ var _topology_Merging__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! ../topology/Merging */ "../../core/geometry/lib/esm/topology/Merging.js");
250297
250477
  /* harmony import */ var _topology_Triangulation__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../topology/Triangulation */ "../../core/geometry/lib/esm/topology/Triangulation.js");
250298
250478
  /* harmony import */ var _CurveCollection__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./CurveCollection */ "../../core/geometry/lib/esm/curve/CurveCollection.js");
250299
- /* harmony import */ var _CurveCurve__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./CurveCurve */ "../../core/geometry/lib/esm/curve/CurveCurve.js");
250479
+ /* harmony import */ var _CurveCurve__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./CurveCurve */ "../../core/geometry/lib/esm/curve/CurveCurve.js");
250480
+ /* harmony import */ var _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ./CurveLocationDetail */ "../../core/geometry/lib/esm/curve/CurveLocationDetail.js");
250300
250481
  /* harmony import */ var _CurveOps__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./CurveOps */ "../../core/geometry/lib/esm/curve/CurveOps.js");
250301
250482
  /* harmony import */ var _CurvePrimitive__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./CurvePrimitive */ "../../core/geometry/lib/esm/curve/CurvePrimitive.js");
250302
250483
  /* harmony import */ var _CurveWireMomentsXYZ__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./CurveWireMomentsXYZ */ "../../core/geometry/lib/esm/curve/CurveWireMomentsXYZ.js");
250303
- /* harmony import */ var _GeometryQuery__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ./GeometryQuery */ "../../core/geometry/lib/esm/curve/GeometryQuery.js");
250484
+ /* harmony import */ var _GeometryQuery__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ./GeometryQuery */ "../../core/geometry/lib/esm/curve/GeometryQuery.js");
250304
250485
  /* harmony import */ var _internalContexts_ChainCollectorContext__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./internalContexts/ChainCollectorContext */ "../../core/geometry/lib/esm/curve/internalContexts/ChainCollectorContext.js");
250305
250486
  /* harmony import */ var _internalContexts_PolygonOffsetContext__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./internalContexts/PolygonOffsetContext */ "../../core/geometry/lib/esm/curve/internalContexts/PolygonOffsetContext.js");
250306
- /* harmony import */ var _internalContexts_TransferWithSplitArcs__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ./internalContexts/TransferWithSplitArcs */ "../../core/geometry/lib/esm/curve/internalContexts/TransferWithSplitArcs.js");
250307
- /* harmony import */ var _LineSegment3d__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
250487
+ /* harmony import */ var _internalContexts_TransferWithSplitArcs__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./internalContexts/TransferWithSplitArcs */ "../../core/geometry/lib/esm/curve/internalContexts/TransferWithSplitArcs.js");
250488
+ /* harmony import */ var _LineSegment3d__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
250308
250489
  /* harmony import */ var _LineString3d__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
250309
250490
  /* harmony import */ var _Loop__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
250310
250491
  /* harmony import */ var _OffsetOptions__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./OffsetOptions */ "../../core/geometry/lib/esm/curve/OffsetOptions.js");
@@ -250363,6 +250544,7 @@ __webpack_require__.r(__webpack_exports__);
250363
250544
 
250364
250545
 
250365
250546
 
250547
+
250366
250548
 
250367
250549
 
250368
250550
  /**
@@ -251062,27 +251244,113 @@ class RegionOps {
251062
251244
  }
251063
251245
  return _geometry3d_SortablePolygon__WEBPACK_IMPORTED_MODULE_33__.SortablePolygon.sortAsAnyRegion(loopAndArea);
251064
251246
  }
251247
+ /**
251248
+ * Simplify the graph by removing bridge edges that do not serve to connect inner and outer loops.
251249
+ * * If edgeTags are `CurveLocationDetail`s, e.g., as set by `PlanarSubdivision.assembleHalfEdgeGraph`, attempt to heal edges split by removed bridge edges.
251250
+ * @param graph half edges to process.
251251
+ * @param isBridgeEdge optional function to identify a bridge edge. Default looks for `HalfEdgeMask.BRIDGE_EDGE`.
251252
+ * @param faceToArea optional function to compute face area. Default is `HalfEdgeGraphSearch.signedFaceArea`.
251253
+ * @returns the number of extraneous bridge edges removed from the graph.
251254
+ * @internal
251255
+ */
251256
+ static removeExtraneousBridgeEdges(graph, isBridgeEdge, faceToArea) {
251257
+ const toHeal = [];
251258
+ const interiorBridges = [];
251259
+ if (!faceToArea)
251260
+ faceToArea = (node) => _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_17__.HalfEdgeGraphSearch.signedFaceArea(node);
251261
+ if (!isBridgeEdge)
251262
+ isBridgeEdge = (node) => node.isMaskSet(_topology_Graph__WEBPACK_IMPORTED_MODULE_15__.HalfEdgeMask.BRIDGE_EDGE);
251263
+ // isolate dangling bridges, bridges separating different faces, and "exterior" bridges in the negative area face
251264
+ graph.announceEdges((_g, node) => {
251265
+ if (isBridgeEdge(node)) {
251266
+ if (node.isDangling || node.edgeMate.isDangling || !node.findAroundFace(node.edgeMate) || faceToArea(node) < 0.0) {
251267
+ toHeal.push(node.vertexSuccessor);
251268
+ toHeal.push(node.edgeMate.vertexSuccessor);
251269
+ node.isolateEdge();
251270
+ }
251271
+ else {
251272
+ interiorBridges.push(node);
251273
+ }
251274
+ }
251275
+ return true;
251276
+ });
251277
+ // Relies only on face loop orientation. Doesn't use static HalfEdgeMasks!
251278
+ const isBoundaryEdge = (node) => {
251279
+ if (faceToArea(node) < 0.0)
251280
+ return true; // exterior face
251281
+ if (node.findAroundFace(node.edgeMate))
251282
+ return false; // interior washer face
251283
+ return faceToArea(node.edgeMate) < 0.0; // adjacent to exterior face
251284
+ };
251285
+ // All bridges in the negative area face were isolated, but this may have promoted other bridges to the
251286
+ // negative area face. Keep isolating these bridge edges until none remain.
251287
+ let numIsolatedThisPass;
251288
+ do {
251289
+ numIsolatedThisPass = 0;
251290
+ for (const node of interiorBridges) {
251291
+ if (!node.isIsolatedEdge && isBoundaryEdge(node)) {
251292
+ toHeal.push(node.vertexSuccessor);
251293
+ toHeal.push(node.edgeMate.vertexSuccessor);
251294
+ node.isolateEdge();
251295
+ numIsolatedThisPass++;
251296
+ }
251297
+ }
251298
+ } while (numIsolatedThisPass > 0);
251299
+ // lambda to extend the detail interval on a side of a healed edge
251300
+ const mergeDetails = (he, newFraction, newPoint) => {
251301
+ if (he && he.edgeTag instanceof _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_34__.CurveLocationDetail && he.sortData !== undefined && newFraction !== undefined && newPoint) {
251302
+ if (he.sortData > 0)
251303
+ he.edgeTag.captureFraction1Point1(newFraction, newPoint);
251304
+ else
251305
+ he.edgeTag.captureFractionPoint(newFraction, newPoint);
251306
+ }
251307
+ };
251308
+ // At this point all removable bridges are isolated. Clean up their original vertex loops, if possible.
251309
+ for (const doomedA of toHeal) {
251310
+ const doomedB = doomedA.vertexSuccessor;
251311
+ if ( // are the geometries mergeable?
251312
+ doomedA !== doomedB &&
251313
+ doomedA.edgeTag instanceof _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_34__.CurveLocationDetail && doomedA.sortData !== undefined &&
251314
+ doomedB.edgeTag instanceof _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_34__.CurveLocationDetail && doomedB.sortData !== undefined &&
251315
+ doomedA.edgeTag.curve === doomedB.edgeTag.curve &&
251316
+ doomedA.edgeTag.isInterval() && doomedB.edgeTag.isInterval() &&
251317
+ doomedA.sortData * doomedB.sortData < 0 &&
251318
+ ((doomedA.sortData > 0 && _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSmallRelative(doomedA.edgeTag.fraction - doomedB.edgeTag.fraction1)) ||
251319
+ (doomedA.sortData < 0 && _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSmallRelative(doomedA.edgeTag.fraction1 - doomedB.edgeTag.fraction)))) {
251320
+ const survivorA = _topology_Graph__WEBPACK_IMPORTED_MODULE_15__.HalfEdge.healEdge(doomedA, false);
251321
+ if (survivorA) {
251322
+ const endFractionA = (doomedA.sortData > 0) ? doomedA.edgeTag.fraction1 : doomedA.edgeTag.fraction;
251323
+ const endPointA = (doomedA.sortData > 0) ? doomedA.edgeTag.point1 : doomedA.edgeTag.point;
251324
+ mergeDetails(survivorA, endFractionA, endPointA);
251325
+ const endFractionB = (doomedB.sortData > 0) ? doomedB.edgeTag.fraction1 : doomedB.edgeTag.fraction;
251326
+ const endPointB = (doomedB.sortData > 0) ? doomedB.edgeTag.point1 : doomedB.edgeTag.point;
251327
+ mergeDetails(survivorA.edgeMate, endFractionB, endPointB);
251328
+ }
251329
+ }
251330
+ }
251331
+ return graph.deleteIsolatedEdges();
251332
+ }
251065
251333
  /**
251066
251334
  * Collect inputs that are nominally closed: regions, and physically closed curves.
251067
251335
  * * Physically closed input curves are each returned wrapped in a Loop to facilitate xy-algorithms,
251068
251336
  * but outside this limited context, these Loops only makes sense if they are planar.
251337
+ * @param curves inputs
251338
+ * @param openCurves optional array to receive open input curves that were not returned as regions.
251339
+ * @param tolerance optional distance tolerance for determining physical closure. Default is [[Geometry.smallMetricDistance]].
251069
251340
  */
251070
- static collectRegionsAndClosedPrimitives(curves, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance) {
251341
+ static collectRegionsAndClosedPrimitives(curves, openCurves, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance) {
251071
251342
  const regions = [];
251072
251343
  if (!Array.isArray(curves))
251073
251344
  curves = [curves];
251074
251345
  for (const curve of curves) {
251075
- if (curve instanceof _Loop__WEBPACK_IMPORTED_MODULE_8__.Loop || curve instanceof _ParityRegion__WEBPACK_IMPORTED_MODULE_9__.ParityRegion || curve instanceof _UnionRegion__WEBPACK_IMPORTED_MODULE_14__.UnionRegion) {
251346
+ if (curve instanceof _Loop__WEBPACK_IMPORTED_MODULE_8__.Loop || curve instanceof _ParityRegion__WEBPACK_IMPORTED_MODULE_9__.ParityRegion || curve instanceof _UnionRegion__WEBPACK_IMPORTED_MODULE_14__.UnionRegion)
251076
251347
  regions.push(curve);
251077
- }
251078
- else if (curve instanceof _Path__WEBPACK_IMPORTED_MODULE_24__.Path) {
251079
- if (curve.isPhysicallyClosedCurve(tolerance))
251080
- regions.push(_Loop__WEBPACK_IMPORTED_MODULE_8__.Loop.create(...curve.children));
251081
- }
251082
- else if (curve instanceof _CurvePrimitive__WEBPACK_IMPORTED_MODULE_27__.CurvePrimitive) {
251083
- if (curve.isPhysicallyClosedCurve(tolerance))
251084
- regions.push(_Loop__WEBPACK_IMPORTED_MODULE_8__.Loop.create(curve));
251085
- }
251348
+ else if (curve instanceof _Path__WEBPACK_IMPORTED_MODULE_24__.Path && curve.isPhysicallyClosedCurve(tolerance))
251349
+ regions.push(_Loop__WEBPACK_IMPORTED_MODULE_8__.Loop.create(...curve.children));
251350
+ else if (curve instanceof _CurvePrimitive__WEBPACK_IMPORTED_MODULE_27__.CurvePrimitive && curve.isPhysicallyClosedCurve(tolerance))
251351
+ regions.push(_Loop__WEBPACK_IMPORTED_MODULE_8__.Loop.create(curve));
251352
+ else if (openCurves)
251353
+ openCurves.push(curve);
251086
251354
  }
251087
251355
  return regions;
251088
251356
  }
@@ -251092,9 +251360,9 @@ class RegionOps {
251092
251360
  * * "Holes" implied/bounded by inputs are _not_ preserved/discovered in output; in particular [[ParityRegion]]
251093
251361
  * hole loops are treated like any other positive area loops.
251094
251362
  * * A common use case of this method is to assemble the bounding negative-area "exterior" loop for each connected
251095
- * component of input curves. Passing `addBridges = true` decreases the number of connected components for nested
251096
- * input [[Loop]]s, and thus increases the likelihood of returning exactly one exterior loop. (This is why the
251097
- * default value for `addBridges` is `true`.)
251363
+ * component of input curves. Passing addBridges = true adds "bridge" segments to connect unconnected input [[Loops]]s
251364
+ * and thereby increases the likelihood that a single connected component is returned. (This is why the default value
251365
+ * for addBridges is true.)
251098
251366
  * @param curvesAndRegions Any collection of curves. Each [[AnyRegion]] contributes its children _stripped of
251099
251367
  * parity context_.
251100
251368
  * @param tolerance optional distance tolerance for coincidence. Default is [[Geometry.smallMetricDistance]].
@@ -251110,24 +251378,33 @@ class RegionOps {
251110
251378
  */
251111
251379
  static constructAllXYRegionLoops(curvesAndRegions, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance, addBridges = true) {
251112
251380
  let primitives = RegionOps.collectCurvePrimitives(curvesAndRegions, undefined, true, true);
251113
- primitives = _internalContexts_TransferWithSplitArcs__WEBPACK_IMPORTED_MODULE_34__.TransferWithSplitArcs.clone(_CurveCollection__WEBPACK_IMPORTED_MODULE_25__.BagOfCurves.create(...primitives)).children;
251381
+ primitives = _internalContexts_TransferWithSplitArcs__WEBPACK_IMPORTED_MODULE_35__.TransferWithSplitArcs.clone(_CurveCollection__WEBPACK_IMPORTED_MODULE_25__.BagOfCurves.create(...primitives)).children;
251114
251382
  const range = this.curveArrayRange(primitives);
251115
251383
  const areaTol = this.computeXYAreaTolerance(range, tolerance);
251116
- if (addBridges) { // generate a temp graph to extract its bridge edges
251384
+ let hasOpenCurve = false;
251385
+ if (addBridges) { // generate a temp graph from ONLY the closed inputs to extract its bridge edges
251117
251386
  const context = _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__.RegionBooleanContext.create(_RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__.RegionGroupOpType.Union, _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__.RegionGroupOpType.Union);
251118
- const regions = this.collectRegionsAndClosedPrimitives(curvesAndRegions, tolerance);
251387
+ const openCurves = [];
251388
+ const regions = this.collectRegionsAndClosedPrimitives(curvesAndRegions, openCurves, tolerance);
251389
+ hasOpenCurve = openCurves.length > 0;
251119
251390
  if (regions.length > 0) {
251120
251391
  context.addMembers(regions, undefined);
251121
251392
  context.annotateAndMergeCurvesInGraph(tolerance);
251122
251393
  context.graph.announceEdges((_graph, edge) => {
251123
- if (edge.isMaskSet(_topology_Graph__WEBPACK_IMPORTED_MODULE_15__.HalfEdgeMask.BRIDGE_EDGE))
251124
- primitives.push(_LineSegment3d__WEBPACK_IMPORTED_MODULE_35__.LineSegment3d.create(edge.getPoint3d(), edge.faceSuccessor.getPoint3d()));
251394
+ if (edge.isMaskSet(_topology_Graph__WEBPACK_IMPORTED_MODULE_15__.HalfEdgeMask.BRIDGE_EDGE)) {
251395
+ // ensure the bridge edge roundtrips thru assembleHalfEdgeGraph so that we can filter it later if necessary
251396
+ const bridgeSegment = _LineSegment3d__WEBPACK_IMPORTED_MODULE_36__.LineSegment3d.create(edge.getPoint3d(), edge.faceSuccessor.getPoint3d());
251397
+ bridgeSegment.parent = new _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__.RegionGroupMember(bridgeSegment, context.extraGeometry);
251398
+ primitives.push(bridgeSegment);
251399
+ }
251125
251400
  return true;
251126
251401
  });
251127
251402
  }
251128
251403
  }
251129
- const intersections = _CurveCurve__WEBPACK_IMPORTED_MODULE_36__.CurveCurve.allIntersectionsAmongPrimitivesXY(primitives, tolerance);
251404
+ const intersections = _CurveCurve__WEBPACK_IMPORTED_MODULE_37__.CurveCurve.allIntersectionsAmongPrimitivesXY(primitives, tolerance);
251130
251405
  const graph = _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_16__.PlanarSubdivision.assembleHalfEdgeGraph(primitives, intersections, tolerance);
251406
+ if (addBridges && hasOpenCurve)
251407
+ RegionOps.removeExtraneousBridgeEdges(graph);
251131
251408
  return _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_16__.PlanarSubdivision.collectSignedLoopSetsInHalfEdgeGraph(graph, areaTol);
251132
251409
  }
251133
251410
  /**
@@ -251184,12 +251461,12 @@ class RegionOps {
251184
251461
  * @param worldToLocal transform to apply to data before computing its range
251185
251462
  */
251186
251463
  static curveArrayRange(data, worldToLocal) {
251187
- const range = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_37__.Range3d.create();
251188
- if (data instanceof _GeometryQuery__WEBPACK_IMPORTED_MODULE_38__.GeometryQuery)
251464
+ const range = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_38__.Range3d.create();
251465
+ if (data instanceof _GeometryQuery__WEBPACK_IMPORTED_MODULE_39__.GeometryQuery)
251189
251466
  data.extendRange(range, worldToLocal);
251190
251467
  else if (Array.isArray(data)) {
251191
251468
  for (const c of data) {
251192
- if (c instanceof _GeometryQuery__WEBPACK_IMPORTED_MODULE_38__.GeometryQuery)
251469
+ if (c instanceof _GeometryQuery__WEBPACK_IMPORTED_MODULE_39__.GeometryQuery)
251193
251470
  c.extendRange(range, worldToLocal);
251194
251471
  else if (c instanceof _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d)
251195
251472
  range.extendPoint(c, worldToLocal);
@@ -251225,7 +251502,7 @@ class RegionOps {
251225
251502
  for (const polygon of polygons)
251226
251503
  writablePolygons.push(_geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_18__.GrowableXYZArray.create(polygon));
251227
251504
  }
251228
- const sortedPolygons = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_39__.PolygonOps.sortOuterAndHoleLoopsXY(writablePolygons);
251505
+ const sortedPolygons = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_40__.PolygonOps.sortOuterAndHoleLoopsXY(writablePolygons);
251229
251506
  if (sortedPolygons.length === 1) { // below requires exactly one outer loop!
251230
251507
  if (graph = _topology_Triangulation__WEBPACK_IMPORTED_MODULE_11__.Triangulator.createTriangulatedGraphFromLoops(sortedPolygons[0]))
251231
251508
  _topology_Triangulation__WEBPACK_IMPORTED_MODULE_11__.Triangulator.flipTriangles(graph);
@@ -251308,7 +251585,7 @@ class RegionOps {
251308
251585
  if (!graph)
251309
251586
  return undefined;
251310
251587
  if (options?.maximizeConvexFacets)
251311
- _topology_Merging__WEBPACK_IMPORTED_MODULE_40__.HalfEdgeGraphOps.expandConvexFaces(graph);
251588
+ _topology_Merging__WEBPACK_IMPORTED_MODULE_41__.HalfEdgeGraphOps.expandConvexFaces(graph);
251312
251589
  return _polyface_PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_12__.PolyfaceBuilder.graphToPolyface(graph, options);
251313
251590
  }
251314
251591
  /**
@@ -251322,7 +251599,7 @@ class RegionOps {
251322
251599
  if (!graph)
251323
251600
  return undefined;
251324
251601
  if (maximize)
251325
- _topology_Merging__WEBPACK_IMPORTED_MODULE_40__.HalfEdgeGraphOps.expandConvexFaces(graph);
251602
+ _topology_Merging__WEBPACK_IMPORTED_MODULE_41__.HalfEdgeGraphOps.expandConvexFaces(graph);
251326
251603
  const convexPolygons = [];
251327
251604
  graph.announceFaceLoops((_graph, seed) => {
251328
251605
  if (!seed.isMaskSet(_topology_Graph__WEBPACK_IMPORTED_MODULE_15__.HalfEdgeMask.EXTERIOR))
@@ -251371,15 +251648,15 @@ __webpack_require__.r(__webpack_exports__);
251371
251648
  /* harmony import */ var _topology_Merging__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../topology/Merging */ "../../core/geometry/lib/esm/topology/Merging.js");
251372
251649
  /* harmony import */ var _topology_RegularizeFace__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../topology/RegularizeFace */ "../../core/geometry/lib/esm/topology/RegularizeFace.js");
251373
251650
  /* harmony import */ var _Arc3d__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./Arc3d */ "../../core/geometry/lib/esm/curve/Arc3d.js");
251374
- /* harmony import */ var _CurveCurve__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./CurveCurve */ "../../core/geometry/lib/esm/curve/CurveCurve.js");
251375
- /* harmony import */ var _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./CurveLocationDetail */ "../../core/geometry/lib/esm/curve/CurveLocationDetail.js");
251651
+ /* harmony import */ var _CurveCurve__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./CurveCurve */ "../../core/geometry/lib/esm/curve/CurveCurve.js");
251652
+ /* harmony import */ var _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./CurveLocationDetail */ "../../core/geometry/lib/esm/curve/CurveLocationDetail.js");
251376
251653
  /* harmony import */ var _GeometryQuery__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./GeometryQuery */ "../../core/geometry/lib/esm/curve/GeometryQuery.js");
251377
251654
  /* harmony import */ var _internalContexts_PlaneAltitudeRangeContext__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./internalContexts/PlaneAltitudeRangeContext */ "../../core/geometry/lib/esm/curve/internalContexts/PlaneAltitudeRangeContext.js");
251378
251655
  /* harmony import */ var _internalContexts_TransferWithSplitArcs__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./internalContexts/TransferWithSplitArcs */ "../../core/geometry/lib/esm/curve/internalContexts/TransferWithSplitArcs.js");
251379
251656
  /* harmony import */ var _LineSegment3d__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
251380
251657
  /* harmony import */ var _Loop__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
251381
251658
  /* harmony import */ var _ParityRegion__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./ParityRegion */ "../../core/geometry/lib/esm/curve/ParityRegion.js");
251382
- /* harmony import */ var _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./Query/PlanarSubdivision */ "../../core/geometry/lib/esm/curve/Query/PlanarSubdivision.js");
251659
+ /* harmony import */ var _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./Query/PlanarSubdivision */ "../../core/geometry/lib/esm/curve/Query/PlanarSubdivision.js");
251383
251660
  /* harmony import */ var _RegionOps__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./RegionOps */ "../../core/geometry/lib/esm/curve/RegionOps.js");
251384
251661
  /* harmony import */ var _UnionRegion__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./UnionRegion */ "../../core/geometry/lib/esm/curve/UnionRegion.js");
251385
251662
  /*---------------------------------------------------------------------------------------------
@@ -251884,94 +252161,6 @@ class RegionBooleanContext {
251884
252161
  this.extraGeometry.addMember(bridgeLine, true);
251885
252162
  }
251886
252163
  }
251887
- /**
251888
- * Simplify the graph by removing bridge edges that do not serve to connect inner and outer loops, i.e.:
251889
- * * the bridge edge is dangling
251890
- * * the bridge edge is adjacent to multiple faces
251891
- * * the bridge edge is adjacent to a negative area face
251892
- * @returns the number of extraneous bridge edges removed from the graph.
251893
- */
251894
- removeExtraneousBridgeEdges() {
251895
- const toHeal = [];
251896
- const interiorBridges = [];
251897
- // lambda test for boundary edge. Relies only on face loop orientation. Doesn't use HalfEdgeMasks!
251898
- const isExteriorEdge = (node) => {
251899
- if (this.faceAreaFunction(node) < 0.0)
251900
- return true;
251901
- if (!node.findAroundFace(node.edgeMate))
251902
- return this.faceAreaFunction(node.edgeMate) < 0.0;
251903
- return false;
251904
- };
251905
- // isolate dangling bridges, bridges separating different faces, and "exterior" bridges in the negative area face
251906
- this.graph.announceEdges((_graph, node) => {
251907
- if (node.edgeTag !== undefined) {
251908
- if (node.edgeTag instanceof _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_16__.CurveLocationDetail) {
251909
- if (node.edgeTag.curve) {
251910
- if (node.edgeTag.curve.parent instanceof RegionGroupMember) {
251911
- if (node.edgeTag.curve.parent.parentGroup === this.extraGeometry) {
251912
- if (node.isDangling || node.edgeMate.isDangling || !node.findAroundFace(node.edgeMate) || this.faceAreaFunction(node) < 0.0) {
251913
- toHeal.push(node.vertexSuccessor);
251914
- toHeal.push(node.edgeMate.vertexSuccessor);
251915
- node.isolateEdge();
251916
- }
251917
- else {
251918
- interiorBridges.push(node);
251919
- }
251920
- }
251921
- }
251922
- }
251923
- }
251924
- }
251925
- return true;
251926
- });
251927
- // At this point, all bridges that were exterior are isolated, but this may have caused formerly
251928
- // interior bridges to become exterior. Now we successively isolate exterior bridges until none remain.
251929
- let numIsolatedThisPass;
251930
- do {
251931
- numIsolatedThisPass = 0;
251932
- for (const node of interiorBridges) {
251933
- if (!node.isIsolatedEdge && isExteriorEdge(node)) {
251934
- toHeal.push(node.vertexSuccessor);
251935
- toHeal.push(node.edgeMate.vertexSuccessor);
251936
- node.isolateEdge();
251937
- numIsolatedThisPass++;
251938
- }
251939
- }
251940
- } while (numIsolatedThisPass > 0);
251941
- // lambda to extend the detail interval on a side of a healed edge
251942
- const mergeDetails = (he, newFraction, newPoint) => {
251943
- if (he && he.edgeTag instanceof _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_16__.CurveLocationDetail && he.sortData !== undefined && newFraction !== undefined && newPoint) {
251944
- if (he.sortData > 0)
251945
- he.edgeTag.captureFraction1Point1(newFraction, newPoint);
251946
- else
251947
- he.edgeTag.captureFractionPoint(newFraction, newPoint);
251948
- }
251949
- };
251950
- // At this point all removable bridges are isolated. Clean up their original vertex loops, if possible.
251951
- for (const doomedA of toHeal) {
251952
- const doomedB = doomedA.vertexSuccessor;
251953
- if ( // are the geometries mergeable?
251954
- doomedA !== doomedB &&
251955
- doomedA.edgeTag instanceof _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_16__.CurveLocationDetail && doomedA.sortData !== undefined &&
251956
- doomedB.edgeTag instanceof _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_16__.CurveLocationDetail && doomedB.sortData !== undefined &&
251957
- doomedA.edgeTag.curve === doomedB.edgeTag.curve &&
251958
- doomedA.edgeTag.isInterval() && doomedB.edgeTag.isInterval() &&
251959
- doomedA.sortData * doomedB.sortData < 0 &&
251960
- ((doomedA.sortData > 0 && _Geometry__WEBPACK_IMPORTED_MODULE_7__.Geometry.isSmallRelative(doomedA.edgeTag.fraction - doomedB.edgeTag.fraction1)) ||
251961
- (doomedA.sortData < 0 && _Geometry__WEBPACK_IMPORTED_MODULE_7__.Geometry.isSmallRelative(doomedA.edgeTag.fraction1 - doomedB.edgeTag.fraction)))) {
251962
- const survivorA = _topology_Graph__WEBPACK_IMPORTED_MODULE_0__.HalfEdge.healEdge(doomedA, false);
251963
- if (survivorA) {
251964
- const endFractionA = (doomedA.sortData > 0) ? doomedA.edgeTag.fraction1 : doomedA.edgeTag.fraction;
251965
- const endPointA = (doomedA.sortData > 0) ? doomedA.edgeTag.point1 : doomedA.edgeTag.point;
251966
- mergeDetails(survivorA, endFractionA, endPointA);
251967
- const endFractionB = (doomedB.sortData > 0) ? doomedB.edgeTag.fraction1 : doomedB.edgeTag.fraction;
251968
- const endPointB = (doomedB.sortData > 0) ? doomedB.edgeTag.point1 : doomedB.edgeTag.point;
251969
- mergeDetails(survivorA.edgeMate, endFractionB, endPointB);
251970
- }
251971
- }
251972
- }
251973
- return this.graph.deleteIsolatedEdges();
251974
- }
251975
252164
  /**
251976
252165
  * Markup and assembly steps for geometry in the RegionGroups.
251977
252166
  * * Annotate connection from group to curves.
@@ -251993,11 +252182,9 @@ class RegionBooleanContext {
251993
252182
  }
251994
252183
  }
251995
252184
  }
251996
- const intersections = _CurveCurve__WEBPACK_IMPORTED_MODULE_17__.CurveCurve.allIntersectionsAmongPrimitivesXY(allPrimitives, mergeTolerance);
251997
- const graph = _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_18__.PlanarSubdivision.assembleHalfEdgeGraph(allPrimitives, intersections, mergeTolerance);
251998
- this.graph = graph;
251999
- this.faceAreaFunction = faceAreaFromCurvedEdgeData;
252000
- this.removeExtraneousBridgeEdges();
252185
+ const intersections = _CurveCurve__WEBPACK_IMPORTED_MODULE_16__.CurveCurve.allIntersectionsAmongPrimitivesXY(allPrimitives, mergeTolerance);
252186
+ const graph = _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_17__.PlanarSubdivision.assembleHalfEdgeGraph(allPrimitives, intersections, mergeTolerance);
252187
+ _RegionOps__WEBPACK_IMPORTED_MODULE_1__.RegionOps.removeExtraneousBridgeEdges(this.graph = graph, undefined, this.faceAreaFunction = faceAreaFromCurvedEdgeData);
252001
252188
  }
252002
252189
  _announceFaceFunction;
252003
252190
  /**
@@ -252083,7 +252270,7 @@ class RegionBooleanContext {
252083
252270
  const data = node.edgeTag;
252084
252271
  if (data instanceof RegionGroupMember)
252085
252272
  return updateRegionGroupMemberState(data);
252086
- if (data instanceof _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_16__.CurveLocationDetail && data.curve) {
252273
+ if (data instanceof _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_18__.CurveLocationDetail && data.curve) {
252087
252274
  // We trust that the caller has linked from the graph node to a curve which has a RegionGroupMember as its parent.
252088
252275
  const member = data.curve.parent;
252089
252276
  if (member instanceof RegionGroupMember)
@@ -252194,7 +252381,7 @@ class GraphComponent {
252194
252381
  f.sumAroundFace(vertexFunction);
252195
252382
  }
252196
252383
  this.faceAreas.length = 0;
252197
- if (faceAreaFunction === faceAreaFromCurvedEdgeData && !this.faces.every((he) => he.edgeTag instanceof _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_16__.CurveLocationDetail))
252384
+ if (faceAreaFunction === faceAreaFromCurvedEdgeData && !this.faces.every((he) => he.edgeTag instanceof _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_18__.CurveLocationDetail))
252198
252385
  faceAreaFunction = undefined; // prerequisite CurveLocationDetails are absent, fall through to default
252199
252386
  if (!faceAreaFunction)
252200
252387
  faceAreaFunction = (node) => _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_4__.HalfEdgeGraphSearch.signedFaceArea(node); // polygon area
@@ -252262,14 +252449,21 @@ __webpack_require__.r(__webpack_exports__);
252262
252449
  * * Nearly all stroke and facet use cases will apply an angle tolerance.
252263
252450
  * * For curves, 15 degrees is typical
252264
252451
  * * For facets, 22.5 degrees is typical.
252265
- * * Halving the angle tolerance will (roughly) make curves get twice as many strokes, and surfaces get 4 times as many facets.
252266
- * * The angle tolerance has the useful property that its effect is independent of scale of that data. If data is suddenly scaled into millimeters rather than meters, the facet counts remain the same.
252452
+ * * Halving the angle tolerance will (roughly) make curves get twice as many strokes, and surfaces get 4 times as
252453
+ * many facets.
252454
+ * * The angle tolerance has the useful property that its effect is independent of scale of that data. If data is
252455
+ * suddenly scaled into millimeters rather than meters, the facet counts remain the same.
252267
252456
  * * When creating output for devices such as 3D printing will want a chord tolerance.
252268
- * * For graphics display, use an angle tolerance of around 15 degrees and an chord tolerance which is the size of several pixels.
252457
+ * * For graphics display, use an angle tolerance of around 15 degrees and an chord tolerance which is the size of
252458
+ * several pixels.
252269
252459
  * * Analysis meshes (e.g. Finite Elements) commonly need to apply maxEdgeLength.
252270
- * * Using maxEdgeLength for graphics probably produces too many facets. For example, it causes long cylinders to get many nearly-square facets instead of the small number of long quads usually used for graphics.
252271
- * * Facet tolerances are, as the Pirates' Code, guidelines, not absolute rules. Facet and stroke code may ignore tolerances in awkward situations.
252272
- * * If multiple tolerances are in effect, the actual count will usually be based on the one that demands the most strokes or facets, unless it is so high that it violates some upper limit on the number of facets on an arc or a section of a curve.
252460
+ * * Using maxEdgeLength for graphics probably produces too many facets. For example, it causes long cylinders to
252461
+ * get many nearly-square facets instead of the small number of long quads usually used for graphics.
252462
+ * * Facet tolerances are, as the Pirates' Code, guidelines, not absolute rules. Facet and stroke code may ignore
252463
+ * tolerances in awkward situations.
252464
+ * * If multiple tolerances are in effect, the actual count will usually be based on the one that demands the most
252465
+ * strokes or facets, unless it is so high that it violates some upper limit on the number of facets on an arc or a
252466
+ * section of a curve.
252273
252467
  * @public
252274
252468
  */
252275
252469
  class StrokeOptions {
@@ -252590,9 +252784,8 @@ __webpack_require__.r(__webpack_exports__);
252590
252784
  /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
252591
252785
  /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
252592
252786
  /* harmony import */ var _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../geometry3d/Ray3d */ "../../core/geometry/lib/esm/geometry3d/Ray3d.js");
252593
- /* harmony import */ var _numerics_Newton__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../numerics/Newton */ "../../core/geometry/lib/esm/numerics/Newton.js");
252594
- /* harmony import */ var _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../CurveLocationDetail */ "../../core/geometry/lib/esm/curve/CurveLocationDetail.js");
252595
- /* harmony import */ var _NewtonRtoRStrokeHandler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./NewtonRtoRStrokeHandler */ "../../core/geometry/lib/esm/curve/internalContexts/NewtonRtoRStrokeHandler.js");
252787
+ /* harmony import */ var _numerics_Newton__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../numerics/Newton */ "../../core/geometry/lib/esm/numerics/Newton.js");
252788
+ /* harmony import */ var _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../CurveLocationDetail */ "../../core/geometry/lib/esm/curve/CurveLocationDetail.js");
252596
252789
  /*---------------------------------------------------------------------------------------------
252597
252790
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
252598
252791
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -252606,12 +252799,11 @@ __webpack_require__.r(__webpack_exports__);
252606
252799
 
252607
252800
 
252608
252801
 
252609
-
252610
252802
  /**
252611
252803
  * Context for searching for the tangent(s) to a CurvePrimitive.
252612
252804
  * @internal
252613
252805
  */
252614
- class AnnounceTangentStrokeHandler extends _NewtonRtoRStrokeHandler__WEBPACK_IMPORTED_MODULE_1__.NewtonRtoRStrokeHandler {
252806
+ class AnnounceTangentStrokeHandler extends _numerics_Newton__WEBPACK_IMPORTED_MODULE_1__.NewtonRtoRStrokeHandler {
252615
252807
  _curve;
252616
252808
  _announceTangent;
252617
252809
  _spacePoint;
@@ -252641,7 +252833,7 @@ class AnnounceTangentStrokeHandler extends _NewtonRtoRStrokeHandler__WEBPACK_IMP
252641
252833
  this._distanceTolSquared = this._distanceTol * this._distanceTol;
252642
252834
  this._workRay = _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_4__.Ray3d.createZero();
252643
252835
  this.startCurvePrimitive(undefined);
252644
- this._newtonSolver = new _numerics_Newton__WEBPACK_IMPORTED_MODULE_5__.Newton1dUnboundedApproximateDerivative(this);
252836
+ this._newtonSolver = new _numerics_Newton__WEBPACK_IMPORTED_MODULE_1__.Newton1dUnboundedApproximateDerivative(this);
252645
252837
  }
252646
252838
  /** Specified by IStrokeHandler. */
252647
252839
  needPrimaryGeometryForStrokes() {
@@ -252674,7 +252866,7 @@ class AnnounceTangentStrokeHandler extends _NewtonRtoRStrokeHandler__WEBPACK_IMP
252674
252866
  cp = this._parentCurvePrimitive;
252675
252867
  if (this._curveMRU === cp && _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.isAlmostEqualOptional(this._fractionMRU, fraction, _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallFloatingPoint))
252676
252868
  return; // avoid announcing duplicate tangents in succession (e.g., at interior stroke point)
252677
- this._workDetail = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_6__.CurveLocationDetail.createCurveFractionPoint(cp, fraction, point, this._workDetail);
252869
+ this._workDetail = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetail.createCurveFractionPoint(cp, fraction, point, this._workDetail);
252678
252870
  this._announceTangent(this._workDetail);
252679
252871
  this._fractionMRU = fraction;
252680
252872
  this._curveMRU = cp;
@@ -252787,12 +252979,11 @@ __webpack_require__.r(__webpack_exports__);
252787
252979
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
252788
252980
  /* harmony export */ AppendPlaneIntersectionStrokeHandler: () => (/* binding */ AppendPlaneIntersectionStrokeHandler)
252789
252981
  /* harmony export */ });
252790
- /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
252982
+ /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
252791
252983
  /* harmony import */ var _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../geometry3d/Ray3d */ "../../core/geometry/lib/esm/geometry3d/Ray3d.js");
252792
- /* harmony import */ var _numerics_BezierPolynomials__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../numerics/BezierPolynomials */ "../../core/geometry/lib/esm/numerics/BezierPolynomials.js");
252793
- /* harmony import */ var _numerics_Newton__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../numerics/Newton */ "../../core/geometry/lib/esm/numerics/Newton.js");
252794
- /* harmony import */ var _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../CurveLocationDetail */ "../../core/geometry/lib/esm/curve/CurveLocationDetail.js");
252795
- /* harmony import */ var _NewtonRtoRStrokeHandler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./NewtonRtoRStrokeHandler */ "../../core/geometry/lib/esm/curve/internalContexts/NewtonRtoRStrokeHandler.js");
252984
+ /* harmony import */ var _numerics_BezierPolynomials__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../numerics/BezierPolynomials */ "../../core/geometry/lib/esm/numerics/BezierPolynomials.js");
252985
+ /* harmony import */ var _numerics_Newton__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../numerics/Newton */ "../../core/geometry/lib/esm/numerics/Newton.js");
252986
+ /* harmony import */ var _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../CurveLocationDetail */ "../../core/geometry/lib/esm/curve/CurveLocationDetail.js");
252796
252987
  /*---------------------------------------------------------------------------------------------
252797
252988
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
252798
252989
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -252805,12 +252996,11 @@ __webpack_require__.r(__webpack_exports__);
252805
252996
 
252806
252997
 
252807
252998
 
252808
-
252809
252999
  /**
252810
253000
  * Context for computing intersections of a CurvePrimitive with a plane.
252811
253001
  * @internal
252812
253002
  */
252813
- class AppendPlaneIntersectionStrokeHandler extends _NewtonRtoRStrokeHandler__WEBPACK_IMPORTED_MODULE_0__.NewtonRtoRStrokeHandler {
253003
+ class AppendPlaneIntersectionStrokeHandler extends _numerics_Newton__WEBPACK_IMPORTED_MODULE_0__.NewtonRtoRStrokeHandler {
252814
253004
  _curve;
252815
253005
  _plane;
252816
253006
  _intersections;
@@ -252839,7 +253029,7 @@ class AppendPlaneIntersectionStrokeHandler extends _NewtonRtoRStrokeHandler__WEB
252839
253029
  this._intersections = intersections;
252840
253030
  this.startCurvePrimitive(undefined);
252841
253031
  this._ray = _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_1__.Ray3d.createZero();
252842
- this._newtonSolver = new _numerics_Newton__WEBPACK_IMPORTED_MODULE_2__.Newton1dUnboundedApproximateDerivative(this);
253032
+ this._newtonSolver = new _numerics_Newton__WEBPACK_IMPORTED_MODULE_0__.Newton1dUnboundedApproximateDerivative(this);
252843
253033
  }
252844
253034
  startCurvePrimitive(curve) {
252845
253035
  this._curve = curve;
@@ -252856,7 +253046,7 @@ class AppendPlaneIntersectionStrokeHandler extends _NewtonRtoRStrokeHandler__WEB
252856
253046
  numStrokes = 1;
252857
253047
  const df = 1.0 / numStrokes;
252858
253048
  for (let i = 0; i <= numStrokes; i++) {
252859
- const fraction = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fraction0, i * df, fraction1);
253049
+ const fraction = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.interpolate(fraction0, i * df, fraction1);
252860
253050
  cp.fractionToPointAndDerivative(fraction, this._ray);
252861
253051
  this.announcePointTangent(this._ray.origin, fraction, this._ray.direction);
252862
253052
  }
@@ -252866,11 +253056,11 @@ class AppendPlaneIntersectionStrokeHandler extends _NewtonRtoRStrokeHandler__WEB
252866
253056
  const h1 = this._plane.altitude(point1);
252867
253057
  if (h0 * h1 > 0.0)
252868
253058
  return;
252869
- const fraction01 = _numerics_BezierPolynomials__WEBPACK_IMPORTED_MODULE_4__.Order2Bezier.solveCoffs(h0, h1);
253059
+ const fraction01 = _numerics_BezierPolynomials__WEBPACK_IMPORTED_MODULE_3__.Order2Bezier.solveCoffs(h0, h1);
252870
253060
  // let numIntersection = 0;
252871
253061
  if (fraction01 !== undefined) {
252872
253062
  // numIntersection++;
252873
- const fraction = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fraction0, fraction01, fraction1);
253063
+ const fraction = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.interpolate(fraction0, fraction01, fraction1);
252874
253064
  this._newtonSolver.setX(fraction);
252875
253065
  if (this._newtonSolver.runIterations()) {
252876
253066
  this.announceSolutionFraction(this._newtonSolver.getX());
@@ -252882,7 +253072,7 @@ class AppendPlaneIntersectionStrokeHandler extends _NewtonRtoRStrokeHandler__WEB
252882
253072
  const curve = this.effectiveCurve();
252883
253073
  if (curve) {
252884
253074
  this._ray = curve.fractionToPointAndDerivative(fraction, this._ray);
252885
- this._intersections.push(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetail.createCurveFractionPoint(curve, fraction, this._ray.origin));
253075
+ this._intersections.push(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetail.createCurveFractionPoint(curve, fraction, this._ray.origin));
252886
253076
  }
252887
253077
  }
252888
253078
  evaluate(fraction) {
@@ -252905,7 +253095,7 @@ class AppendPlaneIntersectionStrokeHandler extends _NewtonRtoRStrokeHandler__WEB
252905
253095
  if (this._functionB === 0)
252906
253096
  this.announceSolutionFraction(this._fractionB);
252907
253097
  if (this._functionA * this._functionB < 0) {
252908
- const fraction = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.inverseInterpolate(this._fractionA, this._functionA, this._fractionB, this._functionB);
253098
+ const fraction = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.inverseInterpolate(this._fractionA, this._functionA, this._fractionB, this._functionB);
252909
253099
  if (fraction) {
252910
253100
  this._newtonSolver.setX(fraction);
252911
253101
  if (this._newtonSolver.runIterations())
@@ -253288,11 +253478,10 @@ __webpack_require__.r(__webpack_exports__);
253288
253478
  /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
253289
253479
  /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
253290
253480
  /* harmony import */ var _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../geometry3d/Ray3d */ "../../core/geometry/lib/esm/geometry3d/Ray3d.js");
253291
- /* harmony import */ var _numerics_Newton__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../numerics/Newton */ "../../core/geometry/lib/esm/numerics/Newton.js");
253292
- /* harmony import */ var _numerics_SmallSystem__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../numerics/SmallSystem */ "../../core/geometry/lib/esm/numerics/SmallSystem.js");
253293
- /* harmony import */ var _CurveExtendMode__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../CurveExtendMode */ "../../core/geometry/lib/esm/curve/CurveExtendMode.js");
253294
- /* harmony import */ var _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../CurveLocationDetail */ "../../core/geometry/lib/esm/curve/CurveLocationDetail.js");
253295
- /* harmony import */ var _NewtonRtoRStrokeHandler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./NewtonRtoRStrokeHandler */ "../../core/geometry/lib/esm/curve/internalContexts/NewtonRtoRStrokeHandler.js");
253481
+ /* harmony import */ var _numerics_Newton__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../numerics/Newton */ "../../core/geometry/lib/esm/numerics/Newton.js");
253482
+ /* harmony import */ var _numerics_SmallSystem__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../numerics/SmallSystem */ "../../core/geometry/lib/esm/numerics/SmallSystem.js");
253483
+ /* harmony import */ var _CurveExtendMode__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../CurveExtendMode */ "../../core/geometry/lib/esm/curve/CurveExtendMode.js");
253484
+ /* harmony import */ var _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../CurveLocationDetail */ "../../core/geometry/lib/esm/curve/CurveLocationDetail.js");
253296
253485
  /*---------------------------------------------------------------------------------------------
253297
253486
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
253298
253487
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -253308,12 +253497,11 @@ __webpack_require__.r(__webpack_exports__);
253308
253497
 
253309
253498
 
253310
253499
 
253311
-
253312
253500
  /**
253313
253501
  * Context for searching for the closest point to a CurvePrimitive.
253314
253502
  * @internal
253315
253503
  */
253316
- class ClosestPointStrokeHandler extends _NewtonRtoRStrokeHandler__WEBPACK_IMPORTED_MODULE_1__.NewtonRtoRStrokeHandler {
253504
+ class ClosestPointStrokeHandler extends _numerics_Newton__WEBPACK_IMPORTED_MODULE_1__.NewtonRtoRStrokeHandler {
253317
253505
  _curve;
253318
253506
  _closestPoint;
253319
253507
  _spacePoint;
@@ -253342,7 +253530,7 @@ class ClosestPointStrokeHandler extends _NewtonRtoRStrokeHandler__WEBPACK_IMPORT
253342
253530
  this._extend = extend ?? false;
253343
253531
  this._xyOnly = xyOnly ?? false;
253344
253532
  this.startCurvePrimitive(undefined);
253345
- this._newtonSolver = new _numerics_Newton__WEBPACK_IMPORTED_MODULE_5__.Newton1dUnboundedApproximateDerivative(this);
253533
+ this._newtonSolver = new _numerics_Newton__WEBPACK_IMPORTED_MODULE_1__.Newton1dUnboundedApproximateDerivative(this);
253346
253534
  }
253347
253535
  claimResult() {
253348
253536
  if (this._closestPoint) {
@@ -253350,7 +253538,7 @@ class ClosestPointStrokeHandler extends _NewtonRtoRStrokeHandler__WEBPACK_IMPORT
253350
253538
  this._curve = this._closestPoint.curve;
253351
253539
  if (this._newtonSolver.runIterations()) {
253352
253540
  let fraction = this._newtonSolver.getX();
253353
- fraction = _CurveExtendMode__WEBPACK_IMPORTED_MODULE_6__.CurveExtendOptions.correctFraction(this._extend, fraction);
253541
+ fraction = _CurveExtendMode__WEBPACK_IMPORTED_MODULE_5__.CurveExtendOptions.correctFraction(this._extend, fraction);
253354
253542
  this.announceSolutionFraction(fraction);
253355
253543
  }
253356
253544
  }
@@ -253384,7 +253572,7 @@ class ClosestPointStrokeHandler extends _NewtonRtoRStrokeHandler__WEBPACK_IMPORT
253384
253572
  const distance = this._xyOnly ? this._spacePoint.distanceXY(point) : this._spacePoint.distance(point);
253385
253573
  if (this._closestPoint && distance > this._closestPoint.a)
253386
253574
  return;
253387
- this._closestPoint = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_7__.CurveLocationDetail.createCurveFractionPoint(cp, fraction, point, this._closestPoint);
253575
+ this._closestPoint = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_6__.CurveLocationDetail.createCurveFractionPoint(cp, fraction, point, this._closestPoint);
253388
253576
  this._closestPoint.a = distance;
253389
253577
  if (this._parentCurvePrimitive !== undefined)
253390
253578
  this._closestPoint.curve = this._parentCurvePrimitive;
@@ -253392,13 +253580,13 @@ class ClosestPointStrokeHandler extends _NewtonRtoRStrokeHandler__WEBPACK_IMPORT
253392
253580
  announceSegmentInterval(cp, point0, point1, _numStrokes, fraction0, fraction1) {
253393
253581
  let localFraction = 0;
253394
253582
  if (this._xyOnly)
253395
- localFraction = _numerics_SmallSystem__WEBPACK_IMPORTED_MODULE_8__.SmallSystem.lineSegment3dXYClosestPointUnbounded(point0, point1, this._spacePoint) ?? 0;
253583
+ localFraction = _numerics_SmallSystem__WEBPACK_IMPORTED_MODULE_7__.SmallSystem.lineSegment3dXYClosestPointUnbounded(point0, point1, this._spacePoint) ?? 0;
253396
253584
  else
253397
253585
  localFraction = this._spacePoint.fractionOfProjectionToLine(point0, point1, 0.0);
253398
253586
  // only consider segment extension at a parent curve endpoint, i.e. when fraction0 is 0 or fraction1 is 1
253399
- const extend0 = (fraction0 === 0) ? _CurveExtendMode__WEBPACK_IMPORTED_MODULE_6__.CurveExtendOptions.resolveVariantCurveExtendParameterToCurveExtendMode(this._extend, 0) : _CurveExtendMode__WEBPACK_IMPORTED_MODULE_6__.CurveExtendMode.None;
253400
- const extend1 = (fraction1 === 1) ? _CurveExtendMode__WEBPACK_IMPORTED_MODULE_6__.CurveExtendOptions.resolveVariantCurveExtendParameterToCurveExtendMode(this._extend, 1) : _CurveExtendMode__WEBPACK_IMPORTED_MODULE_6__.CurveExtendMode.None;
253401
- localFraction = _CurveExtendMode__WEBPACK_IMPORTED_MODULE_6__.CurveExtendOptions.correctFraction([extend0, extend1], localFraction);
253587
+ const extend0 = (fraction0 === 0) ? _CurveExtendMode__WEBPACK_IMPORTED_MODULE_5__.CurveExtendOptions.resolveVariantCurveExtendParameterToCurveExtendMode(this._extend, 0) : _CurveExtendMode__WEBPACK_IMPORTED_MODULE_5__.CurveExtendMode.None;
253588
+ const extend1 = (fraction1 === 1) ? _CurveExtendMode__WEBPACK_IMPORTED_MODULE_5__.CurveExtendOptions.resolveVariantCurveExtendParameterToCurveExtendMode(this._extend, 1) : _CurveExtendMode__WEBPACK_IMPORTED_MODULE_5__.CurveExtendMode.None;
253589
+ localFraction = _CurveExtendMode__WEBPACK_IMPORTED_MODULE_5__.CurveExtendOptions.correctFraction([extend0, extend1], localFraction);
253402
253590
  this._workPoint = point0.interpolate(localFraction, point1);
253403
253591
  const globalFraction = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.interpolate(fraction0, localFraction, fraction1);
253404
253592
  this.announceCandidate(cp, globalFraction, this._workPoint);
@@ -253545,21 +253733,25 @@ __webpack_require__.r(__webpack_exports__);
253545
253733
  /* harmony export */ CurveCurveCloseApproachXY: () => (/* binding */ CurveCurveCloseApproachXY)
253546
253734
  /* harmony export */ });
253547
253735
  /* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
253548
- /* harmony import */ var _bspline_BSplineCurve__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../bspline/BSplineCurve */ "../../core/geometry/lib/esm/bspline/BSplineCurve.js");
253736
+ /* harmony import */ var _bspline_BSplineCurve__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../../bspline/BSplineCurve */ "../../core/geometry/lib/esm/bspline/BSplineCurve.js");
253549
253737
  /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
253550
253738
  /* harmony import */ var _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../geometry3d/GeometryHandler */ "../../core/geometry/lib/esm/geometry3d/GeometryHandler.js");
253551
- /* harmony import */ var _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../geometry3d/GrowableFloat64Array */ "../../core/geometry/lib/esm/geometry3d/GrowableFloat64Array.js");
253739
+ /* harmony import */ var _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../geometry3d/GrowableFloat64Array */ "../../core/geometry/lib/esm/geometry3d/GrowableFloat64Array.js");
253552
253740
  /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
253553
- /* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
253554
- /* harmony import */ var _numerics_Newton__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../numerics/Newton */ "../../core/geometry/lib/esm/numerics/Newton.js");
253555
- /* harmony import */ var _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../numerics/Polynomials */ "../../core/geometry/lib/esm/numerics/Polynomials.js");
253556
- /* harmony import */ var _numerics_SmallSystem__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../numerics/SmallSystem */ "../../core/geometry/lib/esm/numerics/SmallSystem.js");
253557
- /* harmony import */ var _Arc3d__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Arc3d */ "../../core/geometry/lib/esm/curve/Arc3d.js");
253558
- /* harmony import */ var _CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../CurveChainWithDistanceIndex */ "../../core/geometry/lib/esm/curve/CurveChainWithDistanceIndex.js");
253559
- /* harmony import */ var _CurveCollection__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../CurveCollection */ "../../core/geometry/lib/esm/curve/CurveCollection.js");
253560
- /* harmony import */ var _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../CurveLocationDetail */ "../../core/geometry/lib/esm/curve/CurveLocationDetail.js");
253561
- /* harmony import */ var _LineSegment3d__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
253562
- /* harmony import */ var _LineString3d__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
253741
+ /* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
253742
+ /* harmony import */ var _numerics_Newton__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../numerics/Newton */ "../../core/geometry/lib/esm/numerics/Newton.js");
253743
+ /* harmony import */ var _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../numerics/Polynomials */ "../../core/geometry/lib/esm/numerics/Polynomials.js");
253744
+ /* harmony import */ var _numerics_SmallSystem__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../numerics/SmallSystem */ "../../core/geometry/lib/esm/numerics/SmallSystem.js");
253745
+ /* harmony import */ var _Arc3d__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Arc3d */ "../../core/geometry/lib/esm/curve/Arc3d.js");
253746
+ /* harmony import */ var _CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../CurveChainWithDistanceIndex */ "../../core/geometry/lib/esm/curve/CurveChainWithDistanceIndex.js");
253747
+ /* harmony import */ var _CurveCollection__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../CurveCollection */ "../../core/geometry/lib/esm/curve/CurveCollection.js");
253748
+ /* harmony import */ var _CurveCurve__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../CurveCurve */ "../../core/geometry/lib/esm/curve/CurveCurve.js");
253749
+ /* harmony import */ var _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../CurveLocationDetail */ "../../core/geometry/lib/esm/curve/CurveLocationDetail.js");
253750
+ /* harmony import */ var _CurvePrimitive__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../CurvePrimitive */ "../../core/geometry/lib/esm/curve/CurvePrimitive.js");
253751
+ /* harmony import */ var _LineSegment3d__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
253752
+ /* harmony import */ var _LineString3d__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
253753
+ /* harmony import */ var _ProxyCurve__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../ProxyCurve */ "../../core/geometry/lib/esm/curve/ProxyCurve.js");
253754
+ /* harmony import */ var _spiral_TransitionSpiral3d__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../spiral/TransitionSpiral3d */ "../../core/geometry/lib/esm/curve/spiral/TransitionSpiral3d.js");
253563
253755
  /*---------------------------------------------------------------------------------------------
253564
253756
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
253565
253757
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -253583,6 +253775,10 @@ __webpack_require__.r(__webpack_exports__);
253583
253775
 
253584
253776
 
253585
253777
 
253778
+
253779
+
253780
+
253781
+
253586
253782
  // cspell:word XYRR currentdFdX
253587
253783
  /**
253588
253784
  * Handler class for XY close approach between _geometryB and another geometry.
@@ -253600,9 +253796,6 @@ __webpack_require__.r(__webpack_exports__);
253600
253796
  */
253601
253797
  class CurveCurveCloseApproachXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODULE_1__.RecurseToCurvesGeometryHandler {
253602
253798
  _geometryB;
253603
- setGeometryB(geometryB) {
253604
- this._geometryB = geometryB;
253605
- }
253606
253799
  /**
253607
253800
  * Maximum XY distance (z is ignored). Approach larger than this is not interesting.
253608
253801
  * This is caller defined and can be undefined.
@@ -253610,6 +253803,8 @@ class CurveCurveCloseApproachXY extends _geometry3d_GeometryHandler__WEBPACK_IMP
253610
253803
  _maxDistanceToAccept;
253611
253804
  /** Squared max distance. Default is [[Geometry.smallMetricDistanceSquared]]. */
253612
253805
  _maxDistanceSquared;
253806
+ _xyTolerance;
253807
+ _newtonTolerance;
253613
253808
  /**
253614
253809
  * Start and end points of line segments that meet closest approach criteria, i.e., they are perpendicular to
253615
253810
  * both curves and their length is smaller than _maxDistanceToAccept.
@@ -253623,18 +253818,28 @@ class CurveCurveCloseApproachXY extends _geometry3d_GeometryHandler__WEBPACK_IMP
253623
253818
  /**
253624
253819
  * Constructor.
253625
253820
  * @param geometryB second curve for intersection. Saved for reference by specific handler methods.
253821
+ * @param xyTolerance optional tolerance for comparing xy points (default [[Geometry.smallMetricDistance]]).
253822
+ * @param newtonTolerance optional relative fraction tolerance for Newton iteration (default [[Geometry.smallNewtonStep]]).
253626
253823
  */
253627
- constructor(geometryB) {
253824
+ constructor(geometryB, xyTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistance, newtonTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallNewtonStep) {
253628
253825
  super();
253629
- this.setGeometryB(geometryB);
253826
+ this._geometryB = geometryB instanceof _ProxyCurve__WEBPACK_IMPORTED_MODULE_4__.ProxyCurve ? geometryB.proxyCurve : geometryB;
253630
253827
  this._maxDistanceSquared = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistanceSquared;
253631
- this._results = [];
253828
+ this._xyTolerance = xyTolerance;
253829
+ this._newtonTolerance = newtonTolerance;
253830
+ const compare = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetailPair.comparePairsByPoints(xyTolerance, true);
253831
+ this._results = new _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.SortedArray(compare, _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.DuplicatePolicy.Retain);
253632
253832
  }
253633
253833
  /** Set the (possibly undefined) max XY distance (z is ignored) to accept. */
253634
253834
  set maxDistanceToAccept(value) {
253635
- this._maxDistanceToAccept = value;
253636
- if (this._maxDistanceToAccept !== undefined && this._maxDistanceToAccept > 0)
253637
- this._maxDistanceSquared = this._maxDistanceToAccept * this._maxDistanceToAccept;
253835
+ if (value === undefined) {
253836
+ this._maxDistanceToAccept = undefined;
253837
+ this._maxDistanceSquared = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistanceSquared;
253838
+ }
253839
+ else {
253840
+ this._maxDistanceToAccept = Math.abs(value);
253841
+ this._maxDistanceSquared = value * value;
253842
+ }
253638
253843
  }
253639
253844
  /** Access the (possibly undefined) max XY distance (z is ignored) to accept. */
253640
253845
  get maxDistanceToAccept() {
@@ -253644,9 +253849,14 @@ class CurveCurveCloseApproachXY extends _geometry3d_GeometryHandler__WEBPACK_IMP
253644
253849
  get isMaxDistanceSet() {
253645
253850
  return this._maxDistanceToAccept !== undefined && this._maxDistanceToAccept > 0;
253646
253851
  }
253647
- /** Reset the geometry and flags, leaving all other parts unchanged (and preserving accumulated intersections) */
253852
+ /**
253853
+ * Reset the geometry.
253854
+ * * Undefined inputs are ignored.
253855
+ * * All other instance data is unchanged, including accumulated intersections.
253856
+ */
253648
253857
  resetGeometry(geometryB) {
253649
- this.setGeometryB(geometryB);
253858
+ if (geometryB)
253859
+ this._geometryB = geometryB;
253650
253860
  }
253651
253861
  /** returns true if `fraction` is in [0,1] within tolerance */
253652
253862
  acceptFraction(fraction, fractionTol = 1.0e-12) {
@@ -253656,131 +253866,103 @@ class CurveCurveCloseApproachXY extends _geometry3d_GeometryHandler__WEBPACK_IMP
253656
253866
  return false;
253657
253867
  return true;
253658
253868
  }
253659
- /**
253660
- * Return the results structure for the intersection calculation, structured as an array of CurveLocationDetailPair.
253661
- * @param reinitialize if true, a new results structure is created for use by later calls.
253662
- */
253663
- grabPairedResults(reinitialize = false) {
253664
- const result = this._results;
253665
- if (reinitialize)
253666
- this._results = [];
253667
- return result;
253668
- }
253669
- /**
253670
- * If distance between pointA and pointB is less than maxDistance, record CurveLocationDetailPair which is
253671
- * the approach from pointA to pointB.
253672
- */
253673
- testAndRecordPointPairApproach(cpA, fA, pointA, cpB, fB, pointB, reversed) {
253869
+ /** Extract (and clear) the results, structured as an array of CurveLocationDetailPair. */
253870
+ grabPairedResults() {
253871
+ return this._results.extractArray();
253872
+ }
253873
+ /**
253874
+ * Create and record a close-approach pair from raw curve/fraction/point data.
253875
+ * * If points are undefined, they are computed from the fractions via `fractionToPoint`.
253876
+ * * Fractions are global (i.e., relative to the full curve, not a sub-segment).
253877
+ * * The pair is recorded only if the XY distance is within `_maxDistanceSquared`.
253878
+ * @param cpA first curve
253879
+ * @param fA global fraction on cpA
253880
+ * @param pointA point on cpA at fA, or undefined to compute from fA
253881
+ * @param cpB second curve
253882
+ * @param fB global fraction on cpB
253883
+ * @param pointB point on cpB at fB, or undefined to compute from fB
253884
+ * @param reversed if true, swap detailA and detailB before recording
253885
+ */
253886
+ testAndRecordPointPair(cpA, fA, pointA, cpB, fB, pointB, reversed) {
253887
+ if (!pointA)
253888
+ pointA = cpA.fractionToPoint(fA);
253889
+ if (!pointB)
253890
+ pointB = cpB.fractionToPoint(fB);
253674
253891
  const d2 = pointA.distanceSquaredXY(pointB);
253675
- if (d2 < this._maxDistanceSquared) {
253892
+ if (d2 <= this._maxDistanceSquared) {
253676
253893
  const d = Math.sqrt(d2);
253677
- const detailA = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetail.createCurveFractionPointDistance(cpA, fA, pointA, d);
253678
- const detailB = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetail.createCurveFractionPointDistance(cpB, fB, pointB, d);
253679
- const pair = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetailPair.createCapture(detailA, detailB);
253894
+ const detailA = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetail.createCurveFractionPointDistance(cpA, fA, pointA, d);
253895
+ const detailB = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetail.createCurveFractionPointDistance(cpB, fB, pointB, d);
253896
+ detailA.setIntervalRole(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveIntervalRole.isolated);
253897
+ detailB.setIntervalRole(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveIntervalRole.isolated);
253898
+ const pair = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetailPair.createCapture(detailA, detailB);
253680
253899
  if (reversed)
253681
253900
  pair.swapDetails();
253682
- this._results.push(pair);
253901
+ this._results.insert(pair);
253683
253902
  }
253684
253903
  }
253685
253904
  /**
253686
- * Create a close approach pair if XY distance is within maxDistance.
253687
- * @param localFractionA a fraction on first curve
253688
- * @param cpA the first curve
253689
- * @param fractionA0 start of the first curve
253690
- * @param fractionA1 end of the first curve
253691
- * @param localFractionB a fraction on second curve
253692
- * @param cpB the second curve
253693
- * @param fractionB0 start of the second curve
253694
- * @param fractionB1 end of the second curve
253695
- * @param reversed whether to reverse the details in the pair (e.g., so that detailB refers to geometryB).
253905
+ * Record a pre-built close-approach pair with global fractions already set.
253906
+ * * Computes and stores the XY distance on both details.
253907
+ * * The pair is recorded only if the XY distance is within `_maxDistanceSquared`.
253908
+ * @param pair details with global fractions and points already set; modified in place
253909
+ * @param reversed if true, swap detailA and detailB before recording
253696
253910
  */
253697
- recordPointWithLocalFractions(localFractionA, cpA, fractionA0, fractionA1, localFractionB, cpB, fractionB0, fractionB1, reversed) {
253698
- const globalFractionA = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionA0, localFractionA, fractionA1);
253699
- const globalFractionB = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionB0, localFractionB, fractionB1);
253700
- // ignore duplicate of most recent approach
253701
- const numPrevious = this._results.length;
253702
- if (numPrevious > 0) {
253703
- const oldDetailA = this._results[numPrevious - 1].detailA;
253704
- const oldDetailB = this._results[numPrevious - 1].detailB;
253705
- if (reversed) {
253706
- if (oldDetailB.isSameCurveAndFraction({ curve: cpA, fraction: globalFractionA }) &&
253707
- oldDetailA.isSameCurveAndFraction({ curve: cpB, fraction: globalFractionB }))
253708
- return;
253709
- }
253710
- else {
253711
- if (oldDetailA.isSameCurveAndFraction({ curve: cpA, fraction: globalFractionA }) &&
253712
- oldDetailB.isSameCurveAndFraction({ curve: cpB, fraction: globalFractionB }))
253713
- return;
253714
- }
253715
- }
253716
- const pointA = cpA.fractionToPoint(globalFractionA);
253717
- const pointB = cpB.fractionToPoint(globalFractionB);
253718
- const d2 = pointA.distanceSquaredXY(pointB);
253911
+ testAndRecordPair(pair, reversed) {
253912
+ const d2 = pair.detailA.point.distanceSquaredXY(pair.detailB.point);
253719
253913
  if (d2 > this._maxDistanceSquared)
253720
253914
  return;
253721
253915
  const d = Math.sqrt(d2);
253722
- const detailA = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetail.createCurveFractionPointDistance(cpA, globalFractionA, pointA, d);
253723
- const detailB = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetail.createCurveFractionPointDistance(cpB, globalFractionB, pointB, d);
253724
- detailA.setIntervalRole(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveIntervalRole.isolated);
253725
- detailB.setIntervalRole(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveIntervalRole.isolated);
253916
+ pair.detailA.a = pair.detailB.a = d;
253917
+ pair.detailA.setIntervalRole(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveIntervalRole.isolated);
253918
+ pair.detailB.setIntervalRole(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveIntervalRole.isolated);
253726
253919
  if (reversed)
253727
- this._results.push(new _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetailPair(detailB, detailA));
253728
- else
253729
- this._results.push(new _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetailPair(detailA, detailB));
253730
- }
253731
- /**
253732
- * Capture a close approach pair that has point and local fraction but not curve.
253733
- * * Record the pair, each detail modified with global fraction and input curve.
253734
- * * Pair is neither modified nor recorded if it would be a duplicate of the last recorded pair.
253735
- * @param pair details computed with local fractions
253736
- * @param cpA curveA
253737
- * @param fractionA0 global start fraction on curveA
253738
- * @param fractionA1 global end fraction on curveA
253739
- * @param cpB curveB
253740
- * @param fractionB0 global start fraction on curveB
253741
- * @param fractionB1 global end fraction on curveB
253742
- * @param reversed whether to reverse the details in the pair (e.g., so that detailB refers to geometryB).
253743
- */
253744
- capturePairWithLocalFractions(pair, cpA, fractionA0, fractionA1, cpB, fractionB0, fractionB1, reversed) {
253920
+ pair.swapDetails();
253921
+ this._results.insert(pair);
253922
+ }
253923
+ /**
253924
+ * Convert a close-approach pair from local (sub-segment) fractions to global fractions, then record it.
253925
+ * * Local fractions in the pair are interpolated into the global fraction ranges.
253926
+ * * Points are recomputed from the parent curves at the global fractions.
253927
+ * * The pair is recorded only if the XY distance is within `_maxDistanceSquared`.
253928
+ * @param pair local details (curve unspecified); modified in place with global fractions, curves, and points
253929
+ * @param cpA parent curve A
253930
+ * @param fractionA0 global fraction corresponding to local fraction 0 on curve A
253931
+ * @param fractionA1 global fraction corresponding to local fraction 1 on curve A
253932
+ * @param cpB parent curve B
253933
+ * @param fractionB0 global fraction corresponding to local fraction 0 on curve B
253934
+ * @param fractionB1 global fraction corresponding to local fraction 1 on curve B
253935
+ * @param reversed if true, swap detailA and detailB before recording
253936
+ */
253937
+ testAndRecordLocalPair(pair, cpA, fractionA0, fractionA1, cpB, fractionB0, fractionB1, reversed) {
253745
253938
  const globalFractionA = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionA0, pair.detailA.fraction, fractionA1);
253746
253939
  const globalFractionB = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionB0, pair.detailB.fraction, fractionB1);
253747
- // ignore duplicate of most recent pair
253748
- const numPrevious = this._results.length;
253749
- if (numPrevious > 0) {
253750
- const oldDetailA = this._results[numPrevious - 1].detailA;
253751
- const oldDetailB = this._results[numPrevious - 1].detailB;
253752
- if (reversed) {
253753
- if (oldDetailB.isSameCurveAndFraction({ curve: cpA, fraction: globalFractionA }) &&
253754
- oldDetailA.isSameCurveAndFraction({ curve: cpB, fraction: globalFractionB }))
253755
- return;
253756
- }
253757
- else {
253758
- if (oldDetailA.isSameCurveAndFraction({ curve: cpA, fraction: globalFractionA }) &&
253759
- oldDetailB.isSameCurveAndFraction({ curve: cpB, fraction: globalFractionB }))
253760
- return;
253761
- }
253762
- }
253763
- // recompute the points just in case
253764
- _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetail.createCurveEvaluatedFraction(cpA, globalFractionA, pair.detailA);
253765
- _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetail.createCurveEvaluatedFraction(cpB, globalFractionB, pair.detailB);
253766
- pair.detailA.a = pair.detailB.a = pair.detailA.point.distanceXY(pair.detailB.point);
253767
- pair.detailA.setIntervalRole(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveIntervalRole.isolated);
253768
- pair.detailB.setIntervalRole(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveIntervalRole.isolated);
253940
+ const pointA = cpA.fractionToPoint(globalFractionA);
253941
+ const pointB = cpB.fractionToPoint(globalFractionB);
253942
+ const d2 = pointA.distanceSquaredXY(pointB);
253943
+ if (d2 > this._maxDistanceSquared)
253944
+ return;
253945
+ const d = Math.sqrt(d2);
253946
+ _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetail.createCurveFractionPointDistance(cpA, globalFractionA, pointA, d, pair.detailA);
253947
+ _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetail.createCurveFractionPointDistance(cpB, globalFractionB, pointB, d, pair.detailB);
253948
+ pair.detailA.setIntervalRole(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveIntervalRole.isolated);
253949
+ pair.detailB.setIntervalRole(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveIntervalRole.isolated);
253769
253950
  if (reversed)
253770
253951
  pair.swapDetails();
253771
- this._results.push(pair);
253952
+ this._results.insert(pair);
253772
253953
  }
253773
- static updatePointToSegmentDistance(fractionA, pointA, pointB0, pointB1, fractionB, maxDistanceSquared, closestApproach) {
253954
+ /** Modify the current closest approach if the inputs are closer. */
253955
+ static updatePointToSegmentDistance(closestApproach, fractionA, pointA, fractionB, pointB0, pointB1, maxDistanceSquared) {
253774
253956
  let updated = false;
253775
253957
  if (fractionB < 0)
253776
253958
  fractionB = 0;
253777
253959
  else if (fractionB > 1)
253778
253960
  fractionB = 1;
253779
- this._workPointB = pointB0.interpolate(fractionB, pointB1, this._workPointB);
253780
- const distanceSquared = this._workPointB.distanceSquaredXY(pointA);
253961
+ const pointB = pointB0.interpolate(fractionB, pointB1, this._workPointB);
253962
+ const distanceSquared = pointB.distanceSquaredXY(pointA);
253781
253963
  if (distanceSquared <= Math.min(maxDistanceSquared, closestApproach.detailA.a)) {
253782
253964
  closestApproach.detailA.setFP(fractionA, pointA, undefined, distanceSquared);
253783
- closestApproach.detailB.setFP(fractionB, this._workPointB, undefined, distanceSquared);
253965
+ closestApproach.detailB.setFP(fractionB, pointB, undefined, distanceSquared);
253784
253966
  updated = true;
253785
253967
  }
253786
253968
  return updated;
@@ -253793,8 +253975,9 @@ class CurveCurveCloseApproachXY extends _geometry3d_GeometryHandler__WEBPACK_IMP
253793
253975
  * @param b0 start point of line b
253794
253976
  * @param b1 end point of line b
253795
253977
  * @param maxDistanceSquared maximum distance squared (assumed to be positive)
253796
- * @returns the fractional (not xy) coordinates in result.x and result.y. result.x is fraction on line a.
253797
- * result.y is fraction on line b.
253978
+ * @returns a pair of details for the closest approach, or `undefined` if no approach is within `maxDistanceSquared`.
253979
+ * `detailA.fraction` is the fraction on segment a; `detailB.fraction` is the fraction on segment b. Returned
253980
+ * details store the *squared* distance in the `a` property.
253798
253981
  */
253799
253982
  static segmentSegmentBoundedApproach(a0, a1, b0, b1, maxDistanceSquared) {
253800
253983
  const ux = a1.x - a0.x;
@@ -253814,32 +253997,32 @@ class CurveCurveCloseApproachXY extends _geometry3d_GeometryHandler__WEBPACK_IMP
253814
253997
  if (hab0 * hab1 < 0.0 && hba0 * hba1 < 0.0) { // true intersection, strictly within both segments
253815
253998
  const fractionA = -hba0 / (hba1 - hba0);
253816
253999
  const fractionB = -hab0 / (hab1 - hab0);
253817
- return _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetailPair.createCapture(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetail.createCurveFractionPoint(undefined, fractionA, a0.interpolate(fractionA, a1)), _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetail.createCurveFractionPoint(undefined, fractionB, b0.interpolate(fractionB, b1)));
254000
+ return _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetailPair.createCapture(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetail.createCurveFractionPoint(undefined, fractionA, a0.interpolate(fractionA, a1)), _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetail.createCurveFractionPoint(undefined, fractionB, b0.interpolate(fractionB, b1)));
253818
254001
  }
253819
254002
  // there's no intersection, so find the closest approach within maxDistance from an endpoint
253820
- const closestApproach = new _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetailPair();
254003
+ const closestApproach = new _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetailPair();
253821
254004
  closestApproach.detailA.a = 2 * maxDistanceSquared; // init to an approach that's too far away
253822
254005
  let reversed = false;
253823
254006
  const uu = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.hypotenuseSquaredXY(ux, uy);
253824
254007
  if (hab0 * hab0 <= maxDistanceSquared * uu) { // test distance of b0 to u
253825
254008
  const fractionA = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.safeDivideFraction(_Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.dotProductXYXY(ux, uy, e00x, e00y), uu, 0.0);
253826
- if (this.updatePointToSegmentDistance(0, b0, a0, a1, fractionA, maxDistanceSquared, closestApproach))
254009
+ if (this.updatePointToSegmentDistance(closestApproach, 0, b0, fractionA, a0, a1, maxDistanceSquared))
253827
254010
  reversed = true;
253828
254011
  }
253829
254012
  if (hab1 * hab1 <= maxDistanceSquared * uu) { // test distance of b1 to u
253830
254013
  const fractionA = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.safeDivideFraction(_Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.dotProductXYXY(ux, uy, e01x, e01y), uu, 0.0);
253831
- if (this.updatePointToSegmentDistance(1, b1, a0, a1, fractionA, maxDistanceSquared, closestApproach))
254014
+ if (this.updatePointToSegmentDistance(closestApproach, 1, b1, fractionA, a0, a1, maxDistanceSquared))
253832
254015
  reversed = true;
253833
254016
  }
253834
254017
  const vv = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.hypotenuseSquaredXY(vx, vy);
253835
254018
  if (hba0 * hba0 <= maxDistanceSquared * vv) { // test distance of a0 to v
253836
254019
  const fractionB = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.safeDivideFraction(-_Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.dotProductXYXY(vx, vy, e00x, e00y), vv, 0.0);
253837
- if (this.updatePointToSegmentDistance(0, a0, b0, b1, fractionB, maxDistanceSquared, closestApproach))
254020
+ if (this.updatePointToSegmentDistance(closestApproach, 0, a0, fractionB, b0, b1, maxDistanceSquared))
253838
254021
  reversed = false;
253839
254022
  }
253840
254023
  if (hba1 * hba1 <= maxDistanceSquared * vv) { // test distance of a1 to v
253841
254024
  const fractionB = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.safeDivideFraction(-_Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.dotProductXYXY(vx, vy, e10x, e10y), vv, 0.0);
253842
- if (this.updatePointToSegmentDistance(1, a1, b0, b1, fractionB, maxDistanceSquared, closestApproach))
254025
+ if (this.updatePointToSegmentDistance(closestApproach, 1, a1, fractionB, b0, b1, maxDistanceSquared))
253843
254026
  reversed = false;
253844
254027
  }
253845
254028
  if (closestApproach.detailA.a > maxDistanceSquared)
@@ -253849,160 +254032,81 @@ class CurveCurveCloseApproachXY extends _geometry3d_GeometryHandler__WEBPACK_IMP
253849
254032
  return closestApproach;
253850
254033
  }
253851
254034
  /**
253852
- * Check different combination of fractions on curveA and curveB. If distance between points at 2 fractions
253853
- * is less than maxDistance, record CurveLocationDetailPair which is the approach between the 2 points.
253854
- * Optionally, record close approaches of one curve's points if they fall between the other curve's points.
253855
- * * If an input curve is a LineString3d, then the corresponding fractions must define a segment of the line string.
254035
+ * Compute closest approaches from the endpoints of each curve (if open) to the other curve.
254036
+ * Record a [[CurveLocationDetailPair]] if such a distance is less than [[maxDistance]].
253856
254037
  * @param cpA curveA
253857
- * @param fA0 fraction0 on curveA
253858
- * @param fA1 fraction1 on curveA
253859
- * @param testProjectionOnA whether to record projections of the given curveB points onto curveA
253860
254038
  * @param cpB curveB
253861
- * @param fB0 fraction0 on curveB
253862
- * @param fB1 fraction0 on curveB
253863
- * @param testProjectionOnB whether to record projections of the given curveA points onto curveB
253864
- * @param reversed whether to reverse the details in the pair (e.g., so that detailB refers to geometryB).
253865
- */
253866
- testAndRecordFractionalPairApproach(cpA, fA0, fA1, testProjectionOnA, cpB, fB0, fB1, testProjectionOnB, reversed) {
253867
- const pointA0 = cpA.fractionToPoint(fA0);
253868
- const pointA1 = cpA.fractionToPoint(fA1);
253869
- const pointB0 = cpB.fractionToPoint(fB0);
253870
- const pointB1 = cpB.fractionToPoint(fB1);
253871
- this.testAndRecordPointPairApproach(cpA, fA0, pointA0, cpB, fB0, pointB0, reversed);
253872
- this.testAndRecordPointPairApproach(cpA, fA1, pointA1, cpB, fB0, pointB0, reversed);
253873
- this.testAndRecordPointPairApproach(cpA, fA0, pointA0, cpB, fB1, pointB1, reversed);
253874
- this.testAndRecordPointPairApproach(cpA, fA1, pointA1, cpB, fB1, pointB1, reversed);
253875
- if (testProjectionOnB) {
253876
- this.testAndRecordProjection(cpA, fA0, pointA0, cpB, fB0, fB1, reversed);
253877
- this.testAndRecordProjection(cpA, fA1, pointA1, cpB, fB0, fB1, reversed);
253878
- }
253879
- if (testProjectionOnA) {
253880
- this.testAndRecordProjection(cpB, fB0, pointB0, cpA, fA0, fA1, !reversed);
253881
- this.testAndRecordProjection(cpB, fB1, pointB1, cpA, fA0, fA1, !reversed);
253882
- }
253883
- }
253884
- /**
253885
- * Return XY closest approach between a curve primitive and a point.
253886
- * Currently, this function only supports Arc3d and LineSegment.
253887
- * Note that this function doesn't handle endpoints.
253888
- */
253889
- getPointCurveClosestApproachXYNewton(curveP, pointQ) {
253890
- if (!(curveP instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_5__.Arc3d) && !(curveP instanceof _LineSegment3d__WEBPACK_IMPORTED_MODULE_6__.LineSegment3d)) {
253891
- (0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.assert)(false, "getPointCurveClosestApproachXYNewton only supports Arc3d and LineSegment");
253892
- }
253893
- const seeds = [0.2, 0.4, 0.6, 0.8]; // HEURISTIC: arcs have up to 4 perpendiculars; lines have only 1
253894
- const newtonEvaluator = new _numerics_Newton__WEBPACK_IMPORTED_MODULE_7__.CurvePointCloseApproachXYRtoRD(curveP, pointQ);
253895
- const newtonSearcher = new _numerics_Newton__WEBPACK_IMPORTED_MODULE_7__.Newton1dUnbounded(newtonEvaluator, 100); // observed convergence to 1.0e-11 in 66 iters
253896
- let minCloseApproachLength = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.largeCoordinateResult;
253897
- let minCurvePFraction;
253898
- let minPointP;
253899
- for (const seed of seeds) {
253900
- newtonSearcher.setX(seed);
253901
- if (newtonSearcher.runIterations()) {
253902
- const curvePFraction = newtonSearcher.getX();
253903
- if (this.acceptFraction(curvePFraction)) {
253904
- const pointP = curveP.fractionToPoint(curvePFraction);
253905
- const closeApproachLength = pointP.distanceSquaredXY(pointQ);
253906
- if (closeApproachLength < minCloseApproachLength) {
253907
- minCloseApproachLength = closeApproachLength;
253908
- minCurvePFraction = curvePFraction;
253909
- minPointP = pointP;
253910
- }
253911
- }
253912
- }
253913
- }
253914
- if (minCurvePFraction && minPointP)
253915
- return _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetail.createCurveFractionPoint(curveP, minCurvePFraction, minPointP);
253916
- return undefined;
253917
- }
253918
- /**
253919
- * Find the closest xy approach between `pointA` and `cpB`. Add the approach if it's within `fB0` and `fB1`.
253920
- * * Does not test the endpoints of `cpB`.
253921
- * * The only types supported for `cpB` are Arc3d, LineSegment3d, and LineString3d.
253922
- * * If `cpB` is a LineString3d, then the interval `[fB0, fB1]` must correspond to a segment of the line string.
253923
- */
253924
- testAndRecordProjection(cpA, fA, pointA, cpB, fB0, fB1, reversed) {
253925
- let detail;
253926
- if (cpB instanceof _LineString3d__WEBPACK_IMPORTED_MODULE_8__.LineString3d) {
253927
- const segParamsB = cpB.globalFractionToSegmentIndexAndLocalFraction(fB0 <= fB1 ? fB0 : fB1);
253928
- const segIndexB = (segParamsB.fraction < 0.999999) ? segParamsB.index : segParamsB.index + 1;
253929
- const segmentB = cpB.getIndexedSegment(segIndexB);
253930
- if (segmentB && (detail = this.getPointCurveClosestApproachXYNewton(segmentB, pointA)))
253931
- _LineString3d__WEBPACK_IMPORTED_MODULE_8__.LineString3d.convertLocalToGlobalDetail(detail, segIndexB, cpB.numEdges(), cpB);
254039
+ * @param reversed whether to reverse the details in the pair (e.g., so that detailB refers to curveA).
254040
+ */
254041
+ testAndRecordEndPointApproaches(cpA, cpB, reversed) {
254042
+ const pt = CurveCurveCloseApproachXY._workPointB;
254043
+ // in closest approach context, endpoints of full sweep arcs are artificial locations, and thus ignored
254044
+ const isClosedArc = (curve) => curve instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_6__.Arc3d && curve.sweep.isFullCircle;
254045
+ if (!isClosedArc(cpA)) {
254046
+ this.testAndRecordProjection(cpA, 0, cpA.startPoint(pt), cpB, reversed);
254047
+ this.testAndRecordProjection(cpA, 1, cpA.endPoint(pt), cpB, reversed);
253932
254048
  }
253933
- else {
253934
- detail = this.getPointCurveClosestApproachXYNewton(cpB, pointA);
253935
- }
253936
- if (detail) {
253937
- const fB = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.restrictToInterval(detail.fraction, fB0, fB1);
253938
- if (fB === detail.fraction) { // if fraction is within fB0 and fB1
253939
- this.testAndRecordPointPairApproach(cpA, fA, pointA, cpB, detail.fraction, detail.point, reversed);
253940
- }
254049
+ if (!isClosedArc(cpB)) {
254050
+ this.testAndRecordProjection(cpB, 0, cpB.startPoint(pt), cpA, !reversed);
254051
+ this.testAndRecordProjection(cpB, 1, cpB.endPoint(pt), cpA, !reversed);
253941
254052
  }
253942
254053
  }
254054
+ /** Find the closest xy approach between `pointA` and `cpB`. */
254055
+ testAndRecordProjection(cpA, fA, pointA, cpB, reversed) {
254056
+ const detail = cpB.closestPointXY(pointA);
254057
+ if (detail)
254058
+ this.testAndRecordPointPair(cpA, fA, pointA, cpB, detail.fraction, detail.point, reversed);
254059
+ }
253943
254060
  /**
253944
254061
  * Compute closest xy approach of two line segments.
253945
254062
  * Filter by extension rules.
253946
254063
  * Record with fraction mapping.
253947
254064
  * * The fraction mappings allow portions of a linestring to be passed here.
253948
254065
  */
253949
- computeSegmentSegment3D(cpA, pointA0, fractionA0, pointA1, fractionA1, cpB, pointB0, fractionB0, pointB1, fractionB1, reversed) {
254066
+ computeSegmentSegment(cpA, pointA0, fractionA0, pointA1, fractionA1, cpB, pointB0, fractionB0, pointB1, fractionB1, reversed) {
253950
254067
  // compute a pair with fractions local to segments
253951
254068
  const approach = CurveCurveCloseApproachXY.segmentSegmentBoundedApproach(pointA0, pointA1, pointB0, pointB1, this._maxDistanceSquared);
253952
254069
  // adjust the pair to refer to input curves and global fractions, then record it if new
253953
254070
  if (approach) {
253954
254071
  approach.detailA.setCurve(cpA);
253955
254072
  approach.detailB.setCurve(cpB);
253956
- this.capturePairWithLocalFractions(approach, cpA, fractionA0, fractionA1, cpB, fractionB0, fractionB1, reversed);
254073
+ this.testAndRecordLocalPair(approach, cpA, fractionA0, fractionA1, cpB, fractionB0, fractionB1, reversed);
253957
254074
  }
253958
254075
  }
253959
- /** Low level dispatch of segment with segment. */
253960
- dispatchSegmentSegment(cpA, pointA0, fractionA0, pointA1, fractionA1, cpB, pointB0, fractionB0, pointB1, fractionB1, reversed) {
253961
- this.computeSegmentSegment3D(cpA, pointA0, fractionA0, pointA1, fractionA1, cpB, pointB0, fractionB0, pointB1, fractionB1, reversed);
253962
- }
253963
254076
  /**
253964
254077
  * Compute the perpendiculars between a line segment and an arc, without extending either curve.
253965
254078
  * * One or two perpendiculars will be found.
253966
254079
  * * Each perpendicular segment starts or ends on the arc where the arc tangent is parallel to the line tangent.
253967
- * * Perpendiculars from an endpoint are not explicitly computed.
253968
- * @param cpA line segment or line string; if it is a line string, then the fractions must specify a segment
253969
- * @param pointA0 start point of the segment
253970
- * @param fractionA0 fraction of the start of the segment
253971
- * @param pointA1 end point of the segment
253972
- * @param fractionA1 fraction of the end of the segment
253973
- * @param arc the arc
253974
- * @param reversed swap the details in the recorded pair (default: false)
253975
- */
253976
- allPerpendicularsSegmentArcBounded(cpA, pointA0, fractionA0, pointA1, fractionA1, arc, reversed = false) {
253977
- const dotUT = arc.vector0.crossProductStartEndXY(pointA0, pointA1);
253978
- const dotVT = arc.vector90.crossProductStartEndXY(pointA0, pointA1);
254080
+ * @param startA line segment start point
254081
+ * @param endA line segment end point
254082
+ * @param arcB the arc
254083
+ * @param announce callback to receive line and arc fractions and optional points of each perpendicular segment computed.
254084
+ */
254085
+ announceAllPerpendicularsSegmentArcBounded(startA, endA, arcB, announce) {
254086
+ const dotUT = arcB.vector0.crossProductStartEndXY(startA, endA);
254087
+ const dotVT = arcB.vector90.crossProductStartEndXY(startA, endA);
253979
254088
  const parallelRadians = Math.atan2(dotVT, dotUT);
253980
254089
  for (const radians1 of [parallelRadians, parallelRadians + Math.PI]) {
253981
- const arcPoint = arc.radiansToPoint(radians1);
253982
- const fArc = arc.sweep.radiansToSignedPeriodicFraction(radians1);
253983
- if (this.acceptFraction(fArc)) { // reject solution outside arc sweep
253984
- const fLine = _numerics_SmallSystem__WEBPACK_IMPORTED_MODULE_9__.SmallSystem.lineSegment3dXYClosestPointUnbounded(pointA0, pointA1, arcPoint);
253985
- if (fLine !== undefined && this.acceptFraction(fLine))
253986
- this.recordPointWithLocalFractions(fLine, cpA, fractionA0, fractionA1, fArc, arc, 0, 1, reversed);
254090
+ const arcPoint = arcB.radiansToPoint(radians1);
254091
+ const arcFraction = arcB.sweep.radiansToSignedPeriodicFraction(radians1);
254092
+ if (this.acceptFraction(arcFraction)) { // reject solution outside arc sweep
254093
+ const lineFraction = _numerics_SmallSystem__WEBPACK_IMPORTED_MODULE_7__.SmallSystem.lineSegment3dXYClosestPointUnbounded(startA, endA, arcPoint);
254094
+ if (lineFraction !== undefined && this.acceptFraction(lineFraction))
254095
+ announce(lineFraction, undefined, arcFraction, arcPoint);
253987
254096
  }
253988
254097
  }
253989
254098
  }
253990
254099
  /**
253991
- * Low level dispatch of line segment with arc.
253992
- * Find close approaches within maxDistance between a line segments (pointA0, pointA1) and an arc.
254100
+ * Find close approaches within maxDistance between a line segment and an arc.
253993
254101
  * To consider:
253994
254102
  * 1) intersection between arc and segment.
253995
- * 2) endpoints to endpoints or endpoints projection to the other curve.
253996
- * 3) arc tangent parallel to line segment (or line string).
253997
- * @param cpA curve A (line segment or line string; if it is a line string, then the fractions must specify a segment)
253998
- * @param pointA0 start point of the segment
253999
- * @param fractionA0 fraction of the start of the segment
254000
- * @param pointA1 end point of the segment
254001
- * @param fractionA1 fraction of the end of the segment
254002
- * @param arc the arc
254003
- * @param reversed whether to reverse the details in the pair (e.g., so that detailB refers to geometryB).
254004
- */
254005
- dispatchSegmentArc(cpA, pointA0, fractionA0, pointA1, fractionA1, arc, reversed) {
254103
+ * 2) endpoints to endpoints, or endpoints projection to the other curve.
254104
+ * 3) arc tangent parallel to line segment
254105
+ * @param lineA the line segment
254106
+ * @param arcB the arc
254107
+ * @param reversed whether to reverse the details in the pair (e.g., so that detailB refers to arcA).
254108
+ */
254109
+ computeSegmentArc(lineA, arcB, reversed) {
254006
254110
  // 1) intersection between arc and line segment (or string).
254007
254111
  // Suppose:
254008
254112
  // Arc: X = C + cU + sV where c = cos(theta) and s = sin(theta)
@@ -254013,56 +254117,56 @@ class CurveCurveCloseApproachXY extends _geometry3d_GeometryHandler__WEBPACK_IMP
254013
254117
  // evaluate points.
254014
254118
  // project back to line.
254015
254119
  let intersectionFound = false;
254016
- const data = arc.toTransformedVectors();
254017
- const pointA0Local = pointA0;
254018
- const pointA1Local = pointA1;
254019
- const alpha = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.center, 1); // det(A0, A1, C)
254020
- const beta = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector0, 0); // det(A0, A1, U)
254021
- const gamma = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector90, 0); // det(A0, A1, V)
254022
- const cosines = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_10__.GrowableFloat64Array(2);
254023
- const sines = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_10__.GrowableFloat64Array(2);
254024
- const radians = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_10__.GrowableFloat64Array(2);
254025
- const numRoots = _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_11__.AnalyticRoots.appendImplicitLineUnitCircleIntersections(// solve the equation
254026
- alpha, beta, gamma, cosines, sines, radians);
254120
+ const data = arcB.toTransformedVectors();
254121
+ const alpha = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductXYW(lineA.point0Ref, 1, lineA.point1Ref, 1, data.center, 1); // det(A0, A1, C)
254122
+ const beta = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductXYW(lineA.point0Ref, 1, lineA.point1Ref, 1, data.vector0, 0); // det(A0, A1, U)
254123
+ const gamma = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductXYW(lineA.point0Ref, 1, lineA.point1Ref, 1, data.vector90, 0); // det(A0, A1, V)
254124
+ const cosines = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_8__.GrowableFloat64Array(2);
254125
+ const sines = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_8__.GrowableFloat64Array(2);
254126
+ const radians = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_8__.GrowableFloat64Array(2);
254127
+ const numRoots = _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_9__.AnalyticRoots.appendImplicitLineUnitCircleIntersections(alpha, beta, gamma, cosines, sines, radians);
254027
254128
  for (let i = 0; i < numRoots; i++) {
254028
254129
  const arcPoint = data.center.plus2Scaled(data.vector0, cosines.atUncheckedIndex(i), data.vector90, sines.atUncheckedIndex(i));
254029
254130
  const arcFraction = data.sweep.radiansToSignedPeriodicFraction(radians.atUncheckedIndex(i));
254030
- const lineFraction = _numerics_SmallSystem__WEBPACK_IMPORTED_MODULE_9__.SmallSystem.lineSegment3dXYClosestPointUnbounded(pointA0Local, pointA1Local, arcPoint);
254031
- // only add if the point is within the start and end fractions of both line segment and arc
254032
- if (lineFraction !== undefined && this.acceptFraction(lineFraction) && this.acceptFraction(arcFraction)) {
254033
- this.recordPointWithLocalFractions(lineFraction, cpA, fractionA0, fractionA1, arcFraction, arc, 0, 1, reversed);
254034
- intersectionFound = true;
254131
+ if (this.acceptFraction(arcFraction)) { // reject solution outside arc sweep
254132
+ const lineFraction = _numerics_SmallSystem__WEBPACK_IMPORTED_MODULE_7__.SmallSystem.lineSegment3dXYClosestPointUnbounded(lineA.point0Ref, lineA.point1Ref, arcPoint);
254133
+ if (lineFraction !== undefined && this.acceptFraction(lineFraction)) {
254134
+ this.testAndRecordPointPair(lineA, lineFraction, undefined, arcB, arcFraction, arcPoint, reversed);
254135
+ intersectionFound = true;
254136
+ }
254035
254137
  }
254036
254138
  }
254037
254139
  if (intersectionFound)
254038
254140
  return;
254039
- // 2) endpoints to endpoints or endpoints projection to the other curve.
254040
- this.testAndRecordFractionalPairApproach(cpA, fractionA0, fractionA1, true, arc, 0, 1, true, reversed);
254041
- // 3) arc tangent parallel to line segment (or string).
254141
+ // 2) endpoints to endpoints, or endpoints projection to the other curve.
254142
+ this.testAndRecordEndPointApproaches(lineA, arcB, reversed);
254143
+ // 3) arc tangent parallel to line segment.
254042
254144
  // If line does not intersect the arc, then the closest (and/or the furthest) point on arc to the line is a
254043
254145
  // point where the tangent line on arc at that point is parallel to the line.
254044
- this.allPerpendicularsSegmentArcBounded(cpA, pointA0, fractionA0, pointA1, fractionA1, arc, reversed);
254146
+ this.announceAllPerpendicularsSegmentArcBounded(lineA.point0Ref, lineA.point1Ref, arcB, (lineFraction, linePoint, arcFraction, arcPoint) => this.testAndRecordPointPair(lineA, lineFraction, linePoint, arcB, arcFraction, arcPoint, reversed));
254045
254147
  }
254046
254148
  /**
254047
254149
  * Compute segments perpendicular to two elliptical arcs, without extending either curve.
254048
254150
  * * Perpendiculars from an endpoint are not explicitly computed.
254049
254151
  * * Intersections are also found by this search: they are reported as zero-length segments.
254152
+ * @param arcA first arc
254153
+ * @param arcB second arc
254050
254154
  * @param reversed swap the details in the recorded pair (default: false)
254051
254155
  */
254052
- allPerpendicularsArcArcBounded(arc0, arc1, reversed = false) {
254053
- const newtonEvaluator = new _numerics_Newton__WEBPACK_IMPORTED_MODULE_7__.CurveCurveCloseApproachXYRRtoRRD(arc0, arc1);
254054
- // HEURISTIC: 2 ellipses have up to 8 perpendiculars and up to 4 intersections
254156
+ allPerpendicularsArcArcBounded(arcA, arcB, reversed = false) {
254157
+ const newtonEvaluator = new _numerics_Newton__WEBPACK_IMPORTED_MODULE_10__.CurveCurveCloseApproachXYRRtoRRD(arcA, arcB);
254158
+ // HEURISTIC: 2 ellipses have up to 8 perpendiculars
254055
254159
  const seedDelta = 1 / 10; // denominator 9 fails the unit test
254056
254160
  const seedStart = seedDelta / 2;
254057
- const newtonSearcher = new _numerics_Newton__WEBPACK_IMPORTED_MODULE_7__.Newton2dUnboundedWithDerivative(newtonEvaluator, 100); // observed convergence to 1.0e-11 in 49 iters
254161
+ const newtonSearcher = new _numerics_Newton__WEBPACK_IMPORTED_MODULE_10__.Newton2dUnboundedWithDerivative(newtonEvaluator, 100); // observed convergence to 1.0e-11 in 49 iters
254058
254162
  for (let seedU = seedStart; seedU < 1; seedU += seedDelta) {
254059
254163
  for (let seedV = seedStart; seedV < 1; seedV += seedDelta) {
254060
254164
  newtonSearcher.setUV(seedU, seedV);
254061
254165
  if (newtonSearcher.runIterations()) {
254062
- const frac0 = newtonSearcher.getU();
254063
- const frac1 = newtonSearcher.getV();
254064
- if (this.acceptFraction(frac0) && this.acceptFraction(frac1)) {
254065
- this.recordPointWithLocalFractions(frac0, arc0, 0, 1, frac1, arc1, 0, 1, reversed);
254166
+ const fractionA = newtonSearcher.getU();
254167
+ const fractionB = newtonSearcher.getV();
254168
+ if (this.acceptFraction(fractionA) && this.acceptFraction(fractionB)) {
254169
+ this.testAndRecordPointPair(arcA, fractionA, undefined, arcB, fractionB, undefined, reversed);
254066
254170
  }
254067
254171
  }
254068
254172
  }
@@ -254077,33 +254181,33 @@ class CurveCurveCloseApproachXY extends _geometry3d_GeometryHandler__WEBPACK_IMP
254077
254181
  if (!rangeB.intersectsRangeXY(rangeA))
254078
254182
  return;
254079
254183
  // 1) endpoints to endpoints or endpoints projection to the other curve
254080
- this.testAndRecordFractionalPairApproach(cpA, 0, 1, true, cpB, 0, 1, true, reversed);
254184
+ this.testAndRecordEndPointApproaches(cpA, cpB, reversed);
254081
254185
  // 2) perpendicular line between 2 arcs (includes intersections)
254082
254186
  this.allPerpendicularsArcArcBounded(cpA, cpB, reversed);
254083
254187
  }
254084
254188
  /** Low level dispatch of arc with (beziers of) a bspline curve */
254085
254189
  dispatchArcBsplineCurve3d(cpA, cpB, reversed) {
254086
- const ls = _LineString3d__WEBPACK_IMPORTED_MODULE_8__.LineString3d.create();
254190
+ const ls = _LineString3d__WEBPACK_IMPORTED_MODULE_11__.LineString3d.create();
254087
254191
  cpB.emitStrokes(ls);
254088
254192
  this.computeArcLineString(cpA, ls, reversed);
254089
254193
  }
254090
254194
  /** Low level dispatch of (beziers of) a bspline curve with (beziers of) a bspline curve */
254091
254195
  dispatchBSplineCurve3dBSplineCurve3d(bcurveA, bcurveB, reversed) {
254092
- const lsA = _LineString3d__WEBPACK_IMPORTED_MODULE_8__.LineString3d.create();
254196
+ const lsA = _LineString3d__WEBPACK_IMPORTED_MODULE_11__.LineString3d.create();
254093
254197
  bcurveA.emitStrokes(lsA);
254094
- const lsB = _LineString3d__WEBPACK_IMPORTED_MODULE_8__.LineString3d.create();
254198
+ const lsB = _LineString3d__WEBPACK_IMPORTED_MODULE_11__.LineString3d.create();
254095
254199
  bcurveB.emitStrokes(lsB);
254096
254200
  this.computeLineStringLineString(lsA, lsB, reversed);
254097
254201
  }
254098
254202
  /** Low level dispatch of linestring with (beziers of) a bspline curve */
254099
254203
  dispatchLineStringBSplineCurve(lsA, curveB, reversed) {
254100
- const lsB = _LineString3d__WEBPACK_IMPORTED_MODULE_8__.LineString3d.create();
254204
+ const lsB = _LineString3d__WEBPACK_IMPORTED_MODULE_11__.LineString3d.create();
254101
254205
  curveB.emitStrokes(lsB);
254102
254206
  this.computeLineStringLineString(lsA, lsB, reversed);
254103
254207
  }
254104
254208
  /** Low level dispatch of segment with (beziers of) a bspline curve */
254105
254209
  dispatchSegmentBsplineCurve(segA, curveB, reversed) {
254106
- const lsB = _LineString3d__WEBPACK_IMPORTED_MODULE_8__.LineString3d.create();
254210
+ const lsB = _LineString3d__WEBPACK_IMPORTED_MODULE_11__.LineString3d.create();
254107
254211
  curveB.emitStrokes(lsB);
254108
254212
  this.computeSegmentLineString(segA, lsB, reversed);
254109
254213
  }
@@ -254120,7 +254224,7 @@ class CurveCurveCloseApproachXY extends _geometry3d_GeometryHandler__WEBPACK_IMP
254120
254224
  const fB1 = (i + 1 === numB - 1) ? 1.0 : (i + 1) * deltaFracB; // make sure we nail the end fraction
254121
254225
  lsB.packedPoints.getPoint3dAtUncheckedPointIndex(i, pointB0);
254122
254226
  lsB.packedPoints.getPoint3dAtUncheckedPointIndex(i + 1, pointB1);
254123
- this.dispatchSegmentSegment(segA, pointA0, 0.0, pointA1, 1.0, lsB, pointB0, fB0, pointB1, fB1, reversed);
254227
+ this.computeSegmentSegment(segA, pointA0, 0.0, pointA1, 1.0, lsB, pointB0, fB0, pointB1, fB1, reversed);
254124
254228
  }
254125
254229
  }
254126
254230
  /** Detail computation for arc approaching linestring. */
@@ -254131,71 +254235,27 @@ class CurveCurveCloseApproachXY extends _geometry3d_GeometryHandler__WEBPACK_IMP
254131
254235
  rangeA.expandInPlace(this._maxDistanceToAccept);
254132
254236
  if (!rangeB.intersectsRangeXY(rangeA))
254133
254237
  return;
254134
- const pointB0 = CurveCurveCloseApproachXY._workPointBB0;
254135
- const pointB1 = CurveCurveCloseApproachXY._workPointBB1;
254136
- const numB = lsB.numPoints();
254137
- if (numB > 1) {
254138
- const dfB = 1.0 / (numB - 1);
254139
- let fB0;
254140
- let fB1;
254141
- fB0 = 0.0;
254142
- lsB.pointAt(0, pointB0);
254143
- for (let ib = 1; ib < numB; ib++, pointB0.setFrom(pointB1), fB0 = fB1) {
254144
- lsB.pointAt(ib, pointB1);
254145
- fB1 = ib * dfB;
254146
- this.dispatchSegmentArc(lsB, pointB0, fB0, pointB1, fB1, arcA, !reversed);
254147
- }
254148
- }
254149
- }
254150
- /** Low level dispatch of curve collection. */
254151
- dispatchCurveCollection(geomA, geomAHandler) {
254152
- const geomB = this._geometryB; // save
254153
- if (!geomB || !geomB.children || !(geomB instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_12__.CurveCollection))
254154
- return;
254155
- for (const child of geomB.children) {
254156
- this.resetGeometry(child);
254157
- geomAHandler(geomA);
254158
- }
254159
- this._geometryB = geomB; // restore
254160
- }
254161
- /** Low level dispatch to geomA given a CurveChainWithDistanceIndex in geometryB. */
254162
- dispatchCurveChainWithDistanceIndex(geomA, geomAHandler) {
254163
- if (!this._geometryB || !(this._geometryB instanceof _CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_13__.CurveChainWithDistanceIndex))
254164
- return;
254165
- if (geomA instanceof _CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_13__.CurveChainWithDistanceIndex) {
254166
- (0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.assert)(false, "call handleCurveChainWithDistanceIndex(geomA) instead");
254167
- }
254168
- const index0 = this._results.length;
254169
- const geomB = this._geometryB; // save
254170
- for (const child of geomB.path.children) {
254171
- this.resetGeometry(child);
254172
- geomAHandler(geomA);
254173
- }
254174
- this.resetGeometry(geomB); // restore
254175
- this._results = _CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_13__.CurveChainWithDistanceIndex.convertChildDetailToChainDetail(this._results, index0, undefined, geomB, true);
254176
- }
254177
- /** Double dispatch handler for strongly typed segment. */
254178
- handleLineSegment3d(segmentA) {
254179
- if (this._geometryB instanceof _LineSegment3d__WEBPACK_IMPORTED_MODULE_6__.LineSegment3d) {
254180
- const segmentB = this._geometryB;
254181
- this.dispatchSegmentSegment(segmentA, segmentA.point0Ref, 0.0, segmentA.point1Ref, 1.0, segmentB, segmentB.point0Ref, 0.0, segmentB.point1Ref, 1.0, false);
254182
- }
254183
- else if (this._geometryB instanceof _LineString3d__WEBPACK_IMPORTED_MODULE_8__.LineString3d) {
254184
- this.computeSegmentLineString(segmentA, this._geometryB, false);
254185
- }
254186
- else if (this._geometryB instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_5__.Arc3d) {
254187
- this.dispatchSegmentArc(segmentA, segmentA.point0Ref, 0.0, segmentA.point1Ref, 1.0, this._geometryB, false);
254188
- }
254189
- else if (this._geometryB instanceof _bspline_BSplineCurve__WEBPACK_IMPORTED_MODULE_14__.BSplineCurve3d) {
254190
- this.dispatchSegmentBsplineCurve(segmentA, this._geometryB, false);
254191
- }
254192
- else if (this._geometryB instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_12__.CurveCollection) {
254193
- this.dispatchCurveCollection(segmentA, this.handleLineSegment3d.bind(this));
254194
- }
254195
- else if (this._geometryB instanceof _CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_13__.CurveChainWithDistanceIndex) {
254196
- this.dispatchCurveChainWithDistanceIndex(segmentA, this.handleLineSegment3d.bind(this));
254238
+ const v0 = CurveCurveCloseApproachXY._workPointBB0;
254239
+ const v1 = CurveCurveCloseApproachXY._workPointBB1;
254240
+ // 1. record intersections
254241
+ const intersections = _CurveCurve__WEBPACK_IMPORTED_MODULE_12__.CurveCurve.intersectionXYPairs(arcA, false, lsB, false, this._xyTolerance);
254242
+ for (const intersection of intersections)
254243
+ this.testAndRecordPair(intersection, reversed);
254244
+ // 2. record linestring interior vertex projections onto arc
254245
+ const fStep = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.safeDivideFraction(1.0, lsB.numEdges(), 0);
254246
+ for (let i = 1; i < lsB.numEdges(); ++i)
254247
+ this.testAndRecordProjection(lsB, i * fStep, lsB.pointAtUnchecked(i, v0), arcA, !reversed);
254248
+ // 3. record arc/linestring endpoint projections onto linestring/arc
254249
+ this.testAndRecordEndPointApproaches(arcA, lsB, reversed);
254250
+ // 4. record perpendiculars from within a segment to the arc
254251
+ lsB.startPoint(v0);
254252
+ for (let iSeg = 0; iSeg < lsB.numEdges(); ++iSeg, v0.setFrom(v1)) {
254253
+ lsB.pointAtUnchecked(iSeg + 1, v1);
254254
+ this.announceAllPerpendicularsSegmentArcBounded(v0, v1, arcA, (lineFraction, linePoint, arcFraction, arcPoint) => {
254255
+ const fLineString = lsB.segmentIndexAndLocalFractionToGlobalFraction(iSeg, lineFraction);
254256
+ this.testAndRecordPointPair(arcA, arcFraction, arcPoint, lsB, fLineString, linePoint, reversed);
254257
+ });
254197
254258
  }
254198
- return undefined;
254199
254259
  }
254200
254260
  /**
254201
254261
  * Set bits for comparison to range xy
@@ -254236,7 +254296,7 @@ class CurveCurveCloseApproachXY extends _geometry3d_GeometryHandler__WEBPACK_IMP
254236
254296
  return;
254237
254297
  let bitB0;
254238
254298
  let bitB1;
254239
- const rangeA1 = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_15__.Range3d.createNull();
254299
+ const rangeA1 = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_13__.Range3d.createNull();
254240
254300
  const pointA0 = CurveCurveCloseApproachXY._workPointAA0;
254241
254301
  const pointA1 = CurveCurveCloseApproachXY._workPointAA1;
254242
254302
  const pointB0 = CurveCurveCloseApproachXY._workPointBB0;
@@ -254269,76 +254329,235 @@ class CurveCurveCloseApproachXY extends _geometry3d_GeometryHandler__WEBPACK_IMP
254269
254329
  // DO NOT study the segment in detail if both bitB bits are on for any of the 4 planes
254270
254330
  // (i.e., no intersection between rangeA1 and the range around line segment [B0,B1])
254271
254331
  if ((bitB0 & bitB1) === 0)
254272
- this.dispatchSegmentSegment(lsA, pointA0, fA0, pointA1, fA1, lsB, pointB0, fB0, pointB1, fB1, reversed);
254332
+ this.computeSegmentSegment(lsA, pointA0, fA0, pointA1, fA1, lsB, pointB0, fB0, pointB1, fB1, reversed);
254273
254333
  }
254274
254334
  }
254275
254335
  }
254276
254336
  }
254277
254337
  }
254338
+ /** Low level dispatch of curve collection. */
254339
+ dispatchCurveCollection(geomA, geomAHandler) {
254340
+ const geomB = this._geometryB; // save
254341
+ if (!geomB || !geomB.children || !(geomB instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_14__.CurveCollection))
254342
+ return;
254343
+ for (const child of geomB.children) {
254344
+ this.resetGeometry(child);
254345
+ geomAHandler(geomA);
254346
+ }
254347
+ this._geometryB = geomB; // restore
254348
+ }
254349
+ /** Low level dispatch to geomA given a CurveChainWithDistanceIndex in geometryB. */
254350
+ dispatchCurveChainWithDistanceIndex(geomA, geomAHandler) {
254351
+ if (!this._geometryB || !(this._geometryB instanceof _CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_15__.CurveChainWithDistanceIndex))
254352
+ return;
254353
+ if (geomA instanceof _CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_15__.CurveChainWithDistanceIndex)
254354
+ (0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.assert)(false, "call handleCurveChainWithDistanceIndex(geomA) instead");
254355
+ const saveResults = this.grabPairedResults();
254356
+ const geomB = this._geometryB;
254357
+ for (const child of geomB.path.children) {
254358
+ this.resetGeometry(child);
254359
+ geomAHandler(geomA);
254360
+ }
254361
+ this.resetGeometry(geomB);
254362
+ const childResults = this._results.extractArray();
254363
+ childResults.forEach((pair) => {
254364
+ _CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_15__.CurveChainWithDistanceIndex.convertChildDetailToChainDetailSingle(pair, undefined, geomB);
254365
+ this._results.insert(pair);
254366
+ });
254367
+ saveResults.forEach((pair) => this._results.insert(pair));
254368
+ }
254369
+ /** Double dispatch handler for strongly typed segment. */
254370
+ handleLineSegment3d(segmentA) {
254371
+ if (this._geometryB instanceof _LineSegment3d__WEBPACK_IMPORTED_MODULE_16__.LineSegment3d) {
254372
+ const segmentB = this._geometryB;
254373
+ this.computeSegmentSegment(segmentA, segmentA.point0Ref, 0.0, segmentA.point1Ref, 1.0, segmentB, segmentB.point0Ref, 0.0, segmentB.point1Ref, 1.0, false);
254374
+ }
254375
+ else if (this._geometryB instanceof _LineString3d__WEBPACK_IMPORTED_MODULE_11__.LineString3d) {
254376
+ this.computeSegmentLineString(segmentA, this._geometryB, false);
254377
+ }
254378
+ else if (this._geometryB instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_6__.Arc3d) {
254379
+ this.computeSegmentArc(segmentA, this._geometryB, false);
254380
+ }
254381
+ else if (this._geometryB instanceof _bspline_BSplineCurve__WEBPACK_IMPORTED_MODULE_17__.BSplineCurve3d) {
254382
+ this.dispatchSegmentBsplineCurve(segmentA, this._geometryB, false);
254383
+ }
254384
+ else if (this._geometryB instanceof _spiral_TransitionSpiral3d__WEBPACK_IMPORTED_MODULE_18__.TransitionSpiral3d) {
254385
+ this.dispatchCurveSpiral(segmentA, this._geometryB, false);
254386
+ }
254387
+ else if (this._geometryB instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_14__.CurveCollection) {
254388
+ this.dispatchCurveCollection(segmentA, this.handleLineSegment3d.bind(this));
254389
+ }
254390
+ else if (this._geometryB instanceof _CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_15__.CurveChainWithDistanceIndex) {
254391
+ this.dispatchCurveChainWithDistanceIndex(segmentA, this.handleLineSegment3d.bind(this));
254392
+ }
254393
+ return undefined;
254394
+ }
254278
254395
  /** Double dispatch handler for strongly typed linestring. */
254279
254396
  handleLineString3d(lsA) {
254280
- if (this._geometryB instanceof _LineString3d__WEBPACK_IMPORTED_MODULE_8__.LineString3d) {
254281
- const lsB = this._geometryB;
254282
- this.computeLineStringLineString(lsA, lsB, false);
254283
- }
254284
- else if (this._geometryB instanceof _LineSegment3d__WEBPACK_IMPORTED_MODULE_6__.LineSegment3d) {
254397
+ if (this._geometryB instanceof _LineSegment3d__WEBPACK_IMPORTED_MODULE_16__.LineSegment3d) {
254285
254398
  this.computeSegmentLineString(this._geometryB, lsA, true);
254286
254399
  }
254287
- else if (this._geometryB instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_5__.Arc3d) {
254400
+ else if (this._geometryB instanceof _LineString3d__WEBPACK_IMPORTED_MODULE_11__.LineString3d) {
254401
+ this.computeLineStringLineString(lsA, this._geometryB, false);
254402
+ }
254403
+ else if (this._geometryB instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_6__.Arc3d) {
254288
254404
  this.computeArcLineString(this._geometryB, lsA, true);
254289
254405
  }
254290
- else if (this._geometryB instanceof _bspline_BSplineCurve__WEBPACK_IMPORTED_MODULE_14__.BSplineCurve3d) {
254406
+ else if (this._geometryB instanceof _bspline_BSplineCurve__WEBPACK_IMPORTED_MODULE_17__.BSplineCurve3d) {
254291
254407
  this.dispatchLineStringBSplineCurve(lsA, this._geometryB, false);
254292
254408
  }
254293
- else if (this._geometryB instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_12__.CurveCollection) {
254409
+ else if (this._geometryB instanceof _spiral_TransitionSpiral3d__WEBPACK_IMPORTED_MODULE_18__.TransitionSpiral3d) {
254410
+ this.dispatchCurveSpiral(lsA, this._geometryB, false);
254411
+ }
254412
+ else if (this._geometryB instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_14__.CurveCollection) {
254294
254413
  this.dispatchCurveCollection(lsA, this.handleLineString3d.bind(this));
254295
254414
  }
254296
- else if (this._geometryB instanceof _CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_13__.CurveChainWithDistanceIndex) {
254415
+ else if (this._geometryB instanceof _CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_15__.CurveChainWithDistanceIndex) {
254297
254416
  this.dispatchCurveChainWithDistanceIndex(lsA, this.handleLineString3d.bind(this));
254298
254417
  }
254299
254418
  return undefined;
254300
254419
  }
254301
254420
  /** Double dispatch handler for strongly typed arc. */
254302
- handleArc3d(arc0) {
254303
- if (this._geometryB instanceof _LineSegment3d__WEBPACK_IMPORTED_MODULE_6__.LineSegment3d) {
254304
- this.dispatchSegmentArc(this._geometryB, this._geometryB.point0Ref, 0.0, this._geometryB.point1Ref, 1.0, arc0, true);
254421
+ handleArc3d(arcA) {
254422
+ if (this._geometryB instanceof _LineSegment3d__WEBPACK_IMPORTED_MODULE_16__.LineSegment3d) {
254423
+ this.computeSegmentArc(this._geometryB, arcA, true);
254305
254424
  }
254306
- else if (this._geometryB instanceof _LineString3d__WEBPACK_IMPORTED_MODULE_8__.LineString3d) {
254307
- this.computeArcLineString(arc0, this._geometryB, false);
254425
+ else if (this._geometryB instanceof _LineString3d__WEBPACK_IMPORTED_MODULE_11__.LineString3d) {
254426
+ this.computeArcLineString(arcA, this._geometryB, false);
254308
254427
  }
254309
- else if (this._geometryB instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_5__.Arc3d) {
254310
- this.dispatchArcArc(arc0, this._geometryB, false);
254428
+ else if (this._geometryB instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_6__.Arc3d) {
254429
+ this.dispatchArcArc(arcA, this._geometryB, false);
254311
254430
  }
254312
- else if (this._geometryB instanceof _bspline_BSplineCurve__WEBPACK_IMPORTED_MODULE_14__.BSplineCurve3d) {
254313
- this.dispatchArcBsplineCurve3d(arc0, this._geometryB, false);
254431
+ else if (this._geometryB instanceof _bspline_BSplineCurve__WEBPACK_IMPORTED_MODULE_17__.BSplineCurve3d) {
254432
+ this.dispatchArcBsplineCurve3d(arcA, this._geometryB, false);
254314
254433
  }
254315
- else if (this._geometryB instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_12__.CurveCollection) {
254316
- this.dispatchCurveCollection(arc0, this.handleArc3d.bind(this));
254434
+ else if (this._geometryB instanceof _spiral_TransitionSpiral3d__WEBPACK_IMPORTED_MODULE_18__.TransitionSpiral3d) {
254435
+ this.dispatchCurveSpiral(arcA, this._geometryB, false);
254317
254436
  }
254318
- else if (this._geometryB instanceof _CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_13__.CurveChainWithDistanceIndex) {
254319
- this.dispatchCurveChainWithDistanceIndex(arc0, this.handleArc3d.bind(this));
254437
+ else if (this._geometryB instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_14__.CurveCollection) {
254438
+ this.dispatchCurveCollection(arcA, this.handleArc3d.bind(this));
254439
+ }
254440
+ else if (this._geometryB instanceof _CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_15__.CurveChainWithDistanceIndex) {
254441
+ this.dispatchCurveChainWithDistanceIndex(arcA, this.handleArc3d.bind(this));
254320
254442
  }
254321
254443
  return undefined;
254322
254444
  }
254323
254445
  /** Double dispatch handler for strongly typed bspline curve. */
254324
- handleBSplineCurve3d(curve) {
254325
- if (this._geometryB instanceof _LineSegment3d__WEBPACK_IMPORTED_MODULE_6__.LineSegment3d) {
254326
- this.dispatchSegmentBsplineCurve(this._geometryB, curve, true);
254446
+ handleBSplineCurve3d(curveA) {
254447
+ if (this._geometryB instanceof _LineSegment3d__WEBPACK_IMPORTED_MODULE_16__.LineSegment3d) {
254448
+ this.dispatchSegmentBsplineCurve(this._geometryB, curveA, true);
254327
254449
  }
254328
- else if (this._geometryB instanceof _LineString3d__WEBPACK_IMPORTED_MODULE_8__.LineString3d) {
254329
- this.dispatchLineStringBSplineCurve(this._geometryB, curve, true);
254450
+ else if (this._geometryB instanceof _LineString3d__WEBPACK_IMPORTED_MODULE_11__.LineString3d) {
254451
+ this.dispatchLineStringBSplineCurve(this._geometryB, curveA, true);
254330
254452
  }
254331
- else if (this._geometryB instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_5__.Arc3d) {
254332
- this.dispatchArcBsplineCurve3d(this._geometryB, curve, true);
254453
+ else if (this._geometryB instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_6__.Arc3d) {
254454
+ this.dispatchArcBsplineCurve3d(this._geometryB, curveA, true);
254333
254455
  }
254334
- else if (this._geometryB instanceof _bspline_BSplineCurve__WEBPACK_IMPORTED_MODULE_14__.BSplineCurve3dBase) {
254335
- this.dispatchBSplineCurve3dBSplineCurve3d(curve, this._geometryB, false);
254456
+ else if (this._geometryB instanceof _bspline_BSplineCurve__WEBPACK_IMPORTED_MODULE_17__.BSplineCurve3dBase) {
254457
+ this.dispatchBSplineCurve3dBSplineCurve3d(curveA, this._geometryB, false);
254336
254458
  }
254337
- else if (this._geometryB instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_12__.CurveCollection) {
254338
- this.dispatchCurveCollection(curve, this.handleBSplineCurve3d.bind(this));
254459
+ else if (this._geometryB instanceof _spiral_TransitionSpiral3d__WEBPACK_IMPORTED_MODULE_18__.TransitionSpiral3d) {
254460
+ this.dispatchCurveSpiral(curveA, this._geometryB, false);
254339
254461
  }
254340
- else if (this._geometryB instanceof _CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_13__.CurveChainWithDistanceIndex) {
254341
- this.dispatchCurveChainWithDistanceIndex(curve, this.handleBSplineCurve3d.bind(this));
254462
+ else if (this._geometryB instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_14__.CurveCollection) {
254463
+ this.dispatchCurveCollection(curveA, this.handleBSplineCurve3d.bind(this));
254464
+ }
254465
+ else if (this._geometryB instanceof _CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_15__.CurveChainWithDistanceIndex) {
254466
+ this.dispatchCurveChainWithDistanceIndex(curveA, this.handleBSplineCurve3d.bind(this));
254467
+ }
254468
+ return undefined;
254469
+ }
254470
+ /**
254471
+ * Process seeds for xy close approach between the curve and spiral.
254472
+ * * Refine each result via Newton iteration. If it doesn't converge, remove it.
254473
+ * @param seeds The initial seed results to refine.
254474
+ * @param curveA The other curve primitive. May also be a transition spiral.
254475
+ * @param spiralB The transition spiral.
254476
+ * @param reversed whether `spiralB` data is in `detailA` of each recorded pair, and `curveA` data in `detailB`.
254477
+ */
254478
+ refineSpiralResultsByNewton(seeds, curveA, spiralB, reversed = false) {
254479
+ const xyMatchingFunction = new _numerics_Newton__WEBPACK_IMPORTED_MODULE_10__.CurveCurveCloseApproachXYRRtoRRD(curveA, spiralB);
254480
+ const newtonSearcher = new _numerics_Newton__WEBPACK_IMPORTED_MODULE_10__.Newton2dUnboundedWithDerivative(xyMatchingFunction, 50, this._newtonTolerance); // seen: 47
254481
+ for (const seed of seeds) {
254482
+ const detailA = reversed ? seed.detailB : seed.detailA;
254483
+ const detailB = reversed ? seed.detailA : seed.detailB;
254484
+ (0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.assert)(detailB.curve instanceof _LineString3d__WEBPACK_IMPORTED_MODULE_11__.LineString3d, "Caller has discretized the spiral");
254485
+ newtonSearcher.setUV(detailA.fraction, detailB.fraction); // use linestring fraction as spiral param; it generally yields a closer point than fractional length!
254486
+ if (newtonSearcher.runIterations()) {
254487
+ const fractionA = newtonSearcher.getU();
254488
+ const fractionB = newtonSearcher.getV();
254489
+ if (this.acceptFraction(fractionA) && this.acceptFraction(fractionB))
254490
+ this.testAndRecordPointPair(curveA, fractionA, undefined, spiralB, fractionB, undefined, reversed);
254491
+ } // ignore failure to converge
254492
+ }
254493
+ }
254494
+ /**
254495
+ * Append stroke points and return the line string.
254496
+ * * This is a convenient wrapper for [[CurvePrimitive.emitStrokes]] but the analogous instance method cannot be added
254497
+ * to that class due to the ensuing recursion with subclass [[LineString3d]].
254498
+ * @param options options for stroking the instance curve.
254499
+ * @param result object to receive appended stroke points; if omitted, a new object is created, populated, and returned.
254500
+ */
254501
+ strokeCurve(curve, options, result) {
254502
+ const ls = result ? result : _LineString3d__WEBPACK_IMPORTED_MODULE_11__.LineString3d.create();
254503
+ curve.emitStrokes(ls, options);
254504
+ return ls;
254505
+ }
254506
+ /** Find and return the close approaches between curveA and the discretization of curveB. */
254507
+ computeDiscreteCloseApproachResults(curveA, lsB, reversed) {
254508
+ const maxDist = this.maxDistanceToAccept;
254509
+ const saveResults = this.grabPairedResults(); // save current results
254510
+ const geomB = this._geometryB;
254511
+ this.maxDistanceToAccept = maxDist ? maxDist * 1.2 : undefined; // HEURISTIC: allow slack for Newton seeds
254512
+ this.resetGeometry(curveA);
254513
+ this.handleLineString3d(lsB); // populate empty results with discrete solutions
254514
+ if (!reversed) {
254515
+ // handleLineString3d put lsB data into detailA, so if we aren't reversing, we need to swap
254516
+ for (const result of this._results)
254517
+ result.swapDetails();
254518
+ }
254519
+ this.resetGeometry(geomB);
254520
+ this.maxDistanceToAccept = maxDist;
254521
+ const discreteResults = this._results.extractArray();
254522
+ saveResults.forEach((pair) => this._results.insert(pair)); // restore current results
254523
+ return discreteResults;
254524
+ }
254525
+ /**
254526
+ * Compute the XY close approach of a curve and a spiral.
254527
+ * @param curveA curve to find its close approach with spiralB. May also be a transition spiral.
254528
+ * @param spiralB transition spiral to find its close approach with curveA.
254529
+ * @param reversed whether `spiralB` data will be recorded in `detailA` of each result, and `curveA` data in `detailB`.
254530
+ */
254531
+ dispatchCurveSpiral(curveA, spiralB, reversed) {
254532
+ // explicit search for intersections (Newton converges too slowly on DirectSpiral3d tangent intersections)
254533
+ const intersections = _CurveCurve__WEBPACK_IMPORTED_MODULE_12__.CurveCurve.intersectionXYPairs(curveA, false, spiralB, false, this._xyTolerance);
254534
+ for (const intersection of intersections)
254535
+ this.testAndRecordPair(intersection, reversed);
254536
+ // append seeds computed by solving the discretized spiral close approach problem, then refine the seeds via Newton
254537
+ let cpA = curveA;
254538
+ if (curveA instanceof _spiral_TransitionSpiral3d__WEBPACK_IMPORTED_MODULE_18__.TransitionSpiral3d)
254539
+ cpA = this.strokeCurve(curveA);
254540
+ const cpB = this.strokeCurve(spiralB);
254541
+ const seeds = this.computeDiscreteCloseApproachResults(cpA, cpB, reversed);
254542
+ this.refineSpiralResultsByNewton(seeds, curveA, spiralB, reversed);
254543
+ if (curveA instanceof _LineString3d__WEBPACK_IMPORTED_MODULE_11__.LineString3d) { // explicitly test corners (where Newton converges too slowly)
254544
+ const fStep = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.safeDivideFraction(1.0, curveA.numEdges(), 0);
254545
+ const v0 = CurveCurveCloseApproachXY._workPointBB0;
254546
+ for (let i = 1; i < curveA.numEdges(); ++i)
254547
+ this.testAndRecordProjection(curveA, i * fStep, curveA.pointAtUnchecked(i, v0), spiralB, reversed);
254548
+ }
254549
+ this.testAndRecordEndPointApproaches(curveA, spiralB, reversed);
254550
+ }
254551
+ /** Double dispatch handler for strongly typed spiral curve. */
254552
+ handleTransitionSpiral(spiral) {
254553
+ if (this._geometryB instanceof _CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_15__.CurveChainWithDistanceIndex) {
254554
+ this.dispatchCurveChainWithDistanceIndex(spiral, this.handleTransitionSpiral.bind(this));
254555
+ }
254556
+ else if (this._geometryB instanceof _CurvePrimitive__WEBPACK_IMPORTED_MODULE_19__.CurvePrimitive) {
254557
+ this.dispatchCurveSpiral(this._geometryB, spiral, true);
254558
+ }
254559
+ else if (this._geometryB instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_14__.CurveCollection) {
254560
+ this.dispatchCurveCollection(spiral, this.handleTransitionSpiral.bind(this));
254342
254561
  }
254343
254562
  return undefined;
254344
254563
  }
@@ -254346,7 +254565,11 @@ class CurveCurveCloseApproachXY extends _geometry3d_GeometryHandler__WEBPACK_IMP
254346
254565
  handleCurveChainWithDistanceIndex(chain) {
254347
254566
  super.handleCurveChainWithDistanceIndex(chain);
254348
254567
  // if _geometryB is also a CurveChainWithDistanceIndex, it will already have been converted by dispatchCurveChainWithDistanceIndex
254349
- this._results = _CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_13__.CurveChainWithDistanceIndex.convertChildDetailToChainDetail(this._results, 0, chain, undefined, true);
254568
+ const childResults = this._results.extractArray();
254569
+ childResults.forEach((pair) => {
254570
+ _CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_15__.CurveChainWithDistanceIndex.convertChildDetailToChainDetailSingle(pair, chain, undefined);
254571
+ this._results.insert(pair);
254572
+ });
254350
254573
  }
254351
254574
  /** Double dispatch handler for strongly typed homogeneous bspline curve .. */
254352
254575
  handleBSplineCurve3dH(_curve) {
@@ -255371,12 +255594,11 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
255371
255594
  }
255372
255595
  /**
255373
255596
  * Process tail of `this._results` for xy-intersections between the curve and spiral.
255374
- * * If a result is not already an intersection, refine it via Newton iteration unless it doesn't converge, in which
255375
- * case remove it.
255597
+ * * Refine each result via Newton iteration. If it doesn't converge, remove it.
255376
255598
  * @param curveA The other curve primitive. May also be a transition spiral.
255377
255599
  * @param spiralB The transition spiral.
255378
255600
  * @param index0 index of first entry in tail of `this._results` to refine.
255379
- * @param reversed Whether `spiralB` data is in `detailA` of each recorded pair, and `curveA` data in `detailB`.
255601
+ * @param reversed whether `spiralB` data is in `detailA` of each recorded pair, and `curveA` data in `detailB`.
255380
255602
  */
255381
255603
  refineSpiralResultsByNewton(curveA, spiralB, index0, reversed = false) {
255382
255604
  if (index0 >= this._results.length)
@@ -255386,25 +255608,16 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
255386
255608
  const maxIterations = 100; // observed 73 iterations to convergence in tangent case
255387
255609
  const newtonSearcher = new _numerics_Newton__WEBPACK_IMPORTED_MODULE_13__.Newton2dUnboundedWithDerivative(xyMatchingFunction, maxIterations);
255388
255610
  const fractionTol = 2 * newtonSearcher.stepSizeTolerance; // relative cluster diameter for Newton convergence
255389
- const comparePairs = (a, b) => {
255390
- (0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.assert)(() => a.detailA.curve === b.detailA.curve && a.detailB.curve === b.detailB.curve, "pairs are compatible");
255391
- // sort on either fraction, then on the point, using appropriate tolerances for each
255392
- if (_Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.isAlmostEqualNumber(a.detailA.fraction, b.detailA.fraction, fractionTol))
255393
- return 0;
255394
- if (a.detailA.point.isAlmostEqualXY(b.detailA.point, this._coincidentGeometryContext.tolerance))
255395
- return 0;
255396
- return a.detailA.fraction - b.detailA.fraction;
255397
- };
255398
- const myResults = new _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.SortedArray(comparePairs, _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.DuplicatePolicy.Retain);
255399
- const pushToMyResults = (cpA, fA, cpB, fB) => {
255400
- const detailA = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_7__.CurveLocationDetail.createCurveFractionPoint(cpA, fA, cpA.fractionToPoint(fA));
255401
- const detailB = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_7__.CurveLocationDetail.createCurveFractionPoint(cpB, fB, cpB.fractionToPoint(fB));
255611
+ const compare = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_7__.CurveLocationDetailPair.comparePairsByFractions(fractionTol, this._coincidentGeometryContext.tolerance, true);
255612
+ const myResults = new _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.SortedArray(compare, _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.DuplicatePolicy.Retain);
255613
+ const pushToMyResults = (cpA, fA, pA, cpB, fB, pB) => {
255614
+ const detailA = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_7__.CurveLocationDetail.createCurveFractionPoint(cpA, fA, pA);
255615
+ const detailB = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_7__.CurveLocationDetail.createCurveFractionPoint(cpB, fB, pB);
255402
255616
  detailA.setIntervalRole(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_7__.CurveIntervalRole.isolated);
255403
255617
  detailB.setIntervalRole(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_7__.CurveIntervalRole.isolated);
255404
- let pushed = false;
255405
- myResults.insert(new _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_7__.CurveLocationDetailPair(reversed ? detailB : detailA, reversed ? detailA : detailB), () => pushed = true);
255406
- return pushed;
255618
+ myResults.insert(new _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_7__.CurveLocationDetailPair(reversed ? detailB : detailA, reversed ? detailA : detailB));
255407
255619
  };
255620
+ const strictTolerance = this._coincidentGeometryContext.tolerance * 0.0001;
255408
255621
  for (let i = index0; i < this._results.length; i++) {
255409
255622
  const pair = this._results[i];
255410
255623
  const detailA = reversed ? pair.detailB : pair.detailA;
@@ -255413,18 +255626,16 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
255413
255626
  const extendA0 = reversed ? this._extendB0 : this._extendA0;
255414
255627
  const extendA1 = reversed ? this._extendB1 : this._extendA1;
255415
255628
  newtonSearcher.setUV(detailA.fraction, detailB.fraction); // use linestring fraction as spiral param; it generally yields a closer point than fractional length!
255416
- if (newtonSearcher.runIterations()) {
255417
- const fractionA = newtonSearcher.getU();
255418
- const fractionB = newtonSearcher.getV();
255419
- if (this.acceptFraction(extendA0, fractionA, extendA1) && this.acceptFraction(false, fractionB, false))
255420
- pushToMyResults(curveA, fractionA, spiralB, fractionB);
255421
- }
255422
- else if (newtonSearcher.numIterations < 10) {
255423
- // if Newton failed early due to vanishing (partial) derivative, check for a root there
255424
- const fractionA = newtonSearcher.getU();
255425
- const fractionB = newtonSearcher.getV();
255426
- if (curveA.fractionToPoint(fractionA).isAlmostEqualXY(spiralB.fractionToPoint(fractionB), this._coincidentGeometryContext.tolerance))
255427
- pushToMyResults(curveA, fractionA, spiralB, fractionB);
255629
+ let converged = newtonSearcher.runIterations();
255630
+ const fractionA = newtonSearcher.getU();
255631
+ const fractionB = newtonSearcher.getV();
255632
+ if (this.acceptFraction(extendA0, fractionA, extendA1) && this.acceptFraction(false, fractionB, false)) {
255633
+ const pointA = curveA.fractionToPoint(fractionA, CurveCurveIntersectXY._workPointA0);
255634
+ const pointB = spiralB.fractionToPoint(fractionB, CurveCurveIntersectXY._workPointB0);
255635
+ if (!converged) // Newton may have found close points even if it didn't converge parametrically
255636
+ converged = pointA.isAlmostEqualXY(pointB, strictTolerance); // we can afford to be choosy
255637
+ if (converged)
255638
+ pushToMyResults(curveA, fractionA, pointA, spiralB, fractionB, pointB);
255428
255639
  }
255429
255640
  }
255430
255641
  this._results.splice(index0, this._results.length - index0, ...myResults.extractArray());
@@ -255469,7 +255680,7 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
255469
255680
  */
255470
255681
  appendDiscreteIntersectionResults(curveA, extendA0, extendA1, lsB, reversed) {
255471
255682
  const i0 = this._results.length;
255472
- // handleLineString3d requires us to swap geometries:
255683
+ // handleLineString3d requires us to swap geometries
255473
255684
  const geomB = this._geometryB;
255474
255685
  const extendB0 = this._extendB0;
255475
255686
  const extendB1 = this._extendB1;
@@ -258107,54 +258318,6 @@ class MultiChainCollector {
258107
258318
  }
258108
258319
 
258109
258320
 
258110
- /***/ }),
258111
-
258112
- /***/ "../../core/geometry/lib/esm/curve/internalContexts/NewtonRtoRStrokeHandler.js":
258113
- /*!*************************************************************************************!*\
258114
- !*** ../../core/geometry/lib/esm/curve/internalContexts/NewtonRtoRStrokeHandler.js ***!
258115
- \*************************************************************************************/
258116
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
258117
-
258118
- "use strict";
258119
- __webpack_require__.r(__webpack_exports__);
258120
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
258121
- /* harmony export */ NewtonRtoRStrokeHandler: () => (/* binding */ NewtonRtoRStrokeHandler)
258122
- /* harmony export */ });
258123
- /* harmony import */ var _numerics_Newton__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../numerics/Newton */ "../../core/geometry/lib/esm/numerics/Newton.js");
258124
- /*---------------------------------------------------------------------------------------------
258125
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
258126
- * See LICENSE.md in the project root for license terms and full copyright notice.
258127
- *--------------------------------------------------------------------------------------------*/
258128
- /** @packageDocumentation
258129
- * @module Curve
258130
- */
258131
-
258132
- /**
258133
- * Intermediate class for managing the parentCurve announcements from an IStrokeHandler.
258134
- * @internal
258135
- */
258136
- class NewtonRtoRStrokeHandler extends _numerics_Newton__WEBPACK_IMPORTED_MODULE_0__.NewtonEvaluatorRtoR {
258137
- _parentCurvePrimitive;
258138
- constructor() {
258139
- super();
258140
- this._parentCurvePrimitive = undefined;
258141
- }
258142
- /**
258143
- * Retain the parentCurvePrimitive.
258144
- * * Calling this method tells the handler that the parent curve is to be used for detail searches.
258145
- * * Example: Transition spiral search is based on linestring first, then the exact spiral.
258146
- * * Example: CurveChainWithDistanceIndex does NOT do this announcement; the constituents act independently.
258147
- */
258148
- startParentCurvePrimitive(curve) {
258149
- this._parentCurvePrimitive = curve;
258150
- }
258151
- /** Forget the parentCurvePrimitive */
258152
- endParentCurvePrimitive(_curve) {
258153
- this._parentCurvePrimitive = undefined;
258154
- }
258155
- }
258156
-
258157
-
258158
258321
  /***/ }),
258159
258322
 
258160
258323
  /***/ "../../core/geometry/lib/esm/curve/internalContexts/PlaneAltitudeRangeContext.js":
@@ -262164,8 +262327,9 @@ __webpack_require__.r(__webpack_exports__);
262164
262327
  /* harmony export */ });
262165
262328
  /* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
262166
262329
  /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
262330
+ /* harmony import */ var _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../geometry3d/GeometryHandler */ "../../core/geometry/lib/esm/geometry3d/GeometryHandler.js");
262167
262331
  /* harmony import */ var _geometry3d_Segment1d__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../geometry3d/Segment1d */ "../../core/geometry/lib/esm/geometry3d/Segment1d.js");
262168
- /* harmony import */ var _internalContexts_CurveLengthContext__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../internalContexts/CurveLengthContext */ "../../core/geometry/lib/esm/curve/internalContexts/CurveLengthContext.js");
262332
+ /* harmony import */ var _internalContexts_CurveLengthContext__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../internalContexts/CurveLengthContext */ "../../core/geometry/lib/esm/curve/internalContexts/CurveLengthContext.js");
262169
262333
  /* harmony import */ var _LineString3d__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
262170
262334
  /* harmony import */ var _StrokeOptions__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../StrokeOptions */ "../../core/geometry/lib/esm/curve/StrokeOptions.js");
262171
262335
  /* harmony import */ var _AustralianRailCorpXYEvaluator__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./AustralianRailCorpXYEvaluator */ "../../core/geometry/lib/esm/curve/spiral/AustralianRailCorpXYEvaluator.js");
@@ -262195,6 +262359,7 @@ __webpack_require__.r(__webpack_exports__);
262195
262359
 
262196
262360
 
262197
262361
 
262362
+
262198
262363
  /**
262199
262364
  * DirectSpiral3d acts like a TransitionSpiral3d for serialization purposes, but implements spiral types that have
262200
262365
  * "direct" xy calculations without the integrations required for IntegratedSpiral3d.
@@ -262572,11 +262737,16 @@ class DirectSpiral3d extends _TransitionSpiral3d__WEBPACK_IMPORTED_MODULE_1__.Tr
262572
262737
  }
262573
262738
  /**
262574
262739
  * Add strokes from this spiral to `dest`.
262575
- * * Line strings will usually stroke as just their points.
262576
- * * If maxEdgeLength is given, this will sub-stroke within the linestring -- not what we want.
262740
+ * @param options optional stroking options. Pass `undefined` to return cached strokes.
262577
262741
  */
262578
262742
  emitStrokes(dest, options) {
262579
- this.activeStrokes.emitStrokes(dest, options);
262743
+ if (!options)
262744
+ this.activeStrokes.emitStrokes(dest, options);
262745
+ else {
262746
+ const stroker = new _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODULE_12__.UniformStrokeCollector(this);
262747
+ this.emitStrokableParts(stroker, options);
262748
+ stroker.claimLineString(dest);
262749
+ }
262580
262750
  }
262581
262751
  /** Emit stroke fragments to `dest` handler. */
262582
262752
  emitStrokableParts(dest, options) {
@@ -262586,7 +262756,7 @@ class DirectSpiral3d extends _TransitionSpiral3d__WEBPACK_IMPORTED_MODULE_1__.Tr
262586
262756
  // hack: specify the extended range so we can compute length of an extended spiral
262587
262757
  let globalFraction0 = 0.0;
262588
262758
  let globalFraction1 = 1.0;
262589
- if (dest instanceof _internalContexts_CurveLengthContext__WEBPACK_IMPORTED_MODULE_12__.CurveLengthContext) {
262759
+ if (dest instanceof _internalContexts_CurveLengthContext__WEBPACK_IMPORTED_MODULE_13__.CurveLengthContext) {
262590
262760
  if (dest.getFraction0 < 0.0)
262591
262761
  globalFraction0 = dest.getFraction0;
262592
262762
  if (dest.getFraction1 > 1.0)
@@ -262692,15 +262862,16 @@ __webpack_require__.r(__webpack_exports__);
262692
262862
  /* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
262693
262863
  /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
262694
262864
  /* harmony import */ var _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../geometry3d/AngleSweep */ "../../core/geometry/lib/esm/geometry3d/AngleSweep.js");
262865
+ /* harmony import */ var _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../geometry3d/GeometryHandler */ "../../core/geometry/lib/esm/geometry3d/GeometryHandler.js");
262695
262866
  /* harmony import */ var _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../geometry3d/Matrix3d */ "../../core/geometry/lib/esm/geometry3d/Matrix3d.js");
262696
- /* harmony import */ var _geometry3d_Plane3dByOriginAndVectors__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../geometry3d/Plane3dByOriginAndVectors */ "../../core/geometry/lib/esm/geometry3d/Plane3dByOriginAndVectors.js");
262867
+ /* harmony import */ var _geometry3d_Plane3dByOriginAndVectors__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../../geometry3d/Plane3dByOriginAndVectors */ "../../core/geometry/lib/esm/geometry3d/Plane3dByOriginAndVectors.js");
262697
262868
  /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
262698
- /* harmony import */ var _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../geometry3d/Ray3d */ "../../core/geometry/lib/esm/geometry3d/Ray3d.js");
262869
+ /* harmony import */ var _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../geometry3d/Ray3d */ "../../core/geometry/lib/esm/geometry3d/Ray3d.js");
262699
262870
  /* harmony import */ var _geometry3d_Segment1d__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../geometry3d/Segment1d */ "../../core/geometry/lib/esm/geometry3d/Segment1d.js");
262700
- /* harmony import */ var _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../geometry3d/Transform */ "../../core/geometry/lib/esm/geometry3d/Transform.js");
262871
+ /* harmony import */ var _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../geometry3d/Transform */ "../../core/geometry/lib/esm/geometry3d/Transform.js");
262701
262872
  /* harmony import */ var _numerics_Quadrature__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../numerics/Quadrature */ "../../core/geometry/lib/esm/numerics/Quadrature.js");
262702
262873
  /* harmony import */ var _LineString3d__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
262703
- /* harmony import */ var _StrokeOptions__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../StrokeOptions */ "../../core/geometry/lib/esm/curve/StrokeOptions.js");
262874
+ /* harmony import */ var _StrokeOptions__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../StrokeOptions */ "../../core/geometry/lib/esm/curve/StrokeOptions.js");
262704
262875
  /* harmony import */ var _NormalizedTransition__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./NormalizedTransition */ "../../core/geometry/lib/esm/curve/spiral/NormalizedTransition.js");
262705
262876
  /* harmony import */ var _TransitionConditionalProperties__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./TransitionConditionalProperties */ "../../core/geometry/lib/esm/curve/spiral/TransitionConditionalProperties.js");
262706
262877
  /* harmony import */ var _TransitionSpiral3d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./TransitionSpiral3d */ "../../core/geometry/lib/esm/curve/spiral/TransitionSpiral3d.js");
@@ -262726,6 +262897,7 @@ __webpack_require__.r(__webpack_exports__);
262726
262897
 
262727
262898
 
262728
262899
 
262900
+
262729
262901
  /**
262730
262902
  * An IntegratedSpiral3d is a curve defined by integrating its curvature.
262731
262903
  * * The first integral of curvature (with respect to distance along the curve) is the bearing angle (in radians).
@@ -262981,11 +263153,16 @@ class IntegratedSpiral3d extends _TransitionSpiral3d__WEBPACK_IMPORTED_MODULE_1_
262981
263153
  }
262982
263154
  /**
262983
263155
  * Add strokes from this spiral to `dest`.
262984
- * * Linestrings will usually stroke as just their points.
262985
- * * If maxEdgeLength is given, this will sub-stroke within the linestring -- not what we want.
263156
+ * @param options optional stroking options. Pass `undefined` to return cached strokes.
262986
263157
  */
262987
263158
  emitStrokes(dest, options) {
262988
- this.activeStrokes.emitStrokes(dest, options);
263159
+ if (!options)
263160
+ this.activeStrokes.emitStrokes(dest, options);
263161
+ else {
263162
+ const stroker = new _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODULE_11__.UniformStrokeCollector(this);
263163
+ this.emitStrokableParts(stroker, options);
263164
+ stroker.claimLineString(dest);
263165
+ }
262989
263166
  }
262990
263167
  /** Emit stroke fragments to `dest` handler. */
262991
263168
  emitStrokableParts(dest, options) {
@@ -263014,7 +263191,7 @@ class IntegratedSpiral3d extends _TransitionSpiral3d__WEBPACK_IMPORTED_MODULE_1_
263014
263191
  numStroke = options.applyMinStrokesPerPrimitive(numStroke);
263015
263192
  }
263016
263193
  else {
263017
- numStroke = _StrokeOptions__WEBPACK_IMPORTED_MODULE_11__.StrokeOptions.applyAngleTol(undefined, 4, this.bearing01.sweepRadians);
263194
+ numStroke = _StrokeOptions__WEBPACK_IMPORTED_MODULE_12__.StrokeOptions.applyAngleTol(undefined, 4, this.bearing01.sweepRadians);
263018
263195
  }
263019
263196
  return numStroke;
263020
263197
  }
@@ -263072,7 +263249,7 @@ class IntegratedSpiral3d extends _TransitionSpiral3d__WEBPACK_IMPORTED_MODULE_1_
263072
263249
  /** Evaluate curve point and derivative with respect to fraction. */
263073
263250
  fractionToPointAndDerivative(activeFraction, result) {
263074
263251
  const globalFraction = this.activeFractionInterval.fractionToPoint(activeFraction);
263075
- result = result ? result : _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_12__.Ray3d.createZero();
263252
+ result = result ? result : _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_13__.Ray3d.createZero();
263076
263253
  this.fractionToPoint(activeFraction, result.origin);
263077
263254
  const radians = this.globalFractionToBearingRadians(globalFraction);
263078
263255
  const a = this._arcLength01 * this.activeFractionInterval.signedDelta();
@@ -263082,7 +263259,7 @@ class IntegratedSpiral3d extends _TransitionSpiral3d__WEBPACK_IMPORTED_MODULE_1_
263082
263259
  /** Return the frenet frame at fractional position. */
263083
263260
  fractionToFrenetFrame(activeFraction, result) {
263084
263261
  const globalFraction = this.activeFractionInterval.fractionToPoint(activeFraction);
263085
- result = result ? result : _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_13__.Transform.createIdentity();
263262
+ result = result ? result : _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_14__.Transform.createIdentity();
263086
263263
  result.origin.setFrom(this.fractionToPoint(activeFraction));
263087
263264
  _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_5__.Matrix3d.createRigidFromMatrix3d(this.localToWorld.matrix, _Geometry__WEBPACK_IMPORTED_MODULE_10__.AxisOrder.XYZ, result.matrix);
263088
263265
  const radians = this.globalFractionToBearingRadians(globalFraction);
@@ -263104,13 +263281,13 @@ class IntegratedSpiral3d extends _TransitionSpiral3d__WEBPACK_IMPORTED_MODULE_1_
263104
263281
  const radians = this.globalFractionToBearingRadians(globalFraction);
263105
263282
  const c = Math.cos(radians);
263106
263283
  const s = Math.sin(radians);
263107
- const delta = this.activeFractionInterval.signedDelta();
263284
+ const delta = this._arcLength01 * this.activeFractionInterval.signedDelta();
263108
263285
  const a = delta;
263109
263286
  const b = a * delta;
263110
263287
  const vectorX = this.localToWorld.matrix.multiplyXY(a * c, a * s);
263111
263288
  const vectorY = this.localToWorld.matrix.multiplyXY(-b * s, b * c);
263112
263289
  vectorY.scaleInPlace(this.globalFractionToCurvature(globalFraction));
263113
- return _geometry3d_Plane3dByOriginAndVectors__WEBPACK_IMPORTED_MODULE_14__.Plane3dByOriginAndVectors.createCapture(origin, vectorX, vectorY, result);
263290
+ return _geometry3d_Plane3dByOriginAndVectors__WEBPACK_IMPORTED_MODULE_15__.Plane3dByOriginAndVectors.createCapture(origin, vectorX, vectorY, result);
263114
263291
  }
263115
263292
  /** Second step of double dispatch: call `handler.handleTransitionSpiral(this)`. */
263116
263293
  dispatchToGeometryHandler(handler) {
@@ -264821,9 +264998,13 @@ class AngleSweep {
264821
264998
  result.setStartEndRadians(startRadians, endRadians);
264822
264999
  return result;
264823
265000
  }
264824
- /** Return the AngleSweep obtained by subtracting radians from the start and end angles of this sweep. */
265001
+ /** Return the AngleSweep obtained by adding `radians` to the start and end angles of this sweep. */
265002
+ clonePlusRadians(radians) {
265003
+ return new AngleSweep(this._radians0 + radians, this._radians1 + radians);
265004
+ }
265005
+ /** Return the AngleSweep obtained by subtracting `radians` from the start and end angles of this sweep. */
264825
265006
  cloneMinusRadians(radians) {
264826
- return new AngleSweep(this._radians0 - radians, this._radians1 - radians);
265007
+ return this.clonePlusRadians(-radians);
264827
265008
  }
264828
265009
  /** Create an AngleSweep from start and end angles given in degrees. */
264829
265010
  static createStartEndDegrees(startDegrees = 0, endDegrees = 360, result) {
@@ -268188,12 +268369,24 @@ __webpack_require__.r(__webpack_exports__);
268188
268369
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
268189
268370
  /* harmony export */ GeometryHandler: () => (/* binding */ GeometryHandler),
268190
268371
  /* harmony export */ NullGeometryHandler: () => (/* binding */ NullGeometryHandler),
268191
- /* harmony export */ RecurseToCurvesGeometryHandler: () => (/* binding */ RecurseToCurvesGeometryHandler)
268372
+ /* harmony export */ RecurseToCurvesGeometryHandler: () => (/* binding */ RecurseToCurvesGeometryHandler),
268373
+ /* harmony export */ UniformStrokeCollector: () => (/* binding */ UniformStrokeCollector)
268192
268374
  /* harmony export */ });
268375
+ /* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
268376
+ /* harmony import */ var _curve_LineString3d__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../curve/LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
268377
+ /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
268378
+ /* harmony import */ var _Point3dVector3d__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
268193
268379
  /*---------------------------------------------------------------------------------------------
268194
268380
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
268195
268381
  * See LICENSE.md in the project root for license terms and full copyright notice.
268196
268382
  *--------------------------------------------------------------------------------------------*/
268383
+ /** @packageDocumentation
268384
+ * @module ArraysAndInterfaces
268385
+ */
268386
+
268387
+
268388
+
268389
+
268197
268390
  /**
268198
268391
  * `GeometryHandler` defines the base abstract methods for double-dispatch geometry computation.
268199
268392
  * * User code that wants to handle one or all of the commonly known geometry types implements a handler class.
@@ -268466,6 +268659,76 @@ class RecurseToCurvesGeometryHandler extends GeometryHandler {
268466
268659
  return undefined;
268467
268660
  }
268468
268661
  }
268662
+ /**
268663
+ * A handler that generates uniformly distributed fractions for stroking a CurvePrimitive.
268664
+ * * [[claimFractions]] returns the fractions
268665
+ * * [[claimLineString]] returns the strokes
268666
+ * @public
268667
+ */
268668
+ class UniformStrokeCollector {
268669
+ _curve;
268670
+ _fractions;
268671
+ /** Constructor. Curve is optional and not needed for [[claimFractions]]. */
268672
+ constructor(cp, fractionTol = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallFraction) {
268673
+ this._curve = undefined;
268674
+ if (cp)
268675
+ this.startCurvePrimitive(cp);
268676
+ this._fractions = new _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.OrderedSet((a, b) => (0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.compareWithTolerance)(a, b, fractionTol));
268677
+ }
268678
+ /** Announce a parent curve primitive (ignored). */
268679
+ startParentCurvePrimitive(_c) { }
268680
+ /** Announce the curve primitive that will be described in subsequent calls. */
268681
+ startCurvePrimitive(cp) {
268682
+ this._curve = cp;
268683
+ }
268684
+ /** Announce a single fraction. */
268685
+ announcePointTangent(_p, f, _v) {
268686
+ this._fractions.add(f);
268687
+ }
268688
+ /** Announce uniformly distributed fractions in the fractional interval. */
268689
+ announceIntervalForUniformStepStrokes(_c, numStrokes, f0, f1) {
268690
+ if (numStrokes < 1)
268691
+ numStrokes = 1;
268692
+ this._fractions.add(f0);
268693
+ const df = 1.0 / numStrokes;
268694
+ for (let i = 1; i < numStrokes; i++)
268695
+ this._fractions.add(_Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.interpolate(f0, i * df, f1));
268696
+ this._fractions.add(f1);
268697
+ }
268698
+ /** Request primary geometry to avoid cached strokes. */
268699
+ needPrimaryGeometryForStrokes() {
268700
+ return true;
268701
+ }
268702
+ /** Announce the fractional span of the segment. */
268703
+ announceSegmentInterval(_c, _p0, _p1, _numStrokes, f0, f1) {
268704
+ this._fractions.add(f0);
268705
+ this._fractions.add(f1);
268706
+ }
268707
+ /** Announce that all data about the curve has been announced (ignored). */
268708
+ endCurvePrimitive(_c) { }
268709
+ /** Announce that all data about the parent curve has been announced (ignored). */
268710
+ endParentCurvePrimitive(_c) { }
268711
+ /** Retrieve the collected fractions, optionally removing 0 and 1 first. */
268712
+ claimFractions(remove01 = false) {
268713
+ if (remove01) {
268714
+ this._fractions.delete(0);
268715
+ this._fractions.delete(1);
268716
+ }
268717
+ return [...this._fractions];
268718
+ }
268719
+ /** Create a [[LineString3d]] by evaluating the curve at the collected fractions. */
268720
+ claimLineString(result) {
268721
+ if (!this._curve)
268722
+ return undefined;
268723
+ result ??= _curve_LineString3d__WEBPACK_IMPORTED_MODULE_2__.LineString3d.create();
268724
+ const pt = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_3__.Point3d.create();
268725
+ for (const f of this._fractions) {
268726
+ result.addPoint(this._curve.fractionToPoint(f, pt));
268727
+ result.addFraction(f);
268728
+ }
268729
+ return result;
268730
+ }
268731
+ }
268469
268732
 
268470
268733
 
268471
268734
  /***/ }),
@@ -269038,21 +269301,31 @@ class GrowableXYArray extends _IndexedXYCollection__WEBPACK_IMPORTED_MODULE_0__.
269038
269301
  _data;
269039
269302
  /** Number of xy tuples (not floats) in the array. */
269040
269303
  _xyInUse;
269041
- /** Capacity in xy tuples. (not floats). */
269304
+ /** Capacity in xy tuples (not floats). */
269042
269305
  _xyCapacity;
269043
- /** Multiplier used by ensureCapacity to expand requested reallocation size. */
269306
+ /** Multiplier used by [[ensureCapacity]] to expand requested reallocation size. */
269044
269307
  _growthFactor;
269045
269308
  /**
269046
- * Construct a new GrowablePoint2d array.
269047
- * @param numPoints initial capacity in xy tuples (default 8).
269048
- * @param growthFactor used by ensureCapacity to expand requested reallocation size (default 1.5).
269049
- * @param data optional pre-existing Float64Array to use as the backing memory. If supplied, numPoints is ignored.
269309
+ * Construct a new growable array.
269310
+ * @param numPoints initial capacity in xy tuples. Default value is 8.
269311
+ * @param growthFactor used by [[ensureCapacity]] to expand requested reallocation size. Default value is 1.5.
269312
+ * For no expansion, use 1.
269313
+ * @param data optional array to serve as the point source. If `data` is supplied, `numPoints` is reinterpreted as
269314
+ * the initial point count, defaulting to and bounded above by the array's point capacity. If a subsequent [[push]]
269315
+ * would exceed the array's capacity, a new Float64Array of the same buffer type is allocated and filled.
269050
269316
  */
269051
- constructor(numPoints = 8, growthFactor, data) {
269317
+ constructor(numPoints, growthFactor, data) {
269052
269318
  super();
269053
- this._data = data || new Float64Array(numPoints * 2); // 2 values per point
269054
- this._xyInUse = 0;
269055
- this._xyCapacity = data ? data.length / 2 : numPoints;
269319
+ if (data) {
269320
+ this._xyCapacity = data.length / 2;
269321
+ this._xyInUse = Math.min(numPoints ?? Infinity, this._xyCapacity);
269322
+ this._data = data;
269323
+ }
269324
+ else {
269325
+ this._xyCapacity = numPoints ?? 8;
269326
+ this._xyInUse = 0;
269327
+ this._data = new Float64Array(2 * this._xyCapacity); // 2 values per point
269328
+ }
269056
269329
  this._growthFactor = (undefined !== growthFactor && growthFactor >= 1.0) ? growthFactor : 1.5;
269057
269330
  }
269058
269331
  /**
@@ -269776,19 +270049,29 @@ class GrowableXYZArray extends _IndexedXYZCollection__WEBPACK_IMPORTED_MODULE_0_
269776
270049
  _xyzInUse;
269777
270050
  /** Capacity in xyz triples (not floats). */
269778
270051
  _xyzCapacity;
269779
- /** Multiplier used by ensureCapacity to expand requested reallocation size. */
270052
+ /** Multiplier used by [[ensureCapacity]] to expand requested reallocation size. */
269780
270053
  _growthFactor;
269781
270054
  /**
269782
- * Construct a new GrowablePoint3d array.
269783
- * @param numPoints initial capacity in xyz triples (default 8).
269784
- * @param growthFactor used by ensureCapacity to expand requested reallocation size (default 1.5).
269785
- * @param data optional pre-existing Float64Array to use as the backing memory. If supplied, numPoints is ignored.
270055
+ * Construct a new growable array.
270056
+ * @param numPoints initial capacity in xyz tuples. Default value is 8.
270057
+ * @param growthFactor used by [[ensureCapacity]] to expand requested reallocation size. Default value is 1.5.
270058
+ * For no expansion, use 1.
270059
+ * @param data optional array to serve as the point source. If `data` is supplied, `numPoints` is reinterpreted as
270060
+ * the initial point count, defaulting to and bounded above by the array's point capacity. If a subsequent [[push]]
270061
+ * would exceed the array's capacity, a new Float64Array of the same buffer type is allocated and filled.
269786
270062
  */
269787
- constructor(numPoints = 8, growthFactor, data) {
270063
+ constructor(numPoints, growthFactor, data) {
269788
270064
  super();
269789
- this._data = data || new Float64Array(numPoints * 3); // 3 values per point
269790
- this._xyzInUse = 0;
269791
- this._xyzCapacity = data ? data.length / 3 : numPoints;
270065
+ if (data) {
270066
+ this._xyzCapacity = data.length / 3;
270067
+ this._xyzInUse = Math.min(numPoints ?? Infinity, this._xyzCapacity);
270068
+ this._data = data;
270069
+ }
270070
+ else {
270071
+ this._xyzCapacity = numPoints ?? 8;
270072
+ this._xyzInUse = 0;
270073
+ this._data = new Float64Array(3 * this._xyzCapacity); // 3 values per point
270074
+ }
269792
270075
  this._growthFactor = (undefined !== growthFactor && growthFactor >= 1.0) ? growthFactor : 1.5;
269793
270076
  }
269794
270077
  /**
@@ -269843,7 +270126,7 @@ class GrowableXYZArray extends _IndexedXYZCollection__WEBPACK_IMPORTED_MODULE_0_
269843
270126
  return this._data;
269844
270127
  }
269845
270128
  /**
269846
- * If necessary, increase the capacity to the new number of points. Current coordinates and point count (length) are
270129
+ * If necessary, increase the capacity to the new number of points. Current coordinates and point count (length) are
269847
270130
  * unchanged.
269848
270131
  */
269849
270132
  ensureCapacity(pointCapacity, applyGrowthFactor = true) {
@@ -272277,17 +272560,18 @@ class Matrix3d {
272277
272560
  target.setColumn(_Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.axisOrderToAxis(axisOrder, 0), vectorU);
272278
272561
  target.setColumn(_Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.axisOrderToAxis(axisOrder, 1), vectorV);
272279
272562
  target.setColumn(_Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.axisOrderToAxis(axisOrder, 2), vectorW);
272563
+ target.inverseState = InverseMatrixState.unknown;
272280
272564
  return target;
272281
272565
  }
272282
272566
  /**
272283
272567
  * Create a new orthogonal matrix (perpendicular columns, unit length, transpose is inverse).
272284
- * * `vectorA1 = Normalized vectorA` is placed in the column specified by **first** letter in
272568
+ * * `vectorA1 = Normalized vectorA` is placed in the column specified by the **first** letter in
272285
272569
  * the AxisOrder name.
272286
- * * Normalized `vectorC1 = vectorA1 cross vectorB` is placed in the column specified by **third**
272570
+ * * Normalized `vectorC1 = vectorA1 cross vectorB` is placed in the column specified by the **third**
272287
272571
  * letter in the AxisOrder name.
272288
- * * Normalized `vectorC1 cross vectorA` is placed in the column specified by **second**
272572
+ * * Normalized `vectorC1 cross vectorA` is placed in the column specified by the **second**
272289
272573
  * letter in the AxisOrder name.
272290
- * * This function internally uses createShuffledColumns.
272574
+ * * This function internally uses [[createShuffledColumns]].
272291
272575
  */
272292
272576
  static createRigidFromColumns(vectorA, vectorB, axisOrder, result) {
272293
272577
  const vectorA1 = vectorA.normalize();
@@ -289536,7 +289820,7 @@ class UnivariateBezier extends BezierCoffs {
289536
289820
  * that the final iteration will clean it up to nearly machine precision.
289537
289821
  * @returns final fraction of iteration if converged. undefined if iteration failed to converge.
289538
289822
  */
289539
- runNewton(startFraction, tolerance = 1.0e-11) {
289823
+ runNewton(startFraction, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallNewtonStep) {
289540
289824
  const derivativeFactor = this.order - 1;
289541
289825
  let numConverged = 0;
289542
289826
  let u = startFraction;
@@ -291105,6 +291389,7 @@ __webpack_require__.r(__webpack_exports__);
291105
291389
  /* harmony export */ NewtonEvaluatorRRtoRRD: () => (/* binding */ NewtonEvaluatorRRtoRRD),
291106
291390
  /* harmony export */ NewtonEvaluatorRtoR: () => (/* binding */ NewtonEvaluatorRtoR),
291107
291391
  /* harmony export */ NewtonEvaluatorRtoRD: () => (/* binding */ NewtonEvaluatorRtoRD),
291392
+ /* harmony export */ NewtonRtoRStrokeHandler: () => (/* binding */ NewtonRtoRStrokeHandler),
291108
291393
  /* harmony export */ SimpleNewton: () => (/* binding */ SimpleNewton)
291109
291394
  /* harmony export */ });
291110
291395
  /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
@@ -291122,6 +291407,12 @@ __webpack_require__.r(__webpack_exports__);
291122
291407
 
291123
291408
 
291124
291409
  // cspell:word currentdFdX XYRR
291410
+ // A note on differences between using derivatives vs. approximate derivatives for Newton:
291411
+ // * Converged values are the same under both schemes.
291412
+ // * With derivatives, Newton convergence is quadratic rather than power 1.62 with approximate derivatives.
291413
+ // * With approximate derivatives:
291414
+ // - the extra iterative cost is incidental for low iteration counts, and may even be offset by simpler computation.
291415
+ // - the step choice is not based on serious analysis, so could be problematic.
291125
291416
  /**
291126
291417
  * Base class for Newton iterations in various dimensions.
291127
291418
  * Dimension-specific classes carry all dimension-related data and answer generalized queries from this base class.
@@ -291135,12 +291426,12 @@ class AbstractNewtonIterator {
291135
291426
  * it is expected that a first "accept" for (say) 10 to 14 digit step will be followed by another
291136
291427
  * iteration. A well behaved newton would then hypothetically double the number of digits to
291137
291428
  * 20 to 28. Since the IEEE double only carries 16 digits, this second-convergence step will
291138
- * typically achieve full precision.
291139
- * @param successiveConvergenceTarget number of successive convergences required for acceptance.
291429
+ * typically achieve full precision. Default [[Geometry.smallNewtonStep]].
291430
+ * @param successiveConvergenceTarget number of successive convergences required for acceptance. Default 2.
291140
291431
  * @param maxIterations max number of iterations. A typical newton step converges in 3 to 6 iterations.
291141
- * Allow 15 to 20 to catch difficult cases.
291432
+ * Allow 15 to 20 to catch difficult cases. Default 15.
291142
291433
  */
291143
- constructor(stepSizeTolerance = 1.0e-11, successiveConvergenceTarget = 2, maxIterations = 15) {
291434
+ constructor(stepSizeTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallNewtonStep, successiveConvergenceTarget = 2, maxIterations = 15) {
291144
291435
  this._stepSizeTolerance = stepSizeTolerance;
291145
291436
  this._successiveConvergenceTarget = successiveConvergenceTarget;
291146
291437
  this._maxIterations = maxIterations;
@@ -291155,6 +291446,12 @@ class AbstractNewtonIterator {
291155
291446
  _maxIterations;
291156
291447
  /** Number of iterations (incremented at each step). */
291157
291448
  numIterations = 0;
291449
+ /** Get the relative tolerance for comparing iterations in [[testConvergence]]. */
291450
+ get stepSizeTolerance() {
291451
+ return this._stepSizeTolerance;
291452
+ }
291453
+ /** Smallest iterate size difference in later iterations. */
291454
+ _leastDelta = Number.MAX_VALUE;
291158
291455
  /**
291159
291456
  * Test if a step is converged.
291160
291457
  * * Convergence is accepted with enough (_successiveConvergenceTarget) small steps (according to _stepSizeTolerance)
@@ -291162,6 +291459,10 @@ class AbstractNewtonIterator {
291162
291459
  * @param delta step size as reported by currentStepSize.
291163
291460
  */
291164
291461
  testConvergence(delta) {
291462
+ if (this.cacheCandidate && delta < this._leastDelta && this.numIterations > 0.5 * this._maxIterations) {
291463
+ this._leastDelta = delta;
291464
+ this.cacheCandidate();
291465
+ }
291165
291466
  if (Math.abs(delta) < this._stepSizeTolerance) {
291166
291467
  this._numAccepted++;
291167
291468
  return this._numAccepted >= this._successiveConvergenceTarget;
@@ -291179,13 +291480,16 @@ class AbstractNewtonIterator {
291179
291480
  runIterations() {
291180
291481
  this._numAccepted = 0;
291181
291482
  this.numIterations = 0;
291483
+ this._leastDelta = Number.MAX_VALUE;
291182
291484
  while (this.numIterations++ < this._maxIterations && this.computeStep()) {
291183
- if (this.testConvergence(this.currentStepSize()) && this.applyCurrentStep(true)) {
291184
- // console.log("iter: " + this.numIterations); // print number of Newton iterations for debug
291485
+ if (this.testConvergence(this.currentStepSize())) {
291486
+ this.applyCurrentStep(true);
291185
291487
  return true;
291186
291488
  }
291187
291489
  this.applyCurrentStep(false);
291188
291490
  }
291491
+ if (this.restoreCandidate && this.numIterations >= this._maxIterations && Math.abs(this.currentStepSize()) > this._leastDelta)
291492
+ this.restoreCandidate(); // we may have ended up in a late cycle; return our best guess
291189
291493
  return false;
291190
291494
  }
291191
291495
  }
@@ -291227,7 +291531,6 @@ class Newton1dUnbounded extends AbstractNewtonIterator {
291227
291531
  /** Set the independent variable, i.e., x_n. */
291228
291532
  setX(x) {
291229
291533
  this._currentX = x;
291230
- return true;
291231
291534
  }
291232
291535
  /** Get the independent variable, i.e., x_n. */
291233
291536
  getX() {
@@ -291239,8 +291542,7 @@ class Newton1dUnbounded extends AbstractNewtonIterator {
291239
291542
  }
291240
291543
  /** Move the current X by the just-computed step, i.e., `x_n - dx`. */
291241
291544
  applyCurrentStep() {
291242
- // console.log(this._currentX - this._currentStep); // print approximations for debug
291243
- return this.setX(this._currentX - this._currentStep);
291545
+ this.setX(this._currentX - this._currentStep);
291244
291546
  }
291245
291547
  /** Compute the univariate newton step dx. */
291246
291548
  computeStep() {
@@ -291266,6 +291568,30 @@ class NewtonEvaluatorRtoR {
291266
291568
  /** Most recent function evaluation, i.e., f(x_n). */
291267
291569
  currentF;
291268
291570
  }
291571
+ /**
291572
+ * Intermediate class for managing the parentCurve announcements from an IStrokeHandler.
291573
+ * @internal
291574
+ */
291575
+ class NewtonRtoRStrokeHandler extends NewtonEvaluatorRtoR {
291576
+ _parentCurvePrimitive;
291577
+ constructor() {
291578
+ super();
291579
+ this._parentCurvePrimitive = undefined;
291580
+ }
291581
+ /**
291582
+ * Retain the parentCurvePrimitive.
291583
+ * * Calling this method tells the handler that the parent curve is to be used for detail searches.
291584
+ * * Example: Transition spiral search is based on linestring first, then the exact spiral.
291585
+ * * Example: CurveChainWithDistanceIndex does NOT do this announcement; the constituents act independently.
291586
+ */
291587
+ startParentCurvePrimitive(curve) {
291588
+ this._parentCurvePrimitive = curve;
291589
+ }
291590
+ /** Forget the parentCurvePrimitive */
291591
+ endParentCurvePrimitive(_curve) {
291592
+ this._parentCurvePrimitive = undefined;
291593
+ }
291594
+ }
291269
291595
  /**
291270
291596
  * Newton iteration for a univariate function, using approximate derivatives.
291271
291597
  * To approximate the derivatives we use a small step `h`, i.e., `f'(x_n) = (f(x_n + h) - f(x_n)) / h`.
@@ -291297,7 +291623,6 @@ class Newton1dUnboundedApproximateDerivative extends AbstractNewtonIterator {
291297
291623
  /** Set the independent variable, i.e., x_n. */
291298
291624
  setX(x) {
291299
291625
  this._currentX = x;
291300
- return true;
291301
291626
  }
291302
291627
  /** Get the independent variable, i.e., x_n. */
291303
291628
  getX() {
@@ -291305,8 +291630,7 @@ class Newton1dUnboundedApproximateDerivative extends AbstractNewtonIterator {
291305
291630
  }
291306
291631
  /** Move the current X by the just-computed step, i.e., `x_n - dx`. */
291307
291632
  applyCurrentStep() {
291308
- // console.log(this._currentX - this._currentStep); // print approximations for debug
291309
- return this.setX(this._currentX - this._currentStep);
291633
+ this.setX(this._currentX - this._currentStep);
291310
291634
  }
291311
291635
  /** Univariate newton step dx, computed with approximate derivative. */
291312
291636
  computeStep() {
@@ -291371,9 +291695,11 @@ class Newton2dUnboundedWithDerivative extends AbstractNewtonIterator {
291371
291695
  /**
291372
291696
  * Constructor for 2D newton iteration with derivatives.
291373
291697
  * @param func function that returns both function value and derivative.
291698
+ * @param maxIterations max number of iterations. Default 15.
291699
+ * @param stepSizeTolerance tolerance to consider a single step converged. Default [[Geometry.smallNewtonStep]].
291374
291700
  */
291375
- constructor(func, maxIterations) {
291376
- super(undefined, undefined, maxIterations);
291701
+ constructor(func, maxIterations, stepSizeTolerance) {
291702
+ super(stepSizeTolerance, undefined, maxIterations);
291377
291703
  this._func = func;
291378
291704
  this._currentStep = _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_2__.Vector2d.createZero();
291379
291705
  this._currentUV = _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_2__.Point2d.createZero();
@@ -291381,7 +291707,6 @@ class Newton2dUnboundedWithDerivative extends AbstractNewtonIterator {
291381
291707
  /** Set the current uv parameters, i.e., `X_n = (u_n, v_n)`. */
291382
291708
  setUV(u, v) {
291383
291709
  this._currentUV.set(u, v);
291384
- return true;
291385
291710
  }
291386
291711
  /** Get the current u parameter of X_n, i.e., u_n. */
291387
291712
  getU() {
@@ -291391,14 +291716,9 @@ class Newton2dUnboundedWithDerivative extends AbstractNewtonIterator {
291391
291716
  getV() {
291392
291717
  return this._currentUV.y;
291393
291718
  }
291394
- /** Get the relative tolerance for comparing iterations in [[testConvergence]]. */
291395
- get stepSizeTolerance() {
291396
- return this._stepSizeTolerance;
291397
- }
291398
291719
  /** Update the current uv parameter by currentStep, i.e., compute `X_{n+1} := X_n - dX = (u_n - du, v_n - dv)`. */
291399
291720
  applyCurrentStep() {
291400
- // console.log("(" + (this._currentUV.x - this._currentStep.x) + "," + (this._currentUV.y - this._currentStep.y) + ")");
291401
- return this.setUV(this._currentUV.x - this._currentStep.x, this._currentUV.y - this._currentStep.y);
291721
+ this.setUV(this._currentUV.x - this._currentStep.x, this._currentUV.y - this._currentStep.y);
291402
291722
  }
291403
291723
  /**
291404
291724
  * Evaluate the functions and derivatives at `X_n = (u_n, v_n)`, and solve the Jacobian matrix equation to
@@ -291422,6 +291742,20 @@ class Newton2dUnboundedWithDerivative extends AbstractNewtonIterator {
291422
291742
  currentStepSize() {
291423
291743
  return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.maxAbsXY(this._currentStep.x / (1.0 + Math.abs(this._currentUV.x)), this._currentStep.y / (1.0 + Math.abs(this._currentUV.y)));
291424
291744
  }
291745
+ /** Candidate solution cache. */
291746
+ _cachedUV;
291747
+ /** The current late iterate has the least delta encountered. Remember it. */
291748
+ cacheCandidate() {
291749
+ if (this._cachedUV)
291750
+ this._cachedUV.setFrom(this._currentUV);
291751
+ else
291752
+ this._cachedUV = this._currentUV.clone();
291753
+ }
291754
+ /** Set Newton result to the cached candidate. */
291755
+ restoreCandidate() {
291756
+ if (this._cachedUV)
291757
+ this.setUV(this._cachedUV.x, this._cachedUV.y);
291758
+ }
291425
291759
  }
291426
291760
  /**
291427
291761
  * SimpleNewton has static methods for newton methods with evaluated functions presented as immediate arguments
@@ -291441,7 +291775,7 @@ class SimpleNewton {
291441
291775
  static runNewton1D(x, func, derivative, absoluteTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallFloatingPoint) {
291442
291776
  let numConverged = 0;
291443
291777
  let tolerance;
291444
- const relTol = 1.0e-11;
291778
+ const relTol = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallNewtonStep;
291445
291779
  for (let iteration = 0; iteration < 20; iteration++) {
291446
291780
  const f = func(x);
291447
291781
  const df = derivative(x);
@@ -302015,20 +302349,20 @@ class PolyfaceQuery {
302015
302349
  return -2;
302016
302350
  }
302017
302351
  /**
302018
- * Test for convex volume by dihedral angle tests on all edges.
302019
- * * This tests if all dihedral angles of the mesh are positive.
302020
- * * In a closed solid, this is a strong test for overall mesh convexity with outward facing normals.
302021
- * * See [[dihedralAngleSummary]] for the definition of "dihedral angle".
302022
- * * With `ignoreBoundaries` true, this may be a useful test when all the facets are in a single edge-connected
302023
- * component, such as a pyramid with no underside.
302024
- * * It is not a correct test if there are multiple, disjoint components.
302025
- * * Take the above-mentioned pyramid with no underside.
302026
- * * Within the same mesh, have a second pyramid placed to the side, still facing upward.
302027
- * * The angles will pass the dihedral convexity test, but the composite thing surely is not convex.
302028
- * @param source mesh.
302029
- * @param ignoreBoundaries if `true` ignore simple boundary edges, i.e., allow unclosed meshes. Default is `false`.
302030
- * @returns true if all dihedral angles of the mesh are positive.
302031
- */
302352
+ * Test for convex volume by dihedral angle tests on all edges.
302353
+ * * This tests if all dihedral angles of the mesh are positive.
302354
+ * * In a closed solid, this is a strong test for overall mesh convexity with outward facing normals.
302355
+ * * See [[dihedralAngleSummary]] for the definition of "dihedral angle".
302356
+ * * With `ignoreBoundaries` true, this may be a useful test when all the facets are in a single edge-connected
302357
+ * component, such as a pyramid with no underside.
302358
+ * * It is not a correct test if there are multiple, disjoint components.
302359
+ * * Take the above-mentioned pyramid with no underside.
302360
+ * * Within the same mesh, have a second pyramid placed to the side, still facing upward.
302361
+ * * The angles will pass the dihedral convexity test, but the composite thing surely is not convex.
302362
+ * @param source mesh.
302363
+ * @param ignoreBoundaries if `true` ignore simple boundary edges, i.e., allow unclosed meshes. Default is `false`.
302364
+ * @returns true if all dihedral angles of the mesh are positive.
302365
+ */
302032
302366
  static isConvexByDihedralAngleCount(source, ignoreBoundaries = false) {
302033
302367
  return this.dihedralAngleSummary(source, ignoreBoundaries) > 0;
302034
302368
  }
@@ -313718,8 +314052,8 @@ class DgnSpiralTypeQueries {
313718
314052
  [12, "biquadratic"],
313719
314053
  [13, "cosine"],
313720
314054
  [14, "sine"],
313721
- [15, "Viennese"],
313722
- [16, "weightedViennese"],
314055
+ [15, "Viennese"], // not supported
314056
+ [16, "weightedViennese"], // not supported
313723
314057
  [50, "WesternAustralian"],
313724
314058
  [51, "Czech"],
313725
314059
  [52, "AustralianRailCorp"],
@@ -320794,7 +321128,7 @@ class HalfEdge {
320794
321128
  * @param bridgeMask mask preset on bridge edges (default is [[HalfEdgeMask.BRIDGE_EDGE]]).
320795
321129
  */
320796
321130
  isSplitWasherFace(bridgeMask = HalfEdgeMask.BRIDGE_EDGE) {
320797
- if (!this.countMaskAroundFace(HalfEdgeMask.BRIDGE_EDGE))
321131
+ if (!this.countMaskAroundFace(bridgeMask))
320798
321132
  return false;
320799
321133
  const bridges = new _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.OrderedSet((a, b) => a.id - b.id);
320800
321134
  let node = this;
@@ -348964,7 +349298,7 @@ class TestContext {
348964
349298
  this.initializeRpcInterfaces({ title: this.settings.Backend.name, version: this.settings.Backend.version });
348965
349299
  const iModelClient = new imodels_client_management_1.IModelsClient({ api: { baseUrl: `https://${process.env.IMJS_URL_PREFIX ?? ""}api.bentley.com/imodels` } });
348966
349300
  await core_frontend_1.NoRenderApp.startup({
348967
- applicationVersion: "5.9.0-dev.7",
349301
+ applicationVersion: "5.9.0-dev.9",
348968
349302
  applicationId: this.settings.gprid,
348969
349303
  authorizationClient: new frontend_1.TestFrontendAuthorizationClient(this.serviceAuthToken),
348970
349304
  hubAccess: new imodels_access_frontend_1.FrontendIModelsAccess(iModelClient),
@@ -376239,7 +376573,7 @@ var loadLanguages = instance.loadLanguages;
376239
376573
  /***/ ((module) => {
376240
376574
 
376241
376575
  "use strict";
376242
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.9.0-dev.7","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs && npm run -s build:esm && npm run -s webpackWorkers && npm run -s copy:workers && npm run -s copy:draco","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2022 --outDir lib/esm","clean":"rimraf -g lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","copy:workers":"cpx \\"./lib/workers/webpack/parse-imdl-worker.js\\" ./lib/public/scripts","copy:draco":"cpx \\"./node_modules/@loaders.gl/draco/dist/libs/*\\" ./lib/public/scripts","docs":"betools docs --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts && npm run -s extract","extract":"betools extract --fileExt=ts --extractFrom=./src/test/example-code --recursive --out=../../generated-docs/extract","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-inline-config -c extraction.eslint.config.js \\"./src/**/*.ts\\" 1>&2","lint":"eslint \\"./src/**/*.ts\\" 1>&2","lint-fix":"eslint --fix -f visualstudio \\"./src/**/*.ts\\" 1>&2","lint-deprecation":"eslint --fix -f visualstudio --no-inline-config -c ../../common/config/eslint/eslint.config.deprecation-policy.js \\"./src/**/*.ts\\"","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run webpackTestWorker && vitest --run","cover":"npm run webpackTestWorker && vitest --run","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2 && npm run -s webpackTestWorker","webpackTestWorker":"webpack --config ./src/test/worker/webpack.config.js 1>&2 && cpx \\"./lib/test/test-worker.js\\" ./lib/test","webpackWorkers":"webpack --config ./src/workers/ImdlParser/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core.git","directory":"core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@bentley/aec-units-schema":"^1.0.3","@bentley/formats-schema":"^1.0.0","@bentley/units-schema":"^1.0.9","@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*","@itwin/object-storage-core":"^3.0.4","@itwin/eslint-plugin":"^6.0.0","@types/chai-as-promised":"^7","@types/draco3d":"^1.4.10","@types/sinon":"^17.0.2","@vitest/browser":"^3.0.6","@vitest/coverage-v8":"^3.0.6","cpx2":"^8.0.0","eslint":"^9.31.0","glob":"^10.5.0","playwright":"~1.56.1","rimraf":"^6.0.1","sinon":"^17.0.2","source-map-loader":"^5.0.0","typescript":"~5.6.2","vitest":"^3.0.6","vite-multiple-assets":"^1.3.1","vite-plugin-static-copy":"2.2.0","webpack":"^5.97.1"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/core-i18n":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"~4.3.4","@loaders.gl/draco":"~4.3.4","fuse.js":"^3.3.0","wms-capabilities":"0.4.0"}}');
376576
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.9.0-dev.9","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs && npm run -s build:esm && npm run -s webpackWorkers && npm run -s copy:workers && npm run -s copy:draco","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2022 --outDir lib/esm","clean":"rimraf -g lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","copy:workers":"cpx \\"./lib/workers/webpack/parse-imdl-worker.js\\" ./lib/public/scripts","copy:draco":"cpx \\"./node_modules/@loaders.gl/draco/dist/libs/*\\" ./lib/public/scripts","docs":"betools docs --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts && npm run -s extract","extract":"betools extract --fileExt=ts --extractFrom=./src/test/example-code --recursive --out=../../generated-docs/extract","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-inline-config -c extraction.eslint.config.js \\"./src/**/*.ts\\" 1>&2","lint":"eslint \\"./src/**/*.ts\\" 1>&2","lint-fix":"eslint --fix -f visualstudio \\"./src/**/*.ts\\" 1>&2","lint-deprecation":"eslint --fix -f visualstudio --no-inline-config -c ../../common/config/eslint/eslint.config.deprecation-policy.js \\"./src/**/*.ts\\"","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run webpackTestWorker && vitest --run","cover":"npm run webpackTestWorker && vitest --run","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2 && npm run -s webpackTestWorker","webpackTestWorker":"webpack --config ./src/test/worker/webpack.config.js 1>&2 && cpx \\"./lib/test/test-worker.js\\" ./lib/test","webpackWorkers":"webpack --config ./src/workers/ImdlParser/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core.git","directory":"core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@bentley/aec-units-schema":"^1.0.3","@bentley/formats-schema":"^1.0.0","@bentley/units-schema":"^1.0.9","@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*","@itwin/object-storage-core":"^3.0.4","@itwin/eslint-plugin":"^6.0.0","@types/chai-as-promised":"^7","@types/draco3d":"^1.4.10","@types/sinon":"^17.0.2","@vitest/browser":"^3.0.6","@vitest/coverage-v8":"^3.0.6","cpx2":"^8.0.0","eslint":"^9.31.0","glob":"^10.5.0","playwright":"~1.56.1","rimraf":"^6.0.1","sinon":"^17.0.2","source-map-loader":"^5.0.0","typescript":"~5.6.2","vitest":"^3.0.6","vite-multiple-assets":"^1.3.1","vite-plugin-static-copy":"2.2.0","webpack":"^5.97.1"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/core-i18n":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"~4.3.4","@loaders.gl/draco":"~4.3.4","fuse.js":"^3.3.0","wms-capabilities":"0.4.0"}}');
376243
376577
 
376244
376578
  /***/ }),
376245
376579