@itwin/ecschema-rpcinterface-tests 5.10.0-dev.6 → 5.10.0-dev.7

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.
@@ -158463,12 +158463,12 @@ class QuantityFormatter {
158463
158463
  const effectiveSystem = args.system ?? this._activeUnitSystem;
158464
158464
  return this._formatSpecsRegistry.get(args.name)?.get(args.persistenceUnitName)?.get(effectiveSystem);
158465
158465
  }
158466
- /** Create a cacheable handle to formatting specs for a specific KoQ and persistence unit.
158467
- * The handle auto-refreshes when the QuantityFormatter reloads. Call `dispose()` when done.
158466
+ /** Create a handle to formatting specs for a specific KoQ and persistence unit.
158467
+ * The handle reads the current specs from the formatter on access. Call `dispose()` when done.
158468
158468
  *
158469
158469
  * @param koqName - The KindOfQuantity name (e.g., "DefaultToolsUnits.LENGTH")
158470
158470
  * @param persistenceUnit - The persistence unit name (e.g., "Units.M")
158471
- * @returns A FormatSpecHandle that auto-updates on reload
158471
+ * @returns A FormatSpecHandle that reflects current formatter state
158472
158472
  * @beta
158473
158473
  */
158474
158474
  getFormatSpecHandle(koqName, persistenceUnit, system) {
@@ -158496,12 +158496,17 @@ class QuantityFormatter {
158496
158496
  formatProps,
158497
158497
  formatName: name,
158498
158498
  });
158499
- if (!this._formatSpecsRegistry.has(name))
158500
- this._formatSpecsRegistry.set(name, new Map());
158501
- const unitMap = this._formatSpecsRegistry.get(name);
158502
- if (!unitMap.has(persistenceUnitName))
158503
- unitMap.set(persistenceUnitName, new Map());
158504
- unitMap.get(persistenceUnitName).set(effectiveSystem, { formatterSpec, parserSpec });
158499
+ let unitMap = this._formatSpecsRegistry.get(name);
158500
+ if (!unitMap) {
158501
+ unitMap = new Map();
158502
+ this._formatSpecsRegistry.set(name, unitMap);
158503
+ }
158504
+ let systemMap = unitMap.get(persistenceUnitName);
158505
+ if (!systemMap) {
158506
+ systemMap = new Map();
158507
+ unitMap.set(persistenceUnitName, systemMap);
158508
+ }
158509
+ systemMap.set(effectiveSystem, { formatterSpec, parserSpec });
158505
158510
  }
158506
158511
  else {
158507
158512
  throw new Error(`Unable to find format properties for ${name} with persistence unit ${persistenceUnitName}`);
@@ -197216,30 +197221,36 @@ __webpack_require__.r(__webpack_exports__);
197216
197221
  /* harmony export */ BooleanClipNodeParity: () => (/* binding */ BooleanClipNodeParity),
197217
197222
  /* harmony export */ BooleanClipNodeUnion: () => (/* binding */ BooleanClipNodeUnion)
197218
197223
  /* harmony export */ });
197219
- /* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
197220
- /* harmony import */ var _numerics_Range1dArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../numerics/Range1dArray */ "../../core/geometry/lib/esm/numerics/Range1dArray.js");
197221
- /* harmony import */ var _ClipUtils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ClipUtils */ "../../core/geometry/lib/esm/clipping/ClipUtils.js");
197224
+ /* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
197225
+ /* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
197226
+ /* harmony import */ var _numerics_Range1dArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../numerics/Range1dArray */ "../../core/geometry/lib/esm/numerics/Range1dArray.js");
197227
+ /* harmony import */ var _ClipUtils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ClipUtils */ "../../core/geometry/lib/esm/clipping/ClipUtils.js");
197222
197228
  /*---------------------------------------------------------------------------------------------
197223
197229
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
197224
197230
  * See LICENSE.md in the project root for license terms and full copyright notice.
197225
197231
  *--------------------------------------------------------------------------------------------*/
197232
+ /** @packageDocumentation
197233
+ * @module CartesianGeometry
197234
+ */
197226
197235
 
197227
197236
 
197228
197237
 
197229
- /** BooleanClipNode is an abstract base class for boolean actions by an array of clippers.
197230
- * * Derived class must implement
197238
+
197239
+ /**
197240
+ * BooleanClipNode is an abstract base class for boolean actions by an array of clippers.
197241
+ * * Derived class must implement:
197231
197242
  * * The single point test `isPointOnOrInsideChildren`
197232
197243
  * * Boolean operation on 1d intervals `combineIntervals`
197233
- * * The `keepInside` flag controls an additional optional flip of the boolean result.
197234
- * * if `keepInside === true`, accept the "inside" of the clip clippers
197244
+ * * The `keepInside` flag controls an additional optional flip of the boolean result:
197245
+ * * if `keepInside === true`, accept the "inside" of the child clippers.
197235
197246
  * * if `keepInside === false`, accept the "outside" of the child clippers.
197236
- * * Hence the combinations of derived classes for (OR, AND, XOR) and keepInside are
197237
- * * (OR, true) = simple union (OR), i.e. "in" one or more clips
197238
- * * (OR, false) = complement of union (NOR), i.e. "outside" all clips
197239
- * * (AND, true) = simple intersection (AND), i.e. "in" all clips
197240
- * * (AND, false) = complement of intersection (NAND), i.e. "outside" one or more clips
197241
- * * (XOR,true) = simple parity, i.e. "in" an odd number of clips
197242
- * * (XOR,false) = complement of parity ), i.e. "in" an even number of clips
197247
+ * * Hence the combinations of derived classes for (OR, AND, XOR) and keepInside are:
197248
+ * * (OR, true) = simple union (OR), i.e., "in" one or more clips.
197249
+ * * (OR, false) = complement of union (NOR), i.e., "outside" all clips.
197250
+ * * (AND, true) = simple intersection (AND), i.e., "in" all clips.
197251
+ * * (AND, false) = complement of intersection (NAND), i.e., "outside" one or more clips.
197252
+ * * (XOR, true) = simple parity, i.e., "in" an odd number of clips.
197253
+ * * (XOR, false) = complement of parity, i.e., "in" an even number of clips.
197243
197254
  * @internal
197244
197255
  */
197245
197256
  class BooleanClipNode {
@@ -197276,18 +197287,18 @@ class BooleanClipNode {
197276
197287
  this._clippers.push(child);
197277
197288
  }
197278
197289
  }
197279
- /** Toggle the "keepInside" behavior. Return the prior value. */
197290
+ /** Toggle the "keepInside" behavior. Return the prior value. */
197280
197291
  toggleResult() {
197281
197292
  return this.selectResult(!this._keepInside);
197282
197293
  }
197283
- /** Set the "keepInside" behavior */
197294
+ /** Set the "keepInside" behavior. */
197284
197295
  selectResult(keepInside) {
197285
197296
  const s = this._keepInside;
197286
197297
  this._keepInside = keepInside;
197287
197298
  return s;
197288
197299
  }
197289
197300
  /**
197290
- * Conditionally (if a1 > a0 strictly) call announce (a0, a1).
197301
+ * Conditionally (if a1 > a0 strictly) call `announce(a0, a1)`.
197291
197302
  * * Return 0 if not called, 1 if called.
197292
197303
  */
197293
197304
  testedAnnounceNN(a0, a1, announce) {
@@ -197299,7 +197310,7 @@ class BooleanClipNode {
197299
197310
  return 0;
197300
197311
  }
197301
197312
  /**
197302
- * Conditionally (if a1 > a0 strictly) call announce (a0, a1, cp).
197313
+ * Conditionally (if a1 > a0 strictly) call `announce(a0, a1, cp)`.
197303
197314
  * * Return 0 if not called, 1 if called.
197304
197315
  */
197305
197316
  testedAnnounceNNC(a0, a1, cp, announce) {
@@ -197310,14 +197321,14 @@ class BooleanClipNode {
197310
197321
  }
197311
197322
  return 0;
197312
197323
  }
197313
- /** Swap the _intervalsA and _intervalsB */
197324
+ /** Swap the `_intervalsA` and `_intervalsB`. */
197314
197325
  swapAB() {
197315
197326
  const q = this._intervalsA;
197316
197327
  this._intervalsA = this._intervalsB;
197317
197328
  this._intervalsB = q;
197318
197329
  }
197319
197330
  /**
197320
- * Announce all "outside intervals" --not masked by intervals
197331
+ * Announce all "outside intervals" -- not masked by intervals.
197321
197332
  * * Return true if any intervals announced.
197322
197333
  */
197323
197334
  announcePartsNN(keepInside, intervals, f0, f1, announce) {
@@ -197339,7 +197350,7 @@ class BooleanClipNode {
197339
197350
  return numAnnounce > 0;
197340
197351
  }
197341
197352
  /**
197342
- * Announce all "outside intervals" --not masked by intervals
197353
+ * Announce all "outside intervals" -- not masked by intervals.
197343
197354
  * * Return true if any intervals announced.
197344
197355
  */
197345
197356
  announcePartsNNC(keepInside, intervals, f0, f1, cp, announce) {
@@ -197360,16 +197371,16 @@ class BooleanClipNode {
197360
197371
  }
197361
197372
  return numAnnounce > 0;
197362
197373
  }
197363
- /** Invoke callback to test if a point is "in" this clipper */
197374
+ /** Invoke callback to test if a point is "in" this clipper. */
197364
197375
  isPointOnOrInside(point) {
197365
197376
  const q = this.isPointOnOrInsideChildren(point);
197366
197377
  return this._keepInside ? q : !q;
197367
197378
  }
197368
- /** Announce "in" portions of a line segment. See `Clipper.announceClippedSegmentIntervals` */
197379
+ /** Method from [[Clipper]] interface. */
197369
197380
  announceClippedSegmentIntervals(f0, f1, pointA, pointB, announce) {
197370
197381
  this._intervalsA.length = 0;
197371
197382
  const announceIntervalB = (a0, a1) => {
197372
- this._intervalsB.push(_geometry3d_Range__WEBPACK_IMPORTED_MODULE_0__.Range1d.createXX(a0, a1));
197383
+ this._intervalsB.push(_geometry3d_Range__WEBPACK_IMPORTED_MODULE_1__.Range1d.createXX(a0, a1));
197373
197384
  };
197374
197385
  // Strategy:
197375
197386
  // _intervalsA is the accumulated UNION of from clippers
@@ -197381,7 +197392,7 @@ class BooleanClipNode {
197381
197392
  for (const c of this._clippers) {
197382
197393
  this._intervalsB.length = 0;
197383
197394
  c.announceClippedSegmentIntervals(f0, f1, pointA, pointB, announceIntervalB);
197384
- _numerics_Range1dArray__WEBPACK_IMPORTED_MODULE_1__.Range1dArray.simplifySortUnion(this._intervalsB);
197395
+ _numerics_Range1dArray__WEBPACK_IMPORTED_MODULE_2__.Range1dArray.simplifySortUnion(this._intervalsB);
197385
197396
  if (i === 0) {
197386
197397
  this.swapAB();
197387
197398
  }
@@ -197392,17 +197403,17 @@ class BooleanClipNode {
197392
197403
  }
197393
197404
  return this.announcePartsNN(this._keepInside, this._intervalsA, f0, f1, announce);
197394
197405
  }
197395
- /** Announce "in" portions of a line segment. See `Clipper.announceClippedSegmentIntervals` */
197406
+ /** Method from [[Clipper]] interface. */
197396
197407
  announceClippedArcIntervals(arc, announce) {
197397
197408
  this._intervalsA.length = 0;
197398
197409
  const announceIntervalB = (a0, a1) => {
197399
- this._intervalsB.push(_geometry3d_Range__WEBPACK_IMPORTED_MODULE_0__.Range1d.createXX(a0, a1));
197410
+ this._intervalsB.push(_geometry3d_Range__WEBPACK_IMPORTED_MODULE_1__.Range1d.createXX(a0, a1));
197400
197411
  };
197401
197412
  let i = 0;
197402
197413
  for (const c of this._clippers) {
197403
197414
  this._intervalsB.length = 0;
197404
197415
  c.announceClippedArcIntervals(arc, announceIntervalB);
197405
- _numerics_Range1dArray__WEBPACK_IMPORTED_MODULE_1__.Range1dArray.simplifySortUnion(this._intervalsB);
197416
+ _numerics_Range1dArray__WEBPACK_IMPORTED_MODULE_2__.Range1dArray.simplifySortUnion(this._intervalsB);
197406
197417
  if (i === 0) {
197407
197418
  this.swapAB();
197408
197419
  }
@@ -197413,17 +197424,40 @@ class BooleanClipNode {
197413
197424
  }
197414
197425
  return this.announcePartsNNC(this._keepInside, this._intervalsA, 0, 1, arc, announce);
197415
197426
  }
197427
+ /* Method from [[Clipper]] interface. */
197428
+ announceClippedCurveIntervals(curve, announce) {
197429
+ this._intervalsA.length = 0;
197430
+ const announceIntervalB = (a0, a1, _cp) => {
197431
+ this._intervalsB.push(_geometry3d_Range__WEBPACK_IMPORTED_MODULE_1__.Range1d.createXX(a0, a1));
197432
+ };
197433
+ let i = 0;
197434
+ for (const c of this._clippers) {
197435
+ this._intervalsB.length = 0;
197436
+ c.announceClippedCurveIntervals?.(curve, announceIntervalB) ?? (0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.assert)(false, () => `Expect ${c.constructor.name} to implement announceClippedCurveIntervals`);
197437
+ _numerics_Range1dArray__WEBPACK_IMPORTED_MODULE_2__.Range1dArray.simplifySortUnion(this._intervalsB);
197438
+ if (i === 0) {
197439
+ this.swapAB();
197440
+ }
197441
+ else {
197442
+ this._intervalsA = this.combineIntervals(this._intervalsA, this._intervalsB);
197443
+ }
197444
+ i++;
197445
+ }
197446
+ return this.announcePartsNNC(this._keepInside, this._intervalsA, 0, 1, curve, announce);
197447
+ }
197416
197448
  }
197417
197449
  /**
197418
- * Implement [BooleanClipNode] virtual methods for intersection (boolean OR) among children
197450
+ * Implement [BooleanClipNode] virtual methods for intersection (boolean OR) among children.
197419
197451
  * @internal
197420
197452
  */
197421
197453
  class BooleanClipNodeUnion extends BooleanClipNode {
197422
- get operationName() { return this._keepInside ? "OR" : "NOR"; }
197454
+ get operationName() {
197455
+ return this._keepInside ? "OR" : "NOR";
197456
+ }
197423
197457
  constructor(keepInside) {
197424
197458
  super(keepInside);
197425
197459
  }
197426
- /** Return true if inside any child clipper */
197460
+ /** Return true if inside any child clipper. */
197427
197461
  isPointOnOrInsideChildren(point) {
197428
197462
  for (const clipper of this._clippers) {
197429
197463
  if (clipper.isPointOnOrInside(point))
@@ -197432,22 +197466,24 @@ class BooleanClipNodeUnion extends BooleanClipNode {
197432
197466
  return false;
197433
197467
  }
197434
197468
  combineIntervals(operandA, operandB) {
197435
- return _numerics_Range1dArray__WEBPACK_IMPORTED_MODULE_1__.Range1dArray.unionSorted(operandA, operandB);
197469
+ return _numerics_Range1dArray__WEBPACK_IMPORTED_MODULE_2__.Range1dArray.unionSorted(operandA, operandB);
197436
197470
  }
197437
197471
  appendPolygonClip(xyz, insideFragments, outsideFragments, arrayCache) {
197438
- _ClipUtils__WEBPACK_IMPORTED_MODULE_2__.ClipUtilities.doPolygonClipSequence(xyz, this._clippers, this._keepInside ? insideFragments : outsideFragments, this._keepInside ? outsideFragments : insideFragments, undefined, _ClipUtils__WEBPACK_IMPORTED_MODULE_2__.ClipStepAction.acceptIn, _ClipUtils__WEBPACK_IMPORTED_MODULE_2__.ClipStepAction.passToNextStep, _ClipUtils__WEBPACK_IMPORTED_MODULE_2__.ClipStepAction.acceptOut, arrayCache);
197472
+ _ClipUtils__WEBPACK_IMPORTED_MODULE_3__.ClipUtilities.doPolygonClipSequence(xyz, this._clippers, this._keepInside ? insideFragments : outsideFragments, this._keepInside ? outsideFragments : insideFragments, undefined, _ClipUtils__WEBPACK_IMPORTED_MODULE_3__.ClipStepAction.acceptIn, _ClipUtils__WEBPACK_IMPORTED_MODULE_3__.ClipStepAction.passToNextStep, _ClipUtils__WEBPACK_IMPORTED_MODULE_3__.ClipStepAction.acceptOut, arrayCache);
197439
197473
  }
197440
197474
  }
197441
197475
  /**
197442
- * Implement [BooleanClipNode] virtual methods for intersection (boolean OR) among children
197476
+ * Implement [BooleanClipNode] virtual methods for intersection (boolean OR) among children.
197443
197477
  * @internal
197444
197478
  */
197445
197479
  class BooleanClipNodeParity extends BooleanClipNode {
197446
- get operationName() { return this._keepInside ? "XOR" : "NXOR"; }
197480
+ get operationName() {
197481
+ return this._keepInside ? "XOR" : "NXOR";
197482
+ }
197447
197483
  constructor(keepInside) {
197448
197484
  super(keepInside);
197449
197485
  }
197450
- /** Return true if inside an odd number of clippers child clipper */
197486
+ /** Return true if inside an odd number of clippers child clipper. */
197451
197487
  isPointOnOrInsideChildren(point) {
197452
197488
  let q = false;
197453
197489
  for (const clipper of this._clippers) {
@@ -197457,18 +197493,20 @@ class BooleanClipNodeParity extends BooleanClipNode {
197457
197493
  return q;
197458
197494
  }
197459
197495
  combineIntervals(operandA, operandB) {
197460
- return _numerics_Range1dArray__WEBPACK_IMPORTED_MODULE_1__.Range1dArray.paritySorted(operandA, operandB);
197496
+ return _numerics_Range1dArray__WEBPACK_IMPORTED_MODULE_2__.Range1dArray.paritySorted(operandA, operandB);
197461
197497
  }
197462
197498
  appendPolygonClip(xyz, insideFragments, outsideFragments, arrayCache) {
197463
- _ClipUtils__WEBPACK_IMPORTED_MODULE_2__.ClipUtilities.doPolygonClipParitySequence(xyz, this._clippers, this._keepInside ? insideFragments : outsideFragments, this._keepInside ? outsideFragments : insideFragments, arrayCache);
197499
+ _ClipUtils__WEBPACK_IMPORTED_MODULE_3__.ClipUtilities.doPolygonClipParitySequence(xyz, this._clippers, this._keepInside ? insideFragments : outsideFragments, this._keepInside ? outsideFragments : insideFragments, arrayCache);
197464
197500
  }
197465
197501
  }
197466
197502
  /**
197467
- * Implement [BooleanClipNode] virtual methods for intersection (boolean OR) among children
197503
+ * Implement [BooleanClipNode] virtual methods for intersection (boolean OR) among children.
197468
197504
  * @internal
197469
197505
  */
197470
197506
  class BooleanClipNodeIntersection extends BooleanClipNode {
197471
- get operationName() { return this._keepInside ? "AND" : "NAND"; }
197507
+ get operationName() {
197508
+ return this._keepInside ? "AND" : "NAND";
197509
+ }
197472
197510
  constructor(keepInside) {
197473
197511
  super(keepInside);
197474
197512
  }
@@ -197481,10 +197519,10 @@ class BooleanClipNodeIntersection extends BooleanClipNode {
197481
197519
  return true;
197482
197520
  }
197483
197521
  combineIntervals(operandA, operandB) {
197484
- return _numerics_Range1dArray__WEBPACK_IMPORTED_MODULE_1__.Range1dArray.intersectSorted(operandA, operandB);
197522
+ return _numerics_Range1dArray__WEBPACK_IMPORTED_MODULE_2__.Range1dArray.intersectSorted(operandA, operandB);
197485
197523
  }
197486
197524
  appendPolygonClip(xyz, insideFragments, outsideFragments, arrayCache) {
197487
- _ClipUtils__WEBPACK_IMPORTED_MODULE_2__.ClipUtilities.doPolygonClipSequence(xyz, this._clippers, this._keepInside ? insideFragments : outsideFragments, this._keepInside ? outsideFragments : insideFragments, undefined, _ClipUtils__WEBPACK_IMPORTED_MODULE_2__.ClipStepAction.passToNextStep, _ClipUtils__WEBPACK_IMPORTED_MODULE_2__.ClipStepAction.acceptOut, _ClipUtils__WEBPACK_IMPORTED_MODULE_2__.ClipStepAction.acceptIn, arrayCache);
197525
+ _ClipUtils__WEBPACK_IMPORTED_MODULE_3__.ClipUtilities.doPolygonClipSequence(xyz, this._clippers, this._keepInside ? insideFragments : outsideFragments, this._keepInside ? outsideFragments : insideFragments, undefined, _ClipUtils__WEBPACK_IMPORTED_MODULE_3__.ClipStepAction.passToNextStep, _ClipUtils__WEBPACK_IMPORTED_MODULE_3__.ClipStepAction.acceptOut, _ClipUtils__WEBPACK_IMPORTED_MODULE_3__.ClipStepAction.acceptIn, arrayCache);
197488
197526
  }
197489
197527
  }
197490
197528
 
@@ -197544,7 +197582,7 @@ __webpack_require__.r(__webpack_exports__);
197544
197582
  * More details can be found at docs/learning/geometry/Clipping.md
197545
197583
  *
197546
197584
  * Hence
197547
- * * The halfspace function evaluation for "point" (x,y,z) is `(x,y,z) DOT (u,v,w) - signedDistance`.
197585
+ * * The halfspace function evaluation for point (x,y,z) is `(x,y,z) DOT (u,v,w) - signedDistance`.
197548
197586
  * * POSITIVE values of the halfspace function are "inside".
197549
197587
  * * ZERO value of the halfspace function is "on".
197550
197588
  * * NEGATIVE value of the halfspace function is "outside".
@@ -197557,7 +197595,7 @@ class ClipPlane extends _geometry3d_Plane3d__WEBPACK_IMPORTED_MODULE_1__.Plane3d
197557
197595
  /**
197558
197596
  * Construct a parallel plane through the origin.
197559
197597
  * * Move it to the actual position.
197560
- * * _distanceFromOrigin is the distance it moved, with the (inward) normal direction as positive
197598
+ * * _distanceFromOrigin is the distance it moved, with the (inward) normal direction as positive.
197561
197599
  */
197562
197600
  _distanceFromOrigin;
197563
197601
  _invisible;
@@ -197893,9 +197931,9 @@ class ClipPlane extends _geometry3d_Plane3d__WEBPACK_IMPORTED_MODULE_1__.Plane3d
197893
197931
  return Math.abs(this.altitude(point)) <= tolerance;
197894
197932
  }
197895
197933
  /**
197896
- * Compute intersections of an (UNBOUNDED) arc with the plane. Append them (as radians) to a growing array.
197897
- * @param arc arc to test. The angle limits of the arc are NOT considered.
197898
- * @param intersectionRadians array to receive results
197934
+ * Compute intersections of an (UNBOUNDED) arc with the plane. Append them (as radians) to a growing array.
197935
+ * @param arc arc to test. The angle limits of the arc are NOT considered.
197936
+ * @param intersectionRadians array to receive results.
197899
197937
  */
197900
197938
  appendIntersectionRadians(arc, intersectionRadians) {
197901
197939
  const arcVectors = arc.toVectors();
@@ -197904,18 +197942,25 @@ class ClipPlane extends _geometry3d_Plane3d__WEBPACK_IMPORTED_MODULE_1__.Plane3d
197904
197942
  const gamma = this.velocity(arcVectors.vector90);
197905
197943
  _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_6__.AnalyticRoots.appendImplicitLineUnitCircleIntersections(alpha, beta, gamma, undefined, undefined, intersectionRadians);
197906
197944
  }
197907
- static _clipArcFractionArray = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array();
197908
- /**
197909
- * Announce fractional intervals of arc clip.
197910
- * * Each call to `announce(fraction0, fraction1, arc)` announces one interval that is inside the clip plane.
197911
- */
197945
+ static _clipFractionArray = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array();
197946
+ /** Method from [[Clipper]] interface. */
197912
197947
  announceClippedArcIntervals(arc, announce) {
197913
- const breaks = ClipPlane._clipArcFractionArray;
197948
+ const breaks = ClipPlane._clipFractionArray;
197914
197949
  breaks.clear();
197915
197950
  this.appendIntersectionRadians(arc, breaks);
197916
197951
  arc.sweep.radiansArrayToPositivePeriodicFractions(breaks);
197917
197952
  return _ClipUtils__WEBPACK_IMPORTED_MODULE_8__.ClipUtilities.selectIntervals01(arc, breaks, this, announce);
197918
197953
  }
197954
+ /** Method from [[Clipper]] interface. */
197955
+ announceClippedCurveIntervals(curve, announce) {
197956
+ const breaks = ClipPlane._clipFractionArray;
197957
+ breaks.clear();
197958
+ const results = [];
197959
+ curve.appendPlaneIntersectionPoints(this, results);
197960
+ for (const r of results)
197961
+ breaks.push(r.fraction);
197962
+ return _ClipUtils__WEBPACK_IMPORTED_MODULE_8__.ClipUtilities.selectIntervals01(curve, breaks, this, announce);
197963
+ }
197919
197964
  /**
197920
197965
  * Compute intersection of (unbounded) segment with the plane.
197921
197966
  * * If the ends are on the same side of the plane, return undefined.
@@ -198010,7 +198055,7 @@ class ClipPlane extends _geometry3d_Plane3d__WEBPACK_IMPORTED_MODULE_1__.Plane3d
198010
198055
  this.setPlane4d(plane);
198011
198056
  return true;
198012
198057
  }
198013
- /** Announce the interval (if any) where a line is within the clip plane half space. */
198058
+ /** Method from [[Clipper]] interface. */
198014
198059
  announceClippedSegmentIntervals(f0, f1, pointA, pointB, announce) {
198015
198060
  if (f1 < f0)
198016
198061
  return false;
@@ -198214,7 +198259,7 @@ var ClipMaskXYZRangePlanes;
198214
198259
  class ClipPrimitive {
198215
198260
  /** The (union of) convex regions. */
198216
198261
  _clipPlanes;
198217
- /** If true, pointInside inverts the sense of the pointInside for the _clipPlanes */
198262
+ /** If true, pointInside inverts the sense of the pointInside for the _clipPlanes. */
198218
198263
  _invisible;
198219
198264
  /**
198220
198265
  * Get a reference to the `UnionOfConvexClipPlaneSets`.
@@ -198302,7 +198347,7 @@ class ClipPrimitive {
198302
198347
  }
198303
198348
  /**
198304
198349
  * Method from [[Clipper]] interface.
198305
- * * Implement as dispatch to clipPlaneSets as supplied by derived class.
198350
+ * * Implement as dispatch to clip volume as supplied by derived class.
198306
198351
  */
198307
198352
  announceClippedSegmentIntervals(f0, f1, pointA, pointB, announce) {
198308
198353
  this.ensurePlaneSets();
@@ -198313,7 +198358,7 @@ class ClipPrimitive {
198313
198358
  }
198314
198359
  /**
198315
198360
  * Method from [[Clipper]] interface.
198316
- * * Implement as dispatch to clipPlaneSets as supplied by derived class.
198361
+ * * Implement as dispatch to clip volume as supplied by derived class.
198317
198362
  */
198318
198363
  announceClippedArcIntervals(arc, announce) {
198319
198364
  this.ensurePlaneSets();
@@ -198322,6 +198367,17 @@ class ClipPrimitive {
198322
198367
  hasInsideParts = this._clipPlanes.announceClippedArcIntervals(arc, announce);
198323
198368
  return hasInsideParts;
198324
198369
  }
198370
+ /**
198371
+ * Method from [[Clipper]] interface.
198372
+ * * Implement as dispatch to clip volume as supplied by derived class.
198373
+ */
198374
+ announceClippedCurveIntervals(curve, announce) {
198375
+ this.ensurePlaneSets();
198376
+ let hasInsideParts = false;
198377
+ if (this._clipPlanes)
198378
+ hasInsideParts = this._clipPlanes.announceClippedCurveIntervals(curve, announce);
198379
+ return hasInsideParts;
198380
+ }
198325
198381
  /**
198326
198382
  * Multiply all ClipPlanes DPoint4d by matrix.
198327
198383
  * @param matrix matrix to apply.
@@ -198447,13 +198503,13 @@ class PolyEdge {
198447
198503
  class ClipShape extends ClipPrimitive {
198448
198504
  /** Points of the polygon, in the xy plane of the local coordinate system. */
198449
198505
  _polygon;
198450
- /** optional low z (in local coordinates). */
198506
+ /** Optional low z (in local coordinates). */
198451
198507
  _zLow;
198452
- /** optional high z (in local coordinates). */
198508
+ /** Optional high z (in local coordinates). */
198453
198509
  _zHigh;
198454
- /** true if this is considered a hole (keep geometry outside of the polygon). */
198510
+ /** True if this is considered a hole (keep geometry outside of the polygon). */
198455
198511
  _isMask;
198456
- /** transform from local to world. */
198512
+ /** Transform from local to world. */
198457
198513
  _transformFromClip;
198458
198514
  /** Transform from world to local. */
198459
198515
  _transformToClip;
@@ -200044,7 +200100,7 @@ __webpack_require__.r(__webpack_exports__);
200044
200100
 
200045
200101
 
200046
200102
  /**
200047
- * Class holding an array structure of shapes defined by `ClipPrimitive`
200103
+ * Class holding an array structure of shapes defined by `ClipPrimitive`.
200048
200104
  * * The `ClipVector` defines an intersection of the member `ClipPrimitive` regions.
200049
200105
  * * In the most common usage, one of the `ClipPrimitive` will be an outer region, and all others are holes with marker
200050
200106
  * flag indicating that the outside of each hole is live.
@@ -200060,12 +200116,16 @@ class ClipVector {
200060
200116
  */
200061
200117
  boundingRange = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_1__.Range3d.createNull();
200062
200118
  /** Returns a reference to the array of ClipShapes. */
200063
- get clips() { return this._clips; }
200119
+ get clips() {
200120
+ return this._clips;
200121
+ }
200064
200122
  constructor(clips) {
200065
200123
  this._clips = clips ? clips : [];
200066
200124
  }
200067
200125
  /** Returns true if this ClipVector contains a ClipPrimitive. */
200068
- get isValid() { return this._clips.length > 0; }
200126
+ get isValid() {
200127
+ return this._clips.length > 0;
200128
+ }
200069
200129
  /** Create a ClipVector with an empty set of ClipShapes. */
200070
200130
  static createEmpty(result) {
200071
200131
  if (result) {
@@ -200160,7 +200220,7 @@ class ClipVector {
200160
200220
  }
200161
200221
  return true;
200162
200222
  }
200163
- // Proxy object to implement line and arc clip.
200223
+ // Proxy object to implement curve clipping.
200164
200224
  _clipNodeProxy;
200165
200225
  ensureProxyClipNode() {
200166
200226
  if (this._clipNodeProxy)
@@ -200178,7 +200238,7 @@ class ClipVector {
200178
200238
  }
200179
200239
  /**
200180
200240
  * Method from [[Clipper]] interface.
200181
- * * Implement as dispatch to clipPlaneSets as supplied by derived class.
200241
+ * * Implement as intersection of child clippers.
200182
200242
  */
200183
200243
  announceClippedSegmentIntervals(f0, f1, pointA, pointB, announce) {
200184
200244
  this.ensureProxyClipNode();
@@ -200186,8 +200246,9 @@ class ClipVector {
200186
200246
  return this._clipNodeProxy.announceClippedSegmentIntervals(f0, f1, pointA, pointB, announce);
200187
200247
  return false;
200188
200248
  }
200189
- /** Method from [[Clipper]] interface.
200190
- * * Implement as dispatch to clipPlaneSets as supplied by derived class.
200249
+ /**
200250
+ * Method from [[Clipper]] interface.
200251
+ * * Implement as intersection of child clippers.
200191
200252
  */
200192
200253
  announceClippedArcIntervals(arc, announce) {
200193
200254
  this.ensureProxyClipNode();
@@ -200195,6 +200256,16 @@ class ClipVector {
200195
200256
  return this._clipNodeProxy.announceClippedArcIntervals(arc, announce);
200196
200257
  return false;
200197
200258
  }
200259
+ /**
200260
+ * Method from [[Clipper]] interface.
200261
+ * * Implement as intersection of child clippers.
200262
+ */
200263
+ announceClippedCurveIntervals(curve, announce) {
200264
+ this.ensureProxyClipNode();
200265
+ if (this._clipNodeProxy)
200266
+ return this._clipNodeProxy.announceClippedCurveIntervals(curve, announce);
200267
+ return false;
200268
+ }
200198
200269
  /** Execute polygon clip as intersection of the child primitives. */
200199
200270
  appendPolygonClip(xyz, insideFragments, outsideFragments, arrayCache) {
200200
200271
  this.ensureProxyClipNode();
@@ -200523,6 +200594,7 @@ __webpack_require__.r(__webpack_exports__);
200523
200594
 
200524
200595
  /**
200525
200596
  * A ConvexClipPlaneSet is a collection of ClipPlanes, often used for bounding regions of space.
200597
+ * The collection must form a single convex volume.
200526
200598
  * @public
200527
200599
  */
200528
200600
  class ConvexClipPlaneSet {
@@ -200838,20 +200910,7 @@ class ConvexClipPlaneSet {
200838
200910
  }
200839
200911
  return true;
200840
200912
  }
200841
- /**
200842
- * Find the parts of the line segment (if any) that is within the convex clip volume.
200843
- * * The line segment is defined by `pointA` and `pointB`.
200844
- * * The input fractional interval from `fraction0` to `fraction1` (increasing) is the active part to consider.
200845
- * * To clip to the usual bounded line segment, start with fractions (0,1).
200846
- * If the clip volume is unbounded, the line interval may also be unbounded.
200847
- * * An unbounded line portion will have fraction coordinates positive or negative `Number.MAX_VALUE`.
200848
- * @param f0 fraction that is the initial lower fraction of the active interval (e.g., 0.0 for bounded segment).
200849
- * @param f1 fraction that is the initial upper fraction of the active interval (e.g., 1.0 for bounded segment).
200850
- * @param pointA segment start (fraction 0)
200851
- * @param pointB segment end (fraction 1)
200852
- * @param announce function to be called to announce a fraction interval that is within the convex clip volume.
200853
- * @returns true if a segment was announced, false if entirely outside.
200854
- */
200913
+ /** Method from [[Clipper]] interface. */
200855
200914
  announceClippedSegmentIntervals(f0, f1, pointA, pointB, announce) {
200856
200915
  let fraction;
200857
200916
  if (f1 < f0)
@@ -200890,13 +200949,10 @@ class ConvexClipPlaneSet {
200890
200949
  }
200891
200950
  return false;
200892
200951
  }
200893
- static _clipArcFractionArray = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_4__.GrowableFloat64Array();
200894
- /**
200895
- * Find fractional parts of the arc that are within this ClipPlaneSet, and announce each as
200896
- * * `announce(fraction, fraction, curve)`
200897
- */
200952
+ static _clipFractionArray = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_4__.GrowableFloat64Array();
200953
+ /** Method from [[Clipper]] interface. */
200898
200954
  announceClippedArcIntervals(arc, announce) {
200899
- const breaks = ConvexClipPlaneSet._clipArcFractionArray;
200955
+ const breaks = ConvexClipPlaneSet._clipFractionArray;
200900
200956
  breaks.clear();
200901
200957
  for (const clipPlane of this.planes) {
200902
200958
  clipPlane.appendIntersectionRadians(arc, breaks);
@@ -200904,6 +200960,17 @@ class ConvexClipPlaneSet {
200904
200960
  arc.sweep.radiansArrayToPositivePeriodicFractions(breaks);
200905
200961
  return _ClipUtils__WEBPACK_IMPORTED_MODULE_5__.ClipUtilities.selectIntervals01(arc, breaks, this, announce);
200906
200962
  }
200963
+ /** Method from [[Clipper]] interface. */
200964
+ announceClippedCurveIntervals(curve, announce) {
200965
+ const breaks = ConvexClipPlaneSet._clipFractionArray;
200966
+ breaks.clear();
200967
+ const results = [];
200968
+ for (const clipPlane of this.planes)
200969
+ curve.appendPlaneIntersectionPoints(clipPlane, results);
200970
+ for (const r of results)
200971
+ breaks.push(r.fraction);
200972
+ return _ClipUtils__WEBPACK_IMPORTED_MODULE_5__.ClipUtilities.selectIntervals01(curve, breaks, this, announce);
200973
+ }
200907
200974
  /**
200908
200975
  * Find the parts of the (unbounded) line segment (if any) that is within the convex clip volume.
200909
200976
  * @param pointA segment start (fraction 0)
@@ -201304,7 +201371,7 @@ __webpack_require__.r(__webpack_exports__);
201304
201371
 
201305
201372
  /**
201306
201373
  * A collection of ConvexClipPlaneSets.
201307
- * * A point is "in" the clip plane set if it is "in" one or more of the ConvexClipPlaneSet
201374
+ * * A point is "in" the clip plane set if it is "in" one or more of the ConvexClipPlaneSets.
201308
201375
  * * Hence the boolean logic is that the ClipPlaneSet is a UNION of its constituents.
201309
201376
  * @public
201310
201377
  */
@@ -201497,17 +201564,7 @@ class UnionOfConvexClipPlaneSets {
201497
201564
  output.push(convexSetOutput);
201498
201565
  }
201499
201566
  }
201500
- /**
201501
- * Announce clipSegment() for each convexSet in this ClipPlaneSet.
201502
- * * all clipPlaneSets are inspected.
201503
- * * announced intervals are for each individual clipPlaneSet -- adjacent intervals are not consolidated.
201504
- * @param f0 active interval start.
201505
- * @param f1 active interval end.
201506
- * @param pointA line segment start.
201507
- * @param pointB line segment end.
201508
- * @param announce function to announce interval.
201509
- * @returns Return true if any announcements are made.
201510
- */
201567
+ /** Method from [[Clipper]] interface. */
201511
201568
  announceClippedSegmentIntervals(f0, f1, pointA, pointB, announce) {
201512
201569
  let numAnnounce = 0;
201513
201570
  for (const convexSet of this._convexSets) {
@@ -201516,22 +201573,29 @@ class UnionOfConvexClipPlaneSets {
201516
201573
  }
201517
201574
  return numAnnounce > 0;
201518
201575
  }
201519
- static _clipArcFractionArray = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_6__.GrowableFloat64Array();
201520
- /**
201521
- * Find parts of an arc that are inside any member clipper.
201522
- * Announce each with `announce(startFraction, endFraction, this)`
201523
- */
201576
+ static _clipFractionArray = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_6__.GrowableFloat64Array();
201577
+ /** Method from [[Clipper]] interface. */
201524
201578
  announceClippedArcIntervals(arc, announce) {
201525
- const breaks = UnionOfConvexClipPlaneSets._clipArcFractionArray;
201579
+ const breaks = UnionOfConvexClipPlaneSets._clipFractionArray;
201526
201580
  breaks.clear();
201527
- for (const convexSet of this._convexSets) {
201528
- for (const clipPlane of convexSet.planes) {
201581
+ for (const convexSet of this._convexSets)
201582
+ for (const clipPlane of convexSet.planes)
201529
201583
  clipPlane.appendIntersectionRadians(arc, breaks);
201530
- }
201531
- }
201532
201584
  arc.sweep.radiansArrayToPositivePeriodicFractions(breaks);
201533
201585
  return _ClipUtils__WEBPACK_IMPORTED_MODULE_4__.ClipUtilities.selectIntervals01(arc, breaks, this, announce);
201534
201586
  }
201587
+ /** Method from [[Clipper]] interface. */
201588
+ announceClippedCurveIntervals(curve, announce) {
201589
+ const breaks = UnionOfConvexClipPlaneSets._clipFractionArray;
201590
+ breaks.clear();
201591
+ const results = [];
201592
+ for (const convexSet of this._convexSets)
201593
+ for (const clipPlane of convexSet.planes)
201594
+ curve.appendPlaneIntersectionPoints(clipPlane, results);
201595
+ for (const r of results)
201596
+ breaks.push(r.fraction);
201597
+ return _ClipUtils__WEBPACK_IMPORTED_MODULE_4__.ClipUtilities.selectIntervals01(curve, breaks, this, announce);
201598
+ }
201535
201599
  /**
201536
201600
  * Collect the output from computePlanePlanePlaneIntersections in all the contained convex sets.
201537
201601
  * @param points (optional) array to which computed points are to be added.
@@ -208605,15 +208669,14 @@ class CurvePrimitive extends _GeometryQuery__WEBPACK_IMPORTED_MODULE_1__.Geometr
208605
208669
  return closestTangent;
208606
208670
  }
208607
208671
  /**
208608
- * Find intervals of this curvePrimitive that are interior to a clipper
208672
+ * Find intervals of this curve that are interior to the clipper.
208673
+ * * Default implementation calls `clipper.announceClippedCurveIntervals`; subclasses can implement more efficiently as necessary.
208609
208674
  * @param clipper clip structure (e.g. clip planes)
208610
- * @param announce (optional) function to be called announcing fractional intervals
208611
- * `announce(fraction0, fraction1, curvePrimitive)`
208675
+ * @param announce (optional) called to announce each fractional interval: `announce(fraction0, fraction1, this)`
208612
208676
  * @returns true if any "in" segments are announced.
208613
208677
  */
208614
- announceClipIntervals(_clipper, _announce) {
208615
- // DEFAULT IMPLEMENTATION -- no interior parts
208616
- return false;
208678
+ announceClipIntervals(clipper, announce) {
208679
+ return clipper.announceClippedCurveIntervals?.(this, announce) ?? false;
208617
208680
  }
208618
208681
  /**
208619
208682
  * Return (if possible) a curve primitive which is a portion of this curve.
@@ -210930,13 +210993,11 @@ class LineString3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_2__.CurvePri
210930
210993
  dispatchToGeometryHandler(handler) {
210931
210994
  return handler.handleLineString3d(this);
210932
210995
  }
210933
- // HARD TO TEST -- tests that get to announceClipInterval for arc, bspline do NOT get here with
210934
- // linestring because the controller has special case loops through segments?
210935
210996
  /**
210936
- * Find intervals of this CurvePrimitive that are interior to a clipper
210937
- * @param clipper clip structure (e.g. clip planes)
210938
- * @param announce (optional) function to be called announcing fractional intervals"
210939
- * ` announce(fraction0, fraction1, curvePrimitive)`
210997
+ * Find intervals of this CurvePrimitive that are interior to a clipper.
210998
+ * @param clipper clip structure (e.g. clip planes).
210999
+ * @param announce (optional) function to be called announcing fractional intervals
211000
+ * `announce(fraction0, fraction1, curvePrimitive)`.
210940
211001
  * @returns true if any "in" segments are announced.
210941
211002
  */
210942
211003
  announceClipIntervals(clipper, announce) {
@@ -216493,7 +216554,7 @@ class AppendPlaneIntersectionStrokeHandler extends _numerics_Newton__WEBPACK_IMP
216493
216554
  _intersections;
216494
216555
  _fractionA = 0;
216495
216556
  _functionA = 0;
216496
- // private derivativeA: number; <---- Not currently used
216557
+ // private derivativeA: number; <---- Not currently used
216497
216558
  _functionB = 0;
216498
216559
  _fractionB = 0;
216499
216560
  _derivativeB = 0;
@@ -216525,8 +216586,7 @@ class AppendPlaneIntersectionStrokeHandler extends _numerics_Newton__WEBPACK_IMP
216525
216586
  this._functionA = 0.0;
216526
216587
  // this.derivativeA = 0.0;
216527
216588
  }
216528
- endCurvePrimitive() {
216529
- }
216589
+ endCurvePrimitive() { }
216530
216590
  announceIntervalForUniformStepStrokes(cp, numStrokes, fraction0, fraction1) {
216531
216591
  this.startCurvePrimitive(cp);
216532
216592
  if (numStrokes < 1)
@@ -216566,13 +216626,13 @@ class AppendPlaneIntersectionStrokeHandler extends _numerics_Newton__WEBPACK_IMP
216566
216626
  const curve = this.effectiveCurve();
216567
216627
  if (!curve)
216568
216628
  return false;
216629
+ // the Newton function is just plane altitude: curve points that lie on the plane are altitude roots (i.e., altitude = 0).
216569
216630
  this.currentF = this._plane.altitude(curve.fractionToPoint(fraction));
216570
216631
  return true;
216571
216632
  }
216572
216633
  /**
216573
- * * ASSUME both the "A" and "B" evaluations (fraction, function, and derivative) are known.
216574
- * * If function value changed sign between, interpolate an approximate root and improve it with
216575
- * the newton solver.
216634
+ * * ASSUME both the "A" and "B" evaluations (fraction, function, and derivative) are known.
216635
+ * * If function value changed sign between, interpolate an approximate root and improve it with the newton solver.
216576
216636
  */
216577
216637
  searchInterval() {
216578
216638
  if (this._functionA * this._functionB > 0)
@@ -230247,7 +230307,8 @@ class Ellipsoid {
230247
230307
  this._workPointA = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_3__.Point3d.create();
230248
230308
  this._workPointB = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_3__.Point3d.create();
230249
230309
  }
230250
- /** Create with a clone (not capture) with given transform.
230310
+ /**
230311
+ * Create with a clone (not capture) with given transform.
230251
230312
  * * If transform is undefined, create a unit sphere.
230252
230313
  */
230253
230314
  static create(matrixOrTransform) {
@@ -230281,7 +230342,9 @@ class Ellipsoid {
230281
230342
  * * In the sphere space, an xyz (vector from origin) with magnitude less than 1 is INSIDE the sphere (hence its world image is INSIDE the ellipsoid)
230282
230343
  * * In the sphere space, an xyz (vector from origin) with magnitude greater than 1 is OUTSIDE the sphere (hence its world image is OUTSIDE the ellipsoid)
230283
230344
  */
230284
- get transformRef() { return this._transform; }
230345
+ get transformRef() {
230346
+ return this._transform;
230347
+ }
230285
230348
  /**
230286
230349
  * * Convert a world point to point within the underlying mapped sphere space.
230287
230350
  * * In the sphere space, an xyz (vector from origin) with magnitude equal to 1 is ON the sphere (hence its world image is ON the ellipsoid)
@@ -230746,7 +230809,7 @@ class Ellipsoid {
230746
230809
  return localPoint.magnitude() <= 1.0;
230747
230810
  return false;
230748
230811
  }
230749
- /** Announce "in" portions of a line segment. Implementation of [[Clipper.announceClippedSegmentIntervals]]. */
230812
+ /** Method from [[Clipper]] interface. */
230750
230813
  announceClippedSegmentIntervals(f0, f1, pointA, pointB, announce) {
230751
230814
  const localA = this._transform.multiplyInversePoint3d(pointA, this._workPointA);
230752
230815
  const localB = this._transform.multiplyInversePoint3d(pointB, this._workPointB);
@@ -230785,7 +230848,7 @@ class Ellipsoid {
230785
230848
  }
230786
230849
  return false;
230787
230850
  }
230788
- /** Announce "in" portions of a line segment. Implementation of [[Clipper.announceClippedArcIntervals]] */
230851
+ /** Method from [[Clipper]] interface. */
230789
230852
  announceClippedArcIntervals(arc, announce) {
230790
230853
  const arcData = arc.toVectors();
230791
230854
  let numAnnounce = 0;
@@ -238465,31 +238528,36 @@ __webpack_require__.r(__webpack_exports__);
238465
238528
 
238466
238529
  /**
238467
238530
  * Plane3d is the abstract base class for multiple 3d plane representations:
238468
- * * [[Plane3dByOriginAndUnitNormal]] -- plane defined by origin and normal, with no preferred in-plane directions
238469
- * * [[Plane3dByOriginAndVectors]] -- plane defined by origin and 2 vectors in the plane, with normal implied by the vectors' cross product
238531
+ * * [[Plane3dByOriginAndUnitNormal]] -- plane defined by origin and normal, with no preferred in-plane directions.
238532
+ * * [[Plane3dByOriginAndVectors]] -- plane defined by origin and 2 vectors in the plane, with normal implied by the
238533
+ * vectors' cross product.
238470
238534
  * * [[Point4d]] -- homogeneous form of xyzw plane.
238471
- * * [[ClipPlane]] -- implicit plane with additional markup as used by compound clip structures such as [[ConvexClipPlaneSet]] and [[UnionOfConvexClipPlaneSets]]
238535
+ * * [[ClipPlane]] -- implicit plane with additional markup as used by compound clip structures such as
238536
+ * [[ConvexClipPlaneSet]] and [[UnionOfConvexClipPlaneSets]].
238472
238537
  *
238473
238538
  * As an abstract base class, Plane3d demands that its derived classes implement queries to answer questions
238474
- * about the plane's normal and the altitude of points above or below the plane. (Altitude is measured perpendicular to the plane.)
238539
+ * about the plane's normal and the altitude of points above or below the plane (altitude is measured perpendicular
238540
+ * to the plane).
238475
238541
  * These abstract methods are:
238476
- * * altitude(Point3d), altitudeXYZ(x,y,z), and altitudeXYZW(Point4d) -- evaluate altitude
238542
+ * * altitude(Point3d), altitudeXYZ(x,y,z), and altitudeXYZW(Point4d) -- evaluate altitude.
238477
238543
  * * normalX(), normalY(), normalZ() -- return components of the plane's normal vector.
238478
238544
  * * velocity(Vector3d), velocityXYZ(x,y,z) -- return dot product of the input vector with the plane normal.
238479
- * * projectPointToPlane (spacePoint: Point3d) -- return projection of spacePoint into the plane.
238545
+ * * projectPointToPlane(spacePoint: Point3d) -- return projection of spacePoint into the plane.
238480
238546
  *
238481
- * The Plane3d base class also provides implementations of several queries which it can implement by calling the abstract queries.
238547
+ * The Plane3d base class also provides implementations of several queries which it can implement by calling
238548
+ * the abstract queries.
238482
238549
  * * Derived classes may choose to override these default implementations using private knowledge of what they have stored.
238483
- * * isPointInPlane(spacePoint, tolerance?) -- test if spacePoint is in the plane with tolerance. Default tolerance is small metric distance
238484
- * * classifyAltitude (spacePoint, tolerance?), classifyAltitudeXYZ (x,y,z,tolerance?) -- return -1,0,1 indicating if spacePoint's altitude
238485
- * is negative, near zero, or positive.
238550
+ * * isPointInPlane(spacePoint, tolerance?) -- test if spacePoint is in the plane with tolerance. Default tolerance is
238551
+ * small metric distance.
238552
+ * * classifyAltitude(spacePoint, tolerance?), classifyAltitudeXYZ(x,y,z,tolerance?) -- return -1,0,1 indicating if
238553
+ * spacePoint's altitude is negative, near zero, or positive.
238486
238554
  *
238487
238555
  * Notes about scaling and signs in methods that compute altitudes, normal components and velocities:
238488
238556
  * * The term "altitude" indicates a _signed_ distance from the plane.
238489
238557
  * * altitude zero is _on_ the plane
238490
238558
  * * positive altitudes are on one side
238491
238559
  * * negatives are on the other.
238492
- * * Altitude values and normal components are not strictly required to be true cartesian distance. If the calling code happens to use "distance scaled by 1000X" it
238560
+ * * Altitude values and normal components are not strictly required to be true cartesian distance. If the calling code happens to use "distance scaled by 1000X" it
238493
238561
  * understands that it can be OK for its plane implementation to have that scaling.
238494
238562
  * * By convention, derived classes whose definitions (normals and vectors in plane) are simple cartesian are expected
238495
238563
  * to return true distances. This applies to:
@@ -308937,19 +309005,17 @@ __webpack_require__.r(__webpack_exports__);
308937
309005
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
308938
309006
  * See LICENSE.md in the project root for license terms and full copyright notice.
308939
309007
  *--------------------------------------------------------------------------------------------*/
308940
- /** A cacheable handle to formatting and parsing specs for a specific KoQ and persistence unit.
308941
- * Automatically refreshes when the QuantityFormatter reloads. Use [[QuantityFormatter.getFormatSpecHandle]]
309008
+ /** A handle to formatting and parsing specs for a specific KoQ and persistence unit.
309009
+ * Reads the current specs from the provider on access. Use [[QuantityFormatter.getFormatSpecHandle]]
308942
309010
  * to create instances.
308943
309011
  *
308944
309012
  * When formatting is not yet ready, [[format]] returns a `value.toString()` fallback.
308945
- * Call [[dispose]] when the handle is no longer needed to unsubscribe from reload events.
309013
+ * Dispose the handle when it is no longer needed to invalidate it.
308946
309014
  *
308947
309015
  * @beta
308948
309016
  */
308949
309017
  class FormatSpecHandle {
308950
- _formatterSpec;
308951
- _parserSpec;
308952
- _removeListener;
309018
+ _disposed = false;
308953
309019
  _provider;
308954
309020
  _koqName;
308955
309021
  _persistenceUnit;
@@ -308960,10 +309026,6 @@ class FormatSpecHandle {
308960
309026
  this._koqName = args.name;
308961
309027
  this._persistenceUnit = args.persistenceUnitName;
308962
309028
  this._system = args.system;
308963
- this._removeListener = args.provider.onFormattingReady.addListener(() => {
308964
- this._refresh();
308965
- });
308966
- this._refresh();
308967
309029
  }
308968
309030
  /** The KoQ name this handle is keyed to. */
308969
309031
  get koqName() { return this._koqName; }
@@ -308972,47 +309034,35 @@ class FormatSpecHandle {
308972
309034
  /** The unit system this handle is pinned to, or `undefined` for the active system. */
308973
309035
  get system() { return this._system; }
308974
309036
  /** The current FormatterSpec, or undefined if not yet loaded. */
308975
- get formatterSpec() { return this._formatterSpec; }
309037
+ get formatterSpec() { return this._getEntry()?.formatterSpec; }
308976
309038
  /** The current ParserSpec, or undefined if not yet loaded. */
308977
- get parserSpec() { return this._parserSpec; }
309039
+ get parserSpec() { return this._getEntry()?.parserSpec; }
308978
309040
  /** Format a quantity value using the current spec.
308979
309041
  * If the formatter is not yet ready, returns `value.toString()` as a fallback.
308980
309042
  * @param value - The numeric value to format.
308981
309043
  * @returns The formatted string.
308982
309044
  */
308983
309045
  format(value) {
308984
- if (!this._formatterSpec)
309046
+ const formatterSpec = this.formatterSpec;
309047
+ if (!formatterSpec)
308985
309048
  return value.toString();
308986
- return this._provider.formatQuantity(value, this._formatterSpec);
309049
+ return this._provider.formatQuantity(value, formatterSpec);
308987
309050
  }
308988
- /** Unsubscribe from reload events and clear cached specs.
308989
- * Idempotent and safe to call during a pending reload.
309051
+ /** Invalidate this handle.
309052
+ * Idempotent and safe to call multiple times.
309053
+ * No additional teardown is required because the handle owns no external resources.
308990
309054
  */
308991
309055
  [Symbol.dispose]() {
308992
- if (this._removeListener) {
308993
- this._removeListener();
308994
- this._removeListener = undefined;
308995
- }
308996
- this._formatterSpec = undefined;
308997
- this._parserSpec = undefined;
309056
+ this._disposed = true;
308998
309057
  }
308999
- _refresh() {
309000
- // Guard against mid-emission callbacks after dispose() — event may still fire during iteration.
309001
- if (!this._removeListener)
309002
- return;
309003
- const entry = this._provider.getSpecsByNameAndUnit({
309058
+ _getEntry() {
309059
+ if (this._disposed)
309060
+ return undefined;
309061
+ return this._provider.getSpecsByNameAndUnit({
309004
309062
  name: this._koqName,
309005
309063
  persistenceUnitName: this._persistenceUnit,
309006
309064
  system: this._system,
309007
309065
  });
309008
- if (entry) {
309009
- this._formatterSpec = entry.formatterSpec;
309010
- this._parserSpec = entry.parserSpec;
309011
- }
309012
- else {
309013
- this._formatterSpec = undefined;
309014
- this._parserSpec = undefined;
309015
- }
309016
309066
  }
309017
309067
  }
309018
309068
 
@@ -327388,7 +327438,7 @@ var loadLanguages = instance.loadLanguages;
327388
327438
  /***/ ((module) => {
327389
327439
 
327390
327440
  "use strict";
327391
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.10.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 && npm run -s build:esm && npm run -s webpackWorkers && npm run -s copy:workers && npm run -s copy:draco","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2022 --outDir lib/esm","clean":"rimraf -g lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","copy:workers":"cpx \\"./lib/workers/webpack/parse-imdl-worker.js\\" ./lib/public/scripts","copy:draco":"cpx \\"./node_modules/@loaders.gl/draco/dist/libs/*\\" ./lib/public/scripts","docs":"betools docs --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts && npm run -s extract","extract":"betools extract --fileExt=ts --extractFrom=./src/test/example-code --recursive --out=../../generated-docs/extract","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-inline-config -c extraction.eslint.config.js \\"./src/**/*.ts\\" 1>&2","lint":"eslint \\"./src/**/*.ts\\" 1>&2","lint-fix":"eslint --fix -f visualstudio \\"./src/**/*.ts\\" 1>&2","lint-deprecation":"eslint --fix -f visualstudio --no-inline-config -c ../../common/config/eslint/eslint.config.deprecation-policy.js \\"./src/**/*.ts\\"","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run webpackTestWorker && vitest --run","cover":"npm run webpackTestWorker && vitest --run","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2 && npm run -s webpackTestWorker","webpackTestWorker":"webpack --config ./src/test/worker/webpack.config.js 1>&2 && cpx \\"./lib/test/test-worker.js\\" ./lib/test","webpackWorkers":"webpack --config ./src/workers/ImdlParser/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core.git","directory":"core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@bentley/aec-units-schema":"^1.0.3","@bentley/formats-schema":"^1.0.0","@bentley/units-schema":"^1.0.9","@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*","@itwin/object-storage-core":"^3.0.4","@itwin/eslint-plugin":"^6.0.0","@types/chai-as-promised":"^7","@types/draco3d":"^1.4.10","@types/sinon":"^17.0.2","@vitest/browser":"^3.0.6","@vitest/coverage-v8":"^3.0.6","cpx2":"^8.0.0","eslint":"^9.31.0","glob":"^10.5.0","playwright":"~1.56.1","rimraf":"^6.0.1","sinon":"^17.0.2","source-map-loader":"^5.0.0","typescript":"~5.6.2","vitest":"^3.0.6","vite-multiple-assets":"^1.3.1","vite-plugin-static-copy":"2.2.0","webpack":"^5.97.1"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/core-i18n":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"~4.3.4","@loaders.gl/draco":"~4.3.4","fuse.js":"^3.3.0","wms-capabilities":"0.4.0"}}');
327441
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.10.0-dev.7","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs && npm run -s build:esm && npm run -s webpackWorkers && npm run -s copy:workers && npm run -s copy:draco","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2022 --outDir lib/esm","clean":"rimraf -g lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","copy:workers":"cpx \\"./lib/workers/webpack/parse-imdl-worker.js\\" ./lib/public/scripts","copy:draco":"cpx \\"./node_modules/@loaders.gl/draco/dist/libs/*\\" ./lib/public/scripts","docs":"betools docs --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts && npm run -s extract","extract":"betools extract --fileExt=ts --extractFrom=./src/test/example-code --recursive --out=../../generated-docs/extract","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-inline-config -c extraction.eslint.config.js \\"./src/**/*.ts\\" 1>&2","lint":"eslint \\"./src/**/*.ts\\" 1>&2","lint-fix":"eslint --fix -f visualstudio \\"./src/**/*.ts\\" 1>&2","lint-deprecation":"eslint --fix -f visualstudio --no-inline-config -c ../../common/config/eslint/eslint.config.deprecation-policy.js \\"./src/**/*.ts\\"","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run webpackTestWorker && vitest --run","cover":"npm run webpackTestWorker && vitest --run","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2 && npm run -s webpackTestWorker","webpackTestWorker":"webpack --config ./src/test/worker/webpack.config.js 1>&2 && cpx \\"./lib/test/test-worker.js\\" ./lib/test","webpackWorkers":"webpack --config ./src/workers/ImdlParser/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core.git","directory":"core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@bentley/aec-units-schema":"^1.0.3","@bentley/formats-schema":"^1.0.0","@bentley/units-schema":"^1.0.9","@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*","@itwin/object-storage-core":"^3.0.4","@itwin/eslint-plugin":"^6.0.0","@types/chai-as-promised":"^7","@types/draco3d":"^1.4.10","@types/sinon":"^17.0.2","@vitest/browser":"^3.0.6","@vitest/coverage-v8":"^3.0.6","cpx2":"^8.0.0","eslint":"^9.31.0","glob":"^10.5.0","playwright":"~1.56.1","rimraf":"^6.0.1","sinon":"^17.0.2","source-map-loader":"^5.0.0","typescript":"~5.6.2","vitest":"^3.0.6","vite-multiple-assets":"^1.3.1","vite-plugin-static-copy":"2.2.0","webpack":"^5.97.1"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/core-i18n":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"~4.3.4","@loaders.gl/draco":"~4.3.4","fuse.js":"^3.3.0","wms-capabilities":"0.4.0"}}');
327392
327442
 
327393
327443
  /***/ })
327394
327444