@itwin/rpcinterface-full-stack-tests 4.0.0-dev.6 → 4.0.0-dev.8

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.
@@ -183333,9 +183333,9 @@ class Geometry {
183333
183333
  return 2 - ((-axis - 1) % 3);
183334
183334
  }
183335
183335
  /** Return the AxisOrder for which axisIndex is the first named axis.
183336
- * * `axisIndex===0`returns AxisOrder.XYZ
183337
- * * `axisIndex===1`returns AxisOrder.YZX
183338
- * * `axisIndex===2`returns AxisOrder.ZXY
183336
+ * * `axisIndex === 0` returns `AxisOrder.XYZ`
183337
+ * * `axisIndex === 1` returns `AxisOrder.YZX`
183338
+ * * `axisIndex === 2` returns `AxisOrder.ZXY`
183339
183339
  */
183340
183340
  static axisIndexToRightHandedAxisOrder(axisIndex) {
183341
183341
  if (axisIndex === 0)
@@ -183347,7 +183347,9 @@ class Geometry {
183347
183347
  return Geometry.axisIndexToRightHandedAxisOrder(Geometry.cyclic3dAxis(axisIndex));
183348
183348
  }
183349
183349
  /** Return the largest absolute distance from a to either of b0 or b1 */
183350
- static maxAbsDiff(a, b0, b1) { return Math.max(Math.abs(a - b0), Math.abs(a - b1)); }
183350
+ static maxAbsDiff(a, b0, b1) {
183351
+ return Math.max(Math.abs(a - b0), Math.abs(a - b1));
183352
+ }
183351
183353
  /** Return the largest absolute absolute value among x,y,z */
183352
183354
  static maxAbsXYZ(x, y, z) {
183353
183355
  return Geometry.maxXYZ(Math.abs(x), Math.abs(y), Math.abs(z));
@@ -183392,19 +183394,33 @@ class Geometry {
183392
183394
  return q;
183393
183395
  }
183394
183396
  /** Return the hypotenuse `sqrt(x*x + y*y)`. This is much faster than `Math.hypot(x,y)`. */
183395
- static hypotenuseXY(x, y) { return Math.sqrt(x * x + y * y); }
183397
+ static hypotenuseXY(x, y) {
183398
+ return Math.sqrt(x * x + y * y);
183399
+ }
183396
183400
  /** Return the squared `hypotenuse (x*x + y*y)`. */
183397
- static hypotenuseSquaredXY(x, y) { return x * x + y * y; }
183401
+ static hypotenuseSquaredXY(x, y) {
183402
+ return x * x + y * y;
183403
+ }
183398
183404
  /** Return the square of x */
183399
- static square(x) { return x * x; }
183405
+ static square(x) {
183406
+ return x * x;
183407
+ }
183400
183408
  /** Return the hypotenuse `sqrt(x*x + y*y + z*z)`. This is much faster than `Math.hypot(x,y,z)`. */
183401
- static hypotenuseXYZ(x, y, z) { return Math.sqrt(x * x + y * y + z * z); }
183409
+ static hypotenuseXYZ(x, y, z) {
183410
+ return Math.sqrt(x * x + y * y + z * z);
183411
+ }
183402
183412
  /** Return the squared hypotenuse `(x*x + y*y + z*z)`. This is much faster than `Math.hypot(x,y,z)`. */
183403
- static hypotenuseSquaredXYZ(x, y, z) { return x * x + y * y + z * z; }
183413
+ static hypotenuseSquaredXYZ(x, y, z) {
183414
+ return x * x + y * y + z * z;
183415
+ }
183404
183416
  /** Return the (full 4d) hypotenuse `sqrt(x*x + y*y + z*z + w*w)`. This is much faster than `Math.hypot(x,y,z,w)`. */
183405
- static hypotenuseXYZW(x, y, z, w) { return Math.sqrt(x * x + y * y + z * z + w * w); }
183417
+ static hypotenuseXYZW(x, y, z, w) {
183418
+ return Math.sqrt(x * x + y * y + z * z + w * w);
183419
+ }
183406
183420
  /** Return the squared hypotenuse `(x*x + y*y + z*z+w*w)`. This is much faster than `Math.hypot(x,y,z)`. */
183407
- static hypotenuseSquaredXYZW(x, y, z, w) { return x * x + y * y + z * z + w * w; }
183421
+ static hypotenuseSquaredXYZW(x, y, z, w) {
183422
+ return x * x + y * y + z * z + w * w;
183423
+ }
183408
183424
  /**
183409
183425
  * Return the distance between xy points given as numbers.
183410
183426
  * @param x0 x coordinate of point 0
@@ -194261,6 +194277,7 @@ __webpack_require__.r(__webpack_exports__);
194261
194277
  /* harmony export */ "NewtonEvaluatorRtoRD": () => (/* reexport safe */ _numerics_Newton__WEBPACK_IMPORTED_MODULE_51__.NewtonEvaluatorRtoRD),
194262
194278
  /* harmony export */ "NullGeometryHandler": () => (/* reexport safe */ _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODULE_8__.NullGeometryHandler),
194263
194279
  /* harmony export */ "NumberArray": () => (/* reexport safe */ _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_23__.NumberArray),
194280
+ /* harmony export */ "OffsetMeshOptions": () => (/* reexport safe */ _polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_116__.OffsetMeshOptions),
194264
194281
  /* harmony export */ "OffsetOptions": () => (/* reexport safe */ _curve_internalContexts_PolygonOffsetContext__WEBPACK_IMPORTED_MODULE_79__.OffsetOptions),
194265
194282
  /* harmony export */ "Order2Bezier": () => (/* reexport safe */ _numerics_BezierPolynomials__WEBPACK_IMPORTED_MODULE_49__.Order2Bezier),
194266
194283
  /* harmony export */ "Order3Bezier": () => (/* reexport safe */ _numerics_BezierPolynomials__WEBPACK_IMPORTED_MODULE_49__.Order3Bezier),
@@ -197272,11 +197289,12 @@ __webpack_require__.r(__webpack_exports__);
197272
197289
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
197273
197290
  /* harmony export */ "CurveCurve": () => (/* binding */ CurveCurve)
197274
197291
  /* harmony export */ });
197275
- /* harmony import */ var _CurveCollection__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./CurveCollection */ "../../core/geometry/lib/esm/curve/CurveCollection.js");
197276
- /* harmony import */ var _CurveCurveIntersectXY__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./CurveCurveIntersectXY */ "../../core/geometry/lib/esm/curve/CurveCurveIntersectXY.js");
197277
- /* harmony import */ var _CurveCurveIntersectXYZ__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./CurveCurveIntersectXYZ */ "../../core/geometry/lib/esm/curve/CurveCurveIntersectXYZ.js");
197278
- /* harmony import */ var _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./CurvePrimitive */ "../../core/geometry/lib/esm/curve/CurvePrimitive.js");
197279
- /* harmony import */ var _CurveCurveCloseApproachXY__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./CurveCurveCloseApproachXY */ "../../core/geometry/lib/esm/curve/CurveCurveCloseApproachXY.js");
197292
+ /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
197293
+ /* harmony import */ var _CurveCollection__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./CurveCollection */ "../../core/geometry/lib/esm/curve/CurveCollection.js");
197294
+ /* harmony import */ var _CurveCurveCloseApproachXY__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./CurveCurveCloseApproachXY */ "../../core/geometry/lib/esm/curve/CurveCurveCloseApproachXY.js");
197295
+ /* harmony import */ var _CurveCurveIntersectXY__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./CurveCurveIntersectXY */ "../../core/geometry/lib/esm/curve/CurveCurveIntersectXY.js");
197296
+ /* harmony import */ var _CurveCurveIntersectXYZ__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./CurveCurveIntersectXYZ */ "../../core/geometry/lib/esm/curve/CurveCurveIntersectXYZ.js");
197297
+ /* harmony import */ var _CurvePrimitive__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./CurvePrimitive */ "../../core/geometry/lib/esm/curve/CurvePrimitive.js");
197280
197298
  /*---------------------------------------------------------------------------------------------
197281
197299
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
197282
197300
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -197289,6 +197307,7 @@ __webpack_require__.r(__webpack_exports__);
197289
197307
 
197290
197308
 
197291
197309
 
197310
+
197292
197311
  /**
197293
197312
  * `CurveCurve` has static method for various computations that work on a pair of curves or curve collections.
197294
197313
  * @public
@@ -197296,17 +197315,18 @@ __webpack_require__.r(__webpack_exports__);
197296
197315
  class CurveCurve {
197297
197316
  /**
197298
197317
  * Return xy intersections of 2 curves.
197299
- * @param geometryA second geometry
197318
+ * @param geometryA first geometry
197300
197319
  * @param extendA true to allow geometryA to extend
197301
197320
  * @param geometryB second geometry
197302
197321
  * @param extendB true to allow geometryB to extend
197322
+ * @param tolerance optional distance tolerance for coincidence
197303
197323
  */
197304
- static intersectionXYPairs(geometryA, extendA, geometryB, extendB) {
197305
- const handler = new _CurveCurveIntersectXY__WEBPACK_IMPORTED_MODULE_0__.CurveCurveIntersectXY(undefined, geometryA, extendA, geometryB, extendB);
197306
- if (geometryB instanceof _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive) {
197324
+ static intersectionXYPairs(geometryA, extendA, geometryB, extendB, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
197325
+ const handler = new _CurveCurveIntersectXY__WEBPACK_IMPORTED_MODULE_1__.CurveCurveIntersectXY(undefined, geometryA, extendA, geometryB, extendB, tolerance);
197326
+ if (geometryB instanceof _CurvePrimitive__WEBPACK_IMPORTED_MODULE_2__.CurvePrimitive) {
197307
197327
  geometryA.dispatchToGeometryHandler(handler);
197308
197328
  }
197309
- else if (geometryB instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_2__.CurveCollection) {
197329
+ else if (geometryB instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_3__.CurveCollection) {
197310
197330
  const allCurves = geometryB.collectCurvePrimitives();
197311
197331
  for (const child of allCurves) {
197312
197332
  handler.resetGeometry(geometryA, false, child, false);
@@ -197317,13 +197337,14 @@ class CurveCurve {
197317
197337
  }
197318
197338
  /**
197319
197339
  * Return xy intersections of 2 projected curves
197320
- * @param geometryA second geometry
197340
+ * @param geometryA first geometry
197321
197341
  * @param extendA true to allow geometryA to extend
197322
197342
  * @param geometryB second geometry
197323
197343
  * @param extendB true to allow geometryB to extend
197344
+ * @param tolerance optional distance tolerance for coincidence
197324
197345
  */
197325
- static intersectionProjectedXYPairs(worldToLocal, geometryA, extendA, geometryB, extendB) {
197326
- const handler = new _CurveCurveIntersectXY__WEBPACK_IMPORTED_MODULE_0__.CurveCurveIntersectXY(worldToLocal, geometryA, extendA, geometryB, extendB);
197346
+ static intersectionProjectedXYPairs(worldToLocal, geometryA, extendA, geometryB, extendB, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
197347
+ const handler = new _CurveCurveIntersectXY__WEBPACK_IMPORTED_MODULE_1__.CurveCurveIntersectXY(worldToLocal, geometryA, extendA, geometryB, extendB, tolerance);
197327
197348
  geometryA.dispatchToGeometryHandler(handler);
197328
197349
  return handler.grabPairedResults();
197329
197350
  }
@@ -197332,25 +197353,26 @@ class CurveCurve {
197332
197353
  * * Implemented for combinations of LineSegment3d, LineString3d, Arc3d.
197333
197354
  * * Not Implemented for bspline and bezier curves.
197334
197355
  * @beta
197335
- * @param geometryA second geometry
197356
+ * @param geometryA first geometry
197336
197357
  * @param extendA true to allow geometryA to extend
197337
197358
  * @param geometryB second geometry
197338
197359
  * @param extendB true to allow geometryB to extend
197339
197360
  */
197340
197361
  static intersectionXYZ(geometryA, extendA, geometryB, extendB) {
197341
- const handler = new _CurveCurveIntersectXYZ__WEBPACK_IMPORTED_MODULE_3__.CurveCurveIntersectXYZ(geometryA, extendA, geometryB, extendB);
197362
+ const handler = new _CurveCurveIntersectXYZ__WEBPACK_IMPORTED_MODULE_4__.CurveCurveIntersectXYZ(geometryA, extendA, geometryB, extendB);
197342
197363
  geometryA.dispatchToGeometryHandler(handler);
197343
197364
  return handler.grabResults();
197344
197365
  }
197345
197366
  /**
197346
197367
  * Return xy intersections of 2 curves.
197347
- * @param geometryA second geometry
197368
+ * @param geometryA first geometry
197348
197369
  * @param extendA true to allow geometryA to extend
197349
197370
  * @param geometryB second geometry
197350
197371
  * @param extendB true to allow geometryB to extend
197372
+ * @param tolerance optional distance tolerance for coincidence
197351
197373
  */
197352
- static allIntersectionsAmongPrimitivesXY(primitives) {
197353
- const handler = new _CurveCurveIntersectXY__WEBPACK_IMPORTED_MODULE_0__.CurveCurveIntersectXY(undefined, undefined, false, undefined, false);
197374
+ static allIntersectionsAmongPrimitivesXY(primitives, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
197375
+ const handler = new _CurveCurveIntersectXY__WEBPACK_IMPORTED_MODULE_1__.CurveCurveIntersectXY(undefined, undefined, false, undefined, false, tolerance);
197354
197376
  for (let i = 0; i < primitives.length; i++) {
197355
197377
  const geometryA = primitives[i];
197356
197378
  for (let j = i + 1; j < primitives.length; j++) {
@@ -197362,11 +197384,11 @@ class CurveCurve {
197362
197384
  }
197363
197385
  /**
197364
197386
  * Return xy close approaches of 2 projected curves
197365
- * @param geometryA second geometry
197387
+ * @param geometryA first geometry
197366
197388
  * @param geometryB second geometry
197367
197389
  */
197368
197390
  static closeApproachProjectedXYPairs(geometryA, geometryB, maxDistance) {
197369
- const handler = new _CurveCurveCloseApproachXY__WEBPACK_IMPORTED_MODULE_4__.CurveCurveCloseApproachXY(geometryA, geometryB);
197391
+ const handler = new _CurveCurveCloseApproachXY__WEBPACK_IMPORTED_MODULE_5__.CurveCurveCloseApproachXY(geometryA, geometryB);
197370
197392
  handler.maxDistanceToAccept = maxDistance;
197371
197393
  geometryA.dispatchToGeometryHandler(handler);
197372
197394
  return handler.grabPairedResults();
@@ -198135,8 +198157,8 @@ __webpack_require__.r(__webpack_exports__);
198135
198157
  /* harmony export */ "CurveLocationDetailArrayPair": () => (/* binding */ CurveLocationDetailArrayPair)
198136
198158
  /* harmony export */ });
198137
198159
  /* harmony import */ var _bspline_BSplineCurve__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../bspline/BSplineCurve */ "../../core/geometry/lib/esm/bspline/BSplineCurve.js");
198138
- /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
198139
- /* harmony import */ var _geometry3d_CoincidentGeometryOps__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../geometry3d/CoincidentGeometryOps */ "../../core/geometry/lib/esm/geometry3d/CoincidentGeometryOps.js");
198160
+ /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
198161
+ /* harmony import */ var _geometry3d_CoincidentGeometryOps__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../geometry3d/CoincidentGeometryOps */ "../../core/geometry/lib/esm/geometry3d/CoincidentGeometryOps.js");
198140
198162
  /* harmony import */ var _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../geometry3d/GeometryHandler */ "../../core/geometry/lib/esm/geometry3d/GeometryHandler.js");
198141
198163
  /* harmony import */ var _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../geometry3d/GrowableFloat64Array */ "../../core/geometry/lib/esm/geometry3d/GrowableFloat64Array.js");
198142
198164
  /* harmony import */ var _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../geometry3d/Matrix3d */ "../../core/geometry/lib/esm/geometry3d/Matrix3d.js");
@@ -198161,14 +198183,12 @@ __webpack_require__.r(__webpack_exports__);
198161
198183
 
198162
198184
 
198163
198185
 
198164
- // import { Arc3d } from "./Arc3d";
198165
198186
 
198166
198187
 
198167
198188
 
198168
198189
 
198169
198190
 
198170
198191
 
198171
- // import { LineString3d } from "./LineString3d";
198172
198192
 
198173
198193
 
198174
198194
 
@@ -198221,8 +198241,9 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
198221
198241
  * @param extendA flag to enable using extension of geometryA.
198222
198242
  * @param geometryB second curve for intersection. Saved for reference by specific handler methods.
198223
198243
  * @param extendB flag for extension of geometryB.
198244
+ * @param tolerance optional distance tolerance for coincidence
198224
198245
  */
198225
- constructor(worldToLocal, _geometryA, extendA, geometryB, extendB) {
198246
+ constructor(worldToLocal, _geometryA, extendA, geometryB, extendB, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistance) {
198226
198247
  super();
198227
198248
  // this.geometryA = _geometryA;
198228
198249
  this._extendA = extendA;
@@ -198235,7 +198256,7 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
198235
198256
  if (!this._worldToLocalAffine)
198236
198257
  this._worldToLocalPerspective = worldToLocal.clone();
198237
198258
  }
198238
- this._coincidentGeometryContext = _geometry3d_CoincidentGeometryOps__WEBPACK_IMPORTED_MODULE_3__.CoincidentGeometryQuery.create();
198259
+ this._coincidentGeometryContext = _geometry3d_CoincidentGeometryOps__WEBPACK_IMPORTED_MODULE_4__.CoincidentGeometryQuery.create(tolerance);
198239
198260
  this.reinitialize();
198240
198261
  }
198241
198262
  reinitialize() {
@@ -198254,13 +198275,15 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
198254
198275
  return false;
198255
198276
  return true;
198256
198277
  }
198257
- // Test the fraction by strict parameter, but allow physical (metric) test at ends.
198258
- acceptFractionOnLine(extend0, fraction, extend1, pointA, pointB) {
198278
+ /** Test the fraction by strict parameter, but allow toleranced distance test at ends.
198279
+ * @param tolerance optional distance tolerance to check proximity to start/end point
198280
+ */
198281
+ acceptFractionOnLine(extend0, fraction, extend1, pointA, pointB, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistance) {
198259
198282
  if (!extend0 && fraction < 0) {
198260
- return _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.isSmallMetricDistance(fraction * pointA.distanceXY(pointB));
198283
+ return _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.isDistanceWithinTol(fraction * pointA.distanceXY(pointB), tolerance);
198261
198284
  }
198262
198285
  else if (!extend1 && fraction > 1.0)
198263
- return _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.isSmallMetricDistance((fraction - 1.0) * pointA.distanceXY(pointB));
198286
+ return _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.isDistanceWithinTol((fraction - 1.0) * pointA.distanceXY(pointB), tolerance);
198264
198287
  return true;
198265
198288
  }
198266
198289
  /**
@@ -198275,7 +198298,7 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
198275
198298
  return result;
198276
198299
  }
198277
198300
  sameCurveAndFraction(cp, fraction, detail) {
198278
- return cp === detail.curve && _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.isAlmostEqualNumber(fraction, detail.fraction);
198301
+ return cp === detail.curve && _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.isAlmostEqualNumber(fraction, detail.fraction);
198279
198302
  }
198280
198303
  /** compute intersection of two line segments.
198281
198304
  * filter by extension rules.
@@ -198287,14 +198310,14 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
198287
198310
  let globalFractionA1, globalFractionB1;
198288
198311
  const isInterval = intervalDetails !== undefined && intervalDetails.detailA.hasFraction1 && intervalDetails.detailB.hasFraction1;
198289
198312
  if (isInterval) {
198290
- globalFractionA = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.interpolate(fractionA0, intervalDetails.detailA.fraction, fractionA1);
198291
- globalFractionB = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.interpolate(fractionB0, intervalDetails.detailB.fraction, fractionB1);
198292
- globalFractionA1 = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.interpolate(fractionA0, intervalDetails.detailA.fraction1, fractionA1);
198293
- globalFractionB1 = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.interpolate(fractionB0, intervalDetails.detailB.fraction1, fractionB1);
198313
+ globalFractionA = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionA0, intervalDetails.detailA.fraction, fractionA1);
198314
+ globalFractionB = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionB0, intervalDetails.detailB.fraction, fractionB1);
198315
+ globalFractionA1 = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionA0, intervalDetails.detailA.fraction1, fractionA1);
198316
+ globalFractionB1 = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionB0, intervalDetails.detailB.fraction1, fractionB1);
198294
198317
  }
198295
198318
  else {
198296
- globalFractionA = globalFractionA1 = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.interpolate(fractionA0, localFractionA, fractionA1);
198297
- globalFractionB = globalFractionB1 = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.interpolate(fractionB0, localFractionB, fractionB1);
198319
+ globalFractionA = globalFractionA1 = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionA0, localFractionA, fractionA1);
198320
+ globalFractionB = globalFractionB1 = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionB0, localFractionB, fractionB1);
198298
198321
  }
198299
198322
  // ignore duplicate of most recent point . ..
198300
198323
  const numPrevious = this._results.length;
@@ -198356,8 +198379,8 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
198356
198379
  this.recordPointWithLocalFractions(overlap.detailA.fraction, cpA, fractionA0, fractionA1, overlap.detailB.fraction, cpB, fractionB0, fractionB1, reversed, overlap);
198357
198380
  }
198358
198381
  else if (_numerics_Polynomials__WEBPACK_IMPORTED_MODULE_6__.SmallSystem.lineSegment3dXYTransverseIntersectionUnbounded(pointA0, pointA1, pointB0, pointB1, uv)) {
198359
- if (this.acceptFractionOnLine(extendA0, uv.x, extendA1, pointA0, pointA1)
198360
- && this.acceptFractionOnLine(extendB0, uv.y, extendB1, pointB0, pointB1)) {
198382
+ if (this.acceptFractionOnLine(extendA0, uv.x, extendA1, pointA0, pointA1, this._coincidentGeometryContext.tolerance)
198383
+ && this.acceptFractionOnLine(extendB0, uv.y, extendB1, pointB0, pointB1, this._coincidentGeometryContext.tolerance)) {
198361
198384
  this.recordPointWithLocalFractions(uv.x, cpA, fractionA0, fractionA1, uv.y, cpB, fractionB0, fractionB1, reversed);
198362
198385
  }
198363
198386
  }
@@ -198415,9 +198438,9 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
198415
198438
  const data = arc.toTransformedPoint4d(this._worldToLocalPerspective);
198416
198439
  const pointA0H = this._worldToLocalPerspective.multiplyPoint3d(pointA0, 1);
198417
198440
  const pointA1H = this._worldToLocalPerspective.multiplyPoint3d(pointA1, 1);
198418
- const alpha = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.center);
198419
- const beta = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.vector0);
198420
- const gamma = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.vector90);
198441
+ const alpha = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.center);
198442
+ const beta = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.vector0);
198443
+ const gamma = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.vector90);
198421
198444
  const cosines = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array(2);
198422
198445
  const sines = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array(2);
198423
198446
  const radians = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array(2);
@@ -198439,9 +198462,9 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
198439
198462
  pointA0Local = this._worldToLocalAffine.multiplyPoint3d(pointA0);
198440
198463
  pointA1Local = this._worldToLocalAffine.multiplyPoint3d(pointA1);
198441
198464
  }
198442
- const alpha = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.center, 1);
198443
- const beta = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector0, 0);
198444
- const gamma = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector90, 0);
198465
+ const alpha = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.center, 1);
198466
+ const beta = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector0, 0);
198467
+ const gamma = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector90, 0);
198445
198468
  const cosines = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array(2);
198446
198469
  const sines = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array(2);
198447
198470
  const radians = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array(2);
@@ -198666,8 +198689,8 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
198666
198689
  let bezierBFraction = r;
198667
198690
  bezierB.fractionToPoint4d(bezierBFraction, this._xyzwB);
198668
198691
  const segmentAFraction = _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_6__.SmallSystem.lineSegment3dHXYClosestPointUnbounded(this._xyzwA0, this._xyzwA1, this._xyzwB);
198669
- if (segmentAFraction && _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.isIn01WithTolerance(segmentAFraction, intervalTolerance)) {
198670
- let bezierAFraction = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.interpolate(f0, segmentAFraction, f1);
198692
+ if (segmentAFraction && _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.isIn01WithTolerance(segmentAFraction, intervalTolerance)) {
198693
+ let bezierAFraction = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(f0, segmentAFraction, f1);
198671
198694
  const xyMatchingFunction = new BezierBezierIntersectionXYRRToRRD(bezierA, bezierB);
198672
198695
  const newtonSearcher = new _numerics_Newton__WEBPACK_IMPORTED_MODULE_0__.Newton2dUnboundedWithDerivative(xyMatchingFunction);
198673
198696
  newtonSearcher.setUV(bezierAFraction, bezierBFraction);
@@ -212656,6 +212679,44 @@ class Angle {
212656
212679
  const uDotV = ux * vx + uy * vy + uz * vz;
212657
212680
  return Math.atan2(_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.crossProductMagnitude(ux, uy, uz, vx, vy, vz), uDotV);
212658
212681
  }
212682
+ /**
212683
+ * * Returns the angle between two vectors, with the vectors given as xyz components, and an up vector to resolve angle to a full 2PI range.
212684
+ * * The returned angle is (-PI < radians <= PI) or (0 <= radians < 2 * PI)
212685
+ * * The angle is in the plane of the U and V vectors.
212686
+ * * The upVector determines a positive side of the plane but need not be strictly perpendicular to the plane.
212687
+ *
212688
+ * @param ux x component of vector u
212689
+ * @param uy y component of vector u
212690
+ * @param uz z component of vector u
212691
+ * @param vx x component of vector v
212692
+ * @param vy y component of vector v
212693
+ * @param vz z component of vector v
212694
+ * @param upVectorX x component of vector to positive side of plane.
212695
+ * @param upVectorY y component of vector to positive side of plane.
212696
+ * @param upVectorZ z component of vector to positive side of plane.
212697
+ * @param adjustToAllPositive if true, return strictly non-negative sweep (0 <= radians < 2*PI). If false, return signed (-PI < radians <= PI)
212698
+ */
212699
+ static orientedRadiansBetweenVectorsXYZ(ux, uy, uz, vx, vy, vz, upVectorX, upVectorY, upVectorZ, adjustToPositive = false) {
212700
+ const uDotV = ux * vx + uy * vy + uz * vz;
212701
+ const wx = uy * vz - uz * vy;
212702
+ const wy = uz * vx - ux * vz;
212703
+ const wz = ux * vy - uy * vx;
212704
+ const upDotW = upVectorX * wx + upVectorY * wy + upVectorZ * wz;
212705
+ const crossMagnitude = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(wx, wy, wz);
212706
+ if (upDotW < 0.0) {
212707
+ if (adjustToPositive) {
212708
+ // The turn is greater than 180 degrees. Take a peculiarly oriented atan2 to get the excess-180 part as addition to PI.
212709
+ // This gives the smoothest numerical transition passing PI.
212710
+ return Math.PI + Math.atan2(crossMagnitude, -uDotV);
212711
+ }
212712
+ else {
212713
+ return -Math.atan2(crossMagnitude, uDotV);
212714
+ }
212715
+ }
212716
+ else {
212717
+ return Math.atan2(crossMagnitude, uDotV);
212718
+ }
212719
+ }
212659
212720
  /**
212660
212721
  * Add a multiple of a full circle angle (360 degrees, 2PI) in place.
212661
212722
  * @param multiple multiplier factor
@@ -213483,6 +213544,9 @@ class CoincidentGeometryQuery {
213483
213544
  constructor(tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
213484
213545
  this._tolerance = tolerance;
213485
213546
  }
213547
+ get tolerance() {
213548
+ return this._tolerance;
213549
+ }
213486
213550
  static create(tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
213487
213551
  return new CoincidentGeometryQuery(tolerance);
213488
213552
  }
@@ -218032,6 +218096,7 @@ __webpack_require__.r(__webpack_exports__);
218032
218096
 
218033
218097
 
218034
218098
  /* eslint-disable @itwin/prefer-get */
218099
+ // cSpell:words XXYZ YXYZ ZXYZ
218035
218100
  /**
218036
218101
  * PackedMatrix3dOps contains static methods for matrix operations where the matrix is a Float64Array.
218037
218102
  * * The Float64Array contains the matrix entries in row-major order
@@ -218659,7 +218724,8 @@ class Matrix3d {
218659
218724
  return undefined;
218660
218725
  }
218661
218726
  /**
218662
- * Construct a rigid matrix using vectorA and its 2 perpendicular.
218727
+ * Construct a rigid matrix (orthogonal matrix with +1 determinant) using vectorA and its 2 perpendicular.
218728
+ * * If axisOrder is not passed then `AxisOrder = AxisOrder.ZXY` is used as default.
218663
218729
  * * This function internally uses createPerpendicularVectorFavorXYPlane and createRigidFromColumns.
218664
218730
  */
218665
218731
  static createRigidHeadsUp(vectorA, axisOrder = _Geometry__WEBPACK_IMPORTED_MODULE_0__.AxisOrder.ZXY, result) {
@@ -218671,7 +218737,7 @@ class Matrix3d {
218671
218737
  }
218672
218738
  return Matrix3d.createIdentity(result);
218673
218739
  }
218674
- /** Return the matrix for rotation of `angle` around `axis` */
218740
+ /** Return the matrix for rotation of `angle` around desired `axis` */
218675
218741
  static createRotationAroundVector(axis, angle, result) {
218676
218742
  // Rodriguez formula (matrix form), https://mathworld.wolfram.com/RodriguesRotationFormula.html
218677
218743
  const c = angle.cos();
@@ -218685,7 +218751,7 @@ class Matrix3d {
218685
218751
  }
218686
218752
  return undefined;
218687
218753
  }
218688
- /** Returns a rotation of specified angle around an axis
218754
+ /** Returns a rotation of specified angle around one of the main axis (X,Y,Z).
218689
218755
  * @param axisIndex index of axis (AxisIndex.X, AxisIndex.Y, AxisIndex.Z) kept fixed by the rotation.
218690
218756
  * @param angle angle of rotation
218691
218757
  * @param result optional result matrix.
@@ -218708,14 +218774,33 @@ class Matrix3d {
218708
218774
  return myResult;
218709
218775
  }
218710
218776
  /**
218711
- * Replace current columns Ui and Uj with (c*Ui - s*Uj) and (c*Uj + s*Ui).
218712
- * * There is no checking for i,j being 0,1,2.
218713
- * * This is used in compute intensive inner loops
218714
- * @param i first row index. **must be 0,1,2** (unchecked)
218715
- * @param j second row index. **must be 0,1,2** (unchecked)
218716
- * @param c fist coefficient
218717
- * @param s second coefficient
218718
- */
218777
+ * Replace current rows Ui and Uj with (c*Ui + s*Uj) and (c*Uj - s*Ui).
218778
+ * * There is no checking for i,j being 0,1,2.
218779
+ * @param i first row index. **must be 0,1,2** (unchecked)
218780
+ * @param j second row index. **must be 0,1,2** (unchecked)
218781
+ * @param c fist coefficient
218782
+ * @param s second coefficient
218783
+ */
218784
+ applyGivensRowOp(i, j, c, s) {
218785
+ let ii = 3 * i;
218786
+ let jj = 3 * j;
218787
+ const limit = ii + 3;
218788
+ for (; ii < limit; ii++, jj++) {
218789
+ const a = this.coffs[ii];
218790
+ const b = this.coffs[jj];
218791
+ this.coffs[ii] = a * c + b * s;
218792
+ this.coffs[jj] = -a * s + b * c;
218793
+ }
218794
+ }
218795
+ /**
218796
+ * Replace current columns Ui and Uj with (c*Ui + s*Uj) and (c*Uj - s*Ui).
218797
+ * * There is no checking for i,j being 0,1,2.
218798
+ * * This is used in compute intensive inner loops
218799
+ * @param i first row index. **must be 0,1,2** (unchecked)
218800
+ * @param j second row index. **must be 0,1,2** (unchecked)
218801
+ * @param c fist coefficient
218802
+ * @param s second coefficient
218803
+ */
218719
218804
  applyGivensColumnOp(i, j, c, s) {
218720
218805
  const limit = i + 9;
218721
218806
  for (; i < limit; i += 3, j += 3) {
@@ -218726,12 +218811,12 @@ class Matrix3d {
218726
218811
  }
218727
218812
  }
218728
218813
  /**
218729
- * Create a matrix from column vectors.
218730
- * ```
218731
- * equation
218732
- * \begin{bmatrix}U_x & V_x & W_x \\ U_y & V_y & W_y \\ U_z & V_z & W_z \end{bmatrix}
218733
- * ```
218734
- */
218814
+ * Create a matrix from column vectors.
218815
+ * ```
218816
+ * equation
218817
+ * \begin{bmatrix}U_x & V_x & W_x \\ U_y & V_y & W_y \\ U_z & V_z & W_z \end{bmatrix}
218818
+ * ```
218819
+ */
218735
218820
  static createColumns(vectorU, vectorV, vectorW, result) {
218736
218821
  return Matrix3d.createRowValues(vectorU.x, vectorV.x, vectorW.x, vectorU.y, vectorV.y, vectorW.y, vectorU.z, vectorV.z, vectorW.z, result);
218737
218822
  }
@@ -218748,8 +218833,9 @@ class Matrix3d {
218748
218833
  * * ColumnX points in the rightVector direction
218749
218834
  * * ColumnY points in the upVector direction
218750
218835
  * * ColumnZ is a unit cross product of ColumnX and ColumnY.
218751
- * * Optionally rotate the standard cube by 45 degrees ccw around Y to bring its left or right vertical edge to center.
218752
- * * Optionally rotate the standard cube by 35.264 degrees ccw around X (isometric rotation).
218836
+ * * Optionally rotate by 45 degrees around `upVector` to bring its left or right vertical edge to center.
218837
+ * * Optionally rotate by arctan(1/sqrt(2)) ~ 35.264 degrees around `rightVector` to bring the top or bottom
218838
+ * horizontal edge of the view to the center (for isometric views).
218753
218839
  * * This is expected to be used with various principal unit vectors that are perpendicular to each other.
218754
218840
  * * STANDARD TOP VIEW: createViewedAxes(Vector3d.unitX(), Vector3d.unitY(), 0, 0)
218755
218841
  * * STANDARD FRONT VIEW: createViewedAxes(Vector3d.unitX(), Vector3d.unitZ(), 0, 0)
@@ -218757,16 +218843,20 @@ class Matrix3d {
218757
218843
  * * STANDARD RIGHT VIEW: createViewedAxes(Vector3d.unitY(), Vector3d.unitZ(), 0, 0)
218758
218844
  * * STANDARD LEFT VIEW: createViewedAxes(Vector3d.unitY(-1), Vector3d.unitZ(), 0, 0)
218759
218845
  * * STANDARD BOTTOM VIEW: createViewedAxes(Vector3d.unitX(), Vector3d.unitY(-1), 0, 0)
218846
+ * * STANDARD ISO VIEW: createViewedAxes(Vector3d.unitX(), Vector3d.unitZ(), -1, 1)
218847
+ * * STANDARD RIGHT ISO VIEW: createViewedAxes(Vector3d.unitX(), Vector3d.unitZ(), 1, 1)
218848
+ * * Front, right, back, left, top, and bottom standard views are views from faces of the cube
218849
+ * and iso and right iso standard views are views from corners of the cube.
218760
218850
  * * Note: createViewedAxes is column-based so always returns local to world
218761
218851
  *
218762
218852
  * @param rightVector ColumnX of the returned matrix. Expected to be perpendicular to upVector.
218763
218853
  * @param upVector ColumnY of the returned matrix. Expected to be perpendicular to rightVector.
218764
- * @param leftNoneRight Specifies the ccw rotation around Y axis. Normally one of "-1", "0", and "1", where
218765
- * "-1" indicates rotation by 45 degrees to bring the left vertical edge to center, "0" means no rotation,
218854
+ * @param leftNoneRight Specifies the ccw rotation around `upVector` axis. Normally one of "-1", "0", and "1",
218855
+ * where "-1" indicates rotation by 45 degrees to bring the left vertical edge to center, "0" means no rotation,
218766
218856
  * and "1" indicates rotation by 45 degrees to bring the right vertical edge to center. Other numbers are
218767
218857
  * used as multiplier for this 45 degree rotation.
218768
- * @param topNoneBottom Specifies the ccw rotation around X axis. Normally one of "-1", "0", and "1", where
218769
- * "-1" indicates isometric rotation (35.264 degrees) to bring the bottom upward, "0" means no rotation,
218858
+ * @param topNoneBottom Specifies the ccw rotation around `rightVector` axis. Normally one of "-1", "0", and "1",
218859
+ * where "-1" indicates isometric rotation (35.264 degrees) to bring the bottom upward, "0" means no rotation,
218770
218860
  * and "1" indicates isometric rotation (35.264 degrees) to bring the top downward. Other numbers are
218771
218861
  * used as multiplier for the 35.264 degree rotation.
218772
218862
  * @returns matrix = [rightVector, upVector, rightVector cross upVector] with the applied rotations specified
@@ -218804,9 +218894,11 @@ class Matrix3d {
218804
218894
  * * Default is TOP view (`local X = world X`, `local Y = world Y`, `local Z = world Z`).
218805
218895
  * * To change view from the TOP to one of the other 7 standard views, we need to multiply "world data" to
218806
218896
  * the corresponding matrix1 provided by `createStandardWorldToView(index, false)` and then
218807
- * `matrix1.multiply(world data)` will returns "local data".
218897
+ * `matrix1.multiply(world data)` will return "local data".
218808
218898
  * * To change view back to the TOP, we need to multiply "local data" to the corresponding matrix2 provided
218809
218899
  * by `createStandardWorldToView(index, true)` and then `matrix2.multiply(local data)` will returns "world data".
218900
+ * * Note: No matter how you rotate the world axis, local X is always pointing right, local Y is always pointing up,
218901
+ * and local Z is always pointing toward you.
218810
218902
  *
218811
218903
  * @param index standard view index `StandardViewIndex.Top, Bottom, Left, Right, Front, Back, Iso, RightIso`
218812
218904
  * @param invert if false (default), the return matrix is world to local (view) and if true, the the return
@@ -218815,343 +218907,182 @@ class Matrix3d {
218815
218907
  */
218816
218908
  static createStandardWorldToView(index, invert = false, result) {
218817
218909
  switch (index) {
218818
- // start with TOP view, ccw rotation by 180 degrees around X
218910
+ // Start with TOP view, ccw rotation by 180 degrees around X
218819
218911
  case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Bottom:
218820
218912
  result = Matrix3d.createRowValues(1, 0, 0, 0, -1, 0, 0, 0, -1);
218821
218913
  break;
218822
- // start with TOP view, ccw rotation by -90 degrees around X and by 90 degrees around Z
218914
+ // Start with TOP view, ccw rotation by -90 degrees around X and by 90 degrees around Z
218823
218915
  case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Left:
218824
218916
  result = Matrix3d.createRowValues(0, -1, 0, 0, 0, 1, -1, 0, 0);
218825
218917
  break;
218826
- // start with TOP view, ccw rotation by -90 degrees around X and by -90 degrees around Z
218918
+ // Start with TOP view, ccw rotation by -90 degrees around X and by -90 degrees around Z
218827
218919
  case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Right:
218828
218920
  result = Matrix3d.createRowValues(0, 1, 0, 0, 0, 1, 1, 0, 0);
218829
218921
  break;
218830
- // start with TOP view, ccw rotation by -90 degrees around X
218922
+ // Start with TOP view, ccw rotation by -90 degrees around X
218831
218923
  case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Front:
218832
218924
  result = Matrix3d.createRowValues(1, 0, 0, 0, 0, 1, 0, -1, 0);
218833
218925
  break;
218834
- // start with TOP view, ccw rotation by -90 degrees around X and by 180 degrees around Z
218926
+ // Start with TOP view, ccw rotation by -90 degrees around X and by 180 degrees around Z
218835
218927
  case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Back:
218836
218928
  result = Matrix3d.createRowValues(-1, 0, 0, 0, 0, 1, 0, 1, 0);
218837
218929
  break;
218930
+ /**
218931
+ * Isometric view
218932
+ * Start with FRONT view, ccw rotation by -45 degrees around Y and by arctan(1/sqrt(2)) ~ 35.264 degrees around X
218933
+ * cos(45) = 1/sqrt(2) = 0.70710678118 and sin(45) = 1/sqrt(2) = 0.70710678118
218934
+ * cos(35.264) = 2/sqrt(6) = 0.81649658092 and sin(35.264) = 1/sqrt(3) = 0.57735026919
218935
+ * More info: https://en.wikipedia.org/wiki/Isometric_projection
218936
+ */
218838
218937
  case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Iso:
218839
- // start with FRONT view, ccw rotation by -45 degrees around Y and by 35.264 degrees around X
218840
218938
  result = Matrix3d.createRowValues(0.707106781186548, -0.70710678118654757, 0.00000000000000000, 0.408248290463863, 0.40824829046386302, 0.81649658092772603, -0.577350269189626, -0.57735026918962573, 0.57735026918962573);
218841
218939
  break;
218940
+ // Start with FRONT view, ccw rotation by 45 degrees around Y and by 35.264 degrees around X
218842
218941
  case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.RightIso:
218843
218942
  result = Matrix3d.createRowValues(0.707106781186548, 0.70710678118654757, 0.00000000000000000, -0.408248290463863, 0.40824829046386302, 0.81649658092772603, 0.577350269189626, -0.57735026918962573, 0.57735026918962573);
218844
218943
  break;
218845
- case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Top: // no rotation
218944
+ // no rotation
218945
+ case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Top:
218846
218946
  default:
218847
218947
  result = Matrix3d.createIdentity(result);
218848
218948
  }
218849
218949
  if (invert)
218850
- result.transposeInPlace();
218950
+ result.transposeInPlace(); // matrix is rigid so transpose and inverse are the same
218851
218951
  return result;
218852
218952
  }
218853
- /*
218854
- // this implementation has problems distinguishing failure (normalize) from small angle.
218855
- public getAxisAndAngleOfRotation(): { axis: Vector3d, angle: Angle, error: boolean } {
218856
-
218857
- const result = { axis: Vector3d.unitZ(), angle: Angle.createRadians(0), error: true };
218858
- if (this.isIdentity) {
218859
- result.error = false;
218860
- return result;
218861
- }
218862
- if (!this.isRigid())
218863
- return result;
218864
- const QMinusI = this.clone();
218865
- QMinusI.coffs[0] -= 1.0;
218866
- QMinusI.coffs[4] -= 1.0;
218867
- QMinusI.coffs[8] -= 1.0;
218868
- // Each column of (Q - I) is the motion of the corresponding axis vector
218869
- // during the rotation.
218870
- // Only one of the three axes can really be close to the rotation axis.
218871
- const delta0 = QMinusI.columnX();
218872
- const delta1 = QMinusI.columnY();
218873
- const delta2 = QMinusI.columnZ();
218874
- const cross01 = delta0.crossProduct(delta1);
218875
- const cross12 = delta1.crossProduct(delta2);
218876
- const cross20 = delta2.crossProduct(delta0);
218877
-
218878
- const aa01 = cross01.magnitudeSquared();
218879
- const aa12 = cross12.magnitudeSquared();
218880
- const aa20 = cross20.magnitudeSquared();
218881
-
218882
- const cross = cross01.clone(); // This will end up as the biggest cross product
218883
- const v0 = delta0.clone(); // This will end up as one of the two largest delta vectors
218884
- let aaMax = aa01;
218885
- if (aa12 > aaMax) {
218886
- cross.setFrom(cross12);
218887
- aaMax = aa12;
218888
- v0.setFrom(delta1);
218889
- }
218890
- if (aa20 > aaMax) {
218891
- cross.setFrom(cross20);
218892
- aaMax = aa20;
218893
- v0.setFrom(delta2);
218894
- }
218895
-
218896
- if (aaMax === 0.0) {
218897
- // The vectors did not move. Just accept the zero rotation, with error flag set.
218898
- return result;
218899
- }
218900
-
218901
- v0.normalizeInPlace();
218902
- // V0 is a unit vector perpendicular to the rotation axis.
218903
- // Rotate it. Its image V1 is also a unit vector, and the angle from V0 to V1 is the quat angle.
218904
- // CrossProduct is axis vector times sine of angle.
218905
- // Dot Product is cosine of angle.
218906
- // V2 is zero in 180 degree case, so we use the Cross from the search as the axis
218907
- // as direction, being careful to keep sine positive.
218908
- const v1 = this.multiplyVector(v0);
218909
- const v2 = v0.crossProduct(v1);
218910
- const sine = v2.magnitude();
218911
- if (v2.dotProduct(cross) < 0.0)
218912
- cross.scaleInPlace(-1.0);
218913
- const cosine = v0.dotProduct(v1);
218914
- result.angle.setRadians(Math.atan2(sine, cosine));
218915
- result.axis.setFrom(cross);
218916
- result.error = !result.axis.tryNormalizeInPlace();
218917
- return result
218953
+ /**
218954
+ * Apply (in place) a jacobi update that zeros out this.at(i,j).
218955
+ * @param i row index of zeroed member
218956
+ * @param j column index of zeroed member
218957
+ * @param k other row/column index (different from i and j)
218958
+ * @param leftEigenVectors a matrix that its columns will be filled by eigenvectors of this Matrix3d
218959
+ * (allocated by caller, computed and filled by this function)
218960
+ */
218961
+ applyFastSymmetricJacobiUpdate(i, j, k, leftEigenVectors) {
218962
+ const indexII = 4 * i;
218963
+ const indexJJ = 4 * j;
218964
+ const indexIJ = 3 * i + j;
218965
+ const indexIK = 3 * i + k;
218966
+ const indexJK = 3 * j + k;
218967
+ const dotUU = this.coffs[indexII];
218968
+ const dotVV = this.coffs[indexJJ];
218969
+ const dotUV = this.coffs[indexIJ];
218970
+ const jacobi = _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.trigValuesToHalfAngleTrigValues(dotUU - dotVV, 2.0 * dotUV);
218971
+ if (Math.abs(dotUV) < 1.0e-15 * (dotUU + dotVV))
218972
+ return 0.0;
218973
+ const c = jacobi.c;
218974
+ const s = jacobi.s;
218975
+ const cc = c * c;
218976
+ const ss = s * s;
218977
+ const sc2 = 2.0 * c * s;
218978
+ this.coffs[indexII] = cc * dotUU + sc2 * dotUV + ss * dotVV;
218979
+ this.coffs[indexJJ] = ss * dotUU - sc2 * dotUV + cc * dotVV;
218980
+ this.coffs[indexIJ] = 0.0;
218981
+ const a = this.coffs[indexIK];
218982
+ const b = this.coffs[indexJK];
218983
+ this.coffs[indexIK] = a * c + b * s;
218984
+ this.coffs[indexJK] = -s * a + c * b;
218985
+ this.coffs[3 * j + i] = 0.0;
218986
+ this.coffs[3 * k + i] = this.coffs[indexIK];
218987
+ this.coffs[3 * k + j] = this.coffs[indexJK];
218988
+ leftEigenVectors.applyGivensColumnOp(i, j, c, s);
218989
+ return Math.abs(dotUV);
218990
+ }
218991
+ /**
218992
+ * Factor this (symmetrized) as a product U * lambda * UT where U is orthogonal, lambda is diagonal.
218993
+ * The upper triangle is mirrored to lower triangle to enforce symmetry.
218994
+ * @param leftEigenvectors a matrix that its columns will be filled by eigenvectors of this Matrix3d
218995
+ * (allocated by caller, computed and filled by this function)
218996
+ * @param lambda a vector that its entries will be filled by eigenvalues of this Matrix3d
218997
+ * (allocated by caller, computed and filled by this function)
218998
+ */
218999
+ fastSymmetricEigenvalues(leftEigenvectors, lambda) {
219000
+ const matrix = this.clone();
219001
+ leftEigenvectors.setIdentity();
219002
+ const tolerance = 1.0e-12 * this.sumSquares();
219003
+ for (let iteration = 0; iteration < 7; iteration++) {
219004
+ const sum = matrix.applyFastSymmetricJacobiUpdate(0, 1, 2, leftEigenvectors)
219005
+ + matrix.applyFastSymmetricJacobiUpdate(0, 2, 1, leftEigenvectors)
219006
+ + matrix.applyFastSymmetricJacobiUpdate(1, 2, 0, leftEigenvectors);
219007
+ // console.log("symmetric sum", sum);
219008
+ // console.log ("sum", sum);
219009
+ if (sum < tolerance) {
219010
+ // console.log("symmetric iterations", iteration);
219011
+ lambda.set(matrix.at(0, 0), matrix.at(1, 1), matrix.at(2, 2));
219012
+ return true;
219013
+ }
219014
+ }
219015
+ return false;
218918
219016
  }
218919
- */
218920
219017
  /**
218921
219018
  * Compute the (unit vector) axis and angle of rotation.
219019
+ * * math details can be found at docs/learning/geometry/Angle.md
218922
219020
  * @returns Returns axis and angle of rotation with result.ok === true when the conversion succeeded.
218923
219021
  */
218924
219022
  getAxisAndAngleOfRotation() {
218925
219023
  const trace = this.coffs[0] + this.coffs[4] + this.coffs[8];
218926
- // trace = (xx + yy * zz) * (1-c) + 3 * c = 1 + 2c ==> c = (trace-1) / 2
218927
- const skewXY = this.coffs[3] - this.coffs[1]; // == 2sz
218928
- const skewYZ = this.coffs[7] - this.coffs[5]; // == 2sx
218929
- const skewZX = this.coffs[2] - this.coffs[6]; // == 2sy
218930
- const c = (trace - 1.0) / 2.0;
218931
- const s = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(skewXY, skewYZ, skewZX) / 2.0;
218932
- const e = c * c + s * s - 1.0;
219024
+ const skewXY = this.coffs[3] - this.coffs[1]; // 2*z*sin
219025
+ const skewYZ = this.coffs[7] - this.coffs[5]; // 2*y*sin
219026
+ const skewZX = this.coffs[2] - this.coffs[6]; // 2*x*sin
219027
+ // trace = (m00^2 + m11^2 + m22^2) * (1-cos) + 3cos = (1-cos) + 3cos = 1 + 2cos ==> cos = (trace-1) / 2
219028
+ const c = (trace - 1.0) / 2.0; // cosine
219029
+ const s = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(skewXY, skewYZ, skewZX) / 2.0; // sine
219030
+ const e = c * c + s * s - 1.0; // s^2 + c^2 = 1
219031
+ // if s^2 + c^2 != 1 then we have a bad matrix so return false
218933
219032
  if (Math.abs(e) > _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallAngleRadians) {
218934
- // the sine and cosine are not a unit circle point. bad matrix . ..
218935
219033
  return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(0), ok: false };
218936
219034
  }
219035
+ // sin is close to 0 then we got to special cases (angle 0 or 180) which needs to be handled differently
218937
219036
  if (Math.abs(s) < _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallAngleRadians) {
218938
- // There is no significant skew.
218939
- // The matrix is symmetric
218940
- // So it has simple eigenvalues -- either (1,1,1) or (1,-1,-1).
218941
- if (c > 0) // no rotation
219037
+ if (c > 0) // sin = 0 and cos = 1 so angle = 0 (i.e., no rotation)
218942
219038
  return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(0), ok: true };
218943
- // 180 degree flip around some axis ?
218944
- // Look for the simple case of a principal rotation ...
218945
- // look for a pair of (-1) entries on the diagonal ...
219039
+ /**
219040
+ * If sin = 0 and cos = -1 then angle = 180 (i.e., 180 degree rotation around some axis)
219041
+ * then the rotation matrix becomes
219042
+ * 2x^2-1 2xy 2xz
219043
+ * 2xy 2y^2-1 2yz
219044
+ * 2xz 2yz 2z^2-1
219045
+ * Note that the matrix is symmetric.
219046
+ * If rotation is around one the standard basis then non-diagonal entries become 0 and we
219047
+ * have one 1 and two -1s on the diagonal.
219048
+ * If rotation is around an axis other than standard basis, then the axis is the eigenvector
219049
+ * of the rotation matrix with eigenvalue = 1.
219050
+ */
218946
219051
  const axx = this.coffs[0];
218947
219052
  const ayy = this.coffs[4];
218948
219053
  const azz = this.coffs[8];
218949
- const theta180 = _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createDegrees(180);
218950
- // Look for principal axis flips as a special case . ..
219054
+ // Look for a pair of "-1" entries on the diagonal (for rotation around the basis X,Y,Z axis)
218951
219055
  if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1.0, ayy) && _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1, azz)) {
218952
- // rotate around
218953
- return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(1, 0, 0), angle: theta180, ok: true };
219056
+ return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(1, 0, 0), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createDegrees(180), ok: true };
218954
219057
  }
218955
219058
  else if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1.0, axx) && _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1, azz)) {
218956
- return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 1, 0), angle: theta180, ok: true };
219059
+ return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 1, 0), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createDegrees(180), ok: true };
218957
219060
  }
218958
219061
  else if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1.0, axx) && _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1, ayy)) {
218959
- return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: theta180, ok: true };
219062
+ return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createDegrees(180), ok: true };
218960
219063
  }
218961
- // 180 degree flip around some other axis ...
218962
- // eigenvalues will have 1.0 once, -1.0 twice.
218963
- // These cases look for each place (x,y,z) that the 1.0 might appear.
218964
- // But fastSymmetricEigenvalues reliably always seems to put the 1.0 as the x eigenvalue.
218965
- // so only the getColumn(0) return seems reachable in unit tests.
219064
+ // Look for eigenvector with eigenvalue = 1
218966
219065
  const eigenvectors = Matrix3d.createIdentity();
218967
219066
  const eigenvalues = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 0);
218968
219067
  if (this.fastSymmetricEigenvalues(eigenvectors, eigenvalues)) {
218969
219068
  for (let axisIndex = 0; axisIndex < 2; axisIndex++) {
218970
219069
  const lambda = eigenvalues.at(axisIndex);
218971
219070
  if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(1, lambda))
218972
- return { axis: eigenvectors.getColumn(axisIndex), angle: theta180, ok: true };
219071
+ return { axis: eigenvectors.getColumn(axisIndex), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createDegrees(180), ok: true };
218973
219072
  }
218974
- // Don't know if this can be reached ....
219073
+ // if no eigenvalue = 1 was found return false
218975
219074
  return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(0), ok: false };
218976
219075
  }
219076
+ // if no axis was found return false
218977
219077
  return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(0), ok: false };
218978
219078
  }
219079
+ // good matrix and non-zero sine
218979
219080
  const a = 1.0 / (2.0 * s);
218980
- const result = { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(skewYZ * a, skewZX * a, skewXY * a), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createAtan2(s, c), ok: true };
218981
- return result;
218982
- }
218983
- /**
218984
- * Returns a matrix that rotates from vectorA to vectorB.
218985
- */
218986
- static createRotationVectorToVector(vectorA, vectorB, result) {
218987
- return this.createPartialRotationVectorToVector(vectorA, 1.0, vectorB, result);
218988
- }
218989
- /**
218990
- * Return a matrix that rotates a fraction of the angular sweep from vectorA to vectorB.
218991
- * @param vectorA initial vector position
218992
- * @param fraction fractional rotation. 1.0 is "all the way"
218993
- * @param vectorB final vector position
218994
- * @param result optional result matrix.
218995
- */
218996
- static createPartialRotationVectorToVector(vectorA, fraction, vectorB, result) {
218997
- let upVector = vectorA.unitCrossProduct(vectorB);
218998
- if (upVector) { // the usual case --
218999
- return Matrix3d.createRotationAroundVector(upVector, _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(fraction * vectorA.planarAngleTo(vectorB, upVector).radians));
219000
- }
219001
- // fail if either vector is zero ...
219002
- if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(vectorA.magnitude())
219003
- || _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(vectorB.magnitude()))
219004
- return undefined;
219005
- // nonzero but aligned vectors ...
219006
- if (vectorA.dotProduct(vectorB) > 0.0)
219007
- return Matrix3d.createIdentity(result);
219008
- // nonzero opposing vectors ..
219009
- upVector = Matrix3d.createPerpendicularVectorFavorPlaneContainingZ(vectorA, upVector);
219010
- return Matrix3d.createRotationAroundVector(upVector, _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(fraction * Math.PI));
219011
- }
219012
- /** Create a 90 degree rotation around a principal axis */
219013
- static create90DegreeRotationAroundAxis(axisIndex) {
219014
- axisIndex = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.cyclic3dAxis(axisIndex);
219015
- if (axisIndex === 0) {
219016
- const retVal = Matrix3d.createRowValues(1, 0, 0, 0, 0, -1, 0, 1, 0);
219017
- retVal.setupInverseTranspose();
219018
- return retVal;
219019
- }
219020
- else if (axisIndex === 1) {
219021
- const retVal = Matrix3d.createRowValues(0, 0, 1, 0, 1, 0, -1, 0, 0);
219022
- retVal.setupInverseTranspose();
219023
- return retVal;
219024
- }
219025
- else {
219026
- const retVal = Matrix3d.createRowValues(0, -1, 0, 1, 0, 0, 0, 0, 1);
219027
- retVal.setupInverseTranspose();
219028
- return retVal;
219029
- }
219030
- }
219031
- /** Return (a copy of) the X column */
219032
- columnX(result) { return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[0], this.coffs[3], this.coffs[6], result); }
219033
- /** Return (a copy of)the Y column */
219034
- columnY(result) { return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[1], this.coffs[4], this.coffs[7], result); }
219035
- /** Return (a copy of)the Z column */
219036
- columnZ(result) { return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[2], this.coffs[5], this.coffs[8], result); }
219037
- /** Return the X column magnitude squared */
219038
- columnXMagnitudeSquared() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[0], this.coffs[3], this.coffs[6]); }
219039
- /** Return the Y column magnitude squared */
219040
- columnYMagnitudeSquared() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[1], this.coffs[4], this.coffs[7]); }
219041
- /** Return the Z column magnitude squared */
219042
- columnZMagnitudeSquared() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[2], this.coffs[5], this.coffs[8]); }
219043
- /** Return the X column magnitude */
219044
- columnXMagnitude() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[0], this.coffs[3], this.coffs[6]); }
219045
- /** Return the Y column magnitude */
219046
- columnYMagnitude() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[1], this.coffs[4], this.coffs[7]); }
219047
- /** Return the Z column magnitude */
219048
- columnZMagnitude() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[2], this.coffs[5], this.coffs[8]); }
219049
- /** Return magnitude of columnX cross columnY. */
219050
- columnXYCrossProductMagnitude() {
219051
- return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.crossProductMagnitude(this.coffs[0], this.coffs[3], this.coffs[6], this.coffs[1], this.coffs[4], this.coffs[7]);
219052
- }
219053
- /** Return the X row magnitude d */
219054
- rowXMagnitude() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[0], this.coffs[1], this.coffs[2]); }
219055
- /** Return the Y row magnitude */
219056
- rowYMagnitude() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[3], this.coffs[4], this.coffs[5]); }
219057
- /** Return the Z row magnitude */
219058
- rowZMagnitude() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[6], this.coffs[7], this.coffs[8]); }
219059
- /** Return the dot product of column X with column Y */
219060
- /** Return the dot product of column X with column Y */
219061
- columnXDotColumnY() {
219062
- return this.coffs[0] * this.coffs[1]
219063
- + this.coffs[3] * this.coffs[4]
219064
- + this.coffs[6] * this.coffs[7];
219065
- }
219066
- /**
219067
- * Dot product of an indexed column with a vector given as x,y,z
219068
- * @param columnIndex index of column. Must be 0,1,2
219069
- * @param x x component of vector
219070
- * @param y y component of vector
219071
- * @param z z component of vector
219072
- */
219073
- columnDotXYZ(columnIndex, x, y, z) {
219074
- return this.coffs[columnIndex] * x + this.coffs[columnIndex + 3] * y + this.coffs[columnIndex + 6] * z;
219075
- }
219076
- /** Return (a copy of) the X row */
219077
- rowX(result) { return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[0], this.coffs[1], this.coffs[2], result); }
219078
- /** Return (a copy of) the Y row */
219079
- rowY(result) { return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[3], this.coffs[4], this.coffs[5], result); }
219080
- /** Return (a copy of) the Z row */
219081
- rowZ(result) { return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[6], this.coffs[7], this.coffs[8], result); }
219082
- /** Return the dot product of the vector parameter with the X column. */
219083
- dotColumnX(vector) { return vector.x * this.coffs[0] + vector.y * this.coffs[3] + vector.z * this.coffs[6]; }
219084
- /** Return the dot product of the vector parameter with the Y column. */
219085
- dotColumnY(vector) { return vector.x * this.coffs[1] + vector.y * this.coffs[4] + vector.z * this.coffs[7]; }
219086
- /** Return the dot product of the vector parameter with the Z column. */
219087
- dotColumnZ(vector) { return vector.x * this.coffs[2] + vector.y * this.coffs[5] + vector.z * this.coffs[8]; }
219088
- /** Return the dot product of the vector parameter with the X row. */
219089
- dotRowX(vector) { return vector.x * this.coffs[0] + vector.y * this.coffs[1] + vector.z * this.coffs[2]; }
219090
- /** Return the dot product of the vector parameter with the Y row. */
219091
- dotRowY(vector) { return vector.x * this.coffs[3] + vector.y * this.coffs[4] + vector.z * this.coffs[5]; }
219092
- /** Return the dot product of the vector parameter with the Z row. */
219093
- dotRowZ(vector) { return vector.x * this.coffs[6] + vector.y * this.coffs[7] + vector.z * this.coffs[8]; }
219094
- // cSpell:words XXYZ YXYZ ZXYZ XYZAs Eigen
219095
- /** Return the dot product of the x,y,z with the X row. */
219096
- dotRowXXYZ(x, y, z) { return x * this.coffs[0] + y * this.coffs[1] + z * this.coffs[2]; }
219097
- /** Return the dot product of the x,y,z with the Y row. */
219098
- dotRowYXYZ(x, y, z) { return x * this.coffs[3] + y * this.coffs[4] + z * this.coffs[5]; }
219099
- /** Return the dot product of the x,y,z with the Z row. */
219100
- dotRowZXYZ(x, y, z) { return x * this.coffs[6] + y * this.coffs[7] + z * this.coffs[8]; }
219101
- /** Return the (vector) cross product of the Z column with the vector parameter. */
219102
- columnZCrossVector(vector, result) {
219103
- return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.crossProductXYZXYZ(this.coffs[2], this.coffs[5], this.coffs[8], vector.x, vector.y, vector.z, result);
219104
- }
219105
- /*
219106
- * Replace current rows Ui Uj with (c*Ui - s*Uj) and (c*Uj + s*Ui).
219107
- * @param i first row index. must be 0,1,2 (unchecked)
219108
- * @param j second row index. must be 0,1,2 (unchecked)
219109
- * @param c fist coefficient
219110
- * @param s second coefficient
219111
- */
219112
- applyGivensRowOp(i, j, c, s) {
219113
- let ii = 3 * i;
219114
- let jj = 3 * j;
219115
- const limit = ii + 3;
219116
- for (; ii < limit; ii++, jj++) {
219117
- const a = this.coffs[ii];
219118
- const b = this.coffs[jj];
219119
- this.coffs[ii] = a * c + b * s;
219120
- this.coffs[jj] = -a * s + b * c;
219121
- }
219122
- }
219123
- /**
219124
- * create a rigid coordinate frame column z parallel to (_x_,_y_,_z_) and column x in the xy plane.
219125
- * * column z points from origin to x,y,z
219126
- * * column x is perpendicular and in the xy plane
219127
- * * column y is perpendicular to both. It is the "up" vector on the view plane.
219128
- * * Multiplying a world vector times the transpose of this matrix transforms into the view xy
219129
- * * Multiplying the matrix times the an in-view vector transforms the vector to world.
219130
- * @param x eye x coordinate
219131
- * @param y eye y coordinate
219132
- * @param z eye z coordinate
219133
- * @param result
219134
- */
219135
- static createRigidViewAxesZTowardsEye(x, y, z, result) {
219136
- result = Matrix3d.createIdentity(result);
219137
- const rxy = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXY(x, y);
219138
- if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(rxy)) {
219139
- // special case for top or bottom view.
219140
- if (z < 0.0)
219141
- result.scaleColumnsInPlace(1.0, -1, -1.0);
219142
- }
219143
- else {
219144
- // const d = Geometry.hypotenuseSquaredXYZ(x, y, z);
219145
- const c = x / rxy;
219146
- const s = y / rxy;
219147
- result.setRowValues(-s, 0, c, c, 0, s, 0, 1, 0);
219148
- if (z !== 0.0) {
219149
- const r = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(x, y, z);
219150
- const s1 = z / r;
219151
- const c1 = rxy / r;
219152
- result.applyGivensColumnOp(1, 2, c1, -s1);
219153
- }
219154
- }
219081
+ const result = {
219082
+ axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(skewYZ * a, skewZX * a, skewXY * a),
219083
+ angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createAtan2(s, c),
219084
+ ok: true,
219085
+ };
219155
219086
  return result;
219156
219087
  }
219157
219088
  /** Rotate so columns i and j become perpendicular */
@@ -219183,8 +219114,7 @@ class Matrix3d {
219183
219114
  factorPerpendicularColumns(matrixC, matrixU) {
219184
219115
  matrixC.setFrom(this);
219185
219116
  matrixU.setIdentity();
219186
- const ss = this.sumSquares();
219187
- const tolerance = 1.0e-12 * ss;
219117
+ const tolerance = 1.0e-12 * this.sumSquares();
219188
219118
  for (let iteration = 0; iteration < 7; iteration++) {
219189
219119
  const sum = matrixC.applyJacobiColumnRotation(0, 1, matrixU)
219190
219120
  + matrixC.applyJacobiColumnRotation(0, 2, matrixU)
@@ -219275,8 +219205,7 @@ class Matrix3d {
219275
219205
  matrix.coffs[3] = matrix.coffs[1];
219276
219206
  matrix.coffs[6] = matrix.coffs[2];
219277
219207
  matrix.coffs[7] = matrix.coffs[5];
219278
- const ss = this.sumSquares();
219279
- const tolerance = 1.0e-12 * ss;
219208
+ const tolerance = 1.0e-12 * this.sumSquares();
219280
219209
  for (let iteration = 0; iteration < 7; iteration++) {
219281
219210
  const sum = leftEigenvectors.applySymmetricJacobi(0, 1, matrix)
219282
219211
  + leftEigenvectors.applySymmetricJacobi(0, 2, matrix)
@@ -219291,68 +219220,174 @@ class Matrix3d {
219291
219220
  }
219292
219221
  return false;
219293
219222
  }
219294
- /** Apply (in place a jacobi update that zeros out this.at(i,j).
219295
- *
219223
+ /**
219224
+ * Return a matrix that rotates a fraction of the angular sweep from vectorA to vectorB.
219225
+ * @param vectorA initial vector position
219226
+ * @param fraction fractional rotation (1 means rotate all the way)
219227
+ * @param vectorB final vector position
219228
+ * @param result optional result matrix.
219296
219229
  */
219297
- applyFastSymmetricJacobiUpdate(i, // row index of zeroed member
219298
- j, // column index of zeroed member
219299
- k, // other row/column index (different from i and j)
219300
- leftEigenVectors) {
219301
- const indexII = 4 * i;
219302
- const indexJJ = 4 * j;
219303
- const indexIJ = 3 * i + j;
219304
- const indexIK = 3 * i + k;
219305
- const indexJK = 3 * j + k;
219306
- const dotUU = this.coffs[indexII];
219307
- const dotVV = this.coffs[indexJJ];
219308
- const dotUV = this.coffs[indexIJ];
219309
- const jacobi = _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.trigValuesToHalfAngleTrigValues(dotUU - dotVV, 2.0 * dotUV);
219310
- if (Math.abs(dotUV) < 1.0e-15 * (dotUU + dotVV))
219311
- return 0.0;
219312
- const c = jacobi.c;
219313
- const s = jacobi.s;
219314
- const cc = c * c;
219315
- const ss = s * s;
219316
- const sc2 = 2.0 * c * s;
219317
- this.coffs[indexII] = cc * dotUU + sc2 * dotUV + ss * dotVV;
219318
- this.coffs[indexJJ] = ss * dotUU - sc2 * dotUV + cc * dotVV;
219319
- this.coffs[indexIJ] = 0.0;
219320
- const a = this.coffs[indexIK];
219321
- const b = this.coffs[indexJK];
219322
- this.coffs[indexIK] = a * c + b * s;
219323
- this.coffs[indexJK] = -s * a + c * b;
219324
- this.coffs[3 * j + i] = 0.0;
219325
- this.coffs[3 * k + i] = this.coffs[indexIK];
219326
- this.coffs[3 * k + j] = this.coffs[indexJK];
219327
- leftEigenVectors.applyGivensColumnOp(i, j, c, s);
219328
- return Math.abs(dotUV);
219230
+ static createPartialRotationVectorToVector(vectorA, fraction, vectorB, result) {
219231
+ let upVector = vectorA.unitCrossProduct(vectorB);
219232
+ // the usual case (both vectors and also their cross product is non-zero)
219233
+ if (upVector) {
219234
+ return Matrix3d.createRotationAroundVector(upVector, _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(fraction * vectorA.planarAngleTo(vectorB, upVector).radians));
219235
+ }
219236
+ // if either vector is zero
219237
+ if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(vectorA.magnitude())
219238
+ || _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(vectorB.magnitude()))
219239
+ return undefined;
219240
+ // aligned vectors (cross product = 0, dot product > 0)
219241
+ if (vectorA.dotProduct(vectorB) > 0.0)
219242
+ return Matrix3d.createIdentity(result);
219243
+ // opposing vectors (cross product = 0, dot product < 0)
219244
+ upVector = Matrix3d.createPerpendicularVectorFavorPlaneContainingZ(vectorA, upVector);
219245
+ return Matrix3d.createRotationAroundVector(upVector, _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(fraction * Math.PI));
219246
+ }
219247
+ /** Returns a matrix that rotates from vectorA to vectorB. */
219248
+ static createRotationVectorToVector(vectorA, vectorB, result) {
219249
+ return this.createPartialRotationVectorToVector(vectorA, 1.0, vectorB, result);
219250
+ }
219251
+ /** Create a 90 degree rotation around a principal axis */
219252
+ static create90DegreeRotationAroundAxis(axisIndex) {
219253
+ axisIndex = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.cyclic3dAxis(axisIndex);
219254
+ if (axisIndex === 0) {
219255
+ const retVal = Matrix3d.createRowValues(1, 0, 0, 0, 0, -1, 0, 1, 0);
219256
+ retVal.setupInverseTranspose();
219257
+ return retVal;
219258
+ }
219259
+ else if (axisIndex === 1) {
219260
+ const retVal = Matrix3d.createRowValues(0, 0, 1, 0, 1, 0, -1, 0, 0);
219261
+ retVal.setupInverseTranspose();
219262
+ return retVal;
219263
+ }
219264
+ else {
219265
+ const retVal = Matrix3d.createRowValues(0, -1, 0, 1, 0, 0, 0, 0, 1);
219266
+ retVal.setupInverseTranspose();
219267
+ return retVal;
219268
+ }
219269
+ }
219270
+ /** Return (a copy of) the X column */
219271
+ columnX(result) {
219272
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[0], this.coffs[3], this.coffs[6], result);
219273
+ }
219274
+ /** Return (a copy of) the Y column */
219275
+ columnY(result) {
219276
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[1], this.coffs[4], this.coffs[7], result);
219277
+ }
219278
+ /** Return (a copy of) the Z column */
219279
+ columnZ(result) {
219280
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[2], this.coffs[5], this.coffs[8], result);
219281
+ }
219282
+ /** Return the X column magnitude squared */
219283
+ columnXMagnitudeSquared() {
219284
+ return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[0], this.coffs[3], this.coffs[6]);
219285
+ }
219286
+ /** Return the Y column magnitude squared */
219287
+ columnYMagnitudeSquared() {
219288
+ return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[1], this.coffs[4], this.coffs[7]);
219289
+ }
219290
+ /** Return the Z column magnitude squared */
219291
+ columnZMagnitudeSquared() {
219292
+ return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[2], this.coffs[5], this.coffs[8]);
219293
+ }
219294
+ /** Return the X column magnitude */
219295
+ columnXMagnitude() {
219296
+ return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[0], this.coffs[3], this.coffs[6]);
219297
+ }
219298
+ /** Return the Y column magnitude */
219299
+ columnYMagnitude() {
219300
+ return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[1], this.coffs[4], this.coffs[7]);
219301
+ }
219302
+ /** Return the Z column magnitude */
219303
+ columnZMagnitude() {
219304
+ return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[2], this.coffs[5], this.coffs[8]);
219305
+ }
219306
+ /** Return magnitude of columnX cross columnY. */
219307
+ columnXYCrossProductMagnitude() {
219308
+ return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.crossProductMagnitude(this.coffs[0], this.coffs[3], this.coffs[6], this.coffs[1], this.coffs[4], this.coffs[7]);
219309
+ }
219310
+ /** Return the X row magnitude */
219311
+ rowXMagnitude() {
219312
+ return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[0], this.coffs[1], this.coffs[2]);
219313
+ }
219314
+ /** Return the Y row magnitude */
219315
+ rowYMagnitude() {
219316
+ return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[3], this.coffs[4], this.coffs[5]);
219317
+ }
219318
+ /** Return the Z row magnitude */
219319
+ rowZMagnitude() {
219320
+ return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[6], this.coffs[7], this.coffs[8]);
219321
+ }
219322
+ /** Return the dot product of column X with column Y */
219323
+ columnXDotColumnY() {
219324
+ return this.coffs[0] * this.coffs[1]
219325
+ + this.coffs[3] * this.coffs[4]
219326
+ + this.coffs[6] * this.coffs[7];
219329
219327
  }
219330
219328
  /**
219331
- * Factor this (symmetrized) as a product U * lambda * UT where U is orthogonal, lambda is diagonal.
219332
- * The upper triangle is mirrored to lower triangle to enforce symmetry.
219333
- * @param matrixC (allocate by caller, computed here)
219334
- * @param factor (allocate by caller, computed here)
219329
+ * Dot product of an indexed column with a vector given as x,y,z
219330
+ * @param columnIndex index of column. Must be 0,1,2.
219331
+ * @param x x component of vector
219332
+ * @param y y component of vector
219333
+ * @param z z component of vector
219335
219334
  */
219336
- fastSymmetricEigenvalues(leftEigenvectors, lambda) {
219337
- const matrix = this.clone();
219338
- leftEigenvectors.setIdentity();
219339
- const ss = this.sumSquares();
219340
- const tolerance = 1.0e-12 * ss;
219341
- for (let iteration = 0; iteration < 7; iteration++) {
219342
- const sum = matrix.applyFastSymmetricJacobiUpdate(0, 1, 2, leftEigenvectors)
219343
- + matrix.applyFastSymmetricJacobiUpdate(0, 2, 1, leftEigenvectors)
219344
- + matrix.applyFastSymmetricJacobiUpdate(1, 2, 0, leftEigenvectors);
219345
- // console.log("symmetric sum", sum);
219346
- // console.log (" sum", sum);
219347
- if (sum < tolerance) {
219348
- // console.log("symmetric iterations", iteration);
219349
- lambda.set(matrix.at(0, 0), matrix.at(1, 1), matrix.at(2, 2));
219350
- return true;
219351
- }
219352
- }
219353
- return false;
219335
+ columnDotXYZ(columnIndex, x, y, z) {
219336
+ return this.coffs[columnIndex] * x + this.coffs[columnIndex + 3] * y + this.coffs[columnIndex + 6] * z;
219337
+ }
219338
+ /** Return (a copy of) the X row */
219339
+ rowX(result) {
219340
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[0], this.coffs[1], this.coffs[2], result);
219341
+ }
219342
+ /** Return (a copy of) the Y row */
219343
+ rowY(result) {
219344
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[3], this.coffs[4], this.coffs[5], result);
219345
+ }
219346
+ /** Return (a copy of) the Z row */
219347
+ rowZ(result) {
219348
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[6], this.coffs[7], this.coffs[8], result);
219354
219349
  }
219355
- /** Install data from xyz parts of Point4d (w part of Point4d ignored) */
219350
+ /** Return the dot product of the vector parameter with the X column. */
219351
+ dotColumnX(vector) {
219352
+ return vector.x * this.coffs[0] + vector.y * this.coffs[3] + vector.z * this.coffs[6];
219353
+ }
219354
+ /** Return the dot product of the vector parameter with the Y column. */
219355
+ dotColumnY(vector) {
219356
+ return vector.x * this.coffs[1] + vector.y * this.coffs[4] + vector.z * this.coffs[7];
219357
+ }
219358
+ /** Return the dot product of the vector parameter with the Z column. */
219359
+ dotColumnZ(vector) {
219360
+ return vector.x * this.coffs[2] + vector.y * this.coffs[5] + vector.z * this.coffs[8];
219361
+ }
219362
+ /** Return the dot product of the vector parameter with the X row. */
219363
+ dotRowX(vector) {
219364
+ return vector.x * this.coffs[0] + vector.y * this.coffs[1] + vector.z * this.coffs[2];
219365
+ }
219366
+ /** Return the dot product of the vector parameter with the Y row. */
219367
+ dotRowY(vector) {
219368
+ return vector.x * this.coffs[3] + vector.y * this.coffs[4] + vector.z * this.coffs[5];
219369
+ }
219370
+ /** Return the dot product of the vector parameter with the Z row. */
219371
+ dotRowZ(vector) {
219372
+ return vector.x * this.coffs[6] + vector.y * this.coffs[7] + vector.z * this.coffs[8];
219373
+ }
219374
+ /** Return the dot product of the x,y,z with the X row. */
219375
+ dotRowXXYZ(x, y, z) {
219376
+ return x * this.coffs[0] + y * this.coffs[1] + z * this.coffs[2];
219377
+ }
219378
+ /** Return the dot product of the x,y,z with the Y row. */
219379
+ dotRowYXYZ(x, y, z) {
219380
+ return x * this.coffs[3] + y * this.coffs[4] + z * this.coffs[5];
219381
+ }
219382
+ /** Return the dot product of the x,y,z with the Z row. */
219383
+ dotRowZXYZ(x, y, z) {
219384
+ return x * this.coffs[6] + y * this.coffs[7] + z * this.coffs[8];
219385
+ }
219386
+ /** Return the cross product of the Z column with the vector parameter. */
219387
+ columnZCrossVector(vector, result) {
219388
+ return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.crossProductXYZXYZ(this.coffs[2], this.coffs[5], this.coffs[8], vector.x, vector.y, vector.z, result);
219389
+ }
219390
+ /** Set data from xyz parts of Point4d (w part of Point4d ignored) */
219356
219391
  setColumnsPoint4dXYZ(vectorU, vectorV, vectorW) {
219357
219392
  this.inverseState = InverseMatrixState.unknown;
219358
219393
  this.setRowValues(vectorU.x, vectorV.x, vectorW.x, vectorU.y, vectorV.y, vectorW.y, vectorU.z, vectorV.z, vectorW.z);
@@ -219376,16 +219411,22 @@ class Matrix3d {
219376
219411
  this.coffs[index + 6] = 0.0;
219377
219412
  }
219378
219413
  }
219379
- /** Set all columns of the matrix. Any undefined vector is zeros. */
219414
+ /**
219415
+ * Set all columns of the matrix. Any undefined vector is zeros.
219416
+ * @param vectorX values for column 0
219417
+ * @param vectorY values for column 1
219418
+ * @param vectorZ optional values for column 2 (it's optional in case column 2 is 000, which is a
219419
+ * projection onto the xy-plane)
219420
+ */
219380
219421
  setColumns(vectorX, vectorY, vectorZ) {
219381
219422
  this.setColumn(0, vectorX);
219382
219423
  this.setColumn(1, vectorY);
219383
219424
  this.setColumn(2, vectorZ);
219384
219425
  }
219385
219426
  /**
219386
- * set entries in one row of the matrix.
219387
- * @param rowIndex row index. this is interpreted cyclically.
219388
- * @param value x,yz, values for row. If undefined, zeros are installed.
219427
+ * Set entries in one row of the matrix.
219428
+ * @param rowIndex row index. This is interpreted cyclically (using Geometry.cyclic3dAxis).
219429
+ * @param value x,y,z values for row.
219389
219430
  */
219390
219431
  setRow(rowIndex, value) {
219391
219432
  const index = 3 * _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.cyclic3dAxis(rowIndex);
@@ -219394,21 +219435,26 @@ class Matrix3d {
219394
219435
  this.coffs[index + 2] = value.z;
219395
219436
  this.inverseState = InverseMatrixState.unknown;
219396
219437
  }
219397
- /** Return a (copy of) a column of the matrix.
219398
- * @param i column index. This is corrected to 012 by Geometry.cyclic3dAxis.
219438
+ /**
219439
+ * Return (a copy of) a column of the matrix.
219440
+ * @param i column index. This is interpreted cyclically (using Geometry.cyclic3dAxis).
219441
+ * @param result optional preallocated result.
219399
219442
  */
219400
219443
  getColumn(columnIndex, result) {
219401
219444
  const index = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.cyclic3dAxis(columnIndex);
219402
219445
  return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[index], this.coffs[index + 3], this.coffs[index + 6], result);
219403
219446
  }
219404
- /** Return a (copy of) a row of the matrix.
219405
- * @param i row index. This is corrected to 012 by Geometry.cyclic3dAxis.
219447
+ /**
219448
+ * Return a (copy of) a row of the matrix.
219449
+ * @param i row index. This is interpreted cyclically (using Geometry.cyclic3dAxis).
219450
+ * @param result optional preallocated result.
219406
219451
  */
219407
219452
  getRow(columnIndex, result) {
219408
219453
  const index = 3 * _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.cyclic3dAxis(columnIndex);
219409
219454
  return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[index], this.coffs[index + 1], this.coffs[index + 2], result);
219410
219455
  }
219411
- /** Create a matrix from row vectors.
219456
+ /**
219457
+ * Create a matrix from row vectors.
219412
219458
  * ```
219413
219459
  * equation
219414
219460
  * \begin{bmatrix}U_x & U_y & U_z \\ V_x & V_y & V_z \\ W_x & W_y & W_z \end{bmatrix}
@@ -219417,13 +219463,18 @@ class Matrix3d {
219417
219463
  static createRows(vectorU, vectorV, vectorW, result) {
219418
219464
  return Matrix3d.createRowValues(vectorU.x, vectorU.y, vectorU.z, vectorV.x, vectorV.y, vectorV.z, vectorW.x, vectorW.y, vectorW.z, result);
219419
219465
  }
219420
- /** Create a matrix that scales along a specified direction.
219421
- * * The scale factor can be negative.
219422
- * * A scale of -1.0 (negative one) is a mirror across the plane perpendicular to the vector.
219466
+ /**
219467
+ * Create a matrix that scales along a specified `direction`. This means if you multiply the returned matrix
219468
+ * by a `vector`, you get `directional scale` of that `vector`. Suppose `plane` is the plane perpendicular
219469
+ * to the `direction`. When scale = 0, `directional scale` is projection of the `vector` to the `plane`.
219470
+ * When scale = 1, `directional scale` is the `vector` itself. When scale = -1, `directional scale` is
219471
+ * mirror of the `vector` across the `plane`. In general, When scale != 0, the result is computed by first
219472
+ * projecting the `vector` to the `plane`, then translating that projection along the `direction` (if scale > 0)
219473
+ * or in opposite direction (if scale < 0).
219423
219474
  * ```
219424
219475
  * equation
219425
- * \text{The matrix is } I - (s-1) U U^T
219426
- * \\ \text{with }U\text{ being the unit vector in the direction of the input vector.}
219476
+ * \text{The matrix is } I + (s-1) D D^T
219477
+ * \\ \text{with }D\text{ being the normalized direction vector and }s\text{ being the scale.}
219427
219478
  * ```
219428
219479
  */
219429
219480
  static createDirectionalScale(direction, scale, result) {
@@ -219432,19 +219483,13 @@ class Matrix3d {
219432
219483
  const x = unit.x;
219433
219484
  const y = unit.y;
219434
219485
  const z = unit.z;
219435
- const a = (scale - 1);
219486
+ const a = scale - 1;
219436
219487
  return Matrix3d.createRowValues(1 + a * x * x, a * x * y, a * x * z, a * y * x, 1 + a * y * y, a * y * z, a * z * x, a * z * y, 1 + a * z * z, result);
219437
219488
  }
219438
219489
  return Matrix3d.createUniformScale(scale);
219439
219490
  }
219440
- /* Create a matrix with the indicated column in the (normalized) direction, and the other two columns perpendicular. All columns are normalized.
219441
- * * The direction vector is normalized and appears in column axisIndex
219442
- * * If the direction vector is not close to Z, the "next" column ((axisIndex + 1) mod 3) will be in the XY plane in the direction of (direction cross Z)
219443
- * * If the direction vector is close to Z, the "next" column ((axisIndex + 1) mode 3) will be in the direction of (direction cross Y)
219444
- */
219445
- // static create1Vector(direction: Vector3d, axisIndex: number): Matrix3d;
219446
- // static createFromXYVectors(vectorX: Vector3d, vectorY: Vector3d, axisIndex: number): Matrix3d;
219447
- /** Multiply the matrix * vector, treating the vector is a column vector on the right.
219491
+ /**
219492
+ * Multiply `matrix * vector`, treating the vector is a column vector on the right.
219448
219493
  * ```
219449
219494
  * equation
219450
219495
  * \matrixXY{A}\columnSubXYZ{U}
@@ -219455,36 +219500,38 @@ class Matrix3d {
219455
219500
  const x = vectorU.x;
219456
219501
  const y = vectorU.y;
219457
219502
  const z = vectorU.z;
219458
- 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);
219503
+ 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);
219459
219504
  }
219460
- /** Multiply matrix * vector for each array member, i.e. the vector is a column vector on the right.
219461
- * @return the vector result
219505
+ /**
219506
+ * Multiply `matrix * vector` in place for vector in the array, i.e. treating the vector is a column
219507
+ * vector on the right.
219508
+ * * Each `vector` is updated to be `matrix * vector`
219462
219509
  */
219463
219510
  multiplyVectorArrayInPlace(data) {
219464
219511
  for (const v of data)
219465
- v.set((this.coffs[0] * v.x + this.coffs[1] * v.y + this.coffs[2] * v.z), (this.coffs[3] * v.x + this.coffs[4] * v.y + this.coffs[5] * v.z), (this.coffs[6] * v.x + this.coffs[7] * v.y + this.coffs[8] * v.z));
219512
+ v.set(this.coffs[0] * v.x + this.coffs[1] * v.y + this.coffs[2] * v.z, this.coffs[3] * v.x + this.coffs[4] * v.y + this.coffs[5] * v.z, this.coffs[6] * v.x + this.coffs[7] * v.y + this.coffs[8] * v.z);
219466
219513
  }
219467
- /** compute `origin - matrix * vector` */
219514
+ /** Compute `origin - matrix * vector` */
219468
219515
  static xyzMinusMatrixTimesXYZ(origin, matrix, vector, result) {
219469
219516
  const x = vector.x;
219470
219517
  const y = vector.y;
219471
219518
  const z = vector.z;
219472
219519
  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);
219473
219520
  }
219474
- /** compute `origin + matrix * vector` using only the xy parts of the inputs. */
219521
+ /** Compute `origin + matrix * vector` using only the xy parts of the inputs. */
219475
219522
  static xyPlusMatrixTimesXY(origin, matrix, vector, result) {
219476
219523
  const x = vector.x;
219477
219524
  const y = vector.y;
219478
219525
  return _Point2dVector2d__WEBPACK_IMPORTED_MODULE_3__.Point2d.create(origin.x + matrix.coffs[0] * x + matrix.coffs[1] * y, origin.y + matrix.coffs[3] * x + matrix.coffs[4] * y, result);
219479
219526
  }
219480
- /** compute `origin + matrix * vector` using all xyz parts of the inputs. */
219527
+ /** Compute `origin + matrix * vector` using all xyz parts of the inputs. */
219481
219528
  static xyzPlusMatrixTimesXYZ(origin, matrix, vector, result) {
219482
219529
  const x = vector.x;
219483
219530
  const y = vector.y;
219484
219531
  const z = vector.z;
219485
219532
  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);
219486
219533
  }
219487
- /** compute `origin + matrix * vector` using all xyz parts of the inputs. */
219534
+ /** Updates vector to be `origin + matrix * vector` using all xyz parts of the inputs. */
219488
219535
  static xyzPlusMatrixTimesXYZInPlace(origin, matrix, vector) {
219489
219536
  const x = vector.x;
219490
219537
  const y = vector.y;
@@ -219493,61 +219540,72 @@ class Matrix3d {
219493
219540
  vector.y = origin.y + matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z;
219494
219541
  vector.z = origin.z + matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z;
219495
219542
  }
219496
- /** compute `origin + matrix * vector` where the final vector is given as direct x,y,z coordinates */
219543
+ /** Compute `origin + matrix * vector` where the final vector is given as direct x,y,z coordinates */
219497
219544
  static xyzPlusMatrixTimesCoordinates(origin, matrix, x, y, z, result) {
219498
219545
  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);
219499
219546
  }
219500
219547
  /**
219501
219548
  * Treat the 3x3 matrix and origin as upper 3x4 part of a 4x4 matrix, with 0001 as the final row.
219502
- * Multiply times point with coordinates `[x,y,z,w]`
219549
+ * Multiply the 4x4 matrix by `[x,y,z,w]`
219550
+ * ```
219551
+ * equation
219552
+ * \begin{bmatrix}M_0 & M_1 & M_2 & Ox \\ M_3 & M_4 & M_5 & Oy \\ M_6 & M_7 & M_8 & Oz \\ 0 & 0 & 0 & 1\end{bmatrix} * \begin{bmatrix}x \\ y \\ z \\ w\end{bmatrix}
219553
+ * ```
219503
219554
  * @param origin translation part (xyz in column 3)
219504
219555
  * @param matrix matrix part (leading 3x3)
219505
219556
  * @param x x part of multiplied point
219506
219557
  * @param y y part of multiplied point
219507
219558
  * @param z z part of multiplied point
219508
219559
  * @param w w part of multiplied point
219509
- * @param result optional result.
219560
+ * @param result optional preallocated result.
219510
219561
  */
219511
219562
  static xyzPlusMatrixTimesWeightedCoordinates(origin, matrix, x, y, z, w, result) {
219512
- return _geometry4d_Point4d__WEBPACK_IMPORTED_MODULE_4__.Point4d.create(w * origin.x + matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z, w * origin.y + matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z, w * origin.z + matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z, w, result);
219563
+ return _geometry4d_Point4d__WEBPACK_IMPORTED_MODULE_4__.Point4d.create(matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z + origin.x * w, matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z + origin.y * w, matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z + origin.z * w, w, result);
219513
219564
  }
219514
219565
  /**
219515
219566
  * Treat the 3x3 matrix and origin as upper 3x4 part of a 4x4 matrix, with 0001 as the final row.
219516
- * Multiply times point with coordinates `[x,y,z,w]`
219567
+ * Multiply the 4x4 matrix by `[x,y,z,w]`
219568
+ * ```
219569
+ * equation
219570
+ * \begin{bmatrix}M_0 & M_1 & M_2 & Ox \\ M_3 & M_4 & M_5 & Oy \\ M_6 & M_7 & M_8 & Oz \\ 0 & 0 & 0 & 1\end{bmatrix} * \begin{bmatrix}x \\ y \\ z \\ w\end{bmatrix}
219571
+ * ```
219517
219572
  * @param origin translation part (xyz in column 3)
219518
219573
  * @param matrix matrix part (leading 3x3)
219519
219574
  * @param x x part of multiplied point
219520
219575
  * @param y y part of multiplied point
219521
219576
  * @param z z part of multiplied point
219522
219577
  * @param w w part of multiplied point
219523
- * @param result optional result.
219578
+ * @param result optional preallocated result.
219524
219579
  */
219525
219580
  static xyzPlusMatrixTimesWeightedCoordinatesToFloat64Array(origin, matrix, x, y, z, w, result) {
219526
219581
  if (!result)
219527
219582
  result = new Float64Array(4);
219528
- result[0] = w * origin.x + matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z;
219529
- result[1] = w * origin.y + matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z;
219530
- result[2] = w * origin.z + matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z;
219583
+ result[0] = matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z + origin.x * w;
219584
+ result[1] = matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z + origin.y * w;
219585
+ result[2] = matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z + origin.z * w;
219531
219586
  result[3] = w;
219532
219587
  return result;
219533
219588
  }
219534
219589
  /**
219535
- * Treat the 3x3 matrix and origin as upper 3x4 part of a 4x4 matrix, with 0001 as the final row.
219536
- * Multiply times point with coordinates `[x,y,z,w]`
219590
+ * Treat the 3x3 matrix and origin as a 3x4 matrix.
219591
+ * * Multiply the 3x4 matrix by `[x,y,z,1]`
219592
+ * ```
219593
+ * equation
219594
+ * \begin{bmatrix}M_0 & M_1 & M_2 & Ox \\ M_3 & M_4 & M_5 & Oy \\ M_6 & M_7 & M_8 & Oz\end{bmatrix} * \begin{bmatrix}x \\ y \\ z \\ 1\end{bmatrix}
219595
+ * ```
219537
219596
  * @param origin translation part (xyz in column 3)
219538
219597
  * @param matrix matrix part (leading 3x3)
219539
219598
  * @param x x part of multiplied point
219540
219599
  * @param y y part of multiplied point
219541
219600
  * @param z z part of multiplied point
219542
- * @param w w part of multiplied point
219543
- * @param result optional result.
219601
+ * @param result optional preallocated result.
219544
219602
  */
219545
219603
  static xyzPlusMatrixTimesCoordinatesToFloat64Array(origin, matrix, x, y, z, result) {
219546
219604
  if (!result)
219547
219605
  result = new Float64Array(3);
219548
- result[0] = origin.x + matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z;
219549
- result[1] = origin.y + matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z;
219550
- result[2] = origin.z + matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z;
219606
+ result[0] = matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z + origin.x;
219607
+ result[1] = matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z + origin.y;
219608
+ result[2] = matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z + origin.z;
219551
219609
  return result;
219552
219610
  }
219553
219611
  /**
@@ -219567,9 +219625,9 @@ class Matrix3d {
219567
219625
  const x = vector.x;
219568
219626
  const y = vector.y;
219569
219627
  const z = vector.z;
219570
- result.x = (this.coffs[0] * x + this.coffs[3] * y + this.coffs[6] * z);
219571
- result.y = (this.coffs[1] * x + this.coffs[4] * y + this.coffs[7] * z);
219572
- result.z = (this.coffs[2] * x + this.coffs[5] * y + this.coffs[8] * z);
219628
+ result.x = this.coffs[0] * x + this.coffs[3] * y + this.coffs[6] * z;
219629
+ result.y = this.coffs[1] * x + this.coffs[4] * y + this.coffs[7] * z;
219630
+ result.z = this.coffs[2] * x + this.coffs[5] * y + this.coffs[8] * z;
219573
219631
  return result;
219574
219632
  }
219575
219633
  /** Multiply the matrix * (x,y,z), i.e. the vector (x,y,z) is a column vector on the right.
@@ -220097,7 +220155,7 @@ class Matrix3d {
220097
220155
  * @param scaleX scale factor for column x
220098
220156
  * @param scaleY scale factor for column y
220099
220157
  * @param scaleZ scale factor for column z
220100
- * @param result optional result.
220158
+ * @param result optional preallocated result.
220101
220159
  */
220102
220160
  scaleColumns(scaleX, scaleY, scaleZ, result) {
220103
220161
  return Matrix3d.createRowValues(this.coffs[0] * scaleX, this.coffs[1] * scaleY, this.coffs[2] * scaleZ, this.coffs[3] * scaleX, this.coffs[4] * scaleY, this.coffs[5] * scaleZ, this.coffs[6] * scaleX, this.coffs[7] * scaleY, this.coffs[8] * scaleZ, result);
@@ -220118,7 +220176,7 @@ class Matrix3d {
220118
220176
  this.coffs[7] *= scaleY;
220119
220177
  this.coffs[8] *= scaleZ;
220120
220178
  if (this.inverseState === InverseMatrixState.inverseStored && this.inverseCoffs !== undefined) {
220121
- // apply reciprocal scales to the ROWS of the inverse . . .
220179
+ // apply reverse scales to the ROWS of the inverse
220122
220180
  const divX = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.conditionalDivideFraction(1.0, scaleX);
220123
220181
  const divY = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.conditionalDivideFraction(1.0, scaleY);
220124
220182
  const divZ = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.conditionalDivideFraction(1.0, scaleZ);
@@ -220141,7 +220199,7 @@ class Matrix3d {
220141
220199
  * @param scaleX scale factor for row x
220142
220200
  * @param scaleY scale factor for row y
220143
220201
  * @param scaleZ scale factor for row z
220144
- * @param result optional result.
220202
+ * @param result optional preallocated result.
220145
220203
  */
220146
220204
  scaleRows(scaleX, scaleY, scaleZ, result) {
220147
220205
  return Matrix3d.createRowValues(this.coffs[0] * scaleX, this.coffs[1] * scaleX, this.coffs[2] * scaleX, this.coffs[3] * scaleY, this.coffs[4] * scaleY, this.coffs[5] * scaleY, this.coffs[6] * scaleZ, this.coffs[7] * scaleZ, this.coffs[8] * scaleZ, result);
@@ -220185,12 +220243,49 @@ class Matrix3d {
220185
220243
  }
220186
220244
  /** create a Matrix3d whose values are uniformly scaled from this.
220187
220245
  * @param scale scale factor to apply.
220188
- * @param result optional result.
220246
+ * @param result optional preallocated result.
220189
220247
  * @returns Return the new or repopulated matrix
220190
220248
  */
220191
220249
  scale(scale, result) {
220192
220250
  return Matrix3d.createRowValues(this.coffs[0] * scale, this.coffs[1] * scale, this.coffs[2] * scale, this.coffs[3] * scale, this.coffs[4] * scale, this.coffs[5] * scale, this.coffs[6] * scale, this.coffs[7] * scale, this.coffs[8] * scale, result);
220193
220251
  }
220252
+ /**
220253
+ * Create a rigid matrix (columns and rows are unit length and pairwise perpendicular) for
220254
+ * the given eye coordinate.
220255
+ * * column z is parallel to x,y,z
220256
+ * * column x is perpendicular to column z and is in the xy plane
220257
+ * * column y is perpendicular to both. It is the "up" vector on the view plane.
220258
+ * * Multiplying the returned matrix times a local (view) vector gives the world vector.
220259
+ * * Multiplying transpose of the returned matrix times a world vector gives the local
220260
+ * (view) vector.
220261
+ * @param x eye x coordinate
220262
+ * @param y eye y coordinate
220263
+ * @param z eye z coordinate
220264
+ * @param result optional preallocated result
220265
+ */
220266
+ static createRigidViewAxesZTowardsEye(x, y, z, result) {
220267
+ result = Matrix3d.createIdentity(result);
220268
+ const rxy = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXY(x, y);
220269
+ // if coordinate is (0,0,z), i.e., Top or Bottom view
220270
+ if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(rxy)) {
220271
+ if (z < 0.0)
220272
+ result.scaleColumnsInPlace(1.0, -1.0, -1.0);
220273
+ }
220274
+ else {
220275
+ const c = x / rxy;
220276
+ const s = y / rxy;
220277
+ // if coordinate is (x,y,0), i.e., Front or Back or Left or Right view
220278
+ result.setRowValues(-s, 0, c, c, 0, s, 0, 1, 0);
220279
+ // if coordinate is (x,y,z), i.e., other views such as Iso or RightIso
220280
+ if (z !== 0.0) {
220281
+ const r = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(x, y, z);
220282
+ const s1 = z / r;
220283
+ const c1 = rxy / r;
220284
+ result.applyGivensColumnOp(1, 2, c1, -s1);
220285
+ }
220286
+ }
220287
+ return result;
220288
+ }
220194
220289
  /** Return the determinant of this matrix. */
220195
220290
  determinant() {
220196
220291
  return this.coffs[0] * this.coffs[4] * this.coffs[8]
@@ -222356,9 +222451,12 @@ __webpack_require__.r(__webpack_exports__);
222356
222451
  * @module CartesianGeometry
222357
222452
  */
222358
222453
  // cspell:word CWXY
222454
+ // cspell:word arctan
222455
+ // cspell:word Rodrigues
222359
222456
 
222360
222457
 
222361
222458
 
222459
+ // cspell:word CCWXY
222362
222460
  /**
222363
222461
  * * `XYZ` is a minimal object containing x,y,z and operations that are meaningful without change in both point and vector.
222364
222462
  * * `XYZ` is not instantiable.
@@ -223195,7 +223293,7 @@ class Vector3d extends XYZ {
223195
223293
  return { v: this.safeDivideOrNull(magnitude, result), mag: magnitude };
223196
223294
  }
223197
223295
  /**
223198
- * Return a unit vector parallel with this. Return undefined if this.magnitude is near zero.
223296
+ * Return a unit vector parallel with this. Return undefined if this.magnitude is near zero.
223199
223297
  * @param result optional result.
223200
223298
  */
223201
223299
  normalize(result) {
@@ -223701,18 +223799,17 @@ class Vector3d extends XYZ {
223701
223799
  else
223702
223800
  return theta;
223703
223801
  }
223704
- /**
223705
- * Return the (strongly typed Angle) angle from this vector to vectorB, measured in the plane containing both,
223706
- * with vectorW indicating which side to view to control sign of the angle.
223707
- * * The returned angle can range from negative 180 degrees (negative PI radians) to positive 180 degrees
223708
- * * (positive PI radians), not closed on the negative side.
223709
- * * The returned angle is "in the plane containing the two vectors"
223710
- * * `vectorW` distinguishes between the sides of the plane, but does not have to be perpendicular.
223711
- * * The returned angle has the same sign as vectorW dot product (thisVector cross vectorB)
223712
- * * Use planarRadiansTo to measure the angle between vectors that are projected to another plane.
223713
- * @param vectorB target vector.
223714
- * @param vectorW distinguishes between the sides of the plane.
223715
- */
223802
+ /** Return the (strongly typed Angle) angle from this vector to vectorB, measured in the plane containing both,
223803
+ * with vectorW indicating which side to view to control sign of the angle.
223804
+ * * The returned angle can range from negative 180 degrees (negative PI radians) to positive 180 degrees
223805
+ * * (positive PI radians), not closed on the negative side.
223806
+ * * The returned angle is "in the plane containing the two vectors"
223807
+ * * `vectorW` distinguishes between the sides of the plane, but does not have to be perpendicular.
223808
+ * * The returned angle has the same sign as vectorW dot product (thisVector cross vectorB)
223809
+ * * Use planarRadiansTo to measure the angle between vectors that are projected to another plane.
223810
+ * @param vectorB target vector.
223811
+ * @param vectorW distinguishes between the sides of the plane.
223812
+ */
223716
223813
  signedAngleTo(vectorB, vectorW) {
223717
223814
  return _Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createRadians(this.signedRadiansTo(vectorB, vectorW));
223718
223815
  }
@@ -228635,7 +228732,7 @@ class Segment1d {
228635
228732
  */
228636
228733
  reverseInPlace() { const x = this.x0; this.x0 = this.x1; this.x1 = x; }
228637
228734
  /**
228638
- * * if `x1<x0` multiplied by the scale factor is (strictly) negative, swap the x0 and x1 member values.
228735
+ * * if `x1-x0` multiplied by the scale factor is (strictly) negative, swap the x0 and x1 member values.
228639
228736
  * * This makes the fractionToPoint evaluates reverse direction.
228640
228737
  */
228641
228738
  reverseIfNeededForDeltaSign(sign = 1) {
@@ -236449,6 +236546,20 @@ class SmallSystem {
236449
236546
  }
236450
236547
  return undefined;
236451
236548
  }
236549
+ /**
236550
+ * Compute the intersection of three planes.
236551
+ * @param xyzA point on the first plane
236552
+ * @param normalA normal of the first plane
236553
+ * @param xyzB point on the second plane
236554
+ * @param normalB normal of the second plane
236555
+ * @param xyzC point on the third plane
236556
+ * @param normalC normal of the third plane
236557
+ * @param result optional result
236558
+ * @returns intersection point of the three planes (as a Vector3d), or undefined if at least two planes are parallel.
236559
+ */
236560
+ static intersect3Planes(xyzA, normalA, xyzB, normalB, xyzC, normalC, result) {
236561
+ return this.linearSystem3d(normalA.x, normalA.y, normalA.z, normalB.x, normalB.y, normalB.z, normalC.x, normalC.y, normalC.z, _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.dotProductXYZXYZ(xyzA.x, xyzA.y, xyzA.z, normalA.x, normalA.y, normalA.z), _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.dotProductXYZXYZ(xyzB.x, xyzB.y, xyzB.z, normalB.x, normalB.y, normalB.z), _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.dotProductXYZXYZ(xyzC.x, xyzC.y, xyzC.z, normalC.x, normalC.y, normalC.z), result);
236562
+ }
236452
236563
  /**
236453
236564
  * * in rowB, replace `rowB[j] += a * rowB[pivot] * rowA[j] / rowA[pivot]` for `j>pivot`
236454
236565
  * @param rowA row that does not change
@@ -240560,10 +240671,29 @@ class PolyfaceBuilder extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
240560
240671
  if (sector.uv)
240561
240672
  sector.uvIndex = this._polyface.addParam(sector.uv);
240562
240673
  }
240674
+ addSectorTriangle(sectorA0, sectorA1, sectorA2) {
240675
+ if (sectorA0.xyz.isAlmostEqual(sectorA1.xyz)
240676
+ || sectorA1.xyz.isAlmostEqual(sectorA2.xyz)
240677
+ || sectorA2.xyz.isAlmostEqual(sectorA0.xyz)) {
240678
+ // trivially degenerate triangle !!! skip !!!
240679
+ }
240680
+ else {
240681
+ if (this._options.needNormals)
240682
+ this.addIndexedTriangleNormalIndexes(sectorA0.normalIndex, sectorA1.normalIndex, sectorA2.normalIndex);
240683
+ if (this._options.needParams)
240684
+ this.addIndexedTriangleParamIndexes(sectorA0.uvIndex, sectorA1.uvIndex, sectorA2.uvIndex);
240685
+ this.addIndexedTrianglePointIndexes(sectorA0.xyzIndex, sectorA1.xyzIndex, sectorA2.xyzIndex);
240686
+ this._polyface.terminateFacet();
240687
+ }
240688
+ }
240563
240689
  addSectorQuadA01B01(sectorA0, sectorA1, sectorB0, sectorB1) {
240564
240690
  if (sectorA0.xyz.isAlmostEqual(sectorA1.xyz) && sectorB0.xyz.isAlmostEqual(sectorB1.xyz)) {
240565
240691
  // ignore null quad !!
240566
240692
  }
240693
+ else if (this._options.shouldTriangulate) {
240694
+ this.addSectorTriangle(sectorA0, sectorA1, sectorB1);
240695
+ this.addSectorTriangle(sectorB1, sectorB0, sectorA0);
240696
+ }
240567
240697
  else {
240568
240698
  if (this._options.needNormals)
240569
240699
  this.addIndexedQuadNormalIndexes(sectorA0.normalIndex, sectorA1.normalIndex, sectorB0.normalIndex, sectorB1.normalIndex);
@@ -240640,12 +240770,30 @@ class PolyfaceBuilder extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
240640
240770
  }
240641
240771
  const numPoints = pointA.length;
240642
240772
  for (let i = 1; i < numPoints; i++) {
240643
- if (pointA.atUncheckedIndex(i - 1) !== pointA.atUncheckedIndex(i) || pointB.atUncheckedIndex(i - 1) !== pointB.atUncheckedIndex(i)) {
240644
- this.addIndexedQuadPointIndexes(pointA.atUncheckedIndex(i - 1), pointA.atUncheckedIndex(i), pointB.atUncheckedIndex(i - 1), pointB.atUncheckedIndex(i));
240645
- if (normalA && normalB)
240646
- this.addIndexedQuadNormalIndexes(normalA.atUncheckedIndex(i - 1), normalA.atUncheckedIndex(i), normalB.atUncheckedIndex(i - 1), normalB.atUncheckedIndex(i));
240647
- if (paramA && paramB)
240648
- this.addIndexedQuadParamIndexes(paramA.atUncheckedIndex(i - 1), paramA.atUncheckedIndex(i), paramB.atUncheckedIndex(i - 1), paramB.atUncheckedIndex(i));
240773
+ if (this.options.shouldTriangulate) {
240774
+ if (distinctIndices(pointA.atUncheckedIndex(i - 1), pointA.atUncheckedIndex(i), pointB.atUncheckedIndex(i))) {
240775
+ this.addIndexedTrianglePointIndexes(pointA.atUncheckedIndex(i - 1), pointA.atUncheckedIndex(i), pointB.atUncheckedIndex(i));
240776
+ if (normalA && normalB)
240777
+ this.addIndexedTriangleNormalIndexes(normalA.atUncheckedIndex(i - 1), normalA.atUncheckedIndex(i), normalB.atUncheckedIndex(i - 1));
240778
+ if (paramA && paramB)
240779
+ this.addIndexedTriangleParamIndexes(paramA.atUncheckedIndex(i - 1), paramA.atUncheckedIndex(i), paramB.atUncheckedIndex(i - 1));
240780
+ }
240781
+ if (distinctIndices(pointB.atUncheckedIndex(i), pointB.atUncheckedIndex(i - 1), pointA.atUncheckedIndex(i - 1))) {
240782
+ this.addIndexedTrianglePointIndexes(pointA.atUncheckedIndex(i - 1), pointB.atUncheckedIndex(i), pointB.atUncheckedIndex(i - 1));
240783
+ if (normalA && normalB)
240784
+ this.addIndexedTriangleNormalIndexes(normalA.atUncheckedIndex(i - 1), normalB.atUncheckedIndex(i), normalB.atUncheckedIndex(i - 1));
240785
+ if (paramA && paramB)
240786
+ this.addIndexedTriangleParamIndexes(paramA.atUncheckedIndex(i - 1), paramB.atUncheckedIndex(i), paramB.atUncheckedIndex(i - 1));
240787
+ }
240788
+ }
240789
+ else {
240790
+ if (pointA.atUncheckedIndex(i - 1) !== pointA.atUncheckedIndex(i) || pointB.atUncheckedIndex(i - 1) !== pointB.atUncheckedIndex(i)) {
240791
+ this.addIndexedQuadPointIndexes(pointA.atUncheckedIndex(i - 1), pointA.atUncheckedIndex(i), pointB.atUncheckedIndex(i - 1), pointB.atUncheckedIndex(i));
240792
+ if (normalA && normalB)
240793
+ this.addIndexedQuadNormalIndexes(normalA.atUncheckedIndex(i - 1), normalA.atUncheckedIndex(i), normalB.atUncheckedIndex(i - 1), normalB.atUncheckedIndex(i));
240794
+ if (paramA && paramB)
240795
+ this.addIndexedQuadParamIndexes(paramA.atUncheckedIndex(i - 1), paramA.atUncheckedIndex(i), paramB.atUncheckedIndex(i - 1), paramB.atUncheckedIndex(i));
240796
+ }
240649
240797
  this._polyface.terminateFacet();
240650
240798
  }
240651
240799
  }
@@ -241642,6 +241790,9 @@ function resolveToIndexedXYZCollectionOrCarrier(points) {
241642
241790
  return points.packedPoints;
241643
241791
  return points;
241644
241792
  }
241793
+ function distinctIndices(i0, i1, i2) {
241794
+ return i0 !== i1 && i1 !== i2 && i2 !== i0;
241795
+ }
241645
241796
 
241646
241797
 
241647
241798
  /***/ }),
@@ -242810,38 +242961,41 @@ function compressUnusedGrowableXYZArray(data: GrowableXYZArray, indices: number[
242810
242961
  __webpack_require__.r(__webpack_exports__);
242811
242962
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
242812
242963
  /* harmony export */ "DuplicateFacetClusterSelector": () => (/* binding */ DuplicateFacetClusterSelector),
242964
+ /* harmony export */ "OffsetMeshOptions": () => (/* binding */ OffsetMeshOptions),
242813
242965
  /* harmony export */ "PolyfaceQuery": () => (/* binding */ PolyfaceQuery)
242814
242966
  /* harmony export */ });
242815
242967
  /* harmony import */ var _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../geometry3d/PointHelpers */ "../../core/geometry/lib/esm/geometry3d/PointHelpers.js");
242816
- /* harmony import */ var _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../curve/CurveCollection */ "../../core/geometry/lib/esm/curve/CurveCollection.js");
242968
+ /* harmony import */ var _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../curve/CurveCollection */ "../../core/geometry/lib/esm/curve/CurveCollection.js");
242817
242969
  /* harmony import */ var _curve_internalContexts_MultiChainCollector__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../curve/internalContexts/MultiChainCollector */ "../../core/geometry/lib/esm/curve/internalContexts/MultiChainCollector.js");
242818
- /* harmony import */ var _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../curve/LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
242819
- /* harmony import */ var _curve_LineString3d__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../curve/LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
242820
- /* harmony import */ var _curve_Loop__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../curve/Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
242970
+ /* harmony import */ var _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../curve/LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
242971
+ /* harmony import */ var _curve_LineString3d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../curve/LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
242972
+ /* harmony import */ var _curve_Loop__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../curve/Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
242821
242973
  /* harmony import */ var _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../curve/StrokeOptions */ "../../core/geometry/lib/esm/curve/StrokeOptions.js");
242822
- /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
242823
- /* harmony import */ var _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../geometry3d/Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
242974
+ /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
242975
+ /* harmony import */ var _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../geometry3d/Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
242824
242976
  /* harmony import */ var _geometry3d_FrameBuilder__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../geometry3d/FrameBuilder */ "../../core/geometry/lib/esm/geometry3d/FrameBuilder.js");
242825
- /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
242826
- /* harmony import */ var _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../geometry3d/PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
242977
+ /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
242978
+ /* harmony import */ var _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../geometry3d/PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
242827
242979
  /* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
242828
- /* harmony import */ var _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../geometry4d/Matrix4d */ "../../core/geometry/lib/esm/geometry4d/Matrix4d.js");
242829
- /* harmony import */ var _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../geometry4d/MomentData */ "../../core/geometry/lib/esm/geometry4d/MomentData.js");
242830
- /* harmony import */ var _numerics_UnionFind__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../numerics/UnionFind */ "../../core/geometry/lib/esm/numerics/UnionFind.js");
242980
+ /* harmony import */ var _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../geometry4d/Matrix4d */ "../../core/geometry/lib/esm/geometry4d/Matrix4d.js");
242981
+ /* harmony import */ var _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../geometry4d/MomentData */ "../../core/geometry/lib/esm/geometry4d/MomentData.js");
242982
+ /* harmony import */ var _numerics_UnionFind__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../numerics/UnionFind */ "../../core/geometry/lib/esm/numerics/UnionFind.js");
242831
242983
  /* harmony import */ var _topology_ChainMerge__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../topology/ChainMerge */ "../../core/geometry/lib/esm/topology/ChainMerge.js");
242832
242984
  /* harmony import */ var _topology_Graph__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../topology/Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
242833
242985
  /* harmony import */ var _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../topology/HalfEdgeGraphSearch */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphSearch.js");
242834
242986
  /* harmony import */ var _topology_Merging__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../topology/Merging */ "../../core/geometry/lib/esm/topology/Merging.js");
242835
- /* harmony import */ var _FacetOrientation__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./FacetOrientation */ "../../core/geometry/lib/esm/polyface/FacetOrientation.js");
242836
- /* harmony import */ var _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./IndexedEdgeMatcher */ "../../core/geometry/lib/esm/polyface/IndexedEdgeMatcher.js");
242987
+ /* harmony import */ var _FacetOrientation__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./FacetOrientation */ "../../core/geometry/lib/esm/polyface/FacetOrientation.js");
242988
+ /* harmony import */ var _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./IndexedEdgeMatcher */ "../../core/geometry/lib/esm/polyface/IndexedEdgeMatcher.js");
242837
242989
  /* harmony import */ var _IndexedPolyfaceVisitor__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./IndexedPolyfaceVisitor */ "../../core/geometry/lib/esm/polyface/IndexedPolyfaceVisitor.js");
242838
- /* harmony import */ var _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./multiclip/BuildAverageNormalsContext */ "../../core/geometry/lib/esm/polyface/multiclip/BuildAverageNormalsContext.js");
242839
- /* harmony import */ var _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./multiclip/SweepLineStringToFacetContext */ "../../core/geometry/lib/esm/polyface/multiclip/SweepLineStringToFacetContext.js");
242990
+ /* harmony import */ var _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./multiclip/BuildAverageNormalsContext */ "../../core/geometry/lib/esm/polyface/multiclip/BuildAverageNormalsContext.js");
242991
+ /* harmony import */ var _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./multiclip/SweepLineStringToFacetContext */ "../../core/geometry/lib/esm/polyface/multiclip/SweepLineStringToFacetContext.js");
242840
242992
  /* harmony import */ var _multiclip_XYPointBuckets__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./multiclip/XYPointBuckets */ "../../core/geometry/lib/esm/polyface/multiclip/XYPointBuckets.js");
242841
- /* harmony import */ var _Polyface__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Polyface */ "../../core/geometry/lib/esm/polyface/Polyface.js");
242993
+ /* harmony import */ var _Polyface__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Polyface */ "../../core/geometry/lib/esm/polyface/Polyface.js");
242842
242994
  /* harmony import */ var _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./PolyfaceBuilder */ "../../core/geometry/lib/esm/polyface/PolyfaceBuilder.js");
242843
242995
  /* harmony import */ var _RangeLengthData__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./RangeLengthData */ "../../core/geometry/lib/esm/polyface/RangeLengthData.js");
242844
242996
  /* harmony import */ var _topology_SpaceTriangulation__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../topology/SpaceTriangulation */ "../../core/geometry/lib/esm/topology/SpaceTriangulation.js");
242997
+ /* harmony import */ var _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../topology/HalfEdgeGraphFromIndexedLoopsContext */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js");
242998
+ /* harmony import */ var _multiclip_OffsetMeshContext__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./multiclip/OffsetMeshContext */ "../../core/geometry/lib/esm/polyface/multiclip/OffsetMeshContext.js");
242845
242999
  /*---------------------------------------------------------------------------------------------
242846
243000
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
242847
243001
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -242881,6 +243035,41 @@ __webpack_require__.r(__webpack_exports__);
242881
243035
 
242882
243036
 
242883
243037
 
243038
+
243039
+
243040
+ /**
243041
+ * Options carrier for [[PolyfaceQuery.cloneOffset]].
243042
+ * * Default options are strongly recommended.
243043
+ * * The option most likely to be changed is chamferTurnAngle
243044
+ * @public
243045
+ */
243046
+ class OffsetMeshOptions {
243047
+ /** Constructor -- CAPTURE parameters ... */
243048
+ constructor(smoothSingleAngleBetweenNormals = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(25), smoothAccumulatedAngleBetweenNormals = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(60), chamferTurnAngle = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(90)) {
243049
+ this.smoothSingleAngleBetweenNormals = smoothSingleAngleBetweenNormals.clone();
243050
+ this.smoothAccumulatedAngleBetweenNormals = smoothAccumulatedAngleBetweenNormals.clone();
243051
+ this.chamferAngleBetweenNormals = chamferTurnAngle.clone();
243052
+ }
243053
+ /** construct and return an OffsetMeshOptions with given parameters.
243054
+ * * Angles are forced to minimum values.
243055
+ * * Clones of the angles are given to the constructor.
243056
+ * @param smoothSingleRadiansBetweenNormals an angle larger than this (between facets) is considered a sharp edge
243057
+ * @param smoothAccumulatedAngleBetweenNormals angles that sum to this much may be consolidated for average normal
243058
+ * @param chamferTurnAngleBetweenNormals when facets meet with larger angle, a chamfer edge may be added if the angle between facet normals is larger than this.
243059
+ */
243060
+ static create(smoothSingleAngleBetweenNormals = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(25), smoothAccumulatedAngleBetweenNormals = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(60), chamferTurnAngleBetweenNormals = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(120)) {
243061
+ const mySmoothSingleRadiansBetweenNormals = smoothSingleAngleBetweenNormals.clone();
243062
+ const mySmoothAccumulatedRadiansBetweenNormals = smoothAccumulatedAngleBetweenNormals.clone();
243063
+ const myChamferTurnAngleBetweenNormals = chamferTurnAngleBetweenNormals.clone();
243064
+ if (mySmoothSingleRadiansBetweenNormals.degrees < 1)
243065
+ mySmoothAccumulatedRadiansBetweenNormals.setDegrees(1.0);
243066
+ if (mySmoothAccumulatedRadiansBetweenNormals.degrees < 1.0)
243067
+ mySmoothAccumulatedRadiansBetweenNormals.setDegrees(1.0);
243068
+ if (mySmoothAccumulatedRadiansBetweenNormals.degrees < 15.0)
243069
+ mySmoothAccumulatedRadiansBetweenNormals.setDegrees(15.0);
243070
+ return new OffsetMeshOptions(mySmoothSingleRadiansBetweenNormals, mySmoothAccumulatedRadiansBetweenNormals, myChamferTurnAngleBetweenNormals);
243071
+ }
243072
+ }
242884
243073
  /**
242885
243074
  * Enumeration of cases for retaining facets among duplicates
242886
243075
  * @public
@@ -242902,12 +243091,12 @@ var DuplicateFacetClusterSelector;
242902
243091
  class PolyfaceQuery {
242903
243092
  /** copy the points from a visitor into a Linestring3d in a Loop object */
242904
243093
  static visitorToLoop(visitor) {
242905
- const ls = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_0__.LineString3d.createPoints(visitor.point.getPoint3dArray());
242906
- return _curve_Loop__WEBPACK_IMPORTED_MODULE_1__.Loop.create(ls);
243094
+ const ls = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_1__.LineString3d.createPoints(visitor.point.getPoint3dArray());
243095
+ return _curve_Loop__WEBPACK_IMPORTED_MODULE_2__.Loop.create(ls);
242907
243096
  }
242908
243097
  /** Create a linestring loop for each facet of the polyface. */
242909
243098
  static indexedPolyfaceToLoops(polyface) {
242910
- const result = _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_2__.BagOfCurves.create();
243099
+ const result = _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_3__.BagOfCurves.create();
242911
243100
  const visitor = polyface.createVisitor(1);
242912
243101
  while (visitor.moveToNextFacet()) {
242913
243102
  const loop = PolyfaceQuery.visitorToLoop(visitor);
@@ -242921,17 +243110,17 @@ class PolyfaceQuery {
242921
243110
  static sumFacetAreas(source, vectorToEye) {
242922
243111
  let s = 0;
242923
243112
  if (source !== undefined) {
242924
- if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface)
243113
+ if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
242925
243114
  return PolyfaceQuery.sumFacetAreas(source.createVisitor(1), vectorToEye);
242926
243115
  let unitVectorToEye;
242927
243116
  if (vectorToEye !== undefined)
242928
243117
  unitVectorToEye = vectorToEye.normalize();
242929
243118
  source.reset();
242930
243119
  while (source.moveToNextFacet()) {
242931
- const scaledNormal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_4__.PolygonOps.areaNormal(source.point.getPoint3dArray());
243120
+ const scaledNormal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.areaNormal(source.point.getPoint3dArray());
242932
243121
  let area = scaledNormal.magnitude();
242933
243122
  if (unitVectorToEye !== undefined) {
242934
- const scale = _Geometry__WEBPACK_IMPORTED_MODULE_5__.Geometry.conditionalDivideCoordinate(1.0, area);
243123
+ const scale = _Geometry__WEBPACK_IMPORTED_MODULE_6__.Geometry.conditionalDivideCoordinate(1.0, area);
242935
243124
  if (scale !== undefined)
242936
243125
  area *= scaledNormal.dotProduct(unitVectorToEye) * scale;
242937
243126
  }
@@ -242948,12 +243137,12 @@ class PolyfaceQuery {
242948
243137
  */
242949
243138
  static sumTetrahedralVolumes(source, origin) {
242950
243139
  let s = 0;
242951
- if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface)
243140
+ if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
242952
243141
  return PolyfaceQuery.sumTetrahedralVolumes(source.createVisitor(0), origin);
242953
243142
  let myOrigin = origin;
242954
- const facetOrigin = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
242955
- const targetA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
242956
- const targetB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
243143
+ const facetOrigin = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
243144
+ const targetA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
243145
+ const targetB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
242957
243146
  source.reset();
242958
243147
  while (source.moveToNextFacet()) {
242959
243148
  if (myOrigin === undefined)
@@ -242974,20 +243163,20 @@ class PolyfaceQuery {
242974
243163
  *
242975
243164
  */
242976
243165
  static sumVolumeBetweenFacetsAndPlane(source, plane) {
242977
- if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface)
243166
+ if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
242978
243167
  return PolyfaceQuery.sumVolumeBetweenFacetsAndPlane(source.createVisitor(0), plane);
242979
- const facetOrigin = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
242980
- const targetA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
242981
- const targetB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
242982
- const triangleNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Vector3d.create();
243168
+ const facetOrigin = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
243169
+ const targetA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
243170
+ const targetB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
243171
+ const triangleNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
242983
243172
  const planeNormal = plane.getNormalRef();
242984
243173
  let h0, hA, hB;
242985
243174
  let signedVolumeSum = 0.0;
242986
243175
  let signedTriangleArea;
242987
243176
  let singleFacetArea;
242988
- const positiveAreaMomentSums = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_7__.MomentData.create(undefined, true);
242989
- const negativeAreaMomentSums = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_7__.MomentData.create(undefined, true);
242990
- const singleFacetProducts = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_8__.Matrix4d.createZero();
243177
+ const positiveAreaMomentSums = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.create(undefined, true);
243178
+ const negativeAreaMomentSums = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.create(undefined, true);
243179
+ const singleFacetProducts = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__.Matrix4d.createZero();
242991
243180
  const projectToPlane = plane.getProjectionToPlane();
242992
243181
  source.reset();
242993
243182
  // For each facet ..
@@ -243014,7 +243203,7 @@ class PolyfaceQuery {
243014
243203
  }
243015
243204
  singleFacetProducts.setZero();
243016
243205
  source.point.multiplyTransformInPlace(projectToPlane);
243017
- _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_4__.PolygonOps.addSecondMomentAreaProducts(source.point, facetOrigin, singleFacetProducts);
243206
+ _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.addSecondMomentAreaProducts(source.point, facetOrigin, singleFacetProducts);
243018
243207
  if (singleFacetArea > 0) {
243019
243208
  positiveAreaMomentSums.accumulateProductsFromOrigin(facetOrigin, singleFacetProducts, 1.0);
243020
243209
  }
@@ -243024,8 +243213,8 @@ class PolyfaceQuery {
243024
243213
  }
243025
243214
  positiveAreaMomentSums.shiftOriginAndSumsToCentroidOfSums();
243026
243215
  negativeAreaMomentSums.shiftOriginAndSumsToCentroidOfSums();
243027
- const positiveAreaMoments = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_7__.MomentData.inertiaProductsToPrincipalAxes(positiveAreaMomentSums.origin, positiveAreaMomentSums.sums);
243028
- const negativeAreaMoments = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_7__.MomentData.inertiaProductsToPrincipalAxes(negativeAreaMomentSums.origin, negativeAreaMomentSums.sums);
243216
+ const positiveAreaMoments = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.inertiaProductsToPrincipalAxes(positiveAreaMomentSums.origin, positiveAreaMomentSums.sums);
243217
+ const negativeAreaMoments = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.inertiaProductsToPrincipalAxes(negativeAreaMomentSums.origin, negativeAreaMomentSums.sums);
243029
243218
  return {
243030
243219
  volume: signedVolumeSum / 6.0,
243031
243220
  positiveProjectedFacetAreaMoments: positiveAreaMoments,
@@ -243034,23 +243223,23 @@ class PolyfaceQuery {
243034
243223
  }
243035
243224
  /** Return the inertia products [xx,xy,xz,xw, yw, etc] integrated over all all facets, as viewed from origin. */
243036
243225
  static sumFacetSecondAreaMomentProducts(source, origin) {
243037
- if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface)
243226
+ if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
243038
243227
  return PolyfaceQuery.sumFacetSecondAreaMomentProducts(source.createVisitor(0), origin);
243039
- const products = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_8__.Matrix4d.createZero();
243228
+ const products = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__.Matrix4d.createZero();
243040
243229
  source.reset();
243041
243230
  while (source.moveToNextFacet()) {
243042
- _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_4__.PolygonOps.addSecondMomentAreaProducts(source.point, origin, products);
243231
+ _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.addSecondMomentAreaProducts(source.point, origin, products);
243043
243232
  }
243044
243233
  return products;
243045
243234
  }
243046
243235
  /** Return the inertia products [xx,xy,xz,xw, yw, etc] integrated over all tetrahedral volumes from origin */
243047
243236
  static sumFacetSecondVolumeMomentProducts(source, origin) {
243048
- if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface)
243237
+ if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
243049
243238
  return PolyfaceQuery.sumFacetSecondVolumeMomentProducts(source.createVisitor(0), origin);
243050
- const products = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_8__.Matrix4d.createZero();
243239
+ const products = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__.Matrix4d.createZero();
243051
243240
  source.reset();
243052
243241
  while (source.moveToNextFacet()) {
243053
- _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_4__.PolygonOps.addSecondMomentVolumeProducts(source.point, origin, products);
243242
+ _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.addSecondMomentVolumeProducts(source.point, origin, products);
243054
243243
  }
243055
243244
  return products;
243056
243245
  }
@@ -243064,7 +243253,7 @@ class PolyfaceQuery {
243064
243253
  if (!origin)
243065
243254
  return undefined;
243066
243255
  const inertiaProducts = PolyfaceQuery.sumFacetSecondAreaMomentProducts(source, origin);
243067
- return _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_7__.MomentData.inertiaProductsToPrincipalAxes(origin, inertiaProducts);
243256
+ return _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.inertiaProductsToPrincipalAxes(origin, inertiaProducts);
243068
243257
  }
243069
243258
  /** Compute area moments for the mesh. In the returned MomentData:
243070
243259
  * * origin is the centroid.
@@ -243078,7 +243267,7 @@ class PolyfaceQuery {
243078
243267
  if (!origin)
243079
243268
  return undefined;
243080
243269
  const inertiaProducts = PolyfaceQuery.sumFacetSecondVolumeMomentProducts(source, origin);
243081
- return _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_7__.MomentData.inertiaProductsToPrincipalAxes(origin, inertiaProducts);
243270
+ return _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.inertiaProductsToPrincipalAxes(origin, inertiaProducts);
243082
243271
  }
243083
243272
  /**
243084
243273
  * Test for convex volume by dihedral angle tests on all edges.
@@ -243110,14 +243299,14 @@ class PolyfaceQuery {
243110
243299
  * * (but null edges are permitted -- These occur naturally at edges of quads at north or south pole)
243111
243300
  */
243112
243301
  static dihedralAngleSummary(source, ignoreBoundaries = false) {
243113
- const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.IndexedEdgeMatcher();
243302
+ const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
243114
243303
  const visitor = source.createVisitor(1);
243115
243304
  visitor.reset();
243116
243305
  const centroidNormal = [];
243117
243306
  let normalCounter = 0;
243118
243307
  while (visitor.moveToNextFacet()) {
243119
243308
  const numEdges = visitor.pointCount - 1;
243120
- const normal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_4__.PolygonOps.centroidAreaNormal(visitor.point);
243309
+ const normal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.centroidAreaNormal(visitor.point);
243121
243310
  if (normal === undefined)
243122
243311
  return 0;
243123
243312
  centroidNormal.push(normal);
@@ -243134,12 +243323,12 @@ class PolyfaceQuery {
243134
243323
  let numPositive = 0;
243135
243324
  let numPlanar = 0;
243136
243325
  let numNegative = 0;
243137
- const edgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Vector3d.create();
243326
+ const edgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
243138
243327
  for (const cluster of manifoldClusters) {
243139
243328
  const sideA = cluster[0];
243140
243329
  const sideB = cluster[1];
243141
- if (sideA instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.SortableEdge
243142
- && sideB instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.SortableEdge
243330
+ if (sideA instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge
243331
+ && sideB instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge
243143
243332
  && source.data.point.vectorIndexIndex(sideA.vertexIndexA, sideA.vertexIndexB, edgeVector)) {
243144
243333
  const dihedralAngle = centroidNormal[sideA.facetIndex].direction.signedAngleTo(centroidNormal[sideB.facetIndex].direction, edgeVector);
243145
243334
  if (dihedralAngle.isAlmostZero)
@@ -243172,7 +243361,7 @@ class PolyfaceQuery {
243172
243361
  * * Any edge with 2 incident facets in the same direction triggers a `false` return.
243173
243362
  */
243174
243363
  static isPolyfaceManifold(source, allowSimpleBoundaries = false) {
243175
- const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.IndexedEdgeMatcher();
243364
+ const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
243176
243365
  const visitor = source.createVisitor(1);
243177
243366
  visitor.reset();
243178
243367
  while (visitor.moveToNextFacet()) {
@@ -243195,9 +243384,9 @@ class PolyfaceQuery {
243195
243384
  * @returns
243196
243385
  */
243197
243386
  static boundaryEdges(source, includeDanglers = true, includeMismatch = true, includeNull = true) {
243198
- const result = new _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_2__.BagOfCurves();
243387
+ const result = new _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_3__.BagOfCurves();
243199
243388
  const announceEdge = (pointA, pointB, _indexA, _indexB, _readIndex) => {
243200
- result.tryAddChild(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_10__.LineSegment3d.create(pointA, pointB));
243389
+ result.tryAddChild(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(pointA, pointB));
243201
243390
  };
243202
243391
  PolyfaceQuery.announceBoundaryEdges(source, announceEdge, includeDanglers, includeMismatch, includeNull);
243203
243392
  if (result.children.length === 0)
@@ -243216,8 +243405,8 @@ class PolyfaceQuery {
243216
243405
  static announceBoundaryEdges(source, announceEdge, includeDanglers = true, includeMismatch = true, includeNull = true) {
243217
243406
  if (source === undefined)
243218
243407
  return undefined;
243219
- const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.IndexedEdgeMatcher();
243220
- const visitor = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface ? source.createVisitor(1) : source;
243408
+ const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
243409
+ const visitor = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface ? source.createVisitor(1) : source;
243221
243410
  visitor.setNumWrap(1);
243222
243411
  visitor.reset();
243223
243412
  while (visitor.moveToNextFacet()) {
@@ -243242,7 +243431,7 @@ class PolyfaceQuery {
243242
243431
  const sourcePolyface = visitor.clientPolyface();
243243
243432
  for (const list of badList) {
243244
243433
  for (const e of list) {
243245
- const e1 = e instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.SortableEdge ? e : e[0];
243434
+ const e1 = e instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge ? e : e[0];
243246
243435
  const indexA = e1.vertexIndexA;
243247
243436
  const indexB = e1.vertexIndexB;
243248
243437
  const pointA = sourcePolyface.data.getPoint(indexA);
@@ -243257,7 +243446,7 @@ class PolyfaceQuery {
243257
243446
  * * Facets are ASSUMED to be convex and planar.
243258
243447
  */
243259
243448
  static announceSweepLinestringToConvexPolyfaceXY(linestringPoints, polyface, announce) {
243260
- const context = _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_11__.SweepLineStringToFacetContext.create(linestringPoints);
243449
+ const context = _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_12__.SweepLineStringToFacetContext.create(linestringPoints);
243261
243450
  if (context) {
243262
243451
  const visitor = polyface.createVisitor(0);
243263
243452
  for (visitor.reset(); visitor.moveToNextFacet();) {
@@ -243290,7 +243479,7 @@ class PolyfaceQuery {
243290
243479
  * @internal
243291
243480
  */
243292
243481
  static async asyncAnnounceSweepLinestringToConvexPolyfaceXY(linestringPoints, polyface, announce) {
243293
- const context = _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_11__.SweepLineStringToFacetContext.create(linestringPoints);
243482
+ const context = _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_12__.SweepLineStringToFacetContext.create(linestringPoints);
243294
243483
  this.awaitBlockCount = 0;
243295
243484
  let workTotal = 0;
243296
243485
  if (context) {
@@ -243310,11 +243499,11 @@ class PolyfaceQuery {
243310
243499
  * * Return array of arrays of facet indices.
243311
243500
  */
243312
243501
  static partitionFacetIndicesByVertexConnectedComponent(polyface) {
243313
- if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface) {
243502
+ if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
243314
243503
  return this.partitionFacetIndicesByVertexConnectedComponent(polyface.createVisitor(0));
243315
243504
  }
243316
243505
  // The polyface is really a visitor !!!
243317
- const context = new _numerics_UnionFind__WEBPACK_IMPORTED_MODULE_12__.UnionFindContext(this.visitorClientPointCount(polyface));
243506
+ const context = new _numerics_UnionFind__WEBPACK_IMPORTED_MODULE_13__.UnionFindContext(this.visitorClientPointCount(polyface));
243318
243507
  for (polyface.reset(); polyface.moveToNextFacet();) {
243319
243508
  const firstVertexIndexOnThisFacet = polyface.pointIndex[0];
243320
243509
  for (const vertexIndex of polyface.pointIndex)
@@ -243347,7 +243536,7 @@ class PolyfaceQuery {
243347
243536
  * * Return array of arrays of facet indices.
243348
243537
  */
243349
243538
  static partitionFacetIndicesByVisibilityVector(polyface, vectorToEye, sideAngleTolerance) {
243350
- if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface) {
243539
+ if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
243351
243540
  return this.partitionFacetIndicesByVisibilityVector(polyface.createVisitor(0), vectorToEye, sideAngleTolerance);
243352
243541
  }
243353
243542
  const facetsInComponent = [];
@@ -243359,7 +243548,7 @@ class PolyfaceQuery {
243359
243548
  const sideComponent = facetsInComponent[2];
243360
243549
  const radiansTol = Math.max(sideAngleTolerance.radians, 1.0e-8);
243361
243550
  for (polyface.reset(); polyface.moveToNextFacet();) {
243362
- const areaNormal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_4__.PolygonOps.areaNormalGo(polyface.point);
243551
+ const areaNormal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.areaNormalGo(polyface.point);
243363
243552
  const index = polyface.currentReadIndex();
243364
243553
  if (areaNormal) {
243365
243554
  const angle = areaNormal.angleFromPerpendicular(vectorToEye);
@@ -243386,7 +243575,7 @@ class PolyfaceQuery {
243386
243575
  * @param vectorToEye
243387
243576
  * @param sideAngleTolerance
243388
243577
  */
243389
- static boundaryOfVisibleSubset(polyface, visibilitySelect, vectorToEye, sideAngleTolerance = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_13__.Angle.createDegrees(1.0e-3)) {
243578
+ static boundaryOfVisibleSubset(polyface, visibilitySelect, vectorToEye, sideAngleTolerance = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(1.0e-3)) {
243390
243579
  const partitionedIndices = this.partitionFacetIndicesByVisibilityVector(polyface, vectorToEye, sideAngleTolerance);
243391
243580
  if (partitionedIndices[visibilitySelect].length === 0)
243392
243581
  return undefined;
@@ -243400,8 +243589,8 @@ class PolyfaceQuery {
243400
243589
  * @param mesh
243401
243590
  */
243402
243591
  static announceBoundaryChainsAsLineString3d(mesh, announceLoop) {
243403
- const collector = new _curve_internalContexts_MultiChainCollector__WEBPACK_IMPORTED_MODULE_15__.MultiChainCollector(_Geometry__WEBPACK_IMPORTED_MODULE_5__.Geometry.smallMetricDistance, 1000);
243404
- PolyfaceQuery.announceBoundaryEdges(mesh, (pointA, pointB, _indexA, _indexB) => collector.captureCurve(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_10__.LineSegment3d.create(pointA, pointB)), true, false, false);
243592
+ const collector = new _curve_internalContexts_MultiChainCollector__WEBPACK_IMPORTED_MODULE_15__.MultiChainCollector(_Geometry__WEBPACK_IMPORTED_MODULE_6__.Geometry.smallMetricDistance, 1000);
243593
+ PolyfaceQuery.announceBoundaryEdges(mesh, (pointA, pointB, _indexA, _indexB) => collector.captureCurve(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(pointA, pointB)), true, false, false);
243405
243594
  collector.announceChainsAsLineString3d(announceLoop);
243406
243595
  }
243407
243596
  /**
@@ -243412,7 +243601,7 @@ class PolyfaceQuery {
243412
243601
  * @returns
243413
243602
  */
243414
243603
  static cloneWithMaximalPlanarFacets(mesh) {
243415
- if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface)
243604
+ if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
243416
243605
  return this.cloneWithMaximalPlanarFacets(mesh.createVisitor(0));
243417
243606
  const numFacets = PolyfaceQuery.visitorClientFacetCount(mesh);
243418
243607
  const smoothEdges = PolyfaceQuery.collectEdgesByDihedralAngle(mesh);
@@ -243437,7 +243626,7 @@ class PolyfaceQuery {
243437
243626
  const edges = [];
243438
243627
  const edgeStrings = [];
243439
243628
  PolyfaceQuery.announceBoundaryEdges(fragment, (pointA, pointB, _indexA, _indexB) => {
243440
- edges.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_10__.LineSegment3d.create(pointA, pointB));
243629
+ edges.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(pointA, pointB));
243441
243630
  edgeStrings.push([pointA.clone(), pointB.clone()]);
243442
243631
  });
243443
243632
  const chains = _curve_internalContexts_MultiChainCollector__WEBPACK_IMPORTED_MODULE_15__.OffsetHelpers.collectChains(edges, gapTolerance, planarityTolerance);
@@ -243478,7 +243667,7 @@ class PolyfaceQuery {
243478
243667
  * @returns
243479
243668
  */
243480
243669
  static fillSimpleHoles(mesh, options, unfilledChains) {
243481
- if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface)
243670
+ if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
243482
243671
  return this.fillSimpleHoles(mesh.createVisitor(0), options, unfilledChains);
243483
243672
  const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create();
243484
243673
  const chains = [];
@@ -243492,7 +243681,7 @@ class PolyfaceQuery {
243492
243681
  rejected = true;
243493
243682
  else if (options.maxPerimeter !== undefined && _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_21__.Point3dArray.sumEdgeLengths(points, false) > options.maxPerimeter)
243494
243683
  rejected = true;
243495
- else if (options.upVector !== undefined && _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_4__.PolygonOps.sumTriangleAreasPerpendicularToUpVector(points, options.upVector) <= 0.0)
243684
+ else if (options.upVector !== undefined && _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.sumTriangleAreasPerpendicularToUpVector(points, options.upVector) <= 0.0)
243496
243685
  rejected = true;
243497
243686
  if (!rejected && _topology_SpaceTriangulation__WEBPACK_IMPORTED_MODULE_22__.SpacePolygonTriangulation.triangulateSimplestSpaceLoop(points, (_loop, triangles) => {
243498
243687
  for (const t of triangles)
@@ -243515,7 +243704,7 @@ class PolyfaceQuery {
243515
243704
  *
243516
243705
  */
243517
243706
  static clonePartitions(polyface, partitions) {
243518
- if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface) {
243707
+ if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
243519
243708
  return this.clonePartitions(polyface.createVisitor(0), partitions);
243520
243709
  }
243521
243710
  polyface.setNumWrap(0);
@@ -243539,7 +243728,7 @@ class PolyfaceQuery {
243539
243728
  /** Clone facets that pass an filter function
243540
243729
  */
243541
243730
  static cloneFiltered(source, filter) {
243542
- if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface) {
243731
+ if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
243543
243732
  return this.cloneFiltered(source.createVisitor(0), filter);
243544
243733
  }
243545
243734
  source.setNumWrap(0);
@@ -243591,9 +243780,9 @@ class PolyfaceQuery {
243591
243780
  * @return collection of facet index arrays, one array per connected component
243592
243781
  */
243593
243782
  static partitionFacetIndicesBySortableEdgeClusters(edgeClusters, numFacets) {
243594
- const context = new _numerics_UnionFind__WEBPACK_IMPORTED_MODULE_12__.UnionFindContext(numFacets);
243783
+ const context = new _numerics_UnionFind__WEBPACK_IMPORTED_MODULE_13__.UnionFindContext(numFacets);
243595
243784
  for (const cluster of edgeClusters) {
243596
- if (cluster instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.SortableEdge) {
243785
+ if (cluster instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge) {
243597
243786
  // this edge does not connect anywhere. Ignore it!!
243598
243787
  }
243599
243788
  else {
@@ -243625,11 +243814,11 @@ class PolyfaceQuery {
243625
243814
  * @return collection of facet index arrays, one per connected component
243626
243815
  */
243627
243816
  static partitionFacetIndicesByEdgeConnectedComponent(polyface, stopAtVisibleEdges = false) {
243628
- if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface) {
243817
+ if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
243629
243818
  return this.partitionFacetIndicesByEdgeConnectedComponent(polyface.createVisitor(0), stopAtVisibleEdges);
243630
243819
  }
243631
243820
  polyface.setNumWrap(1);
243632
- const matcher = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.IndexedEdgeMatcher();
243821
+ const matcher = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
243633
243822
  polyface.reset();
243634
243823
  let numFacets = 0;
243635
243824
  while (polyface.moveToNextFacet()) {
@@ -243667,7 +243856,7 @@ class PolyfaceQuery {
243667
243856
  static sweepLinestringToFacetsXYReturnLines(linestringPoints, polyface) {
243668
243857
  const drapeGeometry = [];
243669
243858
  this.announceSweepLinestringToConvexPolyfaceXY(linestringPoints, polyface, (_linestring, _segmentIndex, _polyface, _facetIndex, points, indexA, indexB) => {
243670
- drapeGeometry.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_10__.LineSegment3d.create(points[indexA], points[indexB]));
243859
+ drapeGeometry.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(points[indexA], points[indexB]));
243671
243860
  });
243672
243861
  return drapeGeometry;
243673
243862
  }
@@ -243702,7 +243891,7 @@ class PolyfaceQuery {
243702
243891
  * * Return statistical summary of x,y,z ranges.
243703
243892
  */
243704
243893
  static collectRangeLengthData(polyface) {
243705
- if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface) {
243894
+ if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
243706
243895
  return this.collectRangeLengthData(polyface.createVisitor(0));
243707
243896
  }
243708
243897
  const rangeData = new _RangeLengthData__WEBPACK_IMPORTED_MODULE_25__.RangeLengthData();
@@ -243720,10 +243909,10 @@ class PolyfaceQuery {
243720
243909
  const rangeSearcher = _multiclip_XYPointBuckets__WEBPACK_IMPORTED_MODULE_26__.XYPointBuckets.create(polyface.data.point, 30);
243721
243910
  const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create();
243722
243911
  const edgeRange = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_27__.Range3d.createNull();
243723
- const point0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
243724
- const point1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
243725
- const spacePoint = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
243726
- const segment = _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_10__.LineSegment3d.create(point0, point1);
243912
+ const point0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
243913
+ const point1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
243914
+ const spacePoint = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
243915
+ const segment = _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(point0, point1);
243727
243916
  for (oldFacetVisitor.reset(); oldFacetVisitor.moveToNextFacet();) {
243728
243917
  newFacetVisitor.clearArrays();
243729
243918
  for (let i = 0; i + 1 < oldFacetVisitor.point.length; i++) {
@@ -243732,7 +243921,7 @@ class PolyfaceQuery {
243732
243921
  oldFacetVisitor.point.getPoint3dAtUncheckedPointIndex(i + 1, point1);
243733
243922
  newFacetVisitor.pushDataFrom(oldFacetVisitor, i);
243734
243923
  edgeRange.setNull();
243735
- _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_10__.LineSegment3d.create(point0, point1, segment);
243924
+ _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(point0, point1, segment);
243736
243925
  let detailArray;
243737
243926
  edgeRange.extend(point0);
243738
243927
  edgeRange.extend(point1);
@@ -243877,8 +244066,8 @@ class PolyfaceQuery {
243877
244066
  const oldFacetVisitor = polyface.createVisitor(2); // This is to visit the existing facets.
243878
244067
  const newFacetVisitor = polyface.createVisitor(0); // This is to build the new facets.
243879
244068
  const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create();
243880
- const vector01 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Vector3d.create();
243881
- const vector12 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Vector3d.create();
244069
+ const vector01 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
244070
+ const vector12 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
243882
244071
  const numPoint = polyface.data.point.length;
243883
244072
  const pointState = new Int32Array(numPoint);
243884
244073
  // FIRST PASS -- in each sector of each facet, determine if the sector has colinear incoming and outgoing vectors.
@@ -243925,7 +244114,7 @@ class PolyfaceQuery {
243925
244114
  */
243926
244115
  static setEdgeVisibility(polyface, clusters, value) {
243927
244116
  for (const cluster of clusters) {
243928
- if (cluster instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.SortableEdge) {
244117
+ if (cluster instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge) {
243929
244118
  this.setSingleEdgeVisibility(polyface, cluster.facetIndex, cluster.vertexIndexA, value);
243930
244119
  }
243931
244120
  else if (Array.isArray(cluster)) {
@@ -243968,9 +244157,9 @@ class PolyfaceQuery {
243968
244157
  * @param polyface a mesh, or a visitor assumed to have numWrap === 1
243969
244158
  */
243970
244159
  static createIndexedEdges(polyface) {
243971
- if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface)
244160
+ if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
243972
244161
  return this.createIndexedEdges(polyface.createVisitor(1));
243973
- const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.IndexedEdgeMatcher();
244162
+ const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
243974
244163
  polyface.reset();
243975
244164
  while (polyface.moveToNextFacet()) {
243976
244165
  const numEdges = polyface.pointCount - 1;
@@ -243989,17 +244178,17 @@ class PolyfaceQuery {
243989
244178
  * @param sharpEdges true to reverse the angle threshold test and return sharp edges; otherwise return smooth edges (default)
243990
244179
  */
243991
244180
  static collectEdgesByDihedralAngle(mesh, maxSmoothEdgeAngle, sharpEdges = false) {
243992
- if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface)
244181
+ if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
243993
244182
  return this.collectEdgesByDihedralAngle(mesh.createVisitor(1), maxSmoothEdgeAngle, sharpEdges);
243994
244183
  mesh.setNumWrap(1);
243995
244184
  const allEdges = this.createIndexedEdges(mesh);
243996
244185
  const manifoldEdges = [];
243997
244186
  allEdges.sortAndCollectClusters(manifoldEdges);
243998
244187
  if (undefined === maxSmoothEdgeAngle || maxSmoothEdgeAngle.radians < 0)
243999
- maxSmoothEdgeAngle = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_13__.Angle.createRadians(_Geometry__WEBPACK_IMPORTED_MODULE_5__.Geometry.smallAngleRadians);
244188
+ maxSmoothEdgeAngle = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createRadians(_Geometry__WEBPACK_IMPORTED_MODULE_6__.Geometry.smallAngleRadians);
244000
244189
  const outEdges = [];
244001
- const normal0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Vector3d.create();
244002
- const normal1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Vector3d.create();
244190
+ const normal0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
244191
+ const normal1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
244003
244192
  for (const pair of manifoldEdges) {
244004
244193
  if (Array.isArray(pair) && pair.length === 2) {
244005
244194
  const e0 = pair[0];
@@ -244038,8 +244227,8 @@ class PolyfaceQuery {
244038
244227
  this.markAllEdgeVisibility(mesh, false);
244039
244228
  this.setEdgeVisibility(mesh, boundaryEdges, true);
244040
244229
  if (sharpEdgeAngle !== undefined) {
244041
- const normal0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Vector3d.create();
244042
- const normal1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Vector3d.create();
244230
+ const normal0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
244231
+ const normal1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
244043
244232
  for (const pair of pairedEdges) {
244044
244233
  if (Array.isArray(pair) && pair.length === 2) {
244045
244234
  const e0 = pair[0];
@@ -244061,9 +244250,9 @@ class PolyfaceQuery {
244061
244250
  */
244062
244251
  static computeFacetUnitNormal(visitor, facetIndex, result) {
244063
244252
  if (!result)
244064
- result = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Vector3d.create();
244253
+ result = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
244065
244254
  if (visitor.moveToReadIndex(facetIndex)) {
244066
- if (_geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_4__.PolygonOps.unitNormal(visitor.point, result))
244255
+ if (_geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.unitNormal(visitor.point, result))
244067
244256
  return result;
244068
244257
  }
244069
244258
  return undefined;
@@ -244078,20 +244267,41 @@ class PolyfaceQuery {
244078
244267
  for (let i = 0; i < data.edgeVisible.length; i++)
244079
244268
  data.edgeVisible[i] = value;
244080
244269
  }
244270
+ /**
244271
+ * Create a HalfEdgeGraph with a face for each facet of the IndexedPolyface
244272
+ * @param mesh mesh to convert
244273
+ * @internal
244274
+ */
244275
+ static convertToHalfEdgeGraph(mesh) {
244276
+ const builder = new _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_28__.HalfEdgeGraphFromIndexedLoopsContext();
244277
+ const visitor = mesh.createVisitor(0);
244278
+ for (visitor.reset(); visitor.moveToNextFacet();) {
244279
+ builder.insertLoop(visitor.pointIndex);
244280
+ }
244281
+ const graph = builder.graph;
244282
+ const xyz = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
244283
+ graph.announceNodes((_graph, halfEdge) => {
244284
+ const vertexIndex = halfEdge.i;
244285
+ mesh.data.getPoint(vertexIndex, xyz);
244286
+ halfEdge.setXYZ(xyz);
244287
+ return true;
244288
+ });
244289
+ return graph;
244290
+ }
244081
244291
  /**
244082
244292
  * * Examine adjacent facet orientations throughout the mesh
244083
244293
  * * If possible, reverse a subset to achieve proper pairing.
244084
244294
  * @param mesh
244085
244295
  */
244086
244296
  static reorientVertexOrderAroundFacetsForConsistentOrientation(mesh) {
244087
- return _FacetOrientation__WEBPACK_IMPORTED_MODULE_28__.FacetOrientationFixup.doFixup(mesh);
244297
+ return _FacetOrientation__WEBPACK_IMPORTED_MODULE_29__.FacetOrientationFixup.doFixup(mesh);
244088
244298
  }
244089
244299
  /**
244090
244300
  * Set up indexed normals with one normal in the plane of each facet of the mesh.
244091
244301
  * @param polyface
244092
244302
  */
244093
244303
  static buildPerFaceNormals(polyface) {
244094
- _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_29__.BuildAverageNormalsContext.buildPerFaceNormals(polyface);
244304
+ _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_30__.BuildAverageNormalsContext.buildPerFaceNormals(polyface);
244095
244305
  }
244096
244306
  /**
244097
244307
  * * At each vertex of the mesh
@@ -244103,8 +244313,21 @@ class PolyfaceQuery {
244103
244313
  * @param polyface polyface to update.
244104
244314
  * @param toleranceAngle averaging is done between normals up to this angle.
244105
244315
  */
244106
- static buildAverageNormals(polyface, toleranceAngle = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_13__.Angle.createDegrees(31.0)) {
244107
- _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_29__.BuildAverageNormalsContext.buildFastAverageNormals(polyface, toleranceAngle);
244316
+ static buildAverageNormals(polyface, toleranceAngle = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(31.0)) {
244317
+ _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_30__.BuildAverageNormalsContext.buildFastAverageNormals(polyface, toleranceAngle);
244318
+ }
244319
+ /**
244320
+ * Offset the faces of the mesh.
244321
+ * @param source original mesh
244322
+ * @param signedOffsetDistance distance to offset
244323
+ * @param offsetOptions angle options. The default options are recommended.
244324
+ * @returns shifted mesh.
244325
+ */
244326
+ static cloneOffset(source, signedOffsetDistance, offsetOptions = OffsetMeshOptions.create()) {
244327
+ const strokeOptions = _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_23__.StrokeOptions.createForFacets();
244328
+ const offsetBuilder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create(strokeOptions);
244329
+ _multiclip_OffsetMeshContext__WEBPACK_IMPORTED_MODULE_31__.OffsetMeshContext.buildOffsetMeshWithEdgeChamfers(source, offsetBuilder, signedOffsetDistance, offsetOptions);
244330
+ return offsetBuilder.claimPolyface();
244108
244331
  }
244109
244332
  }
244110
244333
  // amount of computation to do per step of async methods.
@@ -245016,6 +245239,1064 @@ class LinearSearchRange2dArray {
245016
245239
  }
245017
245240
 
245018
245241
 
245242
+ /***/ }),
245243
+
245244
+ /***/ "../../core/geometry/lib/esm/polyface/multiclip/OffsetMeshContext.js":
245245
+ /*!***************************************************************************!*\
245246
+ !*** ../../core/geometry/lib/esm/polyface/multiclip/OffsetMeshContext.js ***!
245247
+ \***************************************************************************/
245248
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
245249
+
245250
+ "use strict";
245251
+ __webpack_require__.r(__webpack_exports__);
245252
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
245253
+ /* harmony export */ "FacetOffsetProperties": () => (/* binding */ FacetOffsetProperties),
245254
+ /* harmony export */ "OffsetMeshContext": () => (/* binding */ OffsetMeshContext),
245255
+ /* harmony export */ "SectorOffsetProperties": () => (/* binding */ SectorOffsetProperties)
245256
+ /* harmony export */ });
245257
+ /* harmony import */ var _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../numerics/Polynomials */ "../../core/geometry/lib/esm/numerics/Polynomials.js");
245258
+ /* harmony import */ var _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../geometry3d/GrowableXYZArray */ "../../core/geometry/lib/esm/geometry3d/GrowableXYZArray.js");
245259
+ /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
245260
+ /* harmony import */ var _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../geometry3d/PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
245261
+ /* harmony import */ var _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../geometry3d/Ray3d */ "../../core/geometry/lib/esm/geometry3d/Ray3d.js");
245262
+ /* harmony import */ var _topology_Graph__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../topology/Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
245263
+ /* harmony import */ var _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../topology/HalfEdgeGraphFromIndexedLoopsContext */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js");
245264
+ /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
245265
+ /* harmony import */ var _geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../geometry3d/PolylineCompressionByEdgeOffset */ "../../core/geometry/lib/esm/geometry3d/PolylineCompressionByEdgeOffset.js");
245266
+ /* harmony import */ var _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../geometry3d/Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
245267
+ /*---------------------------------------------------------------------------------------------
245268
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
245269
+ * See LICENSE.md in the project root for license terms and full copyright notice.
245270
+ *--------------------------------------------------------------------------------------------*/
245271
+ /** @packageDocumentation
245272
+ * @module Polyface
245273
+ */
245274
+
245275
+
245276
+
245277
+
245278
+
245279
+
245280
+
245281
+
245282
+
245283
+
245284
+ function isDefinedAndTrue(value) {
245285
+ if (value === undefined)
245286
+ return false;
245287
+ return value;
245288
+ }
245289
+ class AverageNormalData {
245290
+ constructor() {
245291
+ this.numActiveSectors = 0;
245292
+ this.numInactiveSectors = 0; // exterior and sling.
245293
+ this.averageNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create();
245294
+ this.radiansSum = 0.0;
245295
+ this.maxDeviationRadiansFromAverage = 0.0;
245296
+ }
245297
+ clear() {
245298
+ this.numActiveSectors = 0;
245299
+ this.numInactiveSectors = 0; // exterior and sling.
245300
+ this.averageNormal.setZero();
245301
+ this.radiansSum = 0.0;
245302
+ this.maxDeviationRadiansFromAverage = 0.0;
245303
+ }
245304
+ /** Add a normal to the evolving sum, scaled by radians in the corner */
245305
+ accumulateNormal(node, normal, inactiveMask) {
245306
+ if (node.isMaskSet(inactiveMask)) {
245307
+ this.numInactiveSectors++;
245308
+ }
245309
+ else {
245310
+ const sectorSweepRadians = _topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.sectorSweepRadiansXYZ(node, normal);
245311
+ this.averageNormal.addScaledInPlace(normal, sectorSweepRadians);
245312
+ this.radiansSum += sectorSweepRadians;
245313
+ this.numActiveSectors++;
245314
+ }
245315
+ }
245316
+ /** normalize the accumulated normals. */
245317
+ finishNormalAveraging() {
245318
+ if (this.numActiveSectors > 0 && this.averageNormal.normalizeInPlace()) {
245319
+ return true;
245320
+ }
245321
+ return false;
245322
+ }
245323
+ /** Compute the deviation from average. update max deviation member */
245324
+ recordDeviation(normal, isActive) {
245325
+ if (isActive) {
245326
+ const radians = this.averageNormal.radiansTo(normal);
245327
+ this.maxDeviationRadiansFromAverage = Math.max(Math.abs(this.maxDeviationRadiansFromAverage), radians);
245328
+ }
245329
+ else {
245330
+ }
245331
+ }
245332
+ /** Return the max deviation as computed on prior calls to recordDeviation */
245333
+ get maxDeviationRadians() { return this.maxDeviationRadiansFromAverage; }
245334
+ }
245335
+ function emitSector(sector) {
245336
+ if (OffsetMeshContext.stringDebugFunction !== undefined) {
245337
+ OffsetMeshContext.stringDebugFunction(` Sector xyz ${sector.xyz.x},${sector.xyz.y},${sector.xyz.z} `);
245338
+ OffsetMeshContext.stringDebugFunction(` normal ${sector.normal.x},${sector.normal.y},${sector.normal.z} `);
245339
+ }
245340
+ }
245341
+ // facet properties used during offset.
245342
+ //
245343
+ class FacetOffsetProperties {
245344
+ constructor(facetIndex, normal) {
245345
+ this.facetIndex = facetIndex;
245346
+ this.facetNormal = normal;
245347
+ }
245348
+ }
245349
+ /**
245350
+ * Sector properties during offset.
245351
+ * * this.normal may be initially assigned as the facet normal but can mutate by
245352
+ * averaging with neighbors.
245353
+ * * this.xyz is initially the base mesh xyz but is expected to move along the normal.
245354
+ * * this.count is used locally in computations.
245355
+ */
245356
+ class SectorOffsetProperties {
245357
+ constructor(normal, xyz) {
245358
+ this.xyz = xyz;
245359
+ this.normal = normal;
245360
+ this.count = 0;
245361
+ }
245362
+ /**
245363
+ * Compute the angle between plane normals on opposite sides of the edge.
245364
+ * * parallel normals have zero angle.
245365
+ * * if the edge cuts inward to the volume behind the faces, the angle is negative.
245366
+ * * if the edge is outward (a convex edge) the the volume, the angle is positive.
245367
+ * @param edgeNodeA node on one side of the edge
245368
+ * @param edgeVector pre-allocated vector to receive vector along edge.
245369
+ * @param averageNormal pre-allocated vector to receive the average normal for a chamfer of the offset edge.
245370
+ * @param offsetDistance distance of offset being constructed. The sign of this resolves angle ambiguity.
245371
+ * @param radiansTolerance tolerance for large angle between normals.
245372
+ * @returns true if this edge has SectorOffsetProperties on both sides and the angle between normals angle exceeds radiansTolerance.
245373
+ */
245374
+ static edgeHasLargeExteriorAngleBetweenNormals(edgeNodeA, edgeVector, averageNormal, offsetDistance, radiansTolerance = Math.PI * 0.5) {
245375
+ const propsA = edgeNodeA.edgeTag;
245376
+ const edgeNodeB = edgeNodeA.edgeMate;
245377
+ const propsB = edgeNodeB.edgeTag;
245378
+ if (propsA !== undefined && propsB !== undefined) {
245379
+ edgeNodeA.vectorToFaceSuccessor(edgeVector);
245380
+ const radians = propsA.normal.signedRadiansTo(propsB.normal, edgeVector);
245381
+ if (_Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.split3WaySign(offsetDistance, -1, 1, 1) * radians >= radiansTolerance) {
245382
+ _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.createAdd2Scaled(propsA.normal, 1.0, propsB.normal, 1.0, averageNormal);
245383
+ if (averageNormal.normalizeInPlace())
245384
+ return true;
245385
+ }
245386
+ }
245387
+ return false;
245388
+ }
245389
+ static almostEqualNormals(sectorA, sectorB, radiansTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallAngleRadians) {
245390
+ return sectorA.normal.radiansTo(sectorB.normal) <= radiansTolerance;
245391
+ }
245392
+ static radiansBetweenNormals(sectorA, sectorB) {
245393
+ return sectorA.normal.radiansTo(sectorB.normal);
245394
+ }
245395
+ // Set the offset point this.xyz as sum of the nodeXyz + distance * this.normal
245396
+ setOffsetPointAtDistanceAtHalfEdge(halfEdge, distance) {
245397
+ halfEdge.getPoint3d(this.xyz);
245398
+ this.xyz.addScaledInPlace(this.normal, distance);
245399
+ }
245400
+ // Copy xyz from parameter into (preexisting object) xyz
245401
+ static setXYZAtHalfEdge(halfEdge, xyz) {
245402
+ const props = halfEdge.edgeTag;
245403
+ if (props !== undefined && xyz !== undefined)
245404
+ props.xyz.set(xyz.x, xyz.y, xyz.z);
245405
+ }
245406
+ // Set the offset point this.xyz directly
245407
+ setXYAndZ(xyz) {
245408
+ this.xyz.set(xyz.x, xyz.y, xyz.z);
245409
+ }
245410
+ // Look through the half edge to its properties. Set the normal there. Optionally set xyz from node xyz and offset distance
245411
+ static setNormalAtHalfEdge(halfEdge, uvw, distance) {
245412
+ const props = halfEdge.edgeTag;
245413
+ if (props !== undefined) {
245414
+ props.normal.set(uvw.x, uvw.y, uvw.z);
245415
+ if (distance !== undefined)
245416
+ props.setOffsetPointAtDistanceAtHalfEdge(halfEdge, distance);
245417
+ }
245418
+ }
245419
+ // Look through the half edge and its vertex successor to properties. Get the two normals. Return the angle sweeping from one to the next
245420
+ static sweepRadiansAroundNormal(nodeA, upVector) {
245421
+ const propsA = nodeA.edgeTag;
245422
+ const propsB = nodeA.vertexSuccessor.edgeTag;
245423
+ if (propsA !== undefined && propsB !== undefined) {
245424
+ return propsA.normal.planarRadiansTo(propsB.normal, upVector);
245425
+ }
245426
+ return undefined;
245427
+ }
245428
+ // Look through the half edge to its properties. return (if possible) the coordinates
245429
+ static getSectorPointAtHalfEdge(halfEdge, xyz, xyzArray) {
245430
+ const props = halfEdge.edgeTag;
245431
+ if (props !== undefined) {
245432
+ if (xyz !== undefined)
245433
+ xyz.setFromPoint3d(props.xyz);
245434
+ if (xyzArray !== undefined)
245435
+ xyzArray.push(props.xyz);
245436
+ return true;
245437
+ }
245438
+ return false;
245439
+ }
245440
+ // access the XYZ and push to the array (which makes copies, not reference)
245441
+ // return pointer to the SectorOffsetProperties
245442
+ static pushXYZ(xyzArray, halfEdge) {
245443
+ const sector = halfEdge.edgeTag;
245444
+ if (sector !== undefined)
245445
+ xyzArray.push(sector.xyz);
245446
+ return sector;
245447
+ }
245448
+ // Dereference to execute: accumulatingVector += halfEdge.edgeTag.normal * scale
245449
+ static accumulateScaledNormalAtHalfEdge(halfEdge, scale, accumulatingVector) {
245450
+ const sector = halfEdge.edgeTag;
245451
+ if (sector !== undefined)
245452
+ accumulatingVector.addScaledInPlace(sector.normal, scale);
245453
+ }
245454
+ }
245455
+ /*
245456
+ About Chamfer Edges ..... as constructed in addChamferTopologyToAllEdges
245457
+
245458
+ When edge vertex X to vertex Y has a sharp angle between normals, a "chamfer face" must be created to "fatten" it.
245459
+
245460
+ The original half edges (nodes) for the edge are AX and AY. These are "mates" in the halfEdge mental model. As always,
245461
+ AX is (as needed)
245462
+ (i) the preferred half edge for the left side of the edge moving from X to Y. (i.e. above the edge)
245463
+ (ii) a part of the face loop for the face to the left when proceeding CCW around the face to the above the drawn edge
245464
+ (iii) a part of the vertex loop around X
245465
+ Likewise, AY is (as needed)
245466
+ (i) the preferred half edge for the left side of the edge moving from Y to X (i.e. below the edge)
245467
+ (ii) a part of the face loop for the face to the left of the edge when proceeding CCW around the face below the edge.
245468
+ (iii) a part of the vertex loop around Y
245469
+
245470
+ AX------>
245471
+ X______________________________________________________________________Y
245472
+ <---AY
245473
+
245474
+ When the chamfer face is created, it needs to have a sliver face "inside the edge" -- something in the space here
245475
+
245476
+ AX------>
245477
+ _____________________________________________________________________
245478
+ / \
245479
+ X Y
245480
+ \_____________________________________________________________________/
245481
+ <---AY
245482
+
245483
+ The chamfer face will have a plane normal is the average of the two faces' plane normals.
245484
+
245485
+ The creation sequence for the chamfer face puts a slit "inside the edge" as above HalfEdges AX and AY remain as parts
245486
+ of their respective face loops. In addition, at each end a singleton edge "sling" face is inserted at each
245487
+ end of the sliver face.
245488
+
245489
+ The sequence is:
245490
+
245491
+ STEP 1: splitEdgeCreateSliver creates the sliver face with 2 half edges DX and DY
245492
+ STEP 2: splitEdge (with undefined as the "prior" edge) creates a sling with HalfEdge CX "inside" and BX "outside".
245493
+ (The sling face is not yet attached to X -- briefly floating in space)
245494
+ STEP 3: pinch of HalfEdges BX and DX inserts the sling face "inside" the slit face at the X end.
245495
+
245496
+ Steps 2 and 3 are executed from each end. Due to the symmetric structure, a 2-pass loop can apply the logic at each end without distinct names in code.
245497
+
245498
+ AX------>
245499
+ _______________________________________________________________
245500
+ / <---DY \
245501
+ / \
245502
+ / BX---> \
245503
+ / _______________ _______________ \
245504
+ | / \ / <----CY \ |
245505
+ |/ \ / \|
245506
+ X | | Y
245507
+ |\ CX---> / \ /|
245508
+ | \_______________/ \_______________/ |
245509
+ \ <---BY /
245510
+ \ /
245511
+ \ DX---> /
245512
+ \ ______________________________________________________________/
245513
+ <---AY
245514
+
245515
+ During the construction, the letters ABCD are used as above, but with prefixes emphasizing their role
245516
+ outsideAX, outsideAY
245517
+ slingB, slingC, sliverD
245518
+
245519
+ The "inside" sling faces (CX and CY) each have their own FacetOffsetProperties and SectorOffsetProperties.
245520
+ The sliver face has its own FacetOffsetProperties which are referenced by DX, BY, DY, BX.
245521
+ Each of those 4 has its own SectorOffSetProperties.
245522
+
245523
+ Important properties during offset construction:
245524
+ 1) the original graph always has original topology and coordinates
245525
+ 2) Each face of the original graph has a FacetOffsetProperties with a representative point and a normal. These are unchanged during the computation.
245526
+ 3) Each node has its own SectorOffsetProperties with a coordinate and normal independent of the parent node.
245527
+ 3.1 The first offset coordinates in each node are directly offset by face normal.
245528
+ 3.2 This creates mismatch across edges and around vertices.
245529
+ 3.3 Various sweeps "around each vertex" try to do intersections among appropriate offset planes to find
245530
+ common coordinates in place of the initial mismatches.
245531
+ 4) The independence of all the sectors allows the offset construction to fix things up in any order it chooses.
245532
+ 5) During the construction, the xyz in SectorOffsetProperties around a single vertex do NOT have to match.
245533
+ 6) At output time, there are three sweeps:
245534
+ 6.1: By face: Go around the face and output a facet with the coordinates in the various sectors.
245535
+ 6.2: By edge: For each edge, if the sector xyz match across both ends output nothing. If not, output a triangle or quad
245536
+ 6.3: By vertex: At each vertex, if all vertex coordinates match output nothing. Otherwise output a facet with all the coordinates.
245537
+ */
245538
+ class OffsetMeshContext {
245539
+ constructor(basePolyface, baseGraph, options) {
245540
+ this._basePolyface = basePolyface;
245541
+ this._baseGraph = baseGraph;
245542
+ this._breakMaskA = baseGraph.grabMask();
245543
+ this._breakMaskB = baseGraph.grabMask();
245544
+ this._insideOfChamferFace = baseGraph.grabMask();
245545
+ this._outsideOfChamferFace = baseGraph.grabMask();
245546
+ this._insideChamferSling = baseGraph.grabMask();
245547
+ this._outsideEndOfChamferFace = baseGraph.grabMask();
245548
+ this._exteriorMask = _topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdgeMask.EXTERIOR;
245549
+ this._offsetCoordinatesReassigned = baseGraph.grabMask();
245550
+ this._smoothRadiansBetweenNormals = options.smoothSingleAngleBetweenNormals.radians;
245551
+ this._chamferTurnRadians = options.chamferAngleBetweenNormals.radians;
245552
+ this._smoothAccumulatedRadiansBetweenNormals = options.smoothAccumulatedAngleBetweenNormals.radians;
245553
+ }
245554
+ /** "Exterior" side of a bare edge of the mesh */
245555
+ get exteriorMask() { return this._exteriorMask; }
245556
+ /** "First" sector of a smooth sequence. */
245557
+ get breakMaskA() { return this._breakMaskA; }
245558
+ /** "Last" sector of a smooth sequence. */
245559
+ get breakMaskB() { return this._breakMaskB; }
245560
+ /** This edge is on a chamfered face, and along the original edge */
245561
+ get insideOfChamferFace() { return this._insideOfChamferFace; }
245562
+ /** This is the original edge of a chamfer face */
245563
+ get outsideOfChamferFace() { return this._outsideOfChamferFace; }
245564
+ /** This edge is on a chamfered face, and at the end -- other side may be a sling */
245565
+ get insideChamferSling() { return this._insideChamferSling; }
245566
+ /** This is the outside of the end of a chamfer face -- i.e. the inside of a new face-at-vertex */
245567
+ get outsideEndOfChamferFace() { return this._outsideEndOfChamferFace; }
245568
+ // At each node . .
245569
+ // * Find the sector data
245570
+ // * recompute the sector point using node XYZ and sectorData normal.
245571
+ applyFaceNormalOffsetsToSectorData(distance) {
245572
+ this._baseGraph.announceNodes((_graph, node) => {
245573
+ const sectorData = node.edgeTag;
245574
+ if (sectorData !== undefined) {
245575
+ sectorData.setOffsetPointAtDistanceAtHalfEdge(node, distance);
245576
+ }
245577
+ return true;
245578
+ });
245579
+ }
245580
+ /**
245581
+ * * build a mesh offset by given distance.
245582
+ * * output the mesh to the given builder.
245583
+ * @param basePolyface original mesh
245584
+ * @param builder polyface builder to receive the new mesh.
245585
+ * @param distance signed offset distance.
245586
+ */
245587
+ static buildOffsetMeshWithEdgeChamfers(basePolyface, builder, distance, options) {
245588
+ const baseGraph = this.buildBaseGraph(basePolyface);
245589
+ if (baseGraph !== undefined) {
245590
+ const offsetBuilder = new OffsetMeshContext(basePolyface, baseGraph, options);
245591
+ offsetBuilder.applyFaceNormalOffsetsToSectorData(distance);
245592
+ if (OffsetMeshContext.graphDebugFunction !== undefined)
245593
+ OffsetMeshContext.graphDebugFunction("BaseGraph", baseGraph, offsetBuilder._breakMaskA, offsetBuilder._breakMaskB);
245594
+ const outputSelector = options.outputSelector ? options.outputSelector : {
245595
+ outputOffsetsFromFaces: true,
245596
+ outputOffsetsFromEdges: true,
245597
+ outputOffsetsFromVertices: true,
245598
+ };
245599
+ if (isDefinedAndTrue(outputSelector.outputOffsetsFromFacesBeforeChamfers))
245600
+ offsetBuilder.announceFacetsWithSectorCoordinatesAroundFaces(builder);
245601
+ offsetBuilder.addChamferTopologyToAllEdges(options, distance);
245602
+ offsetBuilder.computeOffsetFacetIntersections(distance);
245603
+ if (OffsetMeshContext.graphDebugFunction !== undefined)
245604
+ OffsetMeshContext.graphDebugFunction("after computeEdgeChamfers", baseGraph, offsetBuilder._breakMaskA, offsetBuilder._breakMaskB);
245605
+ if (isDefinedAndTrue(outputSelector.outputOffsetsFromFaces))
245606
+ offsetBuilder.announceFacetsWithSectorCoordinatesAroundFaces(builder);
245607
+ if (isDefinedAndTrue(outputSelector.outputOffsetsFromEdges))
245608
+ offsetBuilder.announceFacetsWithSectorCoordinatesAroundEdges(builder);
245609
+ if (isDefinedAndTrue(outputSelector.outputOffsetsFromVertices))
245610
+ offsetBuilder.announceFacetsWithSectorCoordinatesAroundVertices(builder);
245611
+ }
245612
+ }
245613
+ /**
245614
+ * For each face of the graph, shift vertices by offsetDistance and emit to the builder as a facet
245615
+ * @param polyfaceBuilder
245616
+ */
245617
+ announceSimpleOffsetFromFaces(polyfaceBuilder, offsetDistance) {
245618
+ const xyzLoop = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__.GrowableXYZArray();
245619
+ const xyz = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create(); // reused at each point around each facet.
245620
+ const uvw = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create(); // reused once per facet
245621
+ const announceNodeAroundFace = (node) => {
245622
+ node.getPoint3d(xyz);
245623
+ xyz.addInPlace(uvw);
245624
+ xyzLoop.push(xyz);
245625
+ return 0;
245626
+ };
245627
+ this._baseGraph.announceFaceLoops((_graph, seed) => {
245628
+ if (!seed.isMaskSet(_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdgeMask.EXTERIOR)) {
245629
+ const facetProperties = seed.faceTag;
245630
+ uvw.setFromVector3d(facetProperties.facetNormal.direction);
245631
+ uvw.scaleInPlace(offsetDistance);
245632
+ xyzLoop.length = 0;
245633
+ seed.sumAroundFace(announceNodeAroundFace);
245634
+ polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);
245635
+ }
245636
+ return true;
245637
+ });
245638
+ }
245639
+ /**
245640
+ * For each face of the graph, output the xyz of the sector data
245641
+ * @param polyfaceBuilder
245642
+ */
245643
+ announceFacetsWithSectorCoordinatesAroundFaces(polyfaceBuilder) {
245644
+ const xyzLoop = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__.GrowableXYZArray();
245645
+ // For face loop visits .. get the point from the sector data.
245646
+ const announceNodeAroundFace = (node) => {
245647
+ const sectorData = node.edgeTag;
245648
+ if (sectorData !== undefined) {
245649
+ xyzLoop.push(sectorData.xyz);
245650
+ }
245651
+ return 0;
245652
+ };
245653
+ this._baseGraph.announceFaceLoops((_graph, seed) => {
245654
+ if (!seed.isMaskSet(_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdgeMask.EXTERIOR)) {
245655
+ xyzLoop.length = 0;
245656
+ seed.sumAroundFace(announceNodeAroundFace);
245657
+ if (xyzLoop.length > 2)
245658
+ polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);
245659
+ }
245660
+ return true;
245661
+ });
245662
+ }
245663
+ countBits(mask) {
245664
+ let n = 0;
245665
+ let mask1 = mask;
245666
+ while (mask1 !== 0) {
245667
+ if (mask1 & 0x01)
245668
+ n++;
245669
+ mask1 = mask1 >> 1;
245670
+ }
245671
+ return n;
245672
+ }
245673
+ /**
245674
+ * For each edge of the graph . .
245675
+ * * Collect coordinates in 4 sectors going around the edge
245676
+ * * Compress with tight tolerance so adjacent sectors with clean point match reduce to a single point.
245677
+ * * Emit as a facet.
245678
+ * @param polyfaceBuilder
245679
+ */
245680
+ announceFacetsWithSectorCoordinatesAroundEdges(polyfaceBuilder) {
245681
+ const xyzLoop = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__.GrowableXYZArray();
245682
+ const primaryCompressionTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallMetricDistance;
245683
+ const allMasksForEdgesToIgnore = this._exteriorMask
245684
+ | this._outsideEndOfChamferFace
245685
+ | this._outsideOfChamferFace
245686
+ | this._insideOfChamferFace
245687
+ | this._insideChamferSling;
245688
+ this._baseGraph.announceEdges((_graph, nodeA) => {
245689
+ // This starts by looking for EXTERIOR on both sides ...
245690
+ if (nodeA.findMaskAroundEdge(this._exteriorMask) !== undefined) {
245691
+ return true;
245692
+ }
245693
+ else if (!nodeA.isMaskSet(allMasksForEdgesToIgnore)) { // By design, we believe that these two test for allMasksForEdgesToIgnore condition would catch the EXTERIOR case above
245694
+ const nodeB = nodeA.faceSuccessor;
245695
+ const nodeC = nodeA.edgeMate;
245696
+ if (!nodeC.isMaskSet(allMasksForEdgesToIgnore)) {
245697
+ const nodeD = nodeC.faceSuccessor;
245698
+ xyzLoop.clear();
245699
+ SectorOffsetProperties.getSectorPointAtHalfEdge(nodeA, undefined, xyzLoop);
245700
+ SectorOffsetProperties.getSectorPointAtHalfEdge(nodeB, undefined, xyzLoop);
245701
+ SectorOffsetProperties.getSectorPointAtHalfEdge(nodeC, undefined, xyzLoop);
245702
+ SectorOffsetProperties.getSectorPointAtHalfEdge(nodeD, undefined, xyzLoop);
245703
+ _geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_4__.PolylineCompressionContext.compressInPlaceByShortEdgeLength(xyzLoop, primaryCompressionTolerance);
245704
+ if (xyzLoop.length > 2) {
245705
+ polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);
245706
+ }
245707
+ }
245708
+ }
245709
+ else {
245710
+ return true;
245711
+ }
245712
+ return true;
245713
+ });
245714
+ }
245715
+ getCoordinateString(node, showXYZ = true, showFaceSuccessorXYZ = false) {
245716
+ if (showXYZ) {
245717
+ if (showFaceSuccessorXYZ) {
245718
+ return `${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(node)} ==> ${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(node.faceSuccessor)}`;
245719
+ }
245720
+ else {
245721
+ return `${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(node)}`;
245722
+ }
245723
+ }
245724
+ else {
245725
+ if (showFaceSuccessorXYZ) {
245726
+ return `==> ${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(node.faceSuccessor)}`;
245727
+ }
245728
+ else {
245729
+ return "";
245730
+ }
245731
+ }
245732
+ }
245733
+ inspectMasks(node, showXYZ = true, showFaceSuccessorXYZ = false) {
245734
+ const s = "[";
245735
+ const v = s.concat(node.id.toString(), node.isMaskSet(this._exteriorMask) ? "X" : "", node.isMaskSet(this.breakMaskA) ? "A" : "", node.isMaskSet(this.breakMaskB) ? "B" : "", node.isMaskSet(this.insideChamferSling) ? "(sling)" : "", node.isMaskSet(this.insideOfChamferFace) ? "(in chamfer)" : "", node.isMaskSet(this.outsideEndOfChamferFace) ? "(@sling)" : "", node.isMaskSet(this.outsideOfChamferFace) ? "(@chamfer)" : "", this.getCoordinateString(node, showXYZ, showFaceSuccessorXYZ), "]");
245736
+ return v;
245737
+ }
245738
+ /**
245739
+ * For each face of the graph, output the xyz of the sector data
245740
+ * @param polyfaceBuilder
245741
+ */
245742
+ announceFacetsWithSectorCoordinatesAroundVertices(polyfaceBuilder) {
245743
+ const xyzLoop = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__.GrowableXYZArray();
245744
+ const primaryCompressionTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallMetricDistance;
245745
+ this._baseGraph.announceVertexLoops((_graph, seed) => {
245746
+ if (!seed.findMaskAroundVertex(this._exteriorMask)) {
245747
+ xyzLoop.length = 0;
245748
+ seed.sumAroundVertex((node) => {
245749
+ if (!node.isMaskSet(this._insideChamferSling))
245750
+ SectorOffsetProperties.getSectorPointAtHalfEdge(node, undefined, xyzLoop);
245751
+ return 0.0;
245752
+ });
245753
+ _geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_4__.PolylineCompressionContext.compressInPlaceByShortEdgeLength(xyzLoop, primaryCompressionTolerance);
245754
+ if (xyzLoop.length > 2) {
245755
+ polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);
245756
+ }
245757
+ }
245758
+ return true;
245759
+ });
245760
+ }
245761
+ /**
245762
+ * * Exterior half edges have HalfEdgeMask.EXTERIOR
245763
+ * * All interior half edge around a facet have facetTag pointing to a facetProperties object for that facet.
245764
+ * * the facetOffsetProperties object has the simple facet normal.
245765
+ * * Each half edge has edgeTag pointing to to a sectorOffsetProperties object
245766
+ * * the sectorOffsetProperties has a copy of the facet normal.
245767
+ * @param polyface
245768
+ * @returns graph
245769
+ */
245770
+ static buildBaseGraph(polyface) {
245771
+ const graphBuilder = new _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_5__.HalfEdgeGraphFromIndexedLoopsContext();
245772
+ const visitor = polyface.createVisitor();
245773
+ const xyzA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
245774
+ const xyzB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
245775
+ for (visitor.reset(); visitor.moveToNextFacet();) {
245776
+ const normal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_6__.PolygonOps.centroidAreaNormal(visitor.point);
245777
+ if (normal !== undefined) {
245778
+ const edgeA = graphBuilder.insertLoop(visitor.pointIndex, (insideHalfEdge) => {
245779
+ const mate = insideHalfEdge.edgeMate;
245780
+ polyface.data.getPoint(insideHalfEdge.i, xyzA);
245781
+ insideHalfEdge.setXYZ(xyzA);
245782
+ polyface.data.getPoint(mate.i, xyzB);
245783
+ mate.setXYZ(xyzB);
245784
+ });
245785
+ const facetProperties = new FacetOffsetProperties(visitor.currentReadIndex(), normal);
245786
+ if (edgeA !== undefined) {
245787
+ edgeA.sumAroundFace((edgeB) => {
245788
+ edgeB.faceTag = facetProperties;
245789
+ edgeB.edgeTag = new SectorOffsetProperties(normal.direction.clone(), edgeB.getPoint3d());
245790
+ return 0;
245791
+ });
245792
+ }
245793
+ }
245794
+ }
245795
+ return graphBuilder.graph;
245796
+ }
245797
+ setOffsetAtDistanceAroundVertex(vertexSeed, distance, ignoreChamfers = false) {
245798
+ vertexSeed.sumAroundVertex((nodeAroundVertex) => {
245799
+ const props = nodeAroundVertex.edgeTag;
245800
+ if (props !== undefined) {
245801
+ if (ignoreChamfers && this.isInsideChamferOrSling(vertexSeed)) {
245802
+ // SKIP !!
245803
+ }
245804
+ else {
245805
+ props.setOffsetPointAtDistanceAtHalfEdge(nodeAroundVertex, distance);
245806
+ }
245807
+ }
245808
+ return 0.0;
245809
+ });
245810
+ }
245811
+ setOffsetXYAndZAroundVertex(vertexSeed, xyz) {
245812
+ vertexSeed.sumAroundVertex((nodeAroundVertex) => {
245813
+ const props = nodeAroundVertex.edgeTag;
245814
+ if (props !== undefined) {
245815
+ props.setXYAndZ(xyz);
245816
+ nodeAroundVertex.setMask(this._offsetCoordinatesReassigned);
245817
+ }
245818
+ return 0.0;
245819
+ });
245820
+ }
245821
+ /**
245822
+ * * start at vertexSeed.
245823
+ * * set the offset point at up to (and including) one with (a) this._breakMaskB or (b) this._exteriorMask
245824
+ * *
245825
+ * @param vertexSeed first node to mark.
245826
+ * @param f function to call to announce each node and its sector properties.
245827
+ * @returns number of nodes marked.
245828
+ */
245829
+ announceNodeAndSectorPropertiesInSmoothSector(vertexSeed, f) {
245830
+ let n = 0;
245831
+ for (let currentNode = vertexSeed;; currentNode = currentNode.vertexSuccessor) {
245832
+ const props = currentNode.edgeTag;
245833
+ if (props !== undefined) {
245834
+ f(currentNode, props);
245835
+ n++;
245836
+ }
245837
+ if (currentNode.isMaskSet(this._breakMaskB))
245838
+ return n;
245839
+ // REMARK: these additional exit conditions should not happen if (a) the graph is properly marked and (b) the start node is not exterior.
245840
+ if (currentNode.isMaskSet(this._exteriorMask))
245841
+ return n;
245842
+ if (currentNode === vertexSeed && n === 0)
245843
+ return n;
245844
+ }
245845
+ }
245846
+ computeAverageNormalAndMaxDeviationAroundVertex(vertexSeed, data) {
245847
+ data.clear();
245848
+ const inactiveNodeMask = this._exteriorMask | this._insideChamferSling;
245849
+ vertexSeed.sumAroundVertex((node) => {
245850
+ const sectorData = node.edgeTag;
245851
+ if (sectorData)
245852
+ data.accumulateNormal(node, sectorData.normal, inactiveNodeMask);
245853
+ return 0.0;
245854
+ });
245855
+ if (!data.finishNormalAveraging()) {
245856
+ return undefined;
245857
+ }
245858
+ vertexSeed.sumAroundVertex((node) => {
245859
+ const sectorData = node.edgeTag;
245860
+ if (sectorData)
245861
+ data.recordDeviation(sectorData.normal, !node.isMaskSet(inactiveNodeMask));
245862
+ return 0.0;
245863
+ });
245864
+ return data.maxDeviationRadians;
245865
+ }
245866
+ assignOffsetByAverageNormalAroundVertex(vertexSeed, maxAllowedDeviationRadians, data, distance) {
245867
+ const maxDeviationRadians = this.computeAverageNormalAndMaxDeviationAroundVertex(vertexSeed, data);
245868
+ if (OffsetMeshContext.stringDebugFunction) {
245869
+ OffsetMeshContext.stringDebugFunction(`XYZ ${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(vertexSeed)} Average Normal ${data.averageNormal.toJSON()}`);
245870
+ OffsetMeshContext.stringDebugFunction(` angle ratio ${data.radiansSum / (2 * Math.PI)} maxDeviation ${data.maxDeviationRadiansFromAverage}`);
245871
+ }
245872
+ if (maxDeviationRadians !== undefined && maxDeviationRadians <= maxAllowedDeviationRadians) {
245873
+ vertexSeed.sumAroundVertex((node) => {
245874
+ SectorOffsetProperties.setNormalAtHalfEdge(node, data.averageNormal, distance);
245875
+ return 0;
245876
+ });
245877
+ return true;
245878
+ }
245879
+ return false;
245880
+ }
245881
+ /** Search around a vertex for a sector which has a different normal from its vertexPredecessor.
245882
+ * * The seed will be the first candidate considered
245883
+ */
245884
+ markBreakEdgesAndSaveAverageNormalsAroundVertex(vertexSeed) {
245885
+ vertexSeed.clearMaskAroundVertex(this._breakMaskA);
245886
+ vertexSeed.clearMaskAroundVertex(this._breakMaskB);
245887
+ const smoothSingleSmoothRadiansBetweenNormals = this._smoothRadiansBetweenNormals;
245888
+ const accumulatedRadiansBetweenNormals = this._smoothAccumulatedRadiansBetweenNormals;
245889
+ // Step 1: Examine the edge between nodeA and the sector on its vertex predecessor side. This (alone) determines single angle breaks.
245890
+ let numBreaks = 0;
245891
+ let nodeP = vertexSeed;
245892
+ let _numSmooth = 0;
245893
+ do {
245894
+ const nodeQ = nodeP.edgeMate;
245895
+ const nodeR = nodeQ.faceSuccessor; // same as nodeA.vertexPredecessor
245896
+ if (nodeP.isMaskSet(this._exteriorMask)) {
245897
+ if (!nodeQ.isMaskSet(this._exteriorMask)) {
245898
+ nodeR.setMask(this._breakMaskB);
245899
+ numBreaks++;
245900
+ }
245901
+ }
245902
+ else {
245903
+ if (nodeP.isMaskSet(this._outsideOfChamferFace)) {
245904
+ nodeP.setMask(this._breakMaskA);
245905
+ }
245906
+ else if (nodeP.isMaskSet(this._outsideEndOfChamferFace)) {
245907
+ nodeP.setMask(this._breakMaskA);
245908
+ nodeP.setMask(this._breakMaskB);
245909
+ }
245910
+ else if (nodeP.isMaskSet(this._insideChamferSling)) {
245911
+ // This is the sling. It's normal is along edge -- not really a break.
245912
+ }
245913
+ else if (nodeP.isMaskSet(this._insideOfChamferFace)) {
245914
+ nodeP.setMask(this._breakMaskA);
245915
+ nodeP.setMask(this._breakMaskB);
245916
+ nodeR.setMask(this._breakMaskB);
245917
+ }
245918
+ else if (nodeQ.isMaskSet(this._exteriorMask)) {
245919
+ numBreaks++;
245920
+ nodeP.setMask(this._breakMaskA);
245921
+ }
245922
+ else if (!SectorOffsetProperties.almostEqualNormals(nodeP.edgeTag, nodeR.edgeTag, smoothSingleSmoothRadiansBetweenNormals)) {
245923
+ nodeP.setMask(this._breakMaskA);
245924
+ numBreaks++;
245925
+ nodeR.setMask(this._breakMaskB);
245926
+ }
245927
+ else {
245928
+ _numSmooth++;
245929
+ }
245930
+ }
245931
+ nodeP = nodeP.vertexSuccessor;
245932
+ } while (nodeP !== vertexSeed);
245933
+ if (OffsetMeshContext.stringDebugFunction !== undefined)
245934
+ OffsetMeshContext.stringDebugFunction(` numSkip ${_numSmooth} `);
245935
+ if (numBreaks === 0) {
245936
+ // make the first vertex a break so subsequent searches have a place to start
245937
+ vertexSeed.setMask(this._breakMaskA);
245938
+ vertexSeed.vertexPredecessor.setMask(this._breakMaskB);
245939
+ numBreaks = 1;
245940
+ }
245941
+ // Step 2: At each single break, sweep forward to its closing breakB. Insert breaks at accumulated angles.
245942
+ // (minor TODO: for the insertion case, try to split more equally.)
245943
+ const nodeAStart = nodeP.findMaskAroundVertex(this._breakMaskA);
245944
+ if (nodeAStart !== undefined) {
245945
+ nodeP = nodeAStart;
245946
+ do {
245947
+ if (nodeP.isMaskSet(this._breakMaskA) && !nodeP.isMaskSet(this._breakMaskB)) {
245948
+ let accumulatedRadians = 0.0;
245949
+ do {
245950
+ const nodeB = nodeP.vertexSuccessor;
245951
+ accumulatedRadians += SectorOffsetProperties.radiansBetweenNormals(nodeP.edgeTag, nodeB.edgeTag);
245952
+ if (accumulatedRadians > accumulatedRadiansBetweenNormals) {
245953
+ nodeP.setMask(this._breakMaskB);
245954
+ nodeB.setMask(this._breakMaskA);
245955
+ numBreaks++;
245956
+ accumulatedRadians = 0.0;
245957
+ }
245958
+ nodeP = nodeB;
245959
+ } while (!nodeP.isMaskSet(this._breakMaskB));
245960
+ }
245961
+ else {
245962
+ nodeP = nodeP.vertexSuccessor;
245963
+ }
245964
+ } while (nodeP !== nodeAStart);
245965
+ }
245966
+ if (numBreaks > 0 && nodeAStart !== undefined) {
245967
+ // In each compound sector, accumulate and install average normal.
245968
+ nodeP = nodeAStart;
245969
+ const averageNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create();
245970
+ const edgeVectorU = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create();
245971
+ const edgeVectorV = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create();
245972
+ averageNormal.setZero();
245973
+ do {
245974
+ if (nodeP.isMaskSet(this._breakMaskA) && !nodeP.isMaskSet(this._breakMaskB)) {
245975
+ let nodeQ = nodeP;
245976
+ averageNormal.setZero();
245977
+ for (;;) {
245978
+ nodeQ.vectorToFaceSuccessor(edgeVectorU);
245979
+ nodeQ.vectorToFacePredecessor(edgeVectorV);
245980
+ let singleSectorRadians = edgeVectorU.signedRadiansTo(edgeVectorV, nodeQ.faceTag.facetNormal.direction);
245981
+ if (singleSectorRadians < 0.0)
245982
+ singleSectorRadians += Math.PI * 2;
245983
+ SectorOffsetProperties.accumulateScaledNormalAtHalfEdge(nodeQ, singleSectorRadians, averageNormal);
245984
+ if (nodeQ.isMaskSet(this._breakMaskB))
245985
+ break;
245986
+ nodeQ = nodeQ.vertexSuccessor;
245987
+ }
245988
+ if (averageNormal.normalizeInPlace()) {
245989
+ nodeQ = nodeP;
245990
+ for (;;) {
245991
+ SectorOffsetProperties.setNormalAtHalfEdge(nodeQ, averageNormal);
245992
+ if (nodeQ.isMaskSet(this._breakMaskB))
245993
+ break;
245994
+ nodeQ = nodeQ.vertexSuccessor;
245995
+ }
245996
+ }
245997
+ }
245998
+ nodeP = nodeP.vertexSuccessor;
245999
+ } while (nodeP !== nodeAStart);
246000
+ }
246001
+ }
246002
+ /** Compute the point of intersection of the planes in the sectors of 3 half edges */
246003
+ compute3SectorIntersection(nodeA, nodeB, nodeC, result) {
246004
+ const sectorA = nodeA.edgeTag;
246005
+ const sectorB = nodeB.edgeTag;
246006
+ const sectorC = nodeC.edgeTag;
246007
+ const vector = _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_7__.SmallSystem.intersect3Planes(sectorA.xyz, sectorA.normal, sectorB.xyz, sectorB.normal, sectorC.xyz, sectorC.normal, result);
246008
+ return vector;
246009
+ }
246010
+ /** Compute the point of intersection of the planes in the sectors of 3 half edges */
246011
+ compute3SectorIntersectionDebug(nodeA, nodeB, nodeC, result) {
246012
+ const sectorA = nodeA.edgeTag;
246013
+ const sectorB = nodeB.edgeTag;
246014
+ const sectorC = nodeC.edgeTag;
246015
+ if (OffsetMeshContext.stringDebugFunction !== undefined) {
246016
+ OffsetMeshContext.stringDebugFunction(`compute3${this.inspectMasks(nodeA)}${this.inspectMasks(nodeB)}${this.inspectMasks(nodeC)} `);
246017
+ for (const sector of [sectorA, sectorB, sectorC])
246018
+ emitSector(sector);
246019
+ }
246020
+ const vector = _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_7__.SmallSystem.intersect3Planes(sectorA.xyz, sectorA.normal, sectorB.xyz, sectorB.normal, sectorC.xyz, sectorC.normal, result);
246021
+ if (OffsetMeshContext.stringDebugFunction !== undefined) {
246022
+ if (vector === undefined)
246023
+ OffsetMeshContext.stringDebugFunction(" NO INTERSECTION");
246024
+ else
246025
+ OffsetMeshContext.stringDebugFunction(` ComputedVector ${vector.x},${vector.y},${vector.z} `);
246026
+ }
246027
+ return vector;
246028
+ }
246029
+ /** Compute the point of intersection of the planes in the sectors of 2 half edges, using cross product of their normals to resolve */
246030
+ compute2SectorIntersection(nodeA, nodeB, result) {
246031
+ const sectorA = nodeA.edgeTag;
246032
+ const sectorB = nodeB.edgeTag;
246033
+ const normalC = sectorA.normal.crossProduct(sectorB.normal);
246034
+ return _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_7__.SmallSystem.intersect3Planes(sectorA.xyz, sectorA.normal, sectorB.xyz, sectorB.normal, sectorB.xyz, normalC, result);
246035
+ }
246036
+ /**
246037
+ * * at input, graph has all original faces and edges
246038
+ * * each sector points to a faceProperties with original facet normal
246039
+ * * at exit:
246040
+ * * new "chamfer faces" are added outside of edges with angle between normal sin excess of options.chamferTurnAngleBetweenNormals
246041
+ * * the original edge is split along its length to create space
246042
+ * * one edge "along" each direction inside the slit.
246043
+ * * a sling edge at each end of the slit.
246044
+ * * outside of the sling is part of the slit face loop.
246045
+ * * inside is a single-node face
246046
+ * * thus the slit itself has 4 nodes.
246047
+ * * the two nodes at each end can thus contain the two distinct points at that end of the chamfer.
246048
+ * * all 4 nodes of the slit face point to a new FacetOffsetProperties with the average normal.
246049
+ * * the inside of each sling face has
246050
+ * * original vertex coordinates in the node
246051
+ * * face properties with a normal pointing outward from that end of the original edge -- hence define a plane that can clip the chamfer
246052
+ * * the two points at each end of the chamfer are computed as the intersection of
246053
+ * * chamfer plane
246054
+ * * sling plane
246055
+ * * adjacent plane of the face on the other side of the edge being chamfered.
246056
+ * @param distance distance to offset. The sign of this is important in the chamfer construction.
246057
+ */
246058
+ addChamferTopologyToAllEdges(options, distance) {
246059
+ const edgesToChamfer = [];
246060
+ const chamferRadians = options.chamferAngleBetweenNormals.radians;
246061
+ const vertexXYZ = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create(); // reuse
246062
+ const edgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create(); // reuse
246063
+ const outwardEdgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create(); // reuse
246064
+ const averageNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create(); // reuse
246065
+ // collect all the edges with sharp turn angle.
246066
+ this._baseGraph.announceEdges((_graph, edgeNode) => {
246067
+ if (SectorOffsetProperties.edgeHasLargeExteriorAngleBetweenNormals(edgeNode, edgeVector, averageNormal, distance, chamferRadians)) {
246068
+ edgesToChamfer.push(edgeNode);
246069
+ return true;
246070
+ }
246071
+ return true;
246072
+ });
246073
+ // Create sliver faces.
246074
+ // Sliver face gets an average normal from its neighbors.
246075
+ // outsideA is the HalfEdge labeled A in the diagram.
246076
+ // sliverDX and sliverDY are the edges "inside the sliver" at the respective X and Y ends.
246077
+ for (const outsideA of edgesToChamfer) {
246078
+ // remark: this recomputes as in collection round.
246079
+ if (SectorOffsetProperties.edgeHasLargeExteriorAngleBetweenNormals(outsideA, edgeVector, averageNormal, chamferRadians)) {
246080
+ // This copies coordinates and vertex id .... sectorOffsetProperties are delayed until late in the 2-pass loop below.
246081
+ // The returned HalfEdge is labeled D in the diagram
246082
+ const sliverDX = this._baseGraph.splitEdgeCreateSliverFace(outsideA);
246083
+ const sliverDY = sliverDX.facePredecessor;
246084
+ const offsetPoint = sliverDX.getPoint3d();
246085
+ offsetPoint.addScaledInPlace(averageNormal, distance);
246086
+ const ray = _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_8__.Ray3d.createCapture(offsetPoint, averageNormal.clone());
246087
+ const facetProperties = new FacetOffsetProperties(-1, ray);
246088
+ // for each side (hence end) of the sliver face, set mask and install a sling loop for the anticipated end of the chamfer face
246089
+ // new node names in the loop omit X or Y suffix because that is implied by which pass is running.
246090
+ let s = -1.0;
246091
+ for (const sliverD of [sliverDX, sliverDY]) {
246092
+ edgeVector.scale(s, outwardEdgeVector);
246093
+ sliverD.getPoint3d(vertexXYZ);
246094
+ sliverD.setMask(this._insideOfChamferFace);
246095
+ sliverD.edgeMate.setMask(this._outsideOfChamferFace);
246096
+ // mark and reference the chamfer face.
246097
+ sliverD.faceTag = facetProperties;
246098
+ // sling at this end
246099
+ const slingB = this._baseGraph.splitEdge(undefined, vertexXYZ.x, vertexXYZ.y, vertexXYZ.z, sliverD.i);
246100
+ const slingC = slingB.edgeMate;
246101
+ slingB.setMask(this._outsideEndOfChamferFace);
246102
+ slingB.faceTag = facetProperties;
246103
+ slingC.setMask(this._insideChamferSling);
246104
+ _topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.pinch(sliverD, slingB);
246105
+ const endNormal = _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_8__.Ray3d.create(vertexXYZ, outwardEdgeVector); // clones the inputs
246106
+ const slingFaceProperties = new FacetOffsetProperties(-1, endNormal);
246107
+ slingC.faceTag = slingFaceProperties;
246108
+ // initialize sectors with existing vertex point.
246109
+ sliverD.edgeTag = new SectorOffsetProperties(averageNormal.clone(), offsetPoint.clone());
246110
+ slingB.edgeTag = new SectorOffsetProperties(averageNormal.clone(), offsetPoint.clone());
246111
+ slingC.edgeTag = new SectorOffsetProperties(outwardEdgeVector.clone(), vertexXYZ.clone());
246112
+ // OffsetMeshContext.stringDebugFunction("Chamfer Setup");
246113
+ const chamferPointE = this.compute3SectorIntersection(sliverD, sliverD.edgeMate, slingC);
246114
+ const chamferPointF = this.compute3SectorIntersection(slingB, slingB.vertexSuccessor, slingC);
246115
+ // sliverD.edgeTag = new SectorOffsetProperties(averageNormal.clone(), vertexXYZ.clone());
246116
+ SectorOffsetProperties.setXYZAtHalfEdge(sliverD, chamferPointE);
246117
+ SectorOffsetProperties.setXYZAtHalfEdge(slingB, chamferPointF);
246118
+ s *= -1.0;
246119
+ }
246120
+ }
246121
+ }
246122
+ }
246123
+ /**
246124
+ * * at input:
246125
+ * * Each node points to sectorOffsetProperties with previously computed XYZ (presumably mismatched)
246126
+ * * at exit:
246127
+ * * Each sectorOffsetProperties has an offset point computed with consideration of offset planes in the neighborhood.
246128
+ * @param distance distance to offset.
246129
+ */
246130
+ computeOffsetFacetIntersections(distance) {
246131
+ if (OffsetMeshContext.stringDebugFunction !== undefined)
246132
+ OffsetMeshContext.stringDebugFunction("***** recompute intersections");
246133
+ const breakEdges = [];
246134
+ const vertexXYZ = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
246135
+ const chamferXYZ = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
246136
+ const maxVertexMove = 2.0 * distance;
246137
+ const averageNormalData = new AverageNormalData();
246138
+ const maxAllowedNormalDeviationRadians = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_9__.Angle.degreesToRadians(25.0);
246139
+ //
246140
+ // FOR EACH VERTEX
246141
+ //
246142
+ this._baseGraph.announceVertexLoops((_graph, vertexSeedA) => {
246143
+ // reposition to an important vertex.
246144
+ // first choice: a chamfer face.
246145
+ let vertexSeed = vertexSeedA.findMaskAroundVertex(this._outsideEndOfChamferFace);
246146
+ if (vertexSeed === undefined)
246147
+ vertexSeed = vertexSeedA.findMaskAroundVertex(this._breakMaskA);
246148
+ if (vertexSeed === undefined)
246149
+ vertexSeed = vertexSeedA;
246150
+ if (OffsetMeshContext.stringDebugFunction !== undefined) {
246151
+ OffsetMeshContext.stringDebugFunction("");
246152
+ OffsetMeshContext.stringDebugFunction(` VERTEX LOOP ${vertexSeed.getPoint3d().toJSON()} `);
246153
+ vertexSeed.sumAroundVertex((node) => { OffsetMeshContext.stringDebugFunction(this.inspectMasks(node, false, true)); return 0; });
246154
+ }
246155
+ // Take care of the easiest vertices directly . . . note that this returns from the lambda, not computeOffsetFacetIntersections
246156
+ if (this.assignOffsetByAverageNormalAroundVertex(vertexSeed, maxAllowedNormalDeviationRadians, averageNormalData, distance))
246157
+ return true;
246158
+ this.markBreakEdgesAndSaveAverageNormalsAroundVertex(vertexSeed);
246159
+ this.setOffsetAtDistanceAroundVertex(vertexSeed, distance, true);
246160
+ vertexSeed.collectMaskedEdgesAroundVertex(this._breakMaskA, true, breakEdges);
246161
+ if (OffsetMeshContext.stringDebugFunction !== undefined) {
246162
+ OffsetMeshContext.stringDebugFunction(` BREAK EDGES from ${this.inspectMasks(vertexSeed, true, false)}`);
246163
+ for (const node of breakEdges) {
246164
+ OffsetMeshContext.stringDebugFunction(this.inspectMasks(node, false, true));
246165
+ }
246166
+ }
246167
+ if (breakEdges.length <= 1) {
246168
+ // just one smooth sequence.
246169
+ // everything is set already.
246170
+ }
246171
+ else if (breakEdges.length === 2) {
246172
+ // exterior vertex with two incident smooth
246173
+ const vectorFromOrigin = this.compute2SectorIntersection(breakEdges[0], breakEdges[1]);
246174
+ if (vectorFromOrigin !== undefined) {
246175
+ this.setOffsetXYAndZAroundVertex(vertexSeed, vectorFromOrigin);
246176
+ }
246177
+ }
246178
+ else if (breakEdges.length === 3) {
246179
+ if (OffsetMeshContext.stringDebugFunction !== undefined)
246180
+ OffsetMeshContext.stringDebugFunction(` Vertex Update just ${breakEdges.length} `);
246181
+ const vectorFromOrigin = this.compute3SectorIntersection(breakEdges[0], breakEdges[1], breakEdges[2]);
246182
+ if (vectorFromOrigin !== undefined) {
246183
+ this.setOffsetXYAndZAroundVertex(vertexSeed, vectorFromOrigin);
246184
+ }
246185
+ // simple 3-face corner . . .
246186
+ }
246187
+ else {
246188
+ // Lots and Lots of edges
246189
+ // each set of 3 sectors independently generates an offset for its central sector.
246190
+ if (OffsetMeshContext.stringDebugFunction !== undefined)
246191
+ OffsetMeshContext.stringDebugFunction(` Vertex Update breakEdges ${breakEdges.length} `);
246192
+ vertexSeed.getPoint3d(vertexXYZ);
246193
+ // Pass 1 -- look for intersection among multiple chamfers
246194
+ for (let i = 0; i < breakEdges.length; i++) {
246195
+ const i0 = i;
246196
+ const i1 = (i0 + 1) % breakEdges.length;
246197
+ const i2 = (i1 + 1) % breakEdges.length;
246198
+ if (breakEdges[i0].isMaskSet(this._outsideEndOfChamferFace)
246199
+ && breakEdges[i1].isMaskSet(this._outsideOfChamferFace)
246200
+ && breakEdges[i2].isMaskSet(this._insideOfChamferFace)) {
246201
+ if (OffsetMeshContext.stringDebugFunction !== undefined)
246202
+ OffsetMeshContext.stringDebugFunction(` ChamferChamfer Fixup ${this.inspectMasks(breakEdges[i0])} ${this.inspectMasks(breakEdges[i1])} ${this.inspectMasks(breakEdges[i2])} `);
246203
+ const vectorFromOrigin = this.compute3SectorIntersection(breakEdges[i0], breakEdges[i1], breakEdges[i2]);
246204
+ if (vectorFromOrigin !== undefined) {
246205
+ // Treat all 3 spots as possibly compound sequences
246206
+ for (const iOutput of [i0, i1, i2]) {
246207
+ this.announceNodeAndSectorPropertiesInSmoothSector(breakEdges[iOutput], (node, properties) => {
246208
+ properties.setXYAndZ(vectorFromOrigin);
246209
+ node.setMask(this._offsetCoordinatesReassigned);
246210
+ });
246211
+ }
246212
+ // Since all three were reset, skip past. This is done on the acyclic integer that controls the loop.
246213
+ i += 2;
246214
+ }
246215
+ }
246216
+ }
246217
+ // Pass 2 -- look for unassigned nodes just before or after a chamfer.
246218
+ // The chamfer wins
246219
+ for (let i = 0; i < breakEdges.length; i++) {
246220
+ const i0 = i;
246221
+ const i1 = (i0 + 1) % breakEdges.length;
246222
+ if (this.isInsideSling(breakEdges[i0], breakEdges[i1]))
246223
+ continue;
246224
+ if (!this.isOffsetAssigned(breakEdges[i0])
246225
+ && breakEdges[i1].isMaskSet(this.insideOfChamferFace)) {
246226
+ this.transferXYZFromNodeToSmoothSector(breakEdges[i1], breakEdges[i0], "push left from chamfer", chamferXYZ);
246227
+ }
246228
+ else if (!this.isOffsetAssigned(breakEdges[i1])
246229
+ && breakEdges[i0].isMaskSet(this.outsideEndOfChamferFace)) {
246230
+ this.transferXYZFromNodeToSmoothSector(breakEdges[i0], breakEdges[i1], "push right from chamfer", chamferXYZ);
246231
+ }
246232
+ }
246233
+ // Pass 3 -- look for unassigned nodes as middle of 3-face intersections
246234
+ for (let i = 0; i < breakEdges.length; i++) {
246235
+ const i0 = i;
246236
+ const i1 = (i0 + 1) % breakEdges.length;
246237
+ const i2 = (i1 + 1) % breakEdges.length;
246238
+ if (this.isInsideSling(breakEdges[i0], breakEdges[i1], breakEdges[i2]))
246239
+ continue;
246240
+ if (this.isOffsetAssigned(breakEdges[i1]))
246241
+ continue;
246242
+ if (OffsetMeshContext.stringDebugFunction !== undefined)
246243
+ OffsetMeshContext.stringDebugFunction(` Intersection Fixup ${this.inspectMasks(breakEdges[i0])} ${this.inspectMasks(breakEdges[i1])} ${this.inspectMasks(breakEdges[i2])} `);
246244
+ const vectorFromOrigin = this.compute3SectorIntersection(breakEdges[i0], breakEdges[i1], breakEdges[i2]);
246245
+ if (vectorFromOrigin !== undefined) {
246246
+ if (vertexXYZ.distance(vectorFromOrigin) < maxVertexMove) {
246247
+ this.announceNodeAndSectorPropertiesInSmoothSector(breakEdges[i1], (node, properties) => {
246248
+ properties.setXYAndZ(vectorFromOrigin);
246249
+ node.setMask(this._offsetCoordinatesReassigned);
246250
+ });
246251
+ }
246252
+ }
246253
+ }
246254
+ }
246255
+ if (OffsetMeshContext.stringDebugFunction !== undefined) {
246256
+ const n0 = vertexSeed.countMaskAroundVertex(this._offsetCoordinatesReassigned, false);
246257
+ const n1 = vertexSeed.countMaskAroundVertex(this._offsetCoordinatesReassigned, true);
246258
+ const message = ` **** Vertex offset mask counts(TRUE ${n1})(FALSE ${n0})`;
246259
+ OffsetMeshContext.stringDebugFunction(message);
246260
+ }
246261
+ return true;
246262
+ });
246263
+ }
246264
+ // return true if any of these nodes is "inside" the sling at the end of a chamfer.
246265
+ isInsideSling(node0, node1, node2) {
246266
+ return node0.isMaskSet(this._insideChamferSling)
246267
+ || (node1 !== undefined && node1.isMaskSet(this._insideChamferSling))
246268
+ || (node2 !== undefined && node2.isMaskSet(this._insideChamferSling));
246269
+ }
246270
+ // return true if any of these nodes is "inside" the sling at the end of a chamfer.
246271
+ isInsideChamferOrSling(node0) {
246272
+ return node0.isMaskSet(this._insideChamferSling)
246273
+ || node0.isMaskSet(this._insideOfChamferFace)
246274
+ || node0.isMaskSet(this._outsideEndOfChamferFace);
246275
+ }
246276
+ isOffsetAssigned(node0, node1, node2) {
246277
+ return node0.isMaskSet(this._offsetCoordinatesReassigned)
246278
+ || (node1 !== undefined && node1.isMaskSet(this._offsetCoordinatesReassigned))
246279
+ || (node2 !== undefined && node2.isMaskSet(this._offsetCoordinatesReassigned));
246280
+ }
246281
+ /**
246282
+ *
246283
+ * @param sourceNode node with good xyz
246284
+ * @param destinationStartNode first of a sequence of nodes to set (delimited by masks)
246285
+ * @param description string for debug
246286
+ * @param workPoint point to use for coordinate transfer.
246287
+ */
246288
+ transferXYZFromNodeToSmoothSector(sourceNode, destinationStartNode, description, workPoint) {
246289
+ if (OffsetMeshContext.stringDebugFunction !== undefined)
246290
+ OffsetMeshContext.stringDebugFunction(` ${description} ${this.inspectMasks(sourceNode)} to ${this.inspectMasks(destinationStartNode)}} `);
246291
+ SectorOffsetProperties.getSectorPointAtHalfEdge(sourceNode, workPoint, undefined);
246292
+ this.announceNodeAndSectorPropertiesInSmoothSector(destinationStartNode, (node, properties) => {
246293
+ properties.setXYAndZ(workPoint);
246294
+ node.setMask(this._offsetCoordinatesReassigned);
246295
+ });
246296
+ }
246297
+ }
246298
+
246299
+
245019
246300
  /***/ }),
245020
246301
 
245021
246302
  /***/ "../../core/geometry/lib/esm/polyface/multiclip/RangeSearch.js":
@@ -254224,16 +255505,16 @@ class Sample {
254224
255505
  _curve_Arc3d__WEBPACK_IMPORTED_MODULE_20__.Arc3d.createXY(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(5, 0), 5, _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_0__.AngleSweep.createStartEndDegrees(180, 0)), _curve_Arc3d__WEBPACK_IMPORTED_MODULE_20__.Arc3d.createXY(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(15, 0), 5, _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_0__.AngleSweep.createStartEndDegrees(180, 360)), _curve_Arc3d__WEBPACK_IMPORTED_MODULE_20__.Arc3d.createXY(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(25, 0), 5, _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_0__.AngleSweep.createStartEndDegrees(180, 0)))));
254225
255506
  result.push(_curve_CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_44__.CurveChainWithDistanceIndex.createCapture(_curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(// 2-pt Interpolation Curve
254226
255507
  _bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3d.createCapture(_bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3dOptions.create({
254227
- fitPoints: [pointsA[0], pointsA[1]]
255508
+ fitPoints: [pointsA[0], pointsA[1]],
254228
255509
  })))));
254229
255510
  result.push(_curve_CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_44__.CurveChainWithDistanceIndex.createCapture(_curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(// 3-pt Interpolation Curve
254230
255511
  _bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3d.createCapture(_bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3dOptions.create({
254231
- fitPoints: [pointsA[0], pointsA[1], pointsA[2]]
255512
+ fitPoints: [pointsA[0], pointsA[1], pointsA[2]],
254232
255513
  })))));
254233
255514
  result.push(_curve_CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_44__.CurveChainWithDistanceIndex.createCapture(_curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(_bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3d.createCapture(_bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3dOptions.create({
254234
255515
  fitPoints: pointsA,
254235
255516
  startTangent: _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(1, -1),
254236
- endTangent: _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(-1, -1)
255517
+ endTangent: _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(-1, -1),
254237
255518
  })))));
254238
255519
  result.push(_curve_CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_44__.CurveChainWithDistanceIndex.createCapture(_curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(_curve_spiral_IntegratedSpiral3d__WEBPACK_IMPORTED_MODULE_39__.IntegratedSpiral3d.createRadiusRadiusBearingBearing(_geometry3d_Segment1d__WEBPACK_IMPORTED_MODULE_40__.Segment1d.create(0, 100), _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_0__.AngleSweep.createStartEndDegrees(10, 75), _geometry3d_Segment1d__WEBPACK_IMPORTED_MODULE_40__.Segment1d.create(0, 1), _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_16__.Transform.createOriginAndMatrix(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.createZero(), _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_12__.Matrix3d.createRotationAroundAxisIndex(2, _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__.Angle.createDegrees(30))), "bloss"))));
254239
255520
  result.push(_curve_CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_44__.CurveChainWithDistanceIndex.createCapture(_curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(_curve_spiral_DirectSpiral3d__WEBPACK_IMPORTED_MODULE_41__.DirectSpiral3d.createDirectHalfCosine(_geometry3d_Transform__WEBPACK_IMPORTED_MODULE_16__.Transform.createOriginAndMatrix(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.createZero(), _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_12__.Matrix3d.createRotationAroundAxisIndex(2, _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__.Angle.createDegrees(110))), 50, 350, _geometry3d_Segment1d__WEBPACK_IMPORTED_MODULE_40__.Segment1d.create(0, 1)))));
@@ -254347,8 +255628,11 @@ class Sample {
254347
255628
  /** Create swept "solids" that can be capped.
254348
255629
  * * At least one of each solid type.
254349
255630
  * * each is within 10 of the origin all directions.
255631
+ * @param capped true to include caps
255632
+ * @param rotationAngle angle of rotation for the angular sweep. The default is 90 degrees.
255633
+ * Beware that the rotation sweep created with the default or any positive angle produces a mesh with inward normals.
254350
255634
  */
254351
- static createClosedSolidSampler(capped) {
255635
+ static createClosedSolidSampler(capped, rotationAngle = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__.Angle.createDegrees(90)) {
254352
255636
  const result = [];
254353
255637
  result.push(_solid_Box__WEBPACK_IMPORTED_MODULE_35__.Box.createRange(_geometry3d_Range__WEBPACK_IMPORTED_MODULE_4__.Range3d.createXYZXYZ(0, 0, 0, 3, 2, 5), capped));
254354
255638
  result.push(_solid_Cone__WEBPACK_IMPORTED_MODULE_33__.Cone.createAxisPoints(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(0, 0, 0), _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(0, 0, 5), 1.0, 1.0, capped));
@@ -254360,18 +255644,23 @@ class Sample {
254360
255644
  const pointQ2 = arcA.fractionAndDistanceToPointOnTangent(1.0, 0.5);
254361
255645
  const pointR1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(point0.x, pointQ1.y);
254362
255646
  const pointR2 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(point0.x, pointQ1.y);
255647
+ const pointR3 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(pointQ1.x - 1, pointQ1.y);
255648
+ const pointR4 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(pointQ1.x - 3, pointQ1.y);
254363
255649
  const linestringQ1 = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_15__.LineString3d.create(arcA.fractionToPoint(1.0), pointQ1, pointR1, point0);
254364
255650
  const linestringQ2 = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_15__.LineString3d.create(arcA.fractionToPoint(1.0), pointQ2, pointR2, point0);
255651
+ const linestringQ3 = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_15__.LineString3d.create(arcA.fractionToPoint(1.0), pointQ2, pointR3, pointR4, point0);
254365
255652
  const contourZ = _curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(linestringQ1.clone());
254366
255653
  const contourA = _curve_Loop__WEBPACK_IMPORTED_MODULE_23__.Loop.create(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_19__.LineSegment3d.create(point0, arcA.fractionToPoint(0)), arcA.clone(), linestringQ1.clone());
254367
255654
  const contourB = _curve_Loop__WEBPACK_IMPORTED_MODULE_23__.Loop.create(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_19__.LineSegment3d.create(point0, arcA.fractionToPoint(0)), arcA.clone(), linestringQ2.clone());
255655
+ const contourC1 = _curve_Loop__WEBPACK_IMPORTED_MODULE_23__.Loop.create(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_19__.LineSegment3d.create(point0, arcA.fractionToPoint(0)), arcA.clone(), linestringQ3.clone());
254368
255656
  contourB.tryTransformInPlace(_geometry3d_Transform__WEBPACK_IMPORTED_MODULE_16__.Transform.createTranslationXYZ(1, 1, 3));
254369
255657
  // const contourC = contourB.cloneTransformed(Transform.createTranslationXYZ(2, 1, 4))!;
254370
255658
  result.push(_solid_LinearSweep__WEBPACK_IMPORTED_MODULE_30__.LinearSweep.create(contourA, _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(0, 0, 5), capped));
255659
+ result.push(_solid_LinearSweep__WEBPACK_IMPORTED_MODULE_30__.LinearSweep.create(contourC1, _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(0, 0, 5), capped));
254371
255660
  const axis = _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_14__.Ray3d.createXYZUVW(0, 8, 0, 1, 0, 0);
254372
- result.push(_solid_RotationalSweep__WEBPACK_IMPORTED_MODULE_31__.RotationalSweep.create(contourA.clone(), axis.clone(), _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__.Angle.createDegrees(90), capped));
255661
+ result.push(_solid_RotationalSweep__WEBPACK_IMPORTED_MODULE_31__.RotationalSweep.create(contourA.clone(), axis.clone(), rotationAngle, capped));
254373
255662
  if (!capped)
254374
- result.push(_solid_RotationalSweep__WEBPACK_IMPORTED_MODULE_31__.RotationalSweep.create(contourZ.clone(), axis.clone(), _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__.Angle.createDegrees(90), false));
255663
+ result.push(_solid_RotationalSweep__WEBPACK_IMPORTED_MODULE_31__.RotationalSweep.create(contourZ.clone(), axis.clone(), rotationAngle, false));
254375
255664
  result.push(_solid_RuledSweep__WEBPACK_IMPORTED_MODULE_36__.RuledSweep.create([contourA.clone(), contourB.clone()], capped));
254376
255665
  const transformC = _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_16__.Transform.createScaleAboutPoint(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(0, 0, 8), 0.5);
254377
255666
  const contourC = contourB.cloneTransformed(transformC);
@@ -258796,12 +260085,13 @@ __webpack_require__.r(__webpack_exports__);
258796
260085
  /* harmony export */ "HalfEdgeGraph": () => (/* binding */ HalfEdgeGraph),
258797
260086
  /* harmony export */ "HalfEdgeMask": () => (/* binding */ HalfEdgeMask)
258798
260087
  /* harmony export */ });
258799
- /* harmony import */ var _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../curve/LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
260088
+ /* harmony import */ var _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../curve/LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
258800
260089
  /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
260090
+ /* harmony import */ var _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../geometry3d/Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
258801
260091
  /* harmony import */ var _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../geometry3d/Point2dVector2d */ "../../core/geometry/lib/esm/geometry3d/Point2dVector2d.js");
258802
260092
  /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
258803
- /* harmony import */ var _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../numerics/Polynomials */ "../../core/geometry/lib/esm/numerics/Polynomials.js");
258804
- /* harmony import */ var _MaskManager__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./MaskManager */ "../../core/geometry/lib/esm/topology/MaskManager.js");
260093
+ /* harmony import */ var _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../numerics/Polynomials */ "../../core/geometry/lib/esm/numerics/Polynomials.js");
260094
+ /* harmony import */ var _MaskManager__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./MaskManager */ "../../core/geometry/lib/esm/topology/MaskManager.js");
258805
260095
  /*---------------------------------------------------------------------------------------------
258806
260096
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
258807
260097
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -258815,6 +260105,7 @@ __webpack_require__.r(__webpack_exports__);
258815
260105
 
258816
260106
 
258817
260107
 
260108
+
258818
260109
  // import { GraphChecker } from "../test/topology/Graph.test";
258819
260110
  /* eslint-disable @typescript-eslint/no-this-alias */
258820
260111
  // cspell:word CONSTU
@@ -258902,6 +260193,7 @@ class HalfEdge {
258902
260193
  this.sortAngle = undefined;
258903
260194
  this.sortData = undefined;
258904
260195
  this.edgeTag = undefined;
260196
+ this.faceTag = undefined;
258905
260197
  // Always created in pairs, init here to make TS compiler and JS runtime happy
258906
260198
  this._facePredecessor = this;
258907
260199
  this._faceSuccessor = this;
@@ -259022,6 +260314,36 @@ class HalfEdge {
259022
260314
  }
259023
260315
  return newA;
259024
260316
  }
260317
+ /**
260318
+ * * Create a new sliver face "inside" an existing edge.
260319
+ * * Insert it "within" the base edge.
260320
+ * * This requires two new half edges.
260321
+ * * if the base is undefined, create a single-edge loop.
260322
+ * * This (unlike pinch) breaks the edgeMate pairing of the base edge.
260323
+ * * This preserves xyz and i properties at all existing vertices.
260324
+ * * The two new half edges are a sliver face (via their predecessor and successor)
260325
+ * * Each new edge mates to one existing edge.
260326
+ * @returns Returns the reference to the half edge created.
260327
+ */
260328
+ static splitEdgeCreateSliverFace(baseA, heArray) {
260329
+ // raw edges ...
260330
+ const newA = new HalfEdge();
260331
+ const newB = new HalfEdge();
260332
+ const baseB = baseA.edgeMate;
260333
+ if (heArray) {
260334
+ heArray.push(newA);
260335
+ heArray.push(newB);
260336
+ }
260337
+ newA._faceSuccessor = newA._facePredecessor = newB;
260338
+ newB._faceSuccessor = newB._facePredecessor = newA;
260339
+ // newA is in vertex loop with baseA etc.
260340
+ // newA mates to baseB
260341
+ HalfEdge.setEdgeMates(newA, baseB);
260342
+ HalfEdge.setEdgeMates(newB, baseA);
260343
+ newA.copyDataFrom(baseA, true, true, false, false);
260344
+ newB.copyDataFrom(baseB, true, true, false, false);
260345
+ return newA;
260346
+ }
259025
260347
  /**
259026
260348
  * Copy "edge based" content of fromNode to toNode
259027
260349
  * * edgeTag
@@ -259232,6 +260554,35 @@ class HalfEdge {
259232
260554
  }
259233
260555
  return count;
259234
260556
  }
260557
+ /** Returns the first node with given mask value around this vertex loop. */
260558
+ findMaskAroundVertex(mask, value = true) {
260559
+ let node = this;
260560
+ do {
260561
+ if (node.isMaskSet(mask) === value)
260562
+ return node;
260563
+ node = node.vertexSuccessor;
260564
+ } while (node !== this);
260565
+ return undefined;
260566
+ }
260567
+ /** Returns the first node with given mask value around this face loop. */
260568
+ findMaskAroundFace(mask, value = true) {
260569
+ let node = this;
260570
+ do {
260571
+ if (node.isMaskSet(mask) === value)
260572
+ return node;
260573
+ node = node.faceSuccessor;
260574
+ } while (node !== this);
260575
+ return undefined;
260576
+ }
260577
+ /** Returns the first node with given mask value on this edge (i.e. examining this and this.mate) */
260578
+ findMaskAroundEdge(mask, value = true) {
260579
+ if (this.isMaskSet(mask) === value)
260580
+ return this;
260581
+ const mate = this.edgeMate;
260582
+ if (mate.isMaskSet(mask) === value)
260583
+ return mate;
260584
+ return undefined;
260585
+ }
259235
260586
  /** Set a mask, and return prior value.
259236
260587
  * @param mask mask to apply
259237
260588
  */
@@ -259249,6 +260600,15 @@ class HalfEdge {
259249
260600
  this.y = node.y;
259250
260601
  this.z = node.z;
259251
260602
  }
260603
+ /**
260604
+ * Set (copy) the this.x, this.y, this.z from xyz.x, xyz.y, xyz.z
260605
+ * @param node source with x,y,z properties
260606
+ */
260607
+ setXYZ(xyz) {
260608
+ this.x = xyz.x;
260609
+ this.y = xyz.y;
260610
+ this.z = xyz.z;
260611
+ }
259252
260612
  /**
259253
260613
  * Test if mask bits are set in the node's bitMask.
259254
260614
  * @return Return true (as a simple boolean, not a mask) if any bits of the mask parameter match bits of the node's bitMask
@@ -259338,6 +260698,10 @@ class HalfEdge {
259338
260698
  const s = `${node.id.toString()}+${HalfEdge.nodeToMaskString(node)}[${node.x},${node.y}]`;
259339
260699
  return s;
259340
260700
  }
260701
+ /** Return the [id, [x,y],z] of a node. Useful for collector methods. */
260702
+ static nodeToIdXYZString(node) {
260703
+ return `[${node.id.toString()}: ${node.x},${node.y},${node.z}]`;
260704
+ }
259341
260705
  /** Create a string representation of the mask
259342
260706
  * * Null mask is empty string.
259343
260707
  * * Appended characters B,P,X for Boundary, Primary, Exterior mask bits.
@@ -259362,7 +260726,13 @@ class HalfEdge {
259362
260726
  }
259363
260727
  /** Return Vector3d to face successor */
259364
260728
  vectorToFaceSuccessor(result) {
259365
- return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(this.faceSuccessor.x - this.x, this.faceSuccessor.y - this.y, this.faceSuccessor.z - this.z, result);
260729
+ const other = this.faceSuccessor;
260730
+ return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(other.x - this.x, other.y - this.y, other.z - this.z, result);
260731
+ }
260732
+ /** Return Vector3d to face successor */
260733
+ vectorToFacePredecessor(result) {
260734
+ const other = this.facePredecessor;
260735
+ return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(other.x - this.x, other.y - this.y, other.z - this.z, result);
259366
260736
  }
259367
260737
  /** test if spaceNode is in the sector at sectorNode */
259368
260738
  static isNodeVisibleInSector(spaceNode, sectorNode) {
@@ -259486,6 +260856,14 @@ class HalfEdge {
259486
260856
  static testNodeMaskNotExterior(node) { return !node.isMaskSet(HalfEdgeMask.EXTERIOR); }
259487
260857
  /** Returns Returns true if the node does NOT have Mask.EXTERIOR_MASK set. */
259488
260858
  static testMateMaskExterior(node) { return node.edgeMate.isMaskSet(HalfEdgeMask.EXTERIOR); }
260859
+ /** Returns radians between this edge and its face predecessor edge, using all three coordinates x,y,z and given normal to resolve sweep direction.
260860
+ * * The returned angle is positive, i.e. may be larger than PI radians.
260861
+ */
260862
+ static sectorSweepRadiansXYZ(node, normal) {
260863
+ const nodeB = node.faceSuccessor;
260864
+ const nodeC = node.facePredecessor;
260865
+ return _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__.Angle.orientedRadiansBetweenVectorsXYZ(nodeB.x - node.x, nodeB.y - node.y, nodeB.z - node.z, nodeC.x - node.x, nodeC.y - node.y, nodeC.z - node.z, normal.x, normal.y, normal.z, true);
260866
+ }
259489
260867
  /** Returns Returns true if the face has positive area in xy parts. */
259490
260868
  static testFacePositiveAreaXY(node) {
259491
260869
  return node.countEdgesAroundFace() > 2 && node.signedFaceArea() > 0.0;
@@ -259517,6 +260895,26 @@ class HalfEdge {
259517
260895
  } while (node !== this);
259518
260896
  return nodes;
259519
260897
  }
260898
+ /**
260899
+ * search around a vertex for nodes that have a specified mask setting.
260900
+ * @param vertexSeed first node to search
260901
+ * @param mask target mask
260902
+ * @param value target value for mask on half edges.
260903
+ * @param collectedNodes optional array to be cleared and receive masked nodes
260904
+ */
260905
+ collectMaskedEdgesAroundVertex(mask, value = true, result) {
260906
+ if (result === undefined)
260907
+ result = [];
260908
+ else
260909
+ result.length = 0;
260910
+ let node = this;
260911
+ do {
260912
+ if (node.isMaskSet(mask) === value)
260913
+ result.push(node);
260914
+ node = node.vertexSuccessor;
260915
+ } while (node !== this);
260916
+ return result;
260917
+ }
259520
260918
  /**
259521
260919
  *
259522
260920
  * * Evaluate f(node) at each outbound node around this node's vertex loop.
@@ -259700,7 +261098,7 @@ class HalfEdge {
259700
261098
  const nodeB1 = nodeB0.faceSuccessor;
259701
261099
  if (!result)
259702
261100
  result = _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_0__.Vector2d.create();
259703
- if (_numerics_Polynomials__WEBPACK_IMPORTED_MODULE_3__.SmallSystem.linearSystem2d(nodeA1.x - nodeA0.x, nodeB0.x - nodeB1.x, nodeA1.y - nodeA0.y, nodeB0.y - nodeB1.y, nodeB0.x - nodeA0.x, nodeB0.y - nodeA0.y, result))
261101
+ if (_numerics_Polynomials__WEBPACK_IMPORTED_MODULE_4__.SmallSystem.linearSystem2d(nodeA1.x - nodeA0.x, nodeB0.x - nodeB1.x, nodeA1.y - nodeA0.y, nodeB0.y - nodeB1.y, nodeB0.x - nodeA0.x, nodeB0.y - nodeA0.y, result))
259704
261102
  return result;
259705
261103
  return undefined;
259706
261104
  }
@@ -259709,8 +261107,7 @@ class HalfEdge {
259709
261107
  * * If the edge is horizontal with (approximate) identical y, return the node.
259710
261108
  * * If the edge is horizontal with different y, return undefined.
259711
261109
  * * If the edge is not horizontal, return the fractional position (possibly outside 0..1) of the intersection.
259712
- * @param nodeA Base node of edge
259713
- * @param result optional preallocated result
261110
+ * @param node0 Base node of edge
259714
261111
  */
259715
261112
  static horizontalScanFraction(node0, y) {
259716
261113
  const node1 = node0.faceSuccessor;
@@ -259725,8 +261122,7 @@ class HalfEdge {
259725
261122
  * * Compute fractional coordinates of the intersection of a horizontal line with an edge.
259726
261123
  * * If the edge is horizontal return undefined (no test for horizontal at y!!!)
259727
261124
  * * If the edge is not horizontal and y is between its end y's, return the fraction
259728
- * @param nodeA Base node of edge
259729
- * @param result optional preallocated result
261125
+ * @param node0 Base node of edge
259730
261126
  */
259731
261127
  static horizontalScanFraction01(node0, y) {
259732
261128
  const node1 = node0.faceSuccessor;
@@ -259740,6 +261136,31 @@ class HalfEdge {
259740
261136
  return fraction;
259741
261137
  return undefined;
259742
261138
  }
261139
+ /**
261140
+ * Copy various data from source to this.
261141
+ * @param source other half edge.
261142
+ * @param XYZ copy simple coordinates
261143
+ * @param copyVertexData true to copy data belonging to the vertex. (i.e. the "i" member)
261144
+ * @param copyVertexData true to copy data belonging to the edge. (i.e. call transferEdgeData)
261145
+ * @param copyFaceData true to copy faceTag
261146
+ */
261147
+ copyDataFrom(source, copyXYZ, copyVertexData, copyEdgeData, copyFaceData) {
261148
+ if (copyXYZ) {
261149
+ this.x = source.x;
261150
+ this.y = source.y;
261151
+ this.z = source.z;
261152
+ }
261153
+ if (copyVertexData) {
261154
+ this.i = source.i;
261155
+ }
261156
+ if (copyEdgeData) {
261157
+ HalfEdge.transferEdgeProperties(source, this);
261158
+ this.edgeTag = source.edgeTag;
261159
+ }
261160
+ if (copyFaceData) {
261161
+ this.faceTag = source.faceTag;
261162
+ }
261163
+ }
259743
261164
  }
259744
261165
  HalfEdge._edgePropertyMasks = [HalfEdgeMask.BOUNDARY_EDGE, HalfEdgeMask.EXTERIOR, HalfEdgeMask.PRIMARY_EDGE, HalfEdgeMask.NULL_FACE];
259745
261166
  HalfEdge._totalNodesCreated = 0;
@@ -259753,7 +261174,7 @@ class HalfEdgeGraph {
259753
261174
  constructor() {
259754
261175
  this._numNodesCreated = 0;
259755
261176
  this.allHalfEdges = [];
259756
- this._maskManager = _MaskManager__WEBPACK_IMPORTED_MODULE_4__.MaskManager.create(HalfEdgeMask.ALL_GRAB_DROP_MASKS);
261177
+ this._maskManager = _MaskManager__WEBPACK_IMPORTED_MODULE_5__.MaskManager.create(HalfEdgeMask.ALL_GRAB_DROP_MASKS);
259757
261178
  }
259758
261179
  /** Ask for a mask (from the graph's free pool.) for caller's use.
259759
261180
  * * Optionally clear the mask throughout the graph.
@@ -259780,6 +261201,19 @@ class HalfEdgeGraph {
259780
261201
  const a = HalfEdge.createHalfEdgePairWithCoordinates(xA, yA, zA, iA, xB, yB, zB, iB, this.allHalfEdges);
259781
261202
  return a;
259782
261203
  }
261204
+ /**
261205
+ * * Create 2 half edges forming 2 vertices, 1 edge, and 1 face
261206
+ * * The two edges are joined as edgeMate pair.
261207
+ * * The two edges are a 2-half-edge face loop in both the faceSuccessor and facePredecessor directions.
261208
+ * * The two edges are added to the graph's HalfEdge set
261209
+ * * Coordinates are set to zero.
261210
+ * * ids are installed in the two half edges.
261211
+ * @returns Return pointer to the first half edge created. (This has idA as its id.)
261212
+ */
261213
+ createEdgeIdId(iA = 0, iB = 0) {
261214
+ const a = HalfEdge.createHalfEdgePairWithCoordinates(0.0, 0.0, 0.0, iA, 0.0, 0.0, 0.0, iB, this.allHalfEdges);
261215
+ return a;
261216
+ }
259783
261217
  /**
259784
261218
  * * create an edge from coordinates x,y,z to (the tail of) an existing half edge.
259785
261219
  * @returns Return pointer to the half edge with tail at x,y,z
@@ -259824,6 +261258,20 @@ class HalfEdgeGraph {
259824
261258
  const he = HalfEdge.splitEdge(base, xA, yA, zA, iA, this.allHalfEdges);
259825
261259
  return he;
259826
261260
  }
261261
+ /**
261262
+ * * Create a sliver face "within" an edge.
261263
+ * * this creates two half edges.
261264
+ * * The existing edges both stay in their same face loops and retain coordinates and i value.
261265
+ * * Each existing edge's mate is a new edge (rather than original mate)
261266
+ * * Coordinates are copied to the new edges at respective vertices.
261267
+ * * New faceTag and edgeTag undefined.
261268
+ * * i members are copied around their respective vertices.
261269
+ * @returns Returns the reference to the half edge created.
261270
+ */
261271
+ splitEdgeCreateSliverFace(base) {
261272
+ const he = HalfEdge.splitEdgeCreateSliverFace(base, this.allHalfEdges);
261273
+ return he;
261274
+ }
259827
261275
  /**
259828
261276
  * * Insert a vertex in the edge beginning at base, with coordinates specified as a fraction along the existing edge.
259829
261277
  * * this creates two half edges.
@@ -259892,7 +261340,7 @@ class HalfEdgeGraph {
259892
261340
  const segments = [];
259893
261341
  for (const node of this.allHalfEdges) {
259894
261342
  if (node.id < node.edgeMate.id)
259895
- segments.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_5__.LineSegment3d.create(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(node.x, node.y), _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(node.faceSuccessor.x, node.faceSuccessor.y)));
261343
+ segments.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_6__.LineSegment3d.create(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(node.x, node.y), _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(node.faceSuccessor.x, node.faceSuccessor.y)));
259896
261344
  }
259897
261345
  return segments;
259898
261346
  }
@@ -259961,6 +261409,26 @@ class HalfEdgeGraph {
259961
261409
  break;
259962
261410
  }
259963
261411
  }
261412
+ /**
261413
+ * * Visit each edge of the graph once.
261414
+ * * Call the announceEdge function.
261415
+ * * the edge mate will NOT appear in an announceEdge call.
261416
+ * * continue search if announceEdge(graph, node) returns true
261417
+ * * terminate search if announceEdge (graph, node) returns false
261418
+ * @param announceEdge function to apply at one node of each edge.
261419
+ */
261420
+ announceEdges(announceEdge) {
261421
+ this.clearMask(HalfEdgeMask.VISITED);
261422
+ for (const node of this.allHalfEdges) {
261423
+ if (node.getMask(HalfEdgeMask.VISITED))
261424
+ continue;
261425
+ const mate = node.edgeMate;
261426
+ node.setMask(HalfEdgeMask.VISITED);
261427
+ mate.setMask(HalfEdgeMask.VISITED);
261428
+ if (!announceEdge(this, node))
261429
+ break;
261430
+ }
261431
+ }
259964
261432
  /**
259965
261433
  * * Visit each vertex loop of the graph once.
259966
261434
  * * Call the announceVertex function
@@ -259979,8 +261447,8 @@ class HalfEdgeGraph {
259979
261447
  }
259980
261448
  }
259981
261449
  /**
259982
- * * Visit each vertex loop of the graph once.
259983
- * * Call the announceVertex function
261450
+ * * Visit each half edge (node) of the graph once.
261451
+ * * Call the announceNode function
259984
261452
  * * continue search if announceNode(graph, node) returns true
259985
261453
  * * terminate search if announce face (graph, node) returns false
259986
261454
  * @param announceNode function to apply at one node of each face.
@@ -260039,6 +261507,99 @@ class HalfEdgeGraph {
260039
261507
  }
260040
261508
 
260041
261509
 
261510
+ /***/ }),
261511
+
261512
+ /***/ "../../core/geometry/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js":
261513
+ /*!************************************************************************************!*\
261514
+ !*** ../../core/geometry/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js ***!
261515
+ \************************************************************************************/
261516
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
261517
+
261518
+ "use strict";
261519
+ __webpack_require__.r(__webpack_exports__);
261520
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
261521
+ /* harmony export */ "HalfEdgeGraphFromIndexedLoopsContext": () => (/* binding */ HalfEdgeGraphFromIndexedLoopsContext)
261522
+ /* harmony export */ });
261523
+ /* harmony import */ var _Graph__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
261524
+ /*---------------------------------------------------------------------------------------------
261525
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
261526
+ * See LICENSE.md in the project root for license terms and full copyright notice.
261527
+ *--------------------------------------------------------------------------------------------*/
261528
+
261529
+ /** @packageDocumentation
261530
+ * @module Topology
261531
+ */
261532
+ /**
261533
+ * Context for building a half edge graph from loops defined only by indices.
261534
+ * * Direct use case:
261535
+ * * Create the context.
261536
+ * * Repeatedly call insertLoop(indicesAroundLoop) to announce various loops.
261537
+ * * Finish by accessing the graph property.
261538
+ * @internal
261539
+ */
261540
+ class HalfEdgeGraphFromIndexedLoopsContext {
261541
+ constructor() {
261542
+ this._unmatchedEdges = new Map();
261543
+ this._graph = new _Graph__WEBPACK_IMPORTED_MODULE_0__.HalfEdgeGraph();
261544
+ this._halfEdgesAroundCurrentLoop = [];
261545
+ }
261546
+ get graph() { return this._graph; }
261547
+ indexPairToString(index0, index1) {
261548
+ return `${index0.toString()},${index1.toString()}`;
261549
+ }
261550
+ /** Create a loop with specified indices at its vertices.
261551
+ * * For an edge with index pair [indexA, indexB]:
261552
+ * * if [indexB, indexA] has never appeared, a HalfEdge mated pair is created.
261553
+ * * One of that mated pair becomes a HalfEdge in this loop.
261554
+ * * The other is "unmatched"
261555
+ * * When announceMatedHalfEdges(halfEdge) is called:
261556
+ * * halfEdge and its mate are "new"
261557
+ * * all coordinates are zeros.
261558
+ * * each contains (as its halfEdge.id property) one index of the [indexA,indexB] pair.
261559
+ * * those coordinates and indices will never be referenced again by this construction sequence -- the caller is free to mutate them as needed.
261560
+ * * if [indexB, indexA] appeared previously (and its outer HalfEdge was left "unmatched"),
261561
+ * the "unmatched" HalfEdge is used in the loop being constructed.
261562
+ * @param indices Array of indices around the edge. This is accessed cyclically.
261563
+ * @param announceMatedHalfEdges optional function to be called as mated pairs are created. At the call,
261564
+ * the given HalfEdge and its mate will have a pair of successive indices from the array.
261565
+ */
261566
+ insertLoop(indices, announceMatedHalfEdges) {
261567
+ const n = indices.length;
261568
+ if (n > 1) {
261569
+ let index0 = indices[indices.length - 1];
261570
+ this._halfEdgesAroundCurrentLoop.length = 0;
261571
+ for (const index1 of indices) {
261572
+ const insideString = this.indexPairToString(index0, index1);
261573
+ const halfEdgePreviouslyConstructedFromOppositeSide = this._unmatchedEdges.get(insideString);
261574
+ if (halfEdgePreviouslyConstructedFromOppositeSide === undefined) {
261575
+ // This is the first appearance of this edge in either direction.
261576
+ const outsideString = this.indexPairToString(index1, index0); // string referencing the "other" side of the new edge.
261577
+ const newHalfEdgeAroundLoop = this._graph.createEdgeIdId(index0, index1);
261578
+ if (announceMatedHalfEdges !== undefined)
261579
+ announceMatedHalfEdges(newHalfEdgeAroundLoop);
261580
+ this._unmatchedEdges.set(outsideString, newHalfEdgeAroundLoop.edgeMate);
261581
+ this._halfEdgesAroundCurrentLoop.push(newHalfEdgeAroundLoop);
261582
+ newHalfEdgeAroundLoop.edgeMate.setMask(_Graph__WEBPACK_IMPORTED_MODULE_0__.HalfEdgeMask.EXTERIOR);
261583
+ }
261584
+ else {
261585
+ this._halfEdgesAroundCurrentLoop.push(halfEdgePreviouslyConstructedFromOppositeSide);
261586
+ halfEdgePreviouslyConstructedFromOppositeSide.clearMask(_Graph__WEBPACK_IMPORTED_MODULE_0__.HalfEdgeMask.EXTERIOR);
261587
+ }
261588
+ index0 = index1;
261589
+ }
261590
+ let halfEdgeA = this._halfEdgesAroundCurrentLoop[this._halfEdgesAroundCurrentLoop.length - 1];
261591
+ for (const halfEdgeB of this._halfEdgesAroundCurrentLoop) {
261592
+ const halfEdgeC = halfEdgeA.faceSuccessor;
261593
+ _Graph__WEBPACK_IMPORTED_MODULE_0__.HalfEdge.pinch(halfEdgeB, halfEdgeC);
261594
+ halfEdgeA = halfEdgeB;
261595
+ }
261596
+ return this._halfEdgesAroundCurrentLoop[0];
261597
+ }
261598
+ return undefined;
261599
+ }
261600
+ }
261601
+
261602
+
260042
261603
  /***/ }),
260043
261604
 
260044
261605
  /***/ "../../core/geometry/lib/esm/topology/HalfEdgeGraphSearch.js":
@@ -285523,7 +287084,7 @@ class TestContext {
285523
287084
  this.initializeRpcInterfaces({ title: this.settings.Backend.name, version: this.settings.Backend.version });
285524
287085
  const iModelClient = new imodels_client_management_1.IModelsClient({ api: { baseUrl: `https://${(_a = process.env.IMJS_URL_PREFIX) !== null && _a !== void 0 ? _a : ""}api.bentley.com/imodels` } });
285525
287086
  await core_frontend_1.NoRenderApp.startup({
285526
- applicationVersion: "4.0.0-dev.6",
287087
+ applicationVersion: "4.0.0-dev.8",
285527
287088
  applicationId: this.settings.gprid,
285528
287089
  authorizationClient: new frontend_1.TestFrontendAuthorizationClient(this.adminUserAccessToken),
285529
287090
  hubAccess: new imodels_access_frontend_1.FrontendIModelsAccess(iModelClient),
@@ -304952,7 +306513,7 @@ module.exports = JSON.parse('{"name":"axios","version":"0.21.4","description":"P
304952
306513
  /***/ ((module) => {
304953
306514
 
304954
306515
  "use strict";
304955
- module.exports = JSON.parse('{"name":"@itwin/core-frontend","version":"4.0.0-dev.6","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","build:ci":"npm run -s build && npm run -s build:esm","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","docs":"betools docs --includes=../../generated-docs/extract --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/primitives,**/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-eslintrc -c \\"../../tools/eslint-plugin/dist/configs/extension-exports-config.js\\" \\"./src/**/*.ts\\" 1>&2","lint":"eslint -f visualstudio \\"./src/**/*.ts\\" 1>&2","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run -s webpackTests && certa -r chrome","cover":"npm -s test","test:debug":"certa -r chrome --debug","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core/tree/master/core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:^4.0.0-dev.6","@itwin/core-bentley":"workspace:^4.0.0-dev.6","@itwin/core-common":"workspace:^4.0.0-dev.6","@itwin/core-geometry":"workspace:^4.0.0-dev.6","@itwin/core-orbitgt":"workspace:^4.0.0-dev.6","@itwin/core-quantity":"workspace:^4.0.0-dev.6"},"//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/certa":"workspace:*","@itwin/eslint-plugin":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@types/chai":"4.3.1","@types/chai-as-promised":"^7","@types/deep-assign":"^0.1.0","@types/lodash":"^4.14.0","@types/mocha":"^8.2.2","@types/node":"18.11.5","@types/qs":"^6.5.0","@types/semver":"7.3.10","@types/superagent":"^4.1.14","@types/sinon":"^9.0.0","babel-loader":"~8.2.5","babel-plugin-istanbul":"~6.1.1","chai":"^4.1.2","chai-as-promised":"^7","cpx2":"^3.0.0","eslint":"^7.11.0","glob":"^7.1.2","mocha":"^10.0.0","nyc":"^15.1.0","rimraf":"^3.0.2","sinon":"^9.0.2","source-map-loader":"^4.0.0","typescript":"~4.4.0","webpack":"^5.64.4"},"//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/object-storage-azure":"~1.4.0","@itwin/cloud-agnostic-core":"~1.4.0","@itwin/object-storage-core":"~1.4.0","@itwin/core-i18n":"workspace:*","@itwin/core-telemetry":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^3.1.6","@loaders.gl/draco":"^3.1.6","deep-assign":"^2.0.0","fuse.js":"^3.3.0","lodash":"^4.17.10","qs":"^6.5.3","semver":"^7.3.5","superagent":"^7.1.5","wms-capabilities":"0.4.0","reflect-metadata":"0.1.13"},"nyc":{"extends":"./node_modules/@itwin/build-tools/.nycrc"},"eslintConfig":{"plugins":["@itwin"],"extends":"plugin:@itwin/itwinjs-recommended","rules":{"@itwin/no-internal-barrel-imports":["error",{"required-barrel-modules":["./src/tile/internal.ts"]}],"@itwin/public-extension-exports":["error",{"releaseTags":["public","preview"],"outputApiFile":false}]},"overrides":[{"files":["*.test.ts","*.test.tsx","**/test/**/*.ts"],"rules":{"@itwin/no-internal-barrel-imports":"off"}}]}}');
306516
+ module.exports = JSON.parse('{"name":"@itwin/core-frontend","version":"4.0.0-dev.8","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","build:ci":"npm run -s build && npm run -s build:esm","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","docs":"betools docs --includes=../../generated-docs/extract --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/primitives,**/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-eslintrc -c \\"../../tools/eslint-plugin/dist/configs/extension-exports-config.js\\" \\"./src/**/*.ts\\" 1>&2","lint":"eslint -f visualstudio \\"./src/**/*.ts\\" 1>&2","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run -s webpackTests && certa -r chrome","cover":"npm -s test","test:debug":"certa -r chrome --debug","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core/tree/master/core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:^4.0.0-dev.8","@itwin/core-bentley":"workspace:^4.0.0-dev.8","@itwin/core-common":"workspace:^4.0.0-dev.8","@itwin/core-geometry":"workspace:^4.0.0-dev.8","@itwin/core-orbitgt":"workspace:^4.0.0-dev.8","@itwin/core-quantity":"workspace:^4.0.0-dev.8"},"//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/certa":"workspace:*","@itwin/eslint-plugin":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@types/chai":"4.3.1","@types/chai-as-promised":"^7","@types/deep-assign":"^0.1.0","@types/lodash":"^4.14.0","@types/mocha":"^8.2.2","@types/node":"18.11.5","@types/qs":"^6.5.0","@types/semver":"7.3.10","@types/superagent":"^4.1.14","@types/sinon":"^9.0.0","babel-loader":"~8.2.5","babel-plugin-istanbul":"~6.1.1","chai":"^4.1.2","chai-as-promised":"^7","cpx2":"^3.0.0","eslint":"^7.11.0","glob":"^7.1.2","mocha":"^10.0.0","nyc":"^15.1.0","rimraf":"^3.0.2","sinon":"^9.0.2","source-map-loader":"^4.0.0","typescript":"~4.4.0","webpack":"^5.64.4"},"//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/object-storage-azure":"~1.4.0","@itwin/cloud-agnostic-core":"~1.4.0","@itwin/object-storage-core":"~1.4.0","@itwin/core-i18n":"workspace:*","@itwin/core-telemetry":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^3.1.6","@loaders.gl/draco":"^3.1.6","deep-assign":"^2.0.0","fuse.js":"^3.3.0","lodash":"^4.17.10","qs":"^6.5.3","semver":"^7.3.5","superagent":"^7.1.5","wms-capabilities":"0.4.0","reflect-metadata":"0.1.13"},"nyc":{"extends":"./node_modules/@itwin/build-tools/.nycrc"},"eslintConfig":{"plugins":["@itwin"],"extends":"plugin:@itwin/itwinjs-recommended","rules":{"@itwin/no-internal-barrel-imports":["error",{"required-barrel-modules":["./src/tile/internal.ts"]}],"@itwin/public-extension-exports":["error",{"releaseTags":["public","preview"],"outputApiFile":false}]},"overrides":[{"files":["*.test.ts","*.test.tsx","**/test/**/*.ts"],"rules":{"@itwin/no-internal-barrel-imports":"off"}}]}}');
304956
306517
 
304957
306518
  /***/ }),
304958
306519