@itwin/rpcinterface-full-stack-tests 5.0.0-dev.4 → 5.0.0-dev.5

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.
@@ -201726,6 +201726,7 @@ __webpack_require__.r(__webpack_exports__);
201726
201726
  /* harmony import */ var _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../geometry3d/Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
201727
201727
  /* harmony import */ var _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../geometry3d/AngleSweep */ "../../core/geometry/lib/esm/geometry3d/AngleSweep.js");
201728
201728
  /* harmony import */ var _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../geometry3d/Matrix3d */ "../../core/geometry/lib/esm/geometry3d/Matrix3d.js");
201729
+ /* harmony import */ var _geometry3d_Plane3dByOriginAndUnitNormal__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../geometry3d/Plane3dByOriginAndUnitNormal */ "../../core/geometry/lib/esm/geometry3d/Plane3dByOriginAndUnitNormal.js");
201729
201730
  /* harmony import */ var _geometry3d_Plane3dByOriginAndVectors__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../geometry3d/Plane3dByOriginAndVectors */ "../../core/geometry/lib/esm/geometry3d/Plane3dByOriginAndVectors.js");
201730
201731
  /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
201731
201732
  /* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
@@ -201735,13 +201736,13 @@ __webpack_require__.r(__webpack_exports__);
201735
201736
  /* harmony import */ var _CurveExtendMode__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./CurveExtendMode */ "../../core/geometry/lib/esm/curve/CurveExtendMode.js");
201736
201737
  /* harmony import */ var _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./CurveLocationDetail */ "../../core/geometry/lib/esm/curve/CurveLocationDetail.js");
201737
201738
  /* harmony import */ var _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./CurvePrimitive */ "../../core/geometry/lib/esm/curve/CurvePrimitive.js");
201738
- /* harmony import */ var _internalContexts_CurveOffsetXYHandler__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./internalContexts/CurveOffsetXYHandler */ "../../core/geometry/lib/esm/curve/internalContexts/CurveOffsetXYHandler.js");
201739
- /* harmony import */ var _internalContexts_EllipticalArcApproximationContext__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./internalContexts/EllipticalArcApproximationContext */ "../../core/geometry/lib/esm/curve/internalContexts/EllipticalArcApproximationContext.js");
201740
- /* harmony import */ var _internalContexts_PlaneAltitudeRangeContext__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./internalContexts/PlaneAltitudeRangeContext */ "../../core/geometry/lib/esm/curve/internalContexts/PlaneAltitudeRangeContext.js");
201739
+ /* harmony import */ var _internalContexts_CurveOffsetXYHandler__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./internalContexts/CurveOffsetXYHandler */ "../../core/geometry/lib/esm/curve/internalContexts/CurveOffsetXYHandler.js");
201740
+ /* harmony import */ var _internalContexts_EllipticalArcApproximationContext__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./internalContexts/EllipticalArcApproximationContext */ "../../core/geometry/lib/esm/curve/internalContexts/EllipticalArcApproximationContext.js");
201741
+ /* harmony import */ var _internalContexts_PlaneAltitudeRangeContext__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./internalContexts/PlaneAltitudeRangeContext */ "../../core/geometry/lib/esm/curve/internalContexts/PlaneAltitudeRangeContext.js");
201741
201742
  /* harmony import */ var _LineSegment3d__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
201742
201743
  /* harmony import */ var _LineString3d__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
201743
- /* harmony import */ var _OffsetOptions__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./OffsetOptions */ "../../core/geometry/lib/esm/curve/OffsetOptions.js");
201744
- /* harmony import */ var _Path__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./Path */ "../../core/geometry/lib/esm/curve/Path.js");
201744
+ /* harmony import */ var _OffsetOptions__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./OffsetOptions */ "../../core/geometry/lib/esm/curve/OffsetOptions.js");
201745
+ /* harmony import */ var _Path__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./Path */ "../../core/geometry/lib/esm/curve/Path.js");
201745
201746
  /* harmony import */ var _StrokeOptions__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./StrokeOptions */ "../../core/geometry/lib/esm/curve/StrokeOptions.js");
201746
201747
  /*---------------------------------------------------------------------------------------------
201747
201748
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
@@ -201767,6 +201768,7 @@ __webpack_require__.r(__webpack_exports__);
201767
201768
 
201768
201769
 
201769
201770
 
201771
+
201770
201772
 
201771
201773
 
201772
201774
  /**
@@ -202505,7 +202507,7 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
202505
202507
  const axy = this._matrix.columnXDotColumnY();
202506
202508
  return _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_8__.Angle.isPerpendicularDotSet(axx, ayy, axy) && _Geometry__WEBPACK_IMPORTED_MODULE_5__.Geometry.isSameCoordinateSquared(axx, ayy);
202507
202509
  }
202508
- /** Return radius if the vector0 and vector90 are of equal length and perpendicular. */
202510
+ /** Return radius if the vector0 and vector90 are of equal length and perpendicular. Ignores z. */
202509
202511
  circularRadiusXY() {
202510
202512
  const ux = this._matrix.at(0, 0);
202511
202513
  const uy = this._matrix.at(1, 0);
@@ -202647,7 +202649,12 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
202647
202649
  setVector0Vector90(vector0, vector90) {
202648
202650
  this._matrix.setColumns(vector0, vector90, vector0.unitCrossProductWithDefault(vector90, 0, 0, 0));
202649
202651
  }
202650
- /** Return the arc definition with rigid matrix form with axis radii. */
202652
+ /**
202653
+ * Return the symmetric definition of the arc, with rigid axes and radii.
202654
+ * * The caller can send the returned data into [[createScaledXYColumns]] to construct the major-minor axis
202655
+ * version of the instance arc. This formulation of the arc has the same shape, but has perpendicular axes,
202656
+ * from which the arc's symmetry is readily apparent.
202657
+ */
202651
202658
  toScaledMatrix3d() {
202652
202659
  const angleData = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_8__.Angle.dotProductsToHalfAngleTrigValues(this._matrix.columnXMagnitudeSquared(), this._matrix.columnYMagnitudeSquared(), this._matrix.columnXDotColumnY(), true);
202653
202660
  const vector0A = this._matrix.multiplyXY(angleData.c, angleData.s);
@@ -202787,9 +202794,9 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
202787
202794
  }
202788
202795
  /**
202789
202796
  * Return an arc whose basis vectors are rotated by given angle within the current basis space.
202790
- * * the result arc will have its zero-degree point (new `vector0`) at the current.
202791
- * `vector0 * cos(theta) + vector90 * sin(theta)`.
202792
- * * the result sweep is adjusted so all fractional coordinates (e.g. start and end) evaluate to the same xyz.
202797
+ * * The returned arc will have `vector0 = this.vector0 * cos(theta) + this.vector90 * sin(theta)`.
202798
+ * * The returned arc has the same shape as the instance.
202799
+ * * In other words, the arc's sweep is adjusted so that all fractional parameters evaluate to the same points.
202793
202800
  * * Specifically, theta is subtracted from the original start and end angles.
202794
202801
  * @param theta the angle (in the input arc space) which is to become the 0-degree point in the new arc.
202795
202802
  */
@@ -202802,6 +202809,39 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
202802
202809
  const arcB = Arc3d.create(this._center.clone(), vector0, vector90, newSweep);
202803
202810
  return arcB;
202804
202811
  }
202812
+ /**
202813
+ * Return a cloned arc with basis rotated to align with the global axes. The arc's shape is unchanged.
202814
+ * * This method is most useful when the instance is an xy-circular arc, for then the aligned arc's stored sweep
202815
+ * angles can be understood as being measured from the global positive x-axis to the arc's start/end. This is *not*
202816
+ * the case for xy-elliptical arcs: the parameter angle difference between two points on an ellipse is in general
202817
+ * not the same as the angle measured between their radials.
202818
+ * * For an xy instance, the output arc will have:
202819
+ * * vector0 is in the same direction as the positive x-axis
202820
+ * * perpendicularVector is in the same direction as the positive z-axis
202821
+ * * For a general instance, the output arc will have:
202822
+ * * vector0 is in the same direction as the projection of the positive x-axis vector onto the arc plane
202823
+ * * perpendicularVector lies in the halfspace z >= 0
202824
+ * @returns cloned arc, or undefined (if the instance normal is parallel to the x-axis, or its matrix is singular)
202825
+ */
202826
+ cloneAxisAligned() {
202827
+ const plane = _geometry3d_Plane3dByOriginAndUnitNormal__WEBPACK_IMPORTED_MODULE_17__.Plane3dByOriginAndUnitNormal.create(this.center, this.perpendicularVector.crossProduct(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_4__.Vector3d.unitX()));
202828
+ if (!plane)
202829
+ return undefined;
202830
+ const axisPts = [];
202831
+ if (2 !== this.appendPlaneIntersectionPoints(plane, axisPts))
202832
+ return undefined;
202833
+ const iAxisPt = plane.getNormalRef().dotProduct(this.perpendicularVector.crossProductStartEnd(this.center, axisPts[0].point)) > 0.0 ? 0 : 1;
202834
+ const toUnitX = this.sweep.fractionToAngle(axisPts[iAxisPt].fraction);
202835
+ const arc1 = this.cloneInRotatedBasis(toUnitX); // rotate in arc's plane
202836
+ if (this.perpendicularVector.dotProduct(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_4__.Vector3d.unitZ()) < -_Geometry__WEBPACK_IMPORTED_MODULE_5__.Geometry.smallAngleRadians) {
202837
+ if (this.matrixRef.isSingular())
202838
+ return undefined;
202839
+ const flip = _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_3__.Matrix3d.createRowValues(1, 0, 0, 0, -1, 0, 0, 0, -1); // rotate 180 degrees around arc's local x-axis
202840
+ arc1.matrixRef.multiplyMatrixMatrix(flip, arc1.matrixRef);
202841
+ arc1.sweep.setStartEndDegrees(-arc1.sweep.startDegrees, -arc1.sweep.endDegrees); // rotation alone is insufficient to flip
202842
+ }
202843
+ return arc1;
202844
+ }
202805
202845
  /**
202806
202846
  * Find intervals of this CurvePrimitive that are interior to a clipper.
202807
202847
  * @param clipper clip structure (e.g.clip planes).
@@ -202901,7 +202941,7 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
202901
202941
  * @param offsetDistanceOrOptions offset distance (positive to left of the instance curve), or options object.
202902
202942
  */
202903
202943
  constructOffsetXY(offsetDistanceOrOptions) {
202904
- const options = _OffsetOptions__WEBPACK_IMPORTED_MODULE_17__.OffsetOptions.create(offsetDistanceOrOptions);
202944
+ const options = _OffsetOptions__WEBPACK_IMPORTED_MODULE_18__.OffsetOptions.create(offsetDistanceOrOptions);
202905
202945
  if (this.isCircular || options.preserveEllipticalArcs) {
202906
202946
  const arcXY = this.cloneAtZ();
202907
202947
  const sign = arcXY.sweep.sweepRadians * arcXY.matrixRef.coffs[8] >= 0.0 ? 1.0 : -1.0;
@@ -202923,7 +202963,7 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
202923
202963
  }
202924
202964
  }
202925
202965
  // default impl
202926
- const handler = new _internalContexts_CurveOffsetXYHandler__WEBPACK_IMPORTED_MODULE_18__.CurveOffsetXYHandler(this, options.leftOffsetDistance);
202966
+ const handler = new _internalContexts_CurveOffsetXYHandler__WEBPACK_IMPORTED_MODULE_19__.CurveOffsetXYHandler(this, options.leftOffsetDistance);
202927
202967
  this.emitStrokableParts(handler, options.strokeOptions);
202928
202968
  return handler.claimResult();
202929
202969
  }
@@ -202934,7 +202974,7 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
202934
202974
  * @returns range of fractional projection parameters onto the ray, where 0.0 is start of the ray and 1.0 is the end of the ray.
202935
202975
  */
202936
202976
  projectedParameterRange(ray, lowHigh) {
202937
- return _internalContexts_PlaneAltitudeRangeContext__WEBPACK_IMPORTED_MODULE_19__.PlaneAltitudeRangeContext.findExtremeFractionsAlongDirection(this, ray, lowHigh);
202977
+ return _internalContexts_PlaneAltitudeRangeContext__WEBPACK_IMPORTED_MODULE_20__.PlaneAltitudeRangeContext.findExtremeFractionsAlongDirection(this, ray, lowHigh);
202938
202978
  }
202939
202979
  /**
202940
202980
  * Construct a circular arc chain approximation to the instance elliptical arc.
@@ -202944,10 +202984,10 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
202944
202984
  constructCircularArcChainApproximation(options) {
202945
202985
  if (!options)
202946
202986
  options = EllipticalArcApproximationOptions.create();
202947
- const context = _internalContexts_EllipticalArcApproximationContext__WEBPACK_IMPORTED_MODULE_20__.EllipticalArcApproximationContext.create(this);
202987
+ const context = _internalContexts_EllipticalArcApproximationContext__WEBPACK_IMPORTED_MODULE_21__.EllipticalArcApproximationContext.create(this);
202948
202988
  const result = context.constructCircularArcChainApproximation(options);
202949
202989
  if (!result && this.isCircular)
202950
- return (this.sweep.isFullCircle && options.forcePath) ? _Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(this) : this;
202990
+ return (this.sweep.isFullCircle && options.forcePath) ? _Path__WEBPACK_IMPORTED_MODULE_22__.Path.create(this) : this;
202951
202991
  return result;
202952
202992
  }
202953
202993
  }
@@ -204113,6 +204153,11 @@ class CurveCollection extends _GeometryQuery__WEBPACK_IMPORTED_MODULE_0__.Geomet
204113
204153
  }
204114
204154
  return detailA;
204115
204155
  }
204156
+ /** Reverse the collection's data so that each child curve's fractional stroking moves in the opposite direction. */
204157
+ reverseInPlace() {
204158
+ for (const curve of this.children)
204159
+ curve.reverseInPlace();
204160
+ }
204116
204161
  /**
204117
204162
  * Return the max gap between adjacent primitives in Path and Loop collections.
204118
204163
  * * In a Path, gaps are computed between consecutive primitives.
@@ -204352,14 +204397,18 @@ class CurveChain extends CurveCollection {
204352
204397
  curve.extendRange(range, transform);
204353
204398
  }
204354
204399
  /**
204355
- * Reverse each child curve (in place)
204356
- * Reverse the order of the children in the CurveChain array.
204400
+ * Reverse each child curve (in place).
204401
+ * Reverse the order of the children array.
204357
204402
  */
204358
204403
  reverseChildrenInPlace() {
204359
204404
  for (const curve of this._curves)
204360
204405
  curve.reverseInPlace();
204361
204406
  this._curves.reverse();
204362
204407
  }
204408
+ /** Same as [[reverseChildrenInPlace]]. */
204409
+ reverseInPlace() {
204410
+ this.reverseChildrenInPlace();
204411
+ }
204363
204412
  /**
204364
204413
  * Return the index where target is found in the array of children.
204365
204414
  * @param alsoSearchProxies whether to also check proxy curves of the children
@@ -207624,34 +207673,34 @@ class LineString3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePri
207624
207673
  }
207625
207674
  /**
207626
207675
  * Return array of fraction parameters.
207627
- * * These Are only present during certain constructions such as faceting.
207676
+ * * These are only present during certain constructions such as faceting.
207628
207677
  * * When present, these fractions are fractions of some other curve being stroked, and are NOT related to the
207629
207678
  * linestring fraction parameters.
207630
207679
  */
207631
207680
  get fractions() {
207632
207681
  return this._fractions;
207633
207682
  }
207634
- /** Return the (optional) array of derivatives. These Are only present during certain constructions such as faceting. */
207683
+ /** Return the (optional) array of derivatives. These are only present during certain constructions such as faceting. */
207635
207684
  get packedDerivatives() {
207636
207685
  return this._derivatives;
207637
207686
  }
207638
- /** Return the (optional) array of uv params. These Are only present during certain constructions such as faceting. */
207687
+ /** Return the (optional) array of uv parameters. These are only present during certain constructions such as faceting. */
207639
207688
  get packedUVParams() {
207640
207689
  return this._uvParams;
207641
207690
  }
207642
- /** Return the (optional) array of surface normals. These Are only present during certain constructions such as faceting. */
207691
+ /** Return the (optional) array of surface normals. These are only present during certain constructions such as faceting. */
207643
207692
  get packedSurfaceNormals() {
207644
207693
  return this._surfaceNormals;
207645
207694
  }
207646
- /** Return the (optional) array of normal indices. These Are only present during certain constructions such as faceting. */
207695
+ /** Return the (optional) array of normal indices. These are only present during certain constructions such as faceting. */
207647
207696
  get normalIndices() {
207648
207697
  return this._normalIndices;
207649
207698
  }
207650
- /** Return the (optional) array of param indices. These Are only present during certain constructions such as faceting. */
207699
+ /** Return the (optional) array of uv parameter indices. These are only present during certain constructions such as faceting. */
207651
207700
  get paramIndices() {
207652
207701
  return this._uvIndices;
207653
207702
  }
207654
- /** Return the (optional) array of point indices. These Are only present during certain constructions such as faceting. */
207703
+ /** Return the (optional) array of point indices. These are only present during certain constructions such as faceting. */
207655
207704
  get pointIndices() {
207656
207705
  return this._pointIndices;
207657
207706
  }
@@ -208233,11 +208282,32 @@ class LineString3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePri
208233
208282
  reverseInPlace() {
208234
208283
  if (this._points.length >= 2) {
208235
208284
  this._points.reverseInPlace();
208285
+ if (this._fractions) {
208286
+ this._fractions.reverseInPlace();
208287
+ for (let i = 0; i < this._fractions.length; ++i)
208288
+ this._fractions.reassign(i, 1.0 - this._fractions.atUncheckedIndex(i));
208289
+ }
208236
208290
  if (this._uvParams)
208237
208291
  this._uvParams.reverseInPlace();
208292
+ if (this._derivatives) {
208293
+ this._derivatives.reverseInPlace();
208294
+ this._derivatives.scaleInPlace(-1.0);
208295
+ }
208296
+ if (this._surfaceNormals)
208297
+ this._surfaceNormals.reverseInPlace();
208298
+ if (this._pointIndices)
208299
+ this._pointIndices.reverseInPlace();
208300
+ if (this._uvIndices)
208301
+ this._uvIndices.reverseInPlace();
208302
+ if (this._normalIndices)
208303
+ this._normalIndices.reverseInPlace();
208238
208304
  }
208239
208305
  }
208240
- /** Apply `transform` to each point of this linestring. */
208306
+ /**
208307
+ * Apply `transform` to each point of this linestring.
208308
+ * * Note that this method always returns true. If transforming the surface normals fails (due to singular matrix or zero
208309
+ * normal), the original normal(s) are left unchanged.
208310
+ */
208241
208311
  tryTransformInPlace(transform) {
208242
208312
  this._points.multiplyTransformInPlace(transform);
208243
208313
  if (this._derivatives)
@@ -209063,7 +209133,6 @@ class Loop extends _CurveCollection__WEBPACK_IMPORTED_MODULE_0__.CurveChain {
209063
209133
  isSameGeometryClass(other) {
209064
209134
  return other instanceof Loop;
209065
209135
  }
209066
- /** Test if `other` is an instance of `Loop` */
209067
209136
  constructor() {
209068
209137
  super();
209069
209138
  /** String name for schema properties */
@@ -209072,8 +209141,10 @@ class Loop extends _CurveCollection__WEBPACK_IMPORTED_MODULE_0__.CurveChain {
209072
209141
  this.isInner = false;
209073
209142
  }
209074
209143
  /**
209075
- * Create a loop from variable length list of CurvePrimitives
209076
- * @param curves array of individual curve primitives
209144
+ * Create a loop from a variable length list of [[CurvePrimitive]]s.
209145
+ * * A significant gap between the end of one curve and the start of the next, or between chain start and end,
209146
+ * is not bridged and may cause unexpected behavior.
209147
+ * @param curves array of individual curve primitives, assumed to form a closed planar loop.
209077
209148
  */
209078
209149
  static create(...curves) {
209079
209150
  const result = new Loop();
@@ -209086,13 +209157,18 @@ class Loop extends _CurveCollection__WEBPACK_IMPORTED_MODULE_0__.CurveChain {
209086
209157
  return result;
209087
209158
  }
209088
209159
  /**
209089
- * Create a loop from an array of curve primitives
209090
- * @param curves array of individual curve primitives
209160
+ * Create a loop from an array of [[CurvePrimitive]]s.
209161
+ * * A significant gap between the end of one curve and the start of the next, or between chain start and end,
209162
+ * is not bridged and may cause unexpected behavior.
209163
+ * @param curves array of individual curve primitives, assumed to form a closed planar loop.
209091
209164
  */
209092
209165
  static createArray(curves) {
209093
209166
  return this.create(...curves);
209094
209167
  }
209095
- /** Create a loop from an array of points */
209168
+ /**
209169
+ * Create a loop from an array of coplanar points.
209170
+ * @param points vertices of polygon, closure point optional.
209171
+ */
209096
209172
  static createPolygon(points) {
209097
209173
  const linestring = _LineString3d__WEBPACK_IMPORTED_MODULE_2__.LineString3d.create(points);
209098
209174
  linestring.addClosurePoint();
@@ -210257,14 +210333,16 @@ class CylindricalRangeQuery extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
210257
210333
  return accumulator._perpVector.clone();
210258
210334
  }
210259
210335
  /**
210260
- * Recurse through geometry.children to find linestrings.
210261
- * In each linestring, compute the surface normal annotation from
210336
+ * Recurse through `geometry.children` to find linestrings.
210337
+ * For each linestring, compute and store the normal of the rotational surface resulting from sweeping the
210338
+ * geometry around `axis` through a positive angle, using:
210262
210339
  * * the curve tangent stored in the linestring
210263
210340
  * * the axis of rotation
210264
- * * a default V vector to be used when the linestring point is close to the axis.
210265
- * @param geometry
210266
- * @param axis
210267
- * @param defaultVectorV
210341
+ * * a default V vector to be used when the linestring point is close to the axis
210342
+ * @param geometry profile curve (e.g., linestring, parity region). The orientation of the curve should be such that
210343
+ * the computed normal lies in the same half-space as the rotational sweep direction.
210344
+ * @param axis rotational axis
210345
+ * @param defaultVectorFromAxis default vector perpendicular to `axis` (e.g., sweepVector)
210268
210346
  */
210269
210347
  static buildRotationalNormalsInLineStrings(geometry, axis, defaultVectorFromAxis) {
210270
210348
  if (geometry instanceof _LineString3d__WEBPACK_IMPORTED_MODULE_3__.LineString3d) {
@@ -210273,18 +210351,20 @@ class CylindricalRangeQuery extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
210273
210351
  const normals = geometry.ensureEmptySurfaceNormals();
210274
210352
  if (derivatives && normals) {
210275
210353
  const vectorU = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create();
210276
- const vectorV = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(); // v direction (forwward along sweep) for surface of rotation.
210354
+ const vectorV = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create();
210277
210355
  const xyz = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create();
210278
210356
  const n = points.length;
210279
210357
  for (let i = 0; i < n; i++) {
210280
210358
  points.getPoint3dAtUncheckedPointIndex(i, xyz);
210281
210359
  axis.perpendicularPartOfVectorToTarget(xyz, vectorU);
210360
+ // compute the positive sweep direction. ASSUME: the rotational sweep angle is positive!
210282
210361
  if (vectorU.isAlmostZero)
210283
210362
  axis.direction.crossProduct(defaultVectorFromAxis, vectorV);
210284
210363
  else
210285
210364
  axis.direction.crossProduct(vectorU, vectorV);
210286
- geometry.packedDerivatives.getVector3dAtCheckedVectorIndex(i, vectorU); // reuse vector U as curve derivative
210287
- vectorU.crossProduct(vectorV, vectorV); // reuse vector V as normal!
210365
+ // ASSUME: orientation-based profile normal is in the same half-space as vectorV
210366
+ geometry.packedDerivatives.getVector3dAtCheckedVectorIndex(i, vectorU); // reuse vectorU
210367
+ vectorU.crossProduct(vectorV, vectorV); // reuse vectorV
210288
210368
  vectorV.normalizeInPlace();
210289
210369
  normals.push(vectorV);
210290
210370
  }
@@ -217298,16 +217378,19 @@ class ArcChainErrorProcessor extends QuadrantFractionsProcessor {
217298
217378
  }
217299
217379
  }
217300
217380
  /**
217301
- * Processor for refining a single Q1 ordered interval [f0,f1] by perturbing an interior fraction f.
217302
- * * This processor expects to repeatedly process a QuadrantFractions `q` with `q.quadrant` = 1 and fractions array
217303
- * [fPrev, f0, f, f1], where fPrev is from the previously processed (possibly refined) adjacent interval; however, if
217304
- * `q.interpolateStartTangent === true`, then no fPrev is necessary and [f0, f, f1] is expected.
217305
- * * This is enough info to compute the two circular arcs spanning [f0,f] and [f,f1] and compare their approximation
217306
- * errors.
217307
- * * The basic idea is to perturb f so that the difference in the two arcs' errors is minimized.
217308
- * * This processor keeps track of a bracket containing f so that when the caller repeatedly processes `q` via
217309
- * [[EllipticalArcApproximationContext.processQuadrantFractions]], a bisection algorithm plays out, informed by the
217310
- * heuristic that moving f toward one end of its bracket decreases the error of the approximating arc on that side of f.
217381
+ * Processor for computing an optimal refinement of a single Q1 ordered interval [f0,f1] by perturbing an interior
217382
+ * seed fraction f.
217383
+ * * Typically the caller (cf. [[AdaptiveSubdivisionQ1ErrorProcessor.announceArc]] processes a
217384
+ * QuadrantFractions `q` with `q.quadrant` = 1 until convergence. The `q.fractions` array is expected to have
217385
+ * one of two forms:
217386
+ * * [fPrev, f0, f, f1], where fPrev is from the adjacent interval (possibly just refined), or
217387
+ * * [f0, f, f1], if `q.interpolateStartTangent === true`.
217388
+ * * This processor implements a bisection algorithm that iteratively shrinks a sub-interval that brackets f,
217389
+ * starting with [f0,f1]:
217390
+ * * During processing, `announceArc` will be called twice to compute the approximation errors of the circular
217391
+ * arcs on either side of f in the current bracket.
217392
+ * * In `announceQuadrantEnd` if these two errors are almost equal, we are done refining [f0,f1]. Otherwise,
217393
+ * we move f halfway to the endpoint of the bracket that decreases the error delta, and shrink our bracket.
217311
217394
  * @internal
217312
217395
  */
217313
217396
  class AdaptiveSubdivisionQ1IntervalErrorProcessor extends QuadrantFractionsProcessor {
@@ -217379,14 +217462,17 @@ class AdaptiveSubdivisionQ1IntervalErrorProcessor extends QuadrantFractionsProce
217379
217462
  /**
217380
217463
  * Processor for computing samples in Q1 for a subdivision-based arc chain approximation.
217381
217464
  * * The basic idea is to build a refinement of `q.fractions` for a QuadrantFractions q with q.quadrant = 1.
217382
- * * Start off the refinement with a copy of `q.fractions`.
217383
- * * When an announced arc exceeds a given maximum approximation error, compute a fraction f in the span
217384
- * such that the error of arcs on either side of f would be almost equal, then add f to the refinement.
217385
- * * If the announced arc does not exceed the maxError, its associated fraction span remains unchanged---no
217386
- * additional samples are needed to decrease approximation error.
217387
- * * After `q` processing completes, `q.fractions` is updated in place with the computed refinement.
217388
- * * The caller typically re-processes `q` until `isRefined` returns false, at which point construction of an
217389
- * approximation that is guaranteed not to exceed the desired error can commence.
217465
+ * * In `announceQuadrantBegin` we start off the refinement with a copy of `q.fractions`.
217466
+ * * In `announceArc` we are called to process the interval [f0,f1] in `q.fractions`. First we test if the
217467
+ * announced arc's approximation error over [f0,f1] exceeds maxError.
217468
+ * * If so, we employ [[AdaptiveSubdivisionQ1IntervalErrorProcessor]] to compute an interior fraction f
217469
+ * that best refines the interval, which becomes [f0,f,f1].
217470
+ * * Otherwise, the fraction span [f0,f1] is unchanged---no additional samples are needed to decrease the
217471
+ * approximation error.
217472
+ * * In `announceQuadrantEnd`, `q.fractions` is updated in place with the computed refinement.
217473
+ * * The caller (e.g., [[AdaptiveSubdivisionSampler.computeRadiansStrictlyInsideQuadrant1]]) typically
217474
+ * re-processes `q` until `isRefined` returns false, at which point construction of an approximation that is
217475
+ * guaranteed not to exceed the desired error can commence.
217390
217476
  * @internal
217391
217477
  */
217392
217478
  class AdaptiveSubdivisionQ1ErrorProcessor extends QuadrantFractionsProcessor {
@@ -223538,16 +223624,22 @@ class BarycentricTriangle {
223538
223624
  }
223539
223625
  /**
223540
223626
  * Compute the intersection of a line (parameterized as a ray) with the plane of this triangle.
223541
- * * This method is slower than `Ray3d.intersectionWithTriangle`.
223627
+ * * Intersection data is returned for the line-plane intersection.
223628
+ * * No intersection is returned if the line is parallel to the plane.
223629
+ * * As for the *ray*, it intersects this triangle if and only if the returned detail `d` has
223630
+ * `d.isValid === true` and `d.a >= 0` and `d.isInsideOrOn === true`.
223631
+ * * This method is slower than `Ray3d.intersectionWithTriangle` but returns more information about the intersection.
223542
223632
  * @param ray infinite line to intersect, as a ray
223543
223633
  * @param result optional pre-allocated object to fill and return
223544
- * @returns details d of the line-plane intersection point `d.world`:
223545
- * * `d.a` is the intersection parameter along the ray.
223546
- * * The line intersects the plane of the triangle if and only if `d.isValid` returns true.
223547
- * * The ray intersects the plane of the triangle if and only if `d.isValid` returns true and `d.a` >= 0.
223548
- * * The ray intersects the triangle if and only if `d.isValid` returns true, `d.a` >= 0, and `d.isInsideOrOn`
223549
- * returns true.
223550
- * * `d.classify` can be used to determine where the intersection lies with respect to the triangle.
223634
+ * @returns details `d` of the intersection point `p` of the line and the plane of this triangle:
223635
+ * * `d.isValid`: false if and only if `ray.direction` is parallel to the plane, or the ray or triangle is degenerate.
223636
+ * * `d.world`: coordinates of `p`.
223637
+ * * `d.local`: barycentric coordinates of `p`.
223638
+ * * `d.a`: the intersection parameter of `p` along the ray. Negative means `p` is behind the ray origin.
223639
+ * * `d.classify`: where `p` lies with respect to the triangle.
223640
+ * * `d.isInsideOrOn`: whether `p` is inside or on the triangle.
223641
+ * * `d.closestEdgeIndex`: the index of the triangle edge `e` onto which `p` projects.
223642
+ * * `d.closestEdgeParam`: the edge parameter at which `p` projects onto `e`.
223551
223643
  * * Visualization can be found at https://www.itwinjs.org/sandbox/SaeedTorabi/RayTriangleIntersection
223552
223644
  * @see [[pointToFraction]]
223553
223645
  */
@@ -223564,6 +223656,9 @@ class BarycentricTriangle {
223564
223656
  const d = ray.direction;
223565
223657
  const u = BarycentricTriangle._workVector0 = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.createStartEnd(this.points[0], this.points[1], BarycentricTriangle._workVector0);
223566
223658
  const v = BarycentricTriangle._workVector1 = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.createStartEnd(this.points[0], this.points[2], BarycentricTriangle._workVector1);
223659
+ const scaledVolume = d.tripleProduct(u, v);
223660
+ if (scaledVolume * scaledVolume <= u.dotProduct(u) * v.dotProduct(v) * d.dotProduct(d) * _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallAngleRadiansSquared)
223661
+ return result; // parallel (no solution)
223567
223662
  const M = BarycentricTriangle._workMatrix = _Matrix3d__WEBPACK_IMPORTED_MODULE_4__.Matrix3d.createColumns(u, v, d, BarycentricTriangle._workMatrix);
223568
223663
  const c = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.createStartEnd(this.points[0], r0, BarycentricTriangle._workVector0); // reuse workVector0
223569
223664
  const solution = BarycentricTriangle._workVector1; // reuse workVector1
@@ -226605,6 +226700,10 @@ class GrowableFloat64Array {
226605
226700
  }
226606
226701
  this._inUse = numAccepted;
226607
226702
  }
226703
+ /** reverse the order of values. */
226704
+ reverseInPlace() {
226705
+ this._data.reverse();
226706
+ }
226608
226707
  }
226609
226708
 
226610
226709
 
@@ -228880,9 +228979,9 @@ __webpack_require__.r(__webpack_exports__);
228880
228979
  /* harmony export */ });
228881
228980
  /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
228882
228981
  /* harmony import */ var _geometry4d_Point4d__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../geometry4d/Point4d */ "../../core/geometry/lib/esm/geometry4d/Point4d.js");
228883
- /* harmony import */ var _Angle__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
228982
+ /* harmony import */ var _Angle__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
228884
228983
  /* harmony import */ var _Point2dVector2d__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Point2dVector2d */ "../../core/geometry/lib/esm/geometry3d/Point2dVector2d.js");
228885
- /* harmony import */ var _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
228984
+ /* harmony import */ var _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
228886
228985
  /* harmony import */ var _Transform__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Transform */ "../../core/geometry/lib/esm/geometry3d/Transform.js");
228887
228986
  /*---------------------------------------------------------------------------------------------
228888
228987
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
@@ -229182,32 +229281,35 @@ class Matrix3d {
229182
229281
  return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isDistanceWithinTol(max, tol);
229183
229282
  }
229184
229283
  /**
229185
- * Test if `this` and `other` have almost equal Z column and have X and Y columns differing only by a
229186
- * rotation of the same angle around that Z.
229187
- * * **WARNING:** X and Y columns have to be perpendicular to Z column in both `this` and `other`.
229188
- * @param tol optional tolerance for comparisons by Geometry.isDistanceWithinTol
229284
+ * A matrix equivalence test, returning true if and only if the matrices are almost equal,
229285
+ * or all of the following column comparisons hold:
229286
+ * * z columns are almost equal, and
229287
+ * * x columns differ only by a rotation of angle t around the z column, and
229288
+ * * y columns differ only by a rotation of the same angle t around the z column.
229289
+ * @param other matrix to compare
229290
+ * @param tol optional distance tolerance, for comparisons by Geometry.isDistanceWithinTol
229291
+ * @return whether matrices are almost equal modulo a rotation around their common nonzero z-column.
229189
229292
  */
229190
229293
  isAlmostEqualAllowZRotation(other, tol) {
229191
229294
  if (this.isAlmostEqual(other, tol))
229192
229295
  return true;
229193
- if (this.isAlmostEqualColumn(_Geometry__WEBPACK_IMPORTED_MODULE_0__.AxisIndex.Z, other, tol)) {
229194
- const radians = _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.radiansBetweenVectorsXYZ(this.coffs[0], this.coffs[3], this.coffs[6], other.coffs[0], other.coffs[3], other.coffs[6]);
229195
- const angle = _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(radians); // angle between X columns in `this` and `other`
229196
- const columnX = this.columnX();
229197
- const columnY = this.columnY();
229198
- const columnZ = this.columnZ();
229199
- /**
229200
- * Here we rotate this.columnX() around this.columnZ() by "angle" and expect to get other.columnX().
229201
- * Then we rotate this.columnY() around this.columnZ() by the same "angle" and if we get other.columnY(),
229202
- * that means `this` and `other` have X and Y columns differing only by a rotation around column Z.
229203
- */
229204
- let column = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.createRotateVectorAroundVector(columnX, columnZ, angle);
229205
- if (other.isAlmostEqualColumnXYZ(0, column.x, column.y, column.z, tol)) {
229206
- column = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.createRotateVectorAroundVector(columnY, columnZ, angle);
229207
- return other.isAlmostEqualColumnXYZ(1, column.x, column.y, column.z, tol);
229208
- }
229209
- }
229210
- return false;
229296
+ if (!this.isAlmostEqualColumn(_Geometry__WEBPACK_IMPORTED_MODULE_0__.AxisIndex.Z, other, tol))
229297
+ return false;
229298
+ const columnX = this.columnX();
229299
+ const columnY = this.columnY();
229300
+ const columnZ = this.columnZ();
229301
+ const toOtherColumnX = columnX.signedAngleTo(other.columnX(), columnZ);
229302
+ let testColumn = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.createRotateVectorAroundVector(columnX, columnZ, toOtherColumnX);
229303
+ if (!testColumn)
229304
+ return false; // columnZ is zero length
229305
+ if (!other.isAlmostEqualColumnXYZ(0, testColumn.x, testColumn.y, testColumn.z, tol))
229306
+ return false; // columnX rotated around columnZ by angle doesn't end up at other.columnX
229307
+ testColumn = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.createRotateVectorAroundVector(columnY, columnZ, toOtherColumnX);
229308
+ if (!testColumn)
229309
+ return false;
229310
+ if (!other.isAlmostEqualColumnXYZ(1, testColumn.x, testColumn.y, testColumn.z, tol))
229311
+ return false; // columnY rotated around columnZ by angle doesn't end up at other.columnY
229312
+ return true;
229211
229313
  }
229212
229314
  /** Test for exact (bitwise) equality with other. */
229213
229315
  isExactEqual(other) {
@@ -229483,10 +229585,10 @@ class Matrix3d {
229483
229585
  const b = a / scale;
229484
229586
  // if vectorA is close to the Z axis
229485
229587
  if (Math.abs(vectorA.x) < b && Math.abs(vectorA.y) < b) {
229486
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.createCrossProduct(vectorA.x, vectorA.y, vectorA.z, 0, -1, 0, result);
229588
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.createCrossProduct(vectorA.x, vectorA.y, vectorA.z, 0, -1, 0, result);
229487
229589
  }
229488
229590
  // if vectorA is NOT close to the Z axis
229489
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.createCrossProduct(0, 0, 1, vectorA.x, vectorA.y, vectorA.z, result);
229591
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.createCrossProduct(0, 0, 1, vectorA.x, vectorA.y, vectorA.z, result);
229490
229592
  }
229491
229593
  /**
229492
229594
  * Return a vector that is perpendicular to the input `vectorA`.
@@ -229707,7 +229809,7 @@ class Matrix3d {
229707
229809
  let c = Math.sqrt(0.5);
229708
229810
  let s = leftNoneRight < 0.0 ? -c : c;
229709
229811
  if (Math.abs(leftNoneRight) !== 1.0) {
229710
- const radians = _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.degreesToRadians(45.0 * leftNoneRight);
229812
+ const radians = _Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.degreesToRadians(45.0 * leftNoneRight);
229711
229813
  c = Math.cos(radians);
229712
229814
  s = Math.sin(radians);
229713
229815
  }
@@ -229801,7 +229903,7 @@ class Matrix3d {
229801
229903
  const sij = lambda.at(i, j);
229802
229904
  if (Math.abs(sij) < _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallFloatingPoint * (sii + sjj))
229803
229905
  return 0.0;
229804
- const jacobi = _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.trigValuesToHalfAngleTrigValues(sii - sjj, 2.0 * sij);
229906
+ const jacobi = _Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.trigValuesToHalfAngleTrigValues(sii - sjj, 2.0 * sij);
229805
229907
  const c = jacobi.c;
229806
229908
  const s = jacobi.s;
229807
229909
  /**
@@ -229881,7 +229983,7 @@ class Matrix3d {
229881
229983
  const sij = this.coffs[indexIJ];
229882
229984
  if (Math.abs(sij) < _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallFloatingPoint * (sii + sjj))
229883
229985
  return 0.0;
229884
- const jacobi = _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.trigValuesToHalfAngleTrigValues(sii - sjj, 2.0 * sij);
229986
+ const jacobi = _Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.trigValuesToHalfAngleTrigValues(sii - sjj, 2.0 * sij);
229885
229987
  const c = jacobi.c;
229886
229988
  const s = jacobi.s;
229887
229989
  const cc = c * c;
@@ -229945,12 +230047,12 @@ class Matrix3d {
229945
230047
  const e = c * c + s * s - 1.0; // s^2 + c^2 = 1
229946
230048
  // if s^2 + c^2 != 1 then we have a bad matrix so return false
229947
230049
  if (Math.abs(e) > _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallAngleRadians) {
229948
- return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(0), ok: false };
230050
+ return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createRadians(0), ok: false };
229949
230051
  }
229950
230052
  // sin is close to 0 then we got to special cases (angle 0 or 180) which needs to be handled differently
229951
230053
  if (Math.abs(s) < _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallAngleRadians) {
229952
230054
  if (c > 0) // sin = 0 and cos = 1 so angle = 0 (i.e., no rotation)
229953
- return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(0), ok: true };
230055
+ return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createRadians(0), ok: true };
229954
230056
  /**
229955
230057
  * If sin = 0 and cos = -1 then angle = 180 (i.e., 180 degree rotation around some axis)
229956
230058
  * then the rotation matrix becomes
@@ -229968,34 +230070,34 @@ class Matrix3d {
229968
230070
  const azz = this.coffs[8];
229969
230071
  // Look for a pair of "-1" entries on the diagonal (for rotation around the basis X,Y,Z axis)
229970
230072
  if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1.0, ayy) && _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1, azz)) {
229971
- return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(1, 0, 0), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createDegrees(180), ok: true };
230073
+ return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(1, 0, 0), angle: _Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createDegrees(180), ok: true };
229972
230074
  }
229973
230075
  else if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1.0, axx) && _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1, azz)) {
229974
- return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 1, 0), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createDegrees(180), ok: true };
230076
+ return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(0, 1, 0), angle: _Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createDegrees(180), ok: true };
229975
230077
  }
229976
230078
  else if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1.0, axx) && _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1, ayy)) {
229977
- return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createDegrees(180), ok: true };
230079
+ return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createDegrees(180), ok: true };
229978
230080
  }
229979
230081
  // Look for eigenvector with eigenvalue = 1
229980
230082
  const eigenvectors = Matrix3d.createIdentity();
229981
- const eigenvalues = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 0);
230083
+ const eigenvalues = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(0, 0, 0);
229982
230084
  if (this.fastSymmetricEigenvalues(eigenvectors, eigenvalues)) { // note: this matrix is "symmetric"
229983
230085
  for (let axisIndex = 0; axisIndex < 2; axisIndex++) {
229984
230086
  const lambda = eigenvalues.at(axisIndex);
229985
230087
  if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(1, lambda))
229986
- return { axis: eigenvectors.getColumn(axisIndex), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createDegrees(180), ok: true };
230088
+ return { axis: eigenvectors.getColumn(axisIndex), angle: _Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createDegrees(180), ok: true };
229987
230089
  }
229988
230090
  // if no eigenvalue = 1 was found return false
229989
- return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(0), ok: false };
230091
+ return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createRadians(0), ok: false };
229990
230092
  }
229991
230093
  // if no axis was found return false
229992
- return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(0), ok: false };
230094
+ return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createRadians(0), ok: false };
229993
230095
  }
229994
230096
  // good matrix and non-zero sine
229995
230097
  const a = 1.0 / (2.0 * s);
229996
230098
  const result = {
229997
- axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(skewYZ * a, skewZX * a, skewXY * a),
229998
- angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createAtan2(s, c),
230099
+ axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(skewYZ * a, skewZX * a, skewXY * a),
230100
+ angle: _Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createAtan2(s, c),
229999
230101
  ok: true,
230000
230102
  };
230001
230103
  return result;
@@ -230019,7 +230121,7 @@ class Matrix3d {
230019
230121
  const uDotV = this.coffs[i] * this.coffs[j]
230020
230122
  + this.coffs[i + 3] * this.coffs[j + 3]
230021
230123
  + this.coffs[i + 6] * this.coffs[j + 6];
230022
- const jacobi = _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.trigValuesToHalfAngleTrigValues(uDotU - vDotV, 2.0 * uDotV);
230124
+ const jacobi = _Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.trigValuesToHalfAngleTrigValues(uDotU - vDotV, 2.0 * uDotV);
230023
230125
  const c = jacobi.c;
230024
230126
  const s = jacobi.s;
230025
230127
  if (Math.abs(s) < 2.0e-15)
@@ -230107,7 +230209,7 @@ class Matrix3d {
230107
230209
  let upVector = vectorA.unitCrossProduct(vectorB);
230108
230210
  // the usual case (both vectors and also their cross product is non-zero)
230109
230211
  if (upVector) {
230110
- return Matrix3d.createRotationAroundVector(upVector, _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(fraction * vectorA.planarAngleTo(vectorB, upVector).radians));
230212
+ return Matrix3d.createRotationAroundVector(upVector, _Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createRadians(fraction * vectorA.planarAngleTo(vectorB, upVector).radians));
230111
230213
  }
230112
230214
  // if either vector is zero
230113
230215
  if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(vectorA.magnitude())
@@ -230118,7 +230220,7 @@ class Matrix3d {
230118
230220
  return Matrix3d.createIdentity(result);
230119
230221
  // opposing vectors (cross product = 0, dot product < 0)
230120
230222
  upVector = Matrix3d.createPerpendicularVectorFavorPlaneContainingZ(vectorA, upVector);
230121
- return Matrix3d.createRotationAroundVector(upVector, _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(fraction * Math.PI));
230223
+ return Matrix3d.createRotationAroundVector(upVector, _Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createRadians(fraction * Math.PI));
230122
230224
  }
230123
230225
  /** Returns a matrix that rotates from vectorA to vectorB. */
230124
230226
  static createRotationVectorToVector(vectorA, vectorB, result) {
@@ -230145,15 +230247,15 @@ class Matrix3d {
230145
230247
  }
230146
230248
  /** Return (a copy of) the X column */
230147
230249
  columnX(result) {
230148
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[0], this.coffs[3], this.coffs[6], result);
230250
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(this.coffs[0], this.coffs[3], this.coffs[6], result);
230149
230251
  }
230150
230252
  /** Return (a copy of) the Y column */
230151
230253
  columnY(result) {
230152
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[1], this.coffs[4], this.coffs[7], result);
230254
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(this.coffs[1], this.coffs[4], this.coffs[7], result);
230153
230255
  }
230154
230256
  /** Return (a copy of) the Z column */
230155
230257
  columnZ(result) {
230156
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[2], this.coffs[5], this.coffs[8], result);
230258
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(this.coffs[2], this.coffs[5], this.coffs[8], result);
230157
230259
  }
230158
230260
  /** Return the X column magnitude squared */
230159
230261
  columnXMagnitudeSquared() {
@@ -230225,15 +230327,15 @@ class Matrix3d {
230225
230327
  }
230226
230328
  /** Return (a copy of) the X row */
230227
230329
  rowX(result) {
230228
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[0], this.coffs[1], this.coffs[2], result);
230330
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(this.coffs[0], this.coffs[1], this.coffs[2], result);
230229
230331
  }
230230
230332
  /** Return (a copy of) the Y row */
230231
230333
  rowY(result) {
230232
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[3], this.coffs[4], this.coffs[5], result);
230334
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(this.coffs[3], this.coffs[4], this.coffs[5], result);
230233
230335
  }
230234
230336
  /** Return (a copy of) the Z row */
230235
230337
  rowZ(result) {
230236
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[6], this.coffs[7], this.coffs[8], result);
230338
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(this.coffs[6], this.coffs[7], this.coffs[8], result);
230237
230339
  }
230238
230340
  /** Return the dot product of the vector parameter with the X column. */
230239
230341
  dotColumnX(vector) {
@@ -230330,7 +230432,7 @@ class Matrix3d {
230330
230432
  */
230331
230433
  getColumn(columnIndex, result) {
230332
230434
  const index = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.cyclic3dAxis(columnIndex);
230333
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[index], this.coffs[index + 3], this.coffs[index + 6], result);
230435
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(this.coffs[index], this.coffs[index + 3], this.coffs[index + 6], result);
230334
230436
  }
230335
230437
  /**
230336
230438
  * Return a (copy of) a row of the matrix.
@@ -230339,7 +230441,7 @@ class Matrix3d {
230339
230441
  */
230340
230442
  getRow(columnIndex, result) {
230341
230443
  const index = 3 * _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.cyclic3dAxis(columnIndex);
230342
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[index], this.coffs[index + 1], this.coffs[index + 2], result);
230444
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(this.coffs[index], this.coffs[index + 1], this.coffs[index + 2], result);
230343
230445
  }
230344
230446
  /**
230345
230447
  * Create a matrix from row vectors.
@@ -230421,7 +230523,7 @@ class Matrix3d {
230421
230523
  const x = point.x;
230422
230524
  const y = point.y;
230423
230525
  const z = point.z;
230424
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(this.coffs[0] * x + this.coffs[1] * y + this.coffs[2] * z, this.coffs[3] * x + this.coffs[4] * y + this.coffs[5] * z, this.coffs[6] * x + this.coffs[7] * y + this.coffs[8] * z, result);
230526
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(this.coffs[0] * x + this.coffs[1] * y + this.coffs[2] * z, this.coffs[3] * x + this.coffs[4] * y + this.coffs[5] * z, this.coffs[6] * x + this.coffs[7] * y + this.coffs[8] * z, result);
230425
230527
  }
230426
230528
  /**
230427
230529
  * Multiply `matrix * vector`, treating the vector is a column vector on the right.
@@ -230435,7 +230537,7 @@ class Matrix3d {
230435
230537
  const x = vectorU.x;
230436
230538
  const y = vectorU.y;
230437
230539
  const z = vectorU.z;
230438
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[0] * x + this.coffs[1] * y + this.coffs[2] * z, this.coffs[3] * x + this.coffs[4] * y + this.coffs[5] * z, this.coffs[6] * x + this.coffs[7] * y + this.coffs[8] * z, result);
230540
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(this.coffs[0] * x + this.coffs[1] * y + this.coffs[2] * z, this.coffs[3] * x + this.coffs[4] * y + this.coffs[5] * z, this.coffs[6] * x + this.coffs[7] * y + this.coffs[8] * z, result);
230439
230541
  }
230440
230542
  /**
230441
230543
  * Multiply `matrix * vector` in place for vector in the array, i.e. treating the vector is a column
@@ -230451,7 +230553,7 @@ class Matrix3d {
230451
230553
  const x = vector.x;
230452
230554
  const y = vector.y;
230453
230555
  const z = vector.z;
230454
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(origin.x - (matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z), origin.y - (matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z), origin.z - (matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z), result);
230556
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(origin.x - (matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z), origin.y - (matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z), origin.z - (matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z), result);
230455
230557
  }
230456
230558
  /** Compute `origin + matrix * vector` using only the xy parts of the inputs. */
230457
230559
  static xyPlusMatrixTimesXY(origin, matrix, vector, result) {
@@ -230464,7 +230566,7 @@ class Matrix3d {
230464
230566
  const x = vector.x;
230465
230567
  const y = vector.y;
230466
230568
  const z = vector.z;
230467
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(origin.x + matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z, origin.y + matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z, origin.z + matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z, result);
230569
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(origin.x + matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z, origin.y + matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z, origin.z + matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z, result);
230468
230570
  }
230469
230571
  /** Updates vector to be `origin + matrix * vector` using all xyz parts of the inputs. */
230470
230572
  static xyzPlusMatrixTimesXYZInPlace(origin, matrix, vector) {
@@ -230477,7 +230579,7 @@ class Matrix3d {
230477
230579
  }
230478
230580
  /** Compute `origin + matrix * vector` where the final vector is given as direct x,y,z coordinates */
230479
230581
  static xyzPlusMatrixTimesCoordinates(origin, matrix, x, y, z, result) {
230480
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(origin.x + matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z, origin.y + matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z, origin.z + matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z, result);
230582
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(origin.x + matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z, origin.y + matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z, origin.z + matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z, result);
230481
230583
  }
230482
230584
  /**
230483
230585
  * Treat the 3x3 matrix and origin as upper 3x4 part of a 4x4 matrix, with 0001 as the final row.
@@ -230556,7 +230658,7 @@ class Matrix3d {
230556
230658
  * @param result the vector result (optional)
230557
230659
  */
230558
230660
  multiplyTransposeVector(vector, result) {
230559
- result = result ? result : new _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d();
230661
+ result = result ? result : new _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d();
230560
230662
  const x = vector.x;
230561
230663
  const y = vector.y;
230562
230664
  const z = vector.z;
@@ -230570,7 +230672,7 @@ class Matrix3d {
230570
230672
  * @param result the vector result (optional)
230571
230673
  */
230572
230674
  multiplyXYZ(x, y, z, result) {
230573
- result = result ? result : new _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d();
230675
+ result = result ? result : new _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d();
230574
230676
  result.x = this.coffs[0] * x + this.coffs[1] * y + this.coffs[2] * z;
230575
230677
  result.y = this.coffs[3] * x + this.coffs[4] * y + this.coffs[5] * z;
230576
230678
  result.z = this.coffs[6] * x + this.coffs[7] * y + this.coffs[8] * z;
@@ -230595,7 +230697,7 @@ class Matrix3d {
230595
230697
  * @param result the vector result (optional)
230596
230698
  */
230597
230699
  multiplyXY(x, y, result) {
230598
- result = result ? result : new _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d();
230700
+ result = result ? result : new _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d();
230599
230701
  result.x = this.coffs[0] * x + this.coffs[1] * y;
230600
230702
  result.y = this.coffs[3] * x + this.coffs[4] * y;
230601
230703
  result.z = this.coffs[6] * x + this.coffs[7] * y;
@@ -230606,7 +230708,7 @@ class Matrix3d {
230606
230708
  * @param result the Point3d result (optional)
230607
230709
  */
230608
230710
  originPlusMatrixTimesXY(origin, x, y, result) {
230609
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(origin.x + this.coffs[0] * x + this.coffs[1] * y, origin.y + this.coffs[3] * x + this.coffs[4] * y, origin.z + this.coffs[6] * x + this.coffs[7] * y, result);
230711
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(origin.x + this.coffs[0] * x + this.coffs[1] * y, origin.y + this.coffs[3] * x + this.coffs[4] * y, origin.z + this.coffs[6] * x + this.coffs[7] * y, result);
230610
230712
  }
230611
230713
  /**
230612
230714
  * Multiply the matrix * (x,y,z) in place, i.e. the vector (x,y,z) is a column vector on the right and
@@ -230649,7 +230751,7 @@ class Matrix3d {
230649
230751
  * @param result the vector result (optional)
230650
230752
  */
230651
230753
  multiplyTransposeXYZ(x, y, z, result) {
230652
- result = result ? result : new _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d();
230754
+ result = result ? result : new _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d();
230653
230755
  result.x = this.coffs[0] * x + this.coffs[3] * y + this.coffs[6] * z;
230654
230756
  result.y = this.coffs[1] * x + this.coffs[4] * y + this.coffs[7] * z;
230655
230757
  result.z = this.coffs[2] * x + this.coffs[5] * y + this.coffs[8] * z;
@@ -230666,7 +230768,7 @@ class Matrix3d {
230666
230768
  const x = vector.x;
230667
230769
  const y = vector.y;
230668
230770
  const z = vector.z;
230669
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.inverseCoffs[0] * x + this.inverseCoffs[1] * y + this.inverseCoffs[2] * z, this.inverseCoffs[3] * x + this.inverseCoffs[4] * y + this.inverseCoffs[5] * z, this.inverseCoffs[6] * x + this.inverseCoffs[7] * y + this.inverseCoffs[8] * z, result);
230771
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(this.inverseCoffs[0] * x + this.inverseCoffs[1] * y + this.inverseCoffs[2] * z, this.inverseCoffs[3] * x + this.inverseCoffs[4] * y + this.inverseCoffs[5] * z, this.inverseCoffs[6] * x + this.inverseCoffs[7] * y + this.inverseCoffs[8] * z, result);
230670
230772
  }
230671
230773
  return undefined;
230672
230774
  }
@@ -230681,7 +230783,7 @@ class Matrix3d {
230681
230783
  const x = vector.x;
230682
230784
  const y = vector.y;
230683
230785
  const z = vector.z;
230684
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.inverseCoffs[0] * x + this.inverseCoffs[3] * y + this.inverseCoffs[6] * z, this.inverseCoffs[1] * x + this.inverseCoffs[4] * y + this.inverseCoffs[7] * z, this.inverseCoffs[2] * x + this.inverseCoffs[5] * y + this.inverseCoffs[8] * z, result);
230786
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(this.inverseCoffs[0] * x + this.inverseCoffs[3] * y + this.inverseCoffs[6] * z, this.inverseCoffs[1] * x + this.inverseCoffs[4] * y + this.inverseCoffs[7] * z, this.inverseCoffs[2] * x + this.inverseCoffs[5] * y + this.inverseCoffs[8] * z, result);
230685
230787
  }
230686
230788
  return undefined;
230687
230789
  }
@@ -230694,7 +230796,7 @@ class Matrix3d {
230694
230796
  multiplyInverseXYZAsVector3d(x, y, z, result) {
230695
230797
  this.computeCachedInverse(true);
230696
230798
  if (this.inverseCoffs) {
230697
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.inverseCoffs[0] * x + this.inverseCoffs[1] * y + this.inverseCoffs[2] * z, this.inverseCoffs[3] * x + this.inverseCoffs[4] * y + this.inverseCoffs[5] * z, this.inverseCoffs[6] * x + this.inverseCoffs[7] * y + this.inverseCoffs[8] * z, result);
230799
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(this.inverseCoffs[0] * x + this.inverseCoffs[1] * y + this.inverseCoffs[2] * z, this.inverseCoffs[3] * x + this.inverseCoffs[4] * y + this.inverseCoffs[5] * z, this.inverseCoffs[6] * x + this.inverseCoffs[7] * y + this.inverseCoffs[8] * z, result);
230698
230800
  }
230699
230801
  return undefined;
230700
230802
  }
@@ -230719,7 +230821,7 @@ class Matrix3d {
230719
230821
  multiplyInverseXYZAsPoint3d(x, y, z, result) {
230720
230822
  this.computeCachedInverse(true);
230721
230823
  if (this.inverseCoffs) {
230722
- return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(this.inverseCoffs[0] * x + this.inverseCoffs[1] * y + this.inverseCoffs[2] * z, this.inverseCoffs[3] * x + this.inverseCoffs[4] * y + this.inverseCoffs[5] * z, this.inverseCoffs[6] * x + this.inverseCoffs[7] * y + this.inverseCoffs[8] * z, result);
230824
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(this.inverseCoffs[0] * x + this.inverseCoffs[1] * y + this.inverseCoffs[2] * z, this.inverseCoffs[3] * x + this.inverseCoffs[4] * y + this.inverseCoffs[5] * z, this.inverseCoffs[6] * x + this.inverseCoffs[7] * y + this.inverseCoffs[8] * z, result);
230723
230825
  }
230724
230826
  return undefined;
230725
230827
  }
@@ -237612,7 +237714,10 @@ class PolygonOps {
237612
237714
  * * Compare to [[closestPoint]].
237613
237715
  * @param polygon points of the polygon, closure point optional
237614
237716
  * @param testPoint point p to project onto the polygon edges. Works best when p is in the plane of the polygon.
237615
- * @param tolerance optional distance tolerance to determine point-vertex and point-edge coincidence.
237717
+ * @param tolerance optional tolerance(s) to determine point-vertex and point-edge coincidence. A single number
237718
+ * is interpreted as distance tolerance. If an array is given, the first number is interpreted as distance tolerance;
237719
+ * the second, as parametric tolerance. Default values are [[Geometry.smallMetricDistance]] for distance tolerance
237720
+ * and 0.0 for parameter tolerance.
237616
237721
  * @param result optional pre-allocated object to fill and return
237617
237722
  * @returns details d of the closest point `d.point`:
237618
237723
  * * `d.isValid()` returns true if and only if the polygon is nontrivial.
@@ -237624,7 +237729,9 @@ class PolygonOps {
237624
237729
  static closestPointOnBoundary(polygon, testPoint, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallMetricDistance, result) {
237625
237730
  if (!(polygon instanceof _IndexedXYZCollection__WEBPACK_IMPORTED_MODULE_5__.IndexedXYZCollection))
237626
237731
  return this.closestPointOnBoundary(new _Point3dArrayCarrier__WEBPACK_IMPORTED_MODULE_4__.Point3dArrayCarrier(polygon), testPoint, tolerance, result);
237627
- const distTol2 = tolerance * tolerance;
237732
+ const distTol = Array.isArray(tolerance) ? tolerance[0] : tolerance;
237733
+ const paramTol = Array.isArray(tolerance) ? Math.abs(tolerance[1]) : 0.0;
237734
+ const distTol2 = distTol * distTol;
237628
237735
  let numPoints = polygon.length;
237629
237736
  while (numPoints > 1) {
237630
237737
  if (polygon.distanceSquaredIndexIndex(0, numPoints - 1) > distTol2)
@@ -237634,29 +237741,59 @@ class PolygonOps {
237634
237741
  result = PolygonLocationDetail.create(result);
237635
237742
  if (0 === numPoints)
237636
237743
  return result; // invalid
237637
- if (1 === numPoints) {
237638
- polygon.getPoint3dAtUncheckedPointIndex(0, result.point);
237744
+ const constructSingletonPoint = (index) => {
237745
+ polygon.getPoint3dAtUncheckedPointIndex(index, result.point);
237639
237746
  result.a = result.point.distance(testPoint);
237640
237747
  result.v.setZero();
237641
237748
  result.code = _Geometry__WEBPACK_IMPORTED_MODULE_2__.PolygonLocation.OnPolygonVertex;
237642
- result.closestEdgeIndex = 0;
237749
+ result.closestEdgeIndex = index;
237643
237750
  result.closestEdgeParam = 0.0;
237644
237751
  return result;
237645
- }
237752
+ };
237753
+ if (1 === numPoints)
237754
+ return constructSingletonPoint(0);
237755
+ // lambda for computing edge parameter at which testPoint projects onto the edge starting at iEdgeStart
237756
+ const projectToEdge = (iEdgeStart) => {
237757
+ let isValid = false;
237758
+ let edgeParam = 0.0;
237759
+ let uDotU = 0.0;
237760
+ let vDotV = 0.0;
237761
+ if (iEdgeStart >= 0 && iEdgeStart < numPoints) {
237762
+ let iEdgeEnd = iEdgeStart + 1;
237763
+ if (iEdgeEnd === numPoints)
237764
+ iEdgeEnd = 0;
237765
+ uDotU = polygon.distanceSquaredIndexIndex(iEdgeStart, iEdgeEnd);
237766
+ if (uDotU > distTol2) { // nontrivial edge
237767
+ vDotV = polygon.distanceSquaredIndexXYAndZ(iEdgeStart, testPoint);
237768
+ const uDotV = polygon.dotProductIndexIndexXYAndZ(iEdgeStart, iEdgeEnd, testPoint);
237769
+ edgeParam = uDotV / uDotU; // param of projection of testPoint onto edge [iEdgeStart, iEdgeEnd]
237770
+ isValid = true;
237771
+ }
237772
+ }
237773
+ return { isValid, edgeParam, uDotU, vDotV };
237774
+ };
237775
+ // find the previous nontrivial edge's projection status before processing the first edge
237776
+ let projBeyondPrevEdge = false;
237646
237777
  let iPrev = numPoints - 1;
237778
+ for (; iPrev > 0; --iPrev) {
237779
+ const projData = projectToEdge(iPrev);
237780
+ if (projData.isValid) {
237781
+ projBeyondPrevEdge = projData.edgeParam > 1.0 + paramTol;
237782
+ break;
237783
+ }
237784
+ }
237785
+ if (iPrev <= 0) // all segments trivial, so treat like single point case
237786
+ return constructSingletonPoint(0);
237647
237787
  let minDist2 = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.largeCoordinateResult;
237648
237788
  for (let iBase = 0; iBase < numPoints; ++iBase) {
237649
237789
  let iNext = iBase + 1;
237650
237790
  if (iNext === numPoints)
237651
237791
  iNext = 0;
237652
- const uDotU = polygon.distanceSquaredIndexIndex(iBase, iNext);
237653
- if (uDotU <= distTol2)
237654
- continue; // ignore trivial polygon edge (keep iPrev)
237655
- const vDotV = polygon.distanceSquaredIndexXYAndZ(iBase, testPoint);
237656
- const uDotV = polygon.dotProductIndexIndexXYAndZ(iBase, iNext, testPoint);
237657
- const edgeParam = uDotV / uDotU; // param of projection of testPoint onto this edge
237658
- if (edgeParam <= 0.0) { // testPoint projects to/before edge start
237659
- const distToStart2 = vDotV;
237792
+ const projData = projectToEdge(iBase);
237793
+ if (!projData.isValid)
237794
+ continue; // ignore trivial polygon edge (keep iPrev, projBeyondPrevEdge)
237795
+ if (projData.edgeParam <= paramTol) { // testPoint projects to/before edge start
237796
+ const distToStart2 = projData.vDotV;
237660
237797
  if (distToStart2 <= distTol2) {
237661
237798
  // testPoint is at edge start; we are done
237662
237799
  polygon.getPoint3dAtUncheckedPointIndex(iBase, result.point);
@@ -237667,25 +237804,25 @@ class PolygonOps {
237667
237804
  result.closestEdgeParam = 0.0;
237668
237805
  return result;
237669
237806
  }
237670
- if (distToStart2 < minDist2) {
237671
- if (polygon.dotProductIndexIndexXYAndZ(iBase, iPrev, testPoint) <= 0.0) {
237672
- // update candidate (to edge start) only if testPoint projected beyond previous edge end
237673
- polygon.getPoint3dAtUncheckedPointIndex(iBase, result.point);
237674
- result.a = Math.sqrt(distToStart2);
237675
- polygon.crossProductIndexIndexIndex(iBase, iPrev, iNext, result.v);
237676
- result.code = _Geometry__WEBPACK_IMPORTED_MODULE_2__.PolygonLocation.OnPolygonVertex;
237677
- result.closestEdgeIndex = iBase;
237678
- result.closestEdgeParam = 0.0;
237679
- minDist2 = distToStart2;
237680
- }
237807
+ if (distToStart2 < minDist2 && projBeyondPrevEdge) {
237808
+ // update candidate (to edge start) only if testPoint projected beyond previous edge end
237809
+ polygon.getPoint3dAtUncheckedPointIndex(iBase, result.point);
237810
+ result.a = Math.sqrt(distToStart2);
237811
+ polygon.crossProductIndexIndexIndex(iBase, iPrev, iNext, result.v);
237812
+ result.code = _Geometry__WEBPACK_IMPORTED_MODULE_2__.PolygonLocation.OnPolygonVertex;
237813
+ result.closestEdgeIndex = iBase;
237814
+ result.closestEdgeParam = 0.0;
237815
+ minDist2 = distToStart2;
237681
237816
  }
237817
+ projBeyondPrevEdge = false;
237682
237818
  }
237683
- else if (edgeParam <= 1.0) { // testPoint projects inside edge, or to edge end
237684
- const projDist2 = vDotV - edgeParam * edgeParam * uDotU;
237819
+ else if (projData.edgeParam <= 1.0 + paramTol) { // testPoint projects inside edge, or to edge end
237820
+ projData.edgeParam = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.clamp(projData.edgeParam, 0.0, 1.0);
237821
+ const projDist2 = projData.vDotV - projData.edgeParam * projData.edgeParam * projData.uDotU;
237685
237822
  if (projDist2 <= distTol2) {
237686
237823
  // testPoint is on edge; we are done
237687
- const distToStart2 = vDotV;
237688
- if (edgeParam <= 0.5 && distToStart2 <= distTol2) {
237824
+ const distToStart2 = projData.vDotV;
237825
+ if (projData.edgeParam <= 0.5 && distToStart2 <= distTol2) {
237689
237826
  // testPoint is at edge start
237690
237827
  polygon.getPoint3dAtUncheckedPointIndex(iBase, result.point);
237691
237828
  result.a = Math.sqrt(distToStart2);
@@ -237695,8 +237832,8 @@ class PolygonOps {
237695
237832
  result.closestEdgeParam = 0.0;
237696
237833
  return result;
237697
237834
  }
237698
- const distToEnd2 = projDist2 + (1.0 - edgeParam) * (1.0 - edgeParam) * uDotU;
237699
- if (edgeParam > 0.5 && distToEnd2 <= distTol2) {
237835
+ const distToEnd2 = projDist2 + (1.0 - projData.edgeParam) * (1.0 - projData.edgeParam) * projData.uDotU;
237836
+ if (projData.edgeParam > 0.5 && distToEnd2 <= distTol2) {
237700
237837
  // testPoint is at edge end
237701
237838
  polygon.getPoint3dAtUncheckedPointIndex(iNext, result.point);
237702
237839
  result.a = Math.sqrt(distToEnd2);
@@ -237707,27 +237844,29 @@ class PolygonOps {
237707
237844
  return result;
237708
237845
  }
237709
237846
  // testPoint is on edge interior
237710
- polygon.interpolateIndexIndex(iBase, edgeParam, iNext, result.point);
237847
+ polygon.interpolateIndexIndex(iBase, projData.edgeParam, iNext, result.point);
237711
237848
  result.a = Math.sqrt(projDist2);
237712
237849
  result.v.setZero();
237713
237850
  result.code = _Geometry__WEBPACK_IMPORTED_MODULE_2__.PolygonLocation.OnPolygonEdgeInterior;
237714
237851
  result.closestEdgeIndex = iBase;
237715
- result.closestEdgeParam = edgeParam;
237852
+ result.closestEdgeParam = projData.edgeParam;
237716
237853
  return result;
237717
237854
  }
237718
237855
  if (projDist2 < minDist2) {
237719
- // update candidate (to edge interior)
237720
- polygon.interpolateIndexIndex(iBase, edgeParam, iNext, result.point);
237856
+ // update candidate
237857
+ polygon.interpolateIndexIndex(iBase, projData.edgeParam, iNext, result.point);
237721
237858
  result.a = Math.sqrt(projDist2);
237722
237859
  polygon.crossProductIndexIndexXYAndZ(iBase, iNext, testPoint, result.v);
237723
- result.code = _Geometry__WEBPACK_IMPORTED_MODULE_2__.PolygonLocation.OnPolygonEdgeInterior;
237860
+ result.code = projData.edgeParam < 1.0 ? _Geometry__WEBPACK_IMPORTED_MODULE_2__.PolygonLocation.OnPolygonEdgeInterior : _Geometry__WEBPACK_IMPORTED_MODULE_2__.PolygonLocation.OnPolygonVertex;
237861
+ ;
237724
237862
  result.closestEdgeIndex = iBase;
237725
- result.closestEdgeParam = edgeParam;
237863
+ result.closestEdgeParam = projData.edgeParam;
237726
237864
  minDist2 = projDist2;
237727
237865
  }
237866
+ projBeyondPrevEdge = false;
237728
237867
  }
237729
- else { // edgeParam > 1.0
237730
- // NOOP: testPoint projects beyond edge end, handled by next edge
237868
+ else {
237869
+ projBeyondPrevEdge = true; // to be handled by next edge
237731
237870
  }
237732
237871
  iPrev = iBase;
237733
237872
  }
@@ -237771,7 +237910,10 @@ class PolygonOps {
237771
237910
  /** Compute the intersection of a line (parameterized as a ray) with the plane of this polygon.
237772
237911
  * @param polygon points of the polygon, closure point optional
237773
237912
  * @param ray infinite line to intersect, as a ray
237774
- * @param tolerance optional distance tolerance to determine point-vertex and point-edge coincidence.
237913
+ * @param tolerance optional tolerance(s) to determine point-vertex and point-edge coincidence. A single number
237914
+ * is interpreted as distance tolerance. If an array is given, the first number is interpreted as distance tolerance;
237915
+ * the second, as parametric tolerance. Default values are [[Geometry.smallMetricDistance]] for distance tolerance
237916
+ * and 0.0 for parameter tolerance.
237775
237917
  * @param result optional pre-allocated object to fill and return
237776
237918
  * @returns details d of the line-plane intersection `d.point`:
237777
237919
  * * `d.isValid()` returns true if and only if the line intersects the plane.
@@ -237798,11 +237940,18 @@ class PolygonOps {
237798
237940
  // NOOP: intersectionPoint is on the polygon, so result.code already classifies it
237799
237941
  }
237800
237942
  else {
237801
- // intersectionPoint is not on polygon, so result.code refers to the closest point. Update it to refer to intersectionPoint.
237802
- if (_Geometry__WEBPACK_IMPORTED_MODULE_2__.PolygonLocation.OnPolygonVertex === result.code)
237803
- result.code = (dot > 0.0) ? _Geometry__WEBPACK_IMPORTED_MODULE_2__.PolygonLocation.InsidePolygonProjectsToVertex : _Geometry__WEBPACK_IMPORTED_MODULE_2__.PolygonLocation.OutsidePolygonProjectsToVertex;
237804
- else if (_Geometry__WEBPACK_IMPORTED_MODULE_2__.PolygonLocation.OnPolygonEdgeInterior === result.code)
237805
- result.code = (dot > 0.0) ? _Geometry__WEBPACK_IMPORTED_MODULE_2__.PolygonLocation.InsidePolygonProjectsToEdgeInterior : _Geometry__WEBPACK_IMPORTED_MODULE_2__.PolygonLocation.OutsidePolygonProjectsToEdgeInterior;
237943
+ // intersectionPoint is not on the polygon, so result.code refers to the closest point;
237944
+ // update it to refer to intersectionPoint.
237945
+ if (_Geometry__WEBPACK_IMPORTED_MODULE_2__.PolygonLocation.OnPolygonVertex === result.code) {
237946
+ result.code = (dot > 0.0)
237947
+ ? _Geometry__WEBPACK_IMPORTED_MODULE_2__.PolygonLocation.InsidePolygonProjectsToVertex
237948
+ : _Geometry__WEBPACK_IMPORTED_MODULE_2__.PolygonLocation.OutsidePolygonProjectsToVertex;
237949
+ }
237950
+ else if (_Geometry__WEBPACK_IMPORTED_MODULE_2__.PolygonLocation.OnPolygonEdgeInterior === result.code) {
237951
+ result.code = (dot > 0.0)
237952
+ ? _Geometry__WEBPACK_IMPORTED_MODULE_2__.PolygonLocation.InsidePolygonProjectsToEdgeInterior
237953
+ : _Geometry__WEBPACK_IMPORTED_MODULE_2__.PolygonLocation.OutsidePolygonProjectsToEdgeInterior;
237954
+ }
237806
237955
  }
237807
237956
  }
237808
237957
  return result;
@@ -249121,11 +249270,11 @@ class AnalyticRoots {
249121
249270
  * * -1 -- beta, gamma are zero, alpha is not.There is no line defined.There are no solutions.
249122
249271
  * * 0 -- the line is well defined, but passes completely outside the unit circle.
249123
249272
  * * In this case, (c1, s1) is the circle point closest to the line and(c2, s2) is the line point closest to the circle.
249124
- * * 1 -- the line is tangent to the unit circle.
249125
- * * Tangency is determined by tolerances, which calls a "close approach" point a tangency.
249126
- * * (c1, s1) is the closest circle point
249127
- * * (c2, s2) is the line point.
249128
- * * 2 -- two simple intersections.
249273
+ * * 1 -- the line is tangent to the unit circle.
249274
+ * * Tangency is determined by tolerances, which calls a "close approach" point a tangency.
249275
+ * * (c1, s1) is the closest circle point
249276
+ * * (c2, s2) is the line point.
249277
+ * * 2 -- two simple intersections.
249129
249278
  * @param alpha constant coefficient on line
249130
249279
  * @param beta x cosine coefficient on line
249131
249280
  * @param gamma y sine coefficient on line
@@ -249257,7 +249406,7 @@ class TrigPolynomial {
249257
249406
  degree--;
249258
249407
  const roots = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_6__.GrowableFloat64Array();
249259
249408
  if (degree === -1) {
249260
- // do nothing
249409
+ // p(t) is identically zero (degenerate); do nothing.
249261
249410
  }
249262
249411
  else {
249263
249412
  if (degree === 0) {
@@ -251136,8 +251285,8 @@ var AuxChannelDataType;
251136
251285
  * When the host Polyface is transformed the displacements are rotated and scaled accordingly.
251137
251286
  */
251138
251287
  AuxChannelDataType[AuxChannelDataType["Vector"] = 2] = "Vector";
251139
- /** (X, Y, Z) normal vectors that replace the host [[Polyface]]'s own normals.
251140
- * When the Polyface is transformed the normals are rotated accordingly.
251288
+ /** (X, Y, Z) unit normal vectors that replace the host [[Polyface]]'s own normals.
251289
+ * When the Polyface is transformed the normals are rotated and renormalized accordingly.
251141
251290
  */
251142
251291
  AuxChannelDataType[AuxChannelDataType["Normal"] = 3] = "Normal";
251143
251292
  })(AuxChannelDataType || (AuxChannelDataType = {}));
@@ -251326,7 +251475,15 @@ class PolyfaceAuxData {
251326
251475
  inverseRot = inverseRot ?? rot.inverse();
251327
251476
  if (!inverseRot)
251328
251477
  return false;
251329
- transformPoints(data.values, (point) => inverseRot.multiplyTransposeVectorInPlace(point));
251478
+ transformPoints(data.values, (point) => {
251479
+ inverseRot.multiplyTransposeVectorInPlace(point);
251480
+ const dot = point.magnitudeSquared();
251481
+ const tol = 1.0e-15; // cf. GrowableXYZArray.multiplyAndRenormalizeMatrix3dInverseTransposeInPlace
251482
+ if (dot > tol && Math.abs(dot - 1.0) > tol) { // only renormalize if magnitude is not near 0 or 1
251483
+ const mag = 1.0 / Math.sqrt(dot);
251484
+ point.scaleInPlace(mag);
251485
+ }
251486
+ });
251330
251487
  break;
251331
251488
  }
251332
251489
  case AuxChannelDataType.Vector: {
@@ -253175,20 +253332,14 @@ class IndexedPolyface extends Polyface {
253175
253332
  }
253176
253333
  /**
253177
253334
  * Transform the mesh.
253178
- * * Apply the transform to points.
253179
- * * Apply the (inverse transpose of the) matrix part to normals.
253180
- * * If determinant of the transform matrix is negative, also
253181
- * * negate normals
253182
- * * reverse index order around each facet.
253335
+ * * If `transform` is a mirror, also reverse the index order around each facet.
253336
+ * * Note that this method always returns true. If transforming the normals fails (due to singular matrix or zero
253337
+ * normal), the original normal(s) are left unchanged.
253183
253338
  */
253184
253339
  tryTransformInPlace(transform) {
253185
- if (!this.data.tryTransformInPlace(transform))
253186
- return false;
253187
- const determinant = transform.matrix.determinant();
253188
- if (determinant < 0) {
253340
+ this.data.tryTransformInPlace(transform);
253341
+ if (transform.matrix.determinant() < 0)
253189
253342
  this.reverseIndices();
253190
- this.reverseNormals();
253191
- }
253192
253343
  return true;
253193
253344
  }
253194
253345
  /** Reverse indices for a single facet. */
@@ -253197,8 +253348,7 @@ class IndexedPolyface extends Polyface {
253197
253348
  }
253198
253349
  /** Return a deep clone. */
253199
253350
  clone() {
253200
- const result = new IndexedPolyface(this.data.clone(), this._facetStart.slice(), this._facetToFaceData.slice());
253201
- return result;
253351
+ return new IndexedPolyface(this.data.clone(), this._facetStart.slice(), this._facetToFaceData.slice());
253202
253352
  }
253203
253353
  /**
253204
253354
  * Return a deep clone with transformed points and normals.
@@ -254779,17 +254929,28 @@ class PolyfaceBuilder extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
254779
254929
  }
254780
254930
  /** Construct facets for a rotational sweep. */
254781
254931
  addRotationalSweep(surface) {
254782
- const contour = surface.getCurves();
254783
- const section0 = _curve_Query_StrokeCountChain__WEBPACK_IMPORTED_MODULE_16__.StrokeCountSection.createForParityRegionOrChain(contour, this._options);
254932
+ const contour = surface.getSweepContourRef();
254933
+ const section0 = _curve_Query_StrokeCountChain__WEBPACK_IMPORTED_MODULE_16__.StrokeCountSection.createForParityRegionOrChain(contour.getCurves(), this._options);
254784
254934
  const baseStrokes = section0.getStrokes();
254935
+ // ensure sweep is positive for buildRotationalNormalsInLineStrings
254785
254936
  const axis = surface.cloneAxisRay();
254937
+ const sweepAngle = surface.getSweep();
254938
+ if (sweepAngle.radians < 0.0) {
254939
+ axis.direction.scaleInPlace(-1);
254940
+ sweepAngle.setRadians(-sweepAngle.radians);
254941
+ }
254942
+ // swingVector points in the direction of positive sweep
254786
254943
  const perpendicularVector = _curve_Query_CylindricalRange__WEBPACK_IMPORTED_MODULE_17__.CylindricalRangeQuery.computeMaxVectorFromRay(axis, baseStrokes);
254787
254944
  const swingVector = axis.direction.crossProduct(perpendicularVector);
254945
+ // ensure contour computed normal is aligned with swingVector for buildRotationalNormalsInLineStrings
254946
+ const contourNormalAgreesWithSwingDir = contour.localToWorld.matrix.dotColumnZ(swingVector) > 0;
254947
+ if (!contourNormalAgreesWithSwingDir)
254948
+ baseStrokes.reverseInPlace();
254788
254949
  if (this._options.needNormals)
254789
254950
  _curve_Query_CylindricalRange__WEBPACK_IMPORTED_MODULE_17__.CylindricalRangeQuery.buildRotationalNormalsInLineStrings(baseStrokes, axis, swingVector);
254790
254951
  const maxDistance = perpendicularVector.magnitude();
254791
- const maxPath = Math.abs(maxDistance * surface.getSweep().radians);
254792
- let numStep = _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_4__.StrokeOptions.applyAngleTol(this._options, 1, surface.getSweep().radians, undefined);
254952
+ const maxPath = Math.abs(maxDistance * sweepAngle.radians);
254953
+ let numStep = _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_4__.StrokeOptions.applyAngleTol(this._options, 1, sweepAngle.radians, undefined);
254793
254954
  numStep = _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_4__.StrokeOptions.applyMaxEdgeLength(this._options, numStep, maxPath);
254794
254955
  for (let i = 1; i <= numStep; i++) {
254795
254956
  const transformA = surface.getFractionalRotationTransform((i - 1) / numStep);
@@ -254797,11 +254958,10 @@ class PolyfaceBuilder extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
254797
254958
  this.addBetweenRotatedStrokeSets(baseStrokes, transformA, i - 1, transformB, i);
254798
254959
  }
254799
254960
  if (surface.capped) {
254800
- const capContour = surface.getSweepContourRef();
254801
- capContour.purgeFacets();
254802
- capContour.emitFacets(this, true, undefined);
254803
- // final loop pass left transformA at end
254804
- capContour.emitFacets(this, false, surface.getFractionalRotationTransform(1.0));
254961
+ contour.purgeFacets();
254962
+ const reverseNearCap = contourNormalAgreesWithSwingDir;
254963
+ contour.emitFacets(this, reverseNearCap, undefined);
254964
+ contour.emitFacets(this, !reverseNearCap, surface.getFractionalRotationTransform(1.0));
254805
254965
  }
254806
254966
  }
254807
254967
  /** Construct facets for any planar region. */
@@ -254865,9 +255025,9 @@ class PolyfaceBuilder extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
254865
255025
  const normalIndices = ls.ensureEmptyNormalIndices();
254866
255026
  const normalIndex0 = this.findOrAddNormalInLineString(ls, 0, transform);
254867
255027
  normalIndices.push(normalIndex0);
254868
- let normalIndexA = normalIndex0;
254869
- let normalIndexB;
254870
255028
  if (n > 1) {
255029
+ let normalIndexA = normalIndex0;
255030
+ let normalIndexB;
254871
255031
  for (let i = 1; i + 1 < n; i++) {
254872
255032
  normalIndexB = this.findOrAddNormalInLineString(ls, i, transform, normalIndexA);
254873
255033
  normalIndices.push(normalIndexB);
@@ -254882,9 +255042,9 @@ class PolyfaceBuilder extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
254882
255042
  const uvIndices = ls.ensureEmptyUVIndices();
254883
255043
  const uvIndex0 = this.findOrAddParamInLineString(ls, 0, vParam);
254884
255044
  uvIndices.push(uvIndex0);
254885
- let uvIndexA = uvIndex0;
254886
- let uvIndexB;
254887
255045
  if (n > 1) {
255046
+ let uvIndexA = uvIndex0;
255047
+ let uvIndexB;
254888
255048
  for (let i = 1; i + 1 < n; i++) {
254889
255049
  uvIndexB = this.findOrAddParamInLineString(ls, i, vParam, uvIndexA);
254890
255050
  uvIndices.push(uvIndexB);
@@ -256813,15 +256973,32 @@ class PolyfaceData {
256813
256973
  return result;
256814
256974
  }
256815
256975
  /**
256816
- * Apply `transform` to point and normal arrays and to auxData.
256817
- * * IMPORTANT This base class is just a data carrier. It does not know if the index order and normal directions
256818
- * have special meaning, i.e., caller must separately reverse index order and normal direction if needed.
256976
+ * Apply a transform to the mesh data.
256977
+ * * Transform the data as follows:
256978
+ * * apply `transform` to points.
256979
+ * * apply inverse transpose of `transform` to normals and renormalize. This preserves normals perpendicular
256980
+ * to transformed facets, and keeps them pointing outward, e.g, if the mesh is closed. If the transform is not
256981
+ * invertible or a normal has zero length, the normal(s) are left unchanged, and this error is silently ignored.
256982
+ * * apply `transform` to auxData.
256983
+ * * scale faceData distances by the cube root of the absolute value of the determinant of `transform.matrix`.
256984
+ * * Note that if the transform is a mirror, this method does NOT reverse index order. This is the caller's
256985
+ * responsibility. This base class is just a data carrier: PolyfaceData does not know if the index order has
256986
+ * special meaning.
256987
+ * * Note that this method always returns true. If transforming normals fails (due to singular matrix or zero
256988
+ * normal), the original normal(s) are left unchanged.
256819
256989
  */
256820
256990
  tryTransformInPlace(transform) {
256821
256991
  this.point.multiplyTransformInPlace(transform);
256822
256992
  if (this.normal && !transform.matrix.isIdentity)
256823
256993
  this.normal.multiplyAndRenormalizeMatrix3dInverseTransposeInPlace(transform.matrix);
256824
- return undefined === this.auxData || this.auxData.tryTransformInPlace(transform);
256994
+ if (this.face.length > 0) {
256995
+ const distScale = Math.cbrt(Math.abs(transform.matrix.determinant()));
256996
+ for (const faceData of this.face)
256997
+ faceData.scaleDistances(distScale);
256998
+ }
256999
+ if (this.auxData)
257000
+ this.auxData.tryTransformInPlace(transform);
257001
+ return true;
256825
257002
  }
256826
257003
  /**
256827
257004
  * Compress the instance by equating duplicate data.
@@ -258757,8 +258934,8 @@ class PolyfaceQuery {
258757
258934
  /**
258758
258935
  * Search facets for the first one that intersects the infinite line.
258759
258936
  * * To process _all_ intersections, callers can supply an `options.acceptIntersection` callback that always
258760
- * returns `false`.
258761
- * In this case, `intersectRay3d` will return `undefined`, but the callback will be invoked for each intersection.
258937
+ * returns `false`. In this case, `intersectRay3d` will return `undefined`, but the callback will be invoked for
258938
+ * each intersection.
258762
258939
  * * Example callback logic:
258763
258940
  * * Accept the first found facet that intersects the half-line specified by the ray: `return detail.a >= 0.0;`
258764
258941
  * * Collect all intersections: `myIntersections.push(detail.clone()); return false;` Then after `intersectRay3d`
@@ -258776,6 +258953,7 @@ class PolyfaceQuery {
258776
258953
  if (visitor instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface)
258777
258954
  return PolyfaceQuery.intersectRay3d(visitor.createVisitor(0), ray, options);
258778
258955
  let detail;
258956
+ const tol = options ? [options.distanceTolerance, options.parameterTolerance] : undefined;
258779
258957
  visitor.setNumWrap(0);
258780
258958
  while (visitor.moveToNextFacet()) {
258781
258959
  const numEdges = visitor.pointCount; // #vertices = #edges since numWrap is zero
@@ -258787,7 +258965,7 @@ class PolyfaceQuery {
258787
258965
  detail = this._workFacetDetail3 = _FacetLocationDetail__WEBPACK_IMPORTED_MODULE_37__.TriangularFacetLocationDetail.create(visitor.currentReadIndex(), detail3, this._workFacetDetail3);
258788
258966
  }
258789
258967
  else {
258790
- const detailN = this._workPolyDetail = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_8__.PolygonOps.intersectRay3d(vertices, ray, options?.distanceTolerance, this._workPolyDetail);
258968
+ const detailN = this._workPolyDetail = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_8__.PolygonOps.intersectRay3d(vertices, ray, tol, this._workPolyDetail);
258791
258969
  if (_geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_8__.PolygonOps.isConvex(vertices))
258792
258970
  detail = this._workFacetDetailC = _FacetLocationDetail__WEBPACK_IMPORTED_MODULE_37__.ConvexFacetLocationDetail.create(visitor.currentReadIndex(), numEdges, detailN, this._workFacetDetailC);
258793
258971
  else
@@ -274450,8 +274628,10 @@ class Box extends _SolidPrimitive__WEBPACK_IMPORTED_MODULE_0__.SolidPrimitive {
274450
274628
  getConstructiveFrame() {
274451
274629
  return this._localToWorld.cloneRigid();
274452
274630
  }
274453
- /** Apply the transform to the box's `localToWorld` frame.
274631
+ /**
274632
+ * Apply the transform to the box's `localToWorld` frame.
274454
274633
  * * Note that this may make the frame nonrigid.
274634
+ * * This fails if the transformation is singular.
274455
274635
  */
274456
274636
  tryTransformInPlace(transform) {
274457
274637
  if (transform.matrix.isSingular())
@@ -274459,11 +274639,14 @@ class Box extends _SolidPrimitive__WEBPACK_IMPORTED_MODULE_0__.SolidPrimitive {
274459
274639
  transform.multiplyTransformTransform(this._localToWorld, this._localToWorld);
274460
274640
  return true;
274461
274641
  }
274462
- /** Clone the box and immediately apply `transform` to the local frame of the clone. */
274642
+ /**
274643
+ * Clone the box and immediately apply `transform` to the local frame of the clone.
274644
+ * * Note that this may make the frame nonrigid.
274645
+ * * This fails if the transformation is singular.
274646
+ */
274463
274647
  cloneTransformed(transform) {
274464
274648
  const result = this.clone();
274465
- transform.multiplyTransformTransform(result._localToWorld, result._localToWorld);
274466
- return result;
274649
+ return result.tryTransformInPlace(transform) ? result : undefined;
274467
274650
  }
274468
274651
  /**
274469
274652
  * Create a new box from vector and size daa.
@@ -274498,7 +274681,7 @@ class Box extends _SolidPrimitive__WEBPACK_IMPORTED_MODULE_0__.SolidPrimitive {
274498
274681
  }
274499
274682
  /**
274500
274683
  * Create an axis-aligned `Box` primitive for a range.
274501
- * @param range range corners Origin of base rectangle
274684
+ * @param range range low point is origin of base rectangle, range extents are box extents
274502
274685
  * @param capped true to define top and bottom closure caps
274503
274686
  */
274504
274687
  static createRange(range, capped) {
@@ -274706,7 +274889,7 @@ class Cone extends _SolidPrimitive__WEBPACK_IMPORTED_MODULE_0__.SolidPrimitive {
274706
274889
  getConstructiveFrame() {
274707
274890
  return this._localToWorld.cloneRigid();
274708
274891
  }
274709
- /** Apply the transform to this cone's locla to world coordinates.
274892
+ /** Apply the transform to this cone's local to world coordinates.
274710
274893
  * * Note that the radii are not changed. Scaling is absorbed into the frame.
274711
274894
  * * This fails if the transformation is singular.
274712
274895
  */
@@ -274718,11 +274901,11 @@ class Cone extends _SolidPrimitive__WEBPACK_IMPORTED_MODULE_0__.SolidPrimitive {
274718
274901
  }
274719
274902
  /**
274720
274903
  * Create a clone and immediately transform the clone.
274904
+ * * This fails if the transformation is singular.
274721
274905
  */
274722
274906
  cloneTransformed(transform) {
274723
274907
  const result = this.clone();
274724
- transform.multiplyTransformTransform(result._localToWorld, result._localToWorld);
274725
- return result;
274908
+ return result.tryTransformInPlace(transform) ? result : undefined;
274726
274909
  }
274727
274910
  /** create a cylinder or cone from two endpoints and their radii. The circular cross sections are perpendicular to the axis line
274728
274911
  * from start to end point.
@@ -275021,7 +275204,10 @@ class LinearSweep extends _SolidPrimitive__WEBPACK_IMPORTED_MODULE_0__.SolidPrim
275021
275204
  clone() {
275022
275205
  return new LinearSweep(this._contour.clone(), this._direction.clone(), this.capped);
275023
275206
  }
275024
- /** apply a transform to the curves and sweep vector */
275207
+ /**
275208
+ * Apply a transform to the curves and sweep vector
275209
+ * * This fails if the transformation is singular.
275210
+ */
275025
275211
  tryTransformInPlace(transform) {
275026
275212
  if (transform.matrix.isSingular())
275027
275213
  return false;
@@ -275039,11 +275225,13 @@ class LinearSweep extends _SolidPrimitive__WEBPACK_IMPORTED_MODULE_0__.SolidPrim
275039
275225
  getConstructiveFrame() {
275040
275226
  return this._contour.localToWorld.cloneRigid();
275041
275227
  }
275042
- /** Return a transformed clone */
275228
+ /**
275229
+ * Return a transformed clone.
275230
+ * * This fails if the transformation is singular.
275231
+ */
275043
275232
  cloneTransformed(transform) {
275044
275233
  const result = this.clone();
275045
- result.tryTransformInPlace(transform);
275046
- return result;
275234
+ return result.tryTransformInPlace(transform) ? result : undefined;
275047
275235
  }
275048
275236
  /** Test for near-equality of coordinates in `other` */
275049
275237
  isAlmostEqual(other) {
@@ -275142,7 +275330,12 @@ class RotationalSweep extends _SolidPrimitive__WEBPACK_IMPORTED_MODULE_0__.Solid
275142
275330
  this.capped = capped;
275143
275331
  this._sweepAngle = sweepAngle;
275144
275332
  }
275145
- /** Create a rotational sweep. */
275333
+ /** Create a rotational sweep.
275334
+ * @param contour profile to sweep, coplanar with axis. CAPTURED
275335
+ * @param axis rotation axis
275336
+ * @param sweepAngle signed angular sweep
275337
+ * @param capped whether to cap the surface to make a solid
275338
+ */
275146
275339
  static create(contour, axis, sweepAngle, capped) {
275147
275340
  if (!axis.direction.normalizeInPlace())
275148
275341
  return undefined;
@@ -275187,20 +275380,28 @@ class RotationalSweep extends _SolidPrimitive__WEBPACK_IMPORTED_MODULE_0__.Solid
275187
275380
  clone() {
275188
275381
  return new RotationalSweep(this._contour.clone(), this._normalizedAxis.clone(), this._sweepAngle.clone(), this.capped);
275189
275382
  }
275190
- /** Transform the contour and axis */
275383
+ /**
275384
+ * Transform the contour and axis.
275385
+ * * This fails if the transformation is singular.
275386
+ */
275191
275387
  tryTransformInPlace(transform) {
275192
- if (!transform.matrix.isSingular()
275193
- && this._contour.tryTransformInPlace(transform)) {
275388
+ if (transform.matrix.isSingular())
275389
+ return false;
275390
+ if (this._contour.tryTransformInPlace(transform)) {
275194
275391
  this._normalizedAxis.transformInPlace(transform);
275392
+ if (transform.matrix.determinant() < 0.0)
275393
+ this._sweepAngle.setRadians(-this._sweepAngle.radians);
275195
275394
  return this._normalizedAxis.direction.normalizeInPlace();
275196
275395
  }
275197
275396
  return false;
275198
275397
  }
275199
- /** return a cloned transform. */
275398
+ /**
275399
+ * Return a transformed clone.
275400
+ * * This fails if the transformation is singular.
275401
+ */
275200
275402
  cloneTransformed(transform) {
275201
275403
  const result = this.clone();
275202
- result.tryTransformInPlace(transform);
275203
- return result;
275404
+ return result.tryTransformInPlace(transform) ? result : undefined;
275204
275405
  }
275205
275406
  /** Dispatch to strongly typed handler `handler.handleRotationalSweep(this)` */
275206
275407
  dispatchToGeometryHandler(handler) {
@@ -275336,20 +275537,26 @@ class RuledSweep extends _SolidPrimitive__WEBPACK_IMPORTED_MODULE_0__.SolidPrimi
275336
275537
  clone() {
275337
275538
  return new RuledSweep(this.cloneSweepContours(), this.capped);
275338
275539
  }
275339
- /** Transform all contours in place. */
275540
+ /**
275541
+ * Transform all contours in place.
275542
+ * * This fails if the transformation is singular.
275543
+ */
275340
275544
  tryTransformInPlace(transform) {
275341
275545
  if (transform.matrix.isSingular())
275342
275546
  return false;
275343
275547
  for (const contour of this._contours) {
275344
- contour.tryTransformInPlace(transform);
275548
+ if (!contour.tryTransformInPlace(transform))
275549
+ return false;
275345
275550
  }
275346
275551
  return true;
275347
275552
  }
275348
- /** Return a cloned transform. */
275553
+ /**
275554
+ * Return a transformed clone.
275555
+ * * This fails if the transformation is singular.
275556
+ */
275349
275557
  cloneTransformed(transform) {
275350
275558
  const result = this.clone();
275351
- result.tryTransformInPlace(transform);
275352
- return result;
275559
+ return result.tryTransformInPlace(transform) ? result : undefined;
275353
275560
  }
275354
275561
  /** Return a coordinate frame (right handed unit vectors)
275355
275562
  * * origin on base contour
@@ -275530,12 +275737,12 @@ __webpack_require__.r(__webpack_exports__);
275530
275737
  /* harmony import */ var _curve_Loop__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../curve/Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
275531
275738
  /* harmony import */ var _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../curve/StrokeOptions */ "../../core/geometry/lib/esm/curve/StrokeOptions.js");
275532
275739
  /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
275533
- /* harmony import */ var _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../geometry3d/AngleSweep */ "../../core/geometry/lib/esm/geometry3d/AngleSweep.js");
275534
- /* harmony import */ var _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../geometry3d/Matrix3d */ "../../core/geometry/lib/esm/geometry3d/Matrix3d.js");
275740
+ /* harmony import */ var _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../geometry3d/AngleSweep */ "../../core/geometry/lib/esm/geometry3d/AngleSweep.js");
275741
+ /* harmony import */ var _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../geometry3d/Matrix3d */ "../../core/geometry/lib/esm/geometry3d/Matrix3d.js");
275535
275742
  /* harmony import */ var _geometry3d_Plane3dByOriginAndVectors__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../geometry3d/Plane3dByOriginAndVectors */ "../../core/geometry/lib/esm/geometry3d/Plane3dByOriginAndVectors.js");
275536
275743
  /* harmony import */ var _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../geometry3d/Point2dVector2d */ "../../core/geometry/lib/esm/geometry3d/Point2dVector2d.js");
275537
275744
  /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
275538
- /* harmony import */ var _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../geometry3d/Transform */ "../../core/geometry/lib/esm/geometry3d/Transform.js");
275745
+ /* harmony import */ var _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../geometry3d/Transform */ "../../core/geometry/lib/esm/geometry3d/Transform.js");
275539
275746
  /* harmony import */ var _SolidPrimitive__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./SolidPrimitive */ "../../core/geometry/lib/esm/solid/SolidPrimitive.js");
275540
275747
  /*---------------------------------------------------------------------------------------------
275541
275748
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
@@ -275579,32 +275786,32 @@ class Sphere extends _SolidPrimitive__WEBPACK_IMPORTED_MODULE_0__.SolidPrimitive
275579
275786
  /** String name for schema properties */
275580
275787
  this.solidPrimitiveType = "sphere";
275581
275788
  this._localToWorld = localToWorld;
275582
- this._latitudeSweep = latitudeSweep ? latitudeSweep : _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_1__.AngleSweep.createFullLatitude();
275789
+ this._latitudeSweep = latitudeSweep;
275583
275790
  this._latitudeSweep.capLatitudeInPlace();
275584
275791
  }
275585
275792
  /** return a deep clone */
275586
275793
  clone() {
275587
275794
  return new Sphere(this._localToWorld.clone(), this._latitudeSweep.clone(), this.capped);
275588
275795
  }
275589
- /** Transform the sphere in place.
275796
+ /**
275797
+ * Transform the sphere in place.
275590
275798
  * * Fails if the transform is singular.
275591
275799
  */
275592
275800
  tryTransformInPlace(transform) {
275593
275801
  if (transform.matrix.isSingular())
275594
275802
  return false;
275595
275803
  transform.multiplyTransformTransform(this._localToWorld, this._localToWorld);
275804
+ if (transform.matrix.determinant() < 0.0)
275805
+ this._latitudeSweep.reverseInPlace();
275596
275806
  return true;
275597
275807
  }
275598
- /** Return a transformed clone. */
275808
+ /**
275809
+ * Return a transformed clone.
275810
+ * * Fails if the transform is singular.
275811
+ */
275599
275812
  cloneTransformed(transform) {
275600
- const sphere1 = this.clone();
275601
- transform.multiplyTransformTransform(sphere1._localToWorld, sphere1._localToWorld);
275602
- if (transform.matrix.determinant() < 0.0) {
275603
- if (sphere1._latitudeSweep !== undefined) {
275604
- sphere1._latitudeSweep.reverseInPlace();
275605
- }
275606
- }
275607
- return sphere1;
275813
+ const result = this.clone();
275814
+ return result.tryTransformInPlace(transform) ? result : undefined;
275608
275815
  }
275609
275816
  /** Return a coordinate frame (right handed, unit axes)
275610
275817
  * * origin at sphere center
@@ -275618,8 +275825,8 @@ class Sphere extends _SolidPrimitive__WEBPACK_IMPORTED_MODULE_0__.SolidPrimitive
275618
275825
  get latitudeSweepFraction() { return this._latitudeSweep.sweepRadians / Math.PI; }
275619
275826
  /** Create from center and radius, with optional restricted latitudes. */
275620
275827
  static createCenterRadius(center, radius, latitudeSweep) {
275621
- const localToWorld = _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_2__.Transform.createOriginAndMatrix(center, _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_3__.Matrix3d.createUniformScale(radius));
275622
- return new Sphere(localToWorld, latitudeSweep ? latitudeSweep.clone() : _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_1__.AngleSweep.createFullLatitude(), false);
275828
+ const localToWorld = _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_1__.Transform.createOriginAndMatrix(center, _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_2__.Matrix3d.createUniformScale(radius));
275829
+ return new Sphere(localToWorld, latitudeSweep ? latitudeSweep.clone() : _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_3__.AngleSweep.createFullLatitude(), false);
275623
275830
  }
275624
275831
  /** Create an ellipsoid which is a unit sphere mapped to position by an (arbitrary, possibly skewed and scaled) transform. */
275625
275832
  static createEllipsoid(localToWorld, latitudeSweep, capped) {
@@ -275629,18 +275836,18 @@ class Sphere extends _SolidPrimitive__WEBPACK_IMPORTED_MODULE_0__.SolidPrimitive
275629
275836
  static createDgnSphere(center, vectorX, vectorZ, radiusXY, radiusZ, latitudeSweep, capped) {
275630
275837
  const vectorY = vectorX.rotate90Around(vectorZ);
275631
275838
  if (vectorY && !vectorX.isParallelTo(vectorZ)) {
275632
- const matrix = _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_3__.Matrix3d.createColumns(vectorX, vectorY, vectorZ);
275839
+ const matrix = _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_2__.Matrix3d.createColumns(vectorX, vectorY, vectorZ);
275633
275840
  matrix.scaleColumns(radiusXY, radiusXY, radiusZ, matrix);
275634
- const frame = _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_2__.Transform.createOriginAndMatrix(center, matrix);
275841
+ const frame = _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_1__.Transform.createOriginAndMatrix(center, matrix);
275635
275842
  return new Sphere(frame, latitudeSweep.clone(), capped);
275636
275843
  }
275637
275844
  return undefined;
275638
275845
  }
275639
275846
  /** Create a sphere from the typical parameters of the Dgn file */
275640
275847
  static createFromAxesAndScales(center, axes, radiusX, radiusY, radiusZ, latitudeSweep, capped) {
275641
- const localToWorld = _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_2__.Transform.createOriginAndMatrix(center, axes);
275848
+ const localToWorld = _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_1__.Transform.createOriginAndMatrix(center, axes);
275642
275849
  localToWorld.matrix.scaleColumnsInPlace(radiusX, radiusY, radiusZ);
275643
- return new Sphere(localToWorld, latitudeSweep ? latitudeSweep.clone() : _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_1__.AngleSweep.createFullLatitude(), capped);
275850
+ return new Sphere(localToWorld, latitudeSweep ? latitudeSweep.clone() : _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_3__.AngleSweep.createFullLatitude(), capped);
275644
275851
  }
275645
275852
  /** return (copy of) sphere center */
275646
275853
  cloneCenter() { return this._localToWorld.getOrigin(); }
@@ -275686,10 +275893,16 @@ class Sphere extends _SolidPrimitive__WEBPACK_IMPORTED_MODULE_0__.SolidPrimitive
275686
275893
  return false;
275687
275894
  }
275688
275895
  /**
275689
- * return strokes for a cross-section (elliptic arc) at specified fraction v along the axis.
275690
- * * if strokeOptions is supplied, it is applied to the equator radii.
275691
- * @param v fractional position along the cone axis
275692
- * @param strokes stroke count or options.
275896
+ * Return strokes for the elliptical arc cross-section at latitude sweep fraction v.
275897
+ * * Optional inputs control the number of strokes along the cross-section:
275898
+ * * If `fixedStrokeCount` is supplied, it is taken as the cross-section stroke count.
275899
+ * * If `fixedStrokeCount` is undefined, stroke count is computed by applying `options` to the cross-section.
275900
+ * * If neither input is supplied, the stroke count default is 16.
275901
+ * * In any case, stroke count is clamped to the interval [4,64].
275902
+ * @param v fractional position along the sphere axis
275903
+ * @param fixedStrokeCount optional stroke count in u-direction
275904
+ * @param options optional stroke options in u-direction
275905
+ * @return strokes as line string
275693
275906
  */
275694
275907
  strokeConstantVSection(v, fixedStrokeCount, options) {
275695
275908
  let strokeCount = 16;
@@ -275705,7 +275918,7 @@ class Sphere extends _SolidPrimitive__WEBPACK_IMPORTED_MODULE_0__.SolidPrimitive
275705
275918
  const c1 = Math.cos(phi);
275706
275919
  const s1 = Math.sin(phi);
275707
275920
  let c0, s0;
275708
- const result = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_6__.LineString3d.createForStrokes(fixedStrokeCount, options);
275921
+ const result = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_6__.LineString3d.createForStrokes(strokeCount, options);
275709
275922
  const deltaRadians = Math.PI * 2.0 / strokeCount;
275710
275923
  const fractions = result.fractions; // possibly undefined !!!
275711
275924
  const derivatives = result.packedDerivatives; // possibly undefined !!!
@@ -275932,7 +276145,7 @@ class SweepContour {
275932
276145
  return undefined;
275933
276146
  }
275934
276147
  /** Create for rotational sweep.
275935
- * @param contour curve to sweep, CAPTURED. For best results, contour should be planar.
276148
+ * @param contour curve to sweep, CAPTURED. For best results, contour should be coplanar with axis.
275936
276149
  * @param axis rotation axis
275937
276150
  */
275938
276151
  static createForRotation(contour, axis) {
@@ -276190,19 +276403,23 @@ class TorusPipe extends _SolidPrimitive__WEBPACK_IMPORTED_MODULE_0__.SolidPrimit
276190
276403
  result._isReversed = this._isReversed;
276191
276404
  return result;
276192
276405
  }
276193
- /** Apply `transform` to the local coordinate system. */
276406
+ /**
276407
+ * Apply `transform` to the local coordinate system.
276408
+ * * Fails if the transformation is singular.
276409
+ */
276194
276410
  tryTransformInPlace(transform) {
276195
276411
  if (transform.matrix.isSingular())
276196
276412
  return false;
276197
276413
  transform.multiplyTransformTransform(this._localToWorld, this._localToWorld);
276198
276414
  return true;
276199
276415
  }
276200
- /** Clone this TorusPipe and transform the clone */
276416
+ /**
276417
+ * Clone this TorusPipe and transform the clone.
276418
+ * * Fails if the transformation is singular.
276419
+ */
276201
276420
  cloneTransformed(transform) {
276202
276421
  const result = this.clone();
276203
- if (!result.tryTransformInPlace(transform))
276204
- return undefined;
276205
- return result;
276422
+ return result.tryTransformInPlace(transform) ? result : undefined;
276206
276423
  }
276207
276424
  /** Create a new `TorusPipe`
276208
276425
  * @param frame local to world transformation. For best results, the matrix part should be a pure rotation.
@@ -304022,7 +304239,7 @@ class TestContext {
304022
304239
  this.initializeRpcInterfaces({ title: this.settings.Backend.name, version: this.settings.Backend.version });
304023
304240
  const iModelClient = new imodels_client_management_1.IModelsClient({ api: { baseUrl: `https://${process.env.IMJS_URL_PREFIX ?? ""}api.bentley.com/imodels` } });
304024
304241
  await core_frontend_1.NoRenderApp.startup({
304025
- applicationVersion: "5.0.0-dev.4",
304242
+ applicationVersion: "5.0.0-dev.5",
304026
304243
  applicationId: this.settings.gprid,
304027
304244
  authorizationClient: new frontend_1.TestFrontendAuthorizationClient(this.adminUserAccessToken),
304028
304245
  hubAccess: new imodels_access_frontend_1.FrontendIModelsAccess(iModelClient),
@@ -312494,13 +312711,13 @@ class FavoritePropertiesManager {
312494
312711
  if (missingClasses.size === 0) {
312495
312712
  return baseClasses;
312496
312713
  }
312497
- const query = `
312498
- SELECT (derivedSchema.Name || ':' || derivedClass.Name) AS "ClassFullName", (baseSchema.Name || ':' || baseClass.Name) AS "BaseClassFullName"
312499
- FROM ECDbMeta.ClassHasAllBaseClasses baseClassRels
312500
- INNER JOIN ECDbMeta.ECClassDef derivedClass ON derivedClass.ECInstanceId = baseClassRels.SourceECInstanceId
312501
- INNER JOIN ECDbMeta.ECSchemaDef derivedSchema ON derivedSchema.ECInstanceId = derivedClass.Schema.Id
312502
- INNER JOIN ECDbMeta.ECClassDef baseClass ON baseClass.ECInstanceId = baseClassRels.TargetECInstanceId
312503
- INNER JOIN ECDbMeta.ECSchemaDef baseSchema ON baseSchema.ECInstanceId = baseClass.Schema.Id
312714
+ const query = `
312715
+ SELECT (derivedSchema.Name || ':' || derivedClass.Name) AS "ClassFullName", (baseSchema.Name || ':' || baseClass.Name) AS "BaseClassFullName"
312716
+ FROM ECDbMeta.ClassHasAllBaseClasses baseClassRels
312717
+ INNER JOIN ECDbMeta.ECClassDef derivedClass ON derivedClass.ECInstanceId = baseClassRels.SourceECInstanceId
312718
+ INNER JOIN ECDbMeta.ECSchemaDef derivedSchema ON derivedSchema.ECInstanceId = derivedClass.Schema.Id
312719
+ INNER JOIN ECDbMeta.ECClassDef baseClass ON baseClass.ECInstanceId = baseClassRels.TargetECInstanceId
312720
+ INNER JOIN ECDbMeta.ECSchemaDef baseSchema ON baseSchema.ECInstanceId = baseClass.Schema.Id
312504
312721
  WHERE (derivedSchema.Name || ':' || derivedClass.Name) IN (${[...missingClasses].map((className) => `'${className}'`).join(",")})`;
312505
312722
  const reader = imodel.createQueryReader(query, undefined, { rowFormat: _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.QueryRowFormat.UseJsPropertyNames });
312506
312723
  while (await reader.step()) {
@@ -331591,7 +331808,7 @@ function __disposeResources(env) {
331591
331808
  /***/ ((module) => {
331592
331809
 
331593
331810
  "use strict";
331594
- module.exports = JSON.parse('{"name":"@itwin/core-frontend","version":"5.0.0-dev.4","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","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 ES2020 --outDir lib/esm","clean":"rimraf 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","docs":"betools docs --includes=../../generated-docs/extract --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts","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","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 --coverage","test:debug":"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:^5.0.0-dev.4","@itwin/core-bentley":"workspace:^5.0.0-dev.4","@itwin/core-common":"workspace:^5.0.0-dev.4","@itwin/core-geometry":"workspace:^5.0.0-dev.4","@itwin/core-orbitgt":"workspace:^5.0.0-dev.4","@itwin/core-quantity":"workspace:^5.0.0-dev.4"},"//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":{"@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/eslint-plugin":"5.0.0-dev.1","@types/chai-as-promised":"^7","@vitest/browser":"^2.1.0","@vitest/coverage-v8":"^2.1.0","babel-loader":"~8.2.5","babel-plugin-istanbul":"~6.1.1","cpx2":"^3.0.0","eslint":"^9.13.0","glob":"^10.3.12","playwright":"~1.47.1","rimraf":"^3.0.2","source-map-loader":"^4.0.0","typescript":"~5.6.2","typemoq":"^2.1.0","vitest":"^2.1.0","vite-multiple-assets":"^1.3.1","vite-plugin-static-copy":"1.0.6","webpack":"^5.76.0"},"//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/cloud-agnostic-core":"^2.2.4","@itwin/object-storage-core":"^2.2.5","@itwin/core-i18n":"workspace:*","@itwin/core-telemetry":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^3.1.6","@loaders.gl/draco":"^3.1.6","fuse.js":"^3.3.0","meshoptimizer":"~0.20.0","wms-capabilities":"0.4.0"}}');
331811
+ module.exports = JSON.parse('{"name":"@itwin/core-frontend","version":"5.0.0-dev.5","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","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 ES2020 --outDir lib/esm","clean":"rimraf 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","docs":"betools docs --includes=../../generated-docs/extract --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts","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","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 --coverage","test:debug":"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:^5.0.0-dev.5","@itwin/core-bentley":"workspace:^5.0.0-dev.5","@itwin/core-common":"workspace:^5.0.0-dev.5","@itwin/core-geometry":"workspace:^5.0.0-dev.5","@itwin/core-orbitgt":"workspace:^5.0.0-dev.5","@itwin/core-quantity":"workspace:^5.0.0-dev.5"},"//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":{"@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/eslint-plugin":"5.0.0-dev.1","@types/chai-as-promised":"^7","@vitest/browser":"^2.1.0","@vitest/coverage-v8":"^2.1.0","babel-loader":"~8.2.5","babel-plugin-istanbul":"~6.1.1","cpx2":"^3.0.0","eslint":"^9.13.0","glob":"^10.3.12","playwright":"~1.47.1","rimraf":"^3.0.2","source-map-loader":"^4.0.0","typescript":"~5.6.2","typemoq":"^2.1.0","vitest":"^2.1.0","vite-multiple-assets":"^1.3.1","vite-plugin-static-copy":"1.0.6","webpack":"^5.76.0"},"//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/cloud-agnostic-core":"^2.2.4","@itwin/object-storage-core":"^2.2.5","@itwin/core-i18n":"workspace:*","@itwin/core-telemetry":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^3.1.6","@loaders.gl/draco":"^3.1.6","fuse.js":"^3.3.0","meshoptimizer":"~0.20.0","wms-capabilities":"0.4.0"}}');
331595
331812
 
331596
331813
  /***/ }),
331597
331814