@itwin/ecschema-rpcinterface-tests 5.1.0-dev.52 → 5.1.0-dev.54

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.
@@ -43182,7 +43182,8 @@ class WhiteOnWhiteReversalSettings {
43182
43182
  "use strict";
43183
43183
  __webpack_require__.r(__webpack_exports__);
43184
43184
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
43185
- /* harmony export */ TextAnnotation: () => (/* binding */ TextAnnotation)
43185
+ /* harmony export */ TextAnnotation: () => (/* binding */ TextAnnotation),
43186
+ /* harmony export */ textAnnotationFrameShapes: () => (/* binding */ textAnnotationFrameShapes)
43186
43187
  /* harmony export */ });
43187
43188
  /* harmony import */ var _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-geometry */ "../../core/geometry/lib/esm/core-geometry.js");
43188
43189
  /* harmony import */ var _TextBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./TextBlock */ "../../core/common/lib/esm/annotation/TextBlock.js");
@@ -43195,6 +43196,10 @@ __webpack_require__.r(__webpack_exports__);
43195
43196
  */
43196
43197
 
43197
43198
 
43199
+ /** Set of predefined shapes that can be computed and drawn around the margins of a [[TextBlock]]
43200
+ * @beta
43201
+ */
43202
+ const textAnnotationFrameShapes = ["none", "line", "rectangle", "circle", "equilateralTriangle", "diamond", "square", "pentagon", "hexagon", "octagon", "capsule", "roundedRectangle"];
43198
43203
  /**
43199
43204
  * Represents a formatted block of text positioned in 2d or 3d space.
43200
43205
  * [TextAnnotation2d]($backend) and [TextAnnotation3d]($backend) elements store a single TextAnnotation from which their geometric representation is generated.
@@ -44353,6 +44358,7 @@ __webpack_require__.r(__webpack_exports__);
44353
44358
  /* harmony export */ readElementMeshes: () => (/* reexport safe */ _ElementMesh__WEBPACK_IMPORTED_MODULE_29__.readElementMeshes),
44354
44359
  /* harmony export */ readTileContentDescription: () => (/* reexport safe */ _tile_TileMetadata__WEBPACK_IMPORTED_MODULE_157__.readTileContentDescription),
44355
44360
  /* harmony export */ rpcOverIpcStrings: () => (/* reexport safe */ _ipc_IpcSession__WEBPACK_IMPORTED_MODULE_75__.rpcOverIpcStrings),
44361
+ /* harmony export */ textAnnotationFrameShapes: () => (/* reexport safe */ _annotation_TextAnnotation__WEBPACK_IMPORTED_MODULE_2__.textAnnotationFrameShapes),
44356
44362
  /* harmony export */ tileFormatFromNumber: () => (/* reexport safe */ _tile_TileIO__WEBPACK_IMPORTED_MODULE_156__.tileFormatFromNumber)
44357
44363
  /* harmony export */ });
44358
44364
  /* harmony import */ var _AmbientOcclusion__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AmbientOcclusion */ "../../core/common/lib/esm/AmbientOcclusion.js");
@@ -72139,7 +72145,15 @@ class ECSchemaRpcLocater {
72139
72145
  * @param matchType The match type to use when locating the schema
72140
72146
  */
72141
72147
  async getSchemaInfo(schemaKey, matchType, context) {
72142
- const schemaJson = await _ECSchemaRpcInterface__WEBPACK_IMPORTED_MODULE_1__.ECSchemaRpcInterface.getClient().getSchemaJSON(this.token, schemaKey.name);
72148
+ let schemaJson;
72149
+ try {
72150
+ schemaJson = await _ECSchemaRpcInterface__WEBPACK_IMPORTED_MODULE_1__.ECSchemaRpcInterface.getClient().getSchemaJSON(this.token, schemaKey.name);
72151
+ }
72152
+ catch (e) {
72153
+ if (e.message && e.message === "schema not found")
72154
+ return undefined;
72155
+ throw (e);
72156
+ }
72143
72157
  const schemaInfo = await _itwin_ecschema_metadata__WEBPACK_IMPORTED_MODULE_0__.Schema.startLoadingFromJson(schemaJson, context || new _itwin_ecschema_metadata__WEBPACK_IMPORTED_MODULE_0__.SchemaContext());
72144
72158
  if (schemaInfo !== undefined && schemaInfo.schemaKey.matches(schemaKey, matchType)) {
72145
72159
  return schemaInfo;
@@ -85179,20 +85193,52 @@ class SnapshotConnection extends IModelConnection {
85179
85193
  /** The collection of [[CodeSpec]] entities for an [[IModelConnection]]. */
85180
85194
  class CodeSpecs {
85181
85195
  _iModel;
85182
- _loaded;
85183
85196
  /** @internal */
85184
85197
  constructor(_iModel) {
85185
85198
  this._iModel = _iModel;
85186
85199
  }
85187
- /** Loads all CodeSpec from the remote IModelDb. */
85188
- async _loadAllCodeSpecs() {
85189
- if (this._loaded)
85190
- return;
85191
- this._loaded = [];
85192
- const codeSpecArray = await _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelReadRpcInterface.getClientForRouting(this._iModel.routingContext.token).getAllCodeSpecs(this._iModel.getRpcProps());
85193
- for (const codeSpec of codeSpecArray) {
85194
- this._loaded.push(_itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.CodeSpec.createFromJson(this._iModel, _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Id64.fromString(codeSpec.id), codeSpec.name, codeSpec.jsonProperties));
85200
+ _isCodeSpecProperties(x) {
85201
+ if (!x || !x.scopeSpec || !Object.values(_itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.CodeScopeSpec.Type).includes(x.scopeSpec.type))
85202
+ return false;
85203
+ if (typeof x.scopeSpec.fGuidRequired !== "boolean" && typeof x.scopeSpec.fGuidRequired !== "undefined")
85204
+ return false;
85205
+ if (typeof x.scopeSpec.relationship !== "string" && typeof x.scopeSpec.relationship !== "undefined")
85206
+ return false;
85207
+ if (typeof x.spec?.isManagedWithDgnDb !== "boolean" && typeof x.spec?.isManagedWithDgnDb !== "undefined")
85208
+ return false;
85209
+ if (typeof x.version !== "string" && typeof x.version !== "undefined")
85210
+ return false;
85211
+ return true;
85212
+ }
85213
+ async _loadCodeSpec(identifier) {
85214
+ const isNameDefined = identifier.name !== undefined;
85215
+ const query = `
85216
+ SELECT ECInstanceId AS Id, Name, JsonProperties
85217
+ FROM BisCore.CodeSpec
85218
+ WHERE ${isNameDefined ? `Name=:name` : `Id=:id`}`;
85219
+ const params = new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.QueryBinder();
85220
+ if (isNameDefined) {
85221
+ params.bindString("name", identifier.name);
85222
+ }
85223
+ else {
85224
+ params.bindId("id", identifier.id);
85195
85225
  }
85226
+ const queryReader = this._iModel.createQueryReader(query, params, {
85227
+ rowFormat: _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.QueryRowFormat.UseECSqlPropertyNames,
85228
+ });
85229
+ const queryResult = await queryReader.next();
85230
+ if (queryResult.done)
85231
+ throw new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelError(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.IModelStatus.NotFound, "CodeSpec not found");
85232
+ const codeSpecResult = queryResult.value;
85233
+ if (typeof codeSpecResult.Id !== "string" ||
85234
+ typeof codeSpecResult.Name !== "string" ||
85235
+ typeof codeSpecResult.JsonProperties !== "string")
85236
+ throw new Error("Invalid CodeSpec was returned");
85237
+ const jsonProperties = JSON.parse(codeSpecResult.JsonProperties);
85238
+ if (!this._isCodeSpecProperties(jsonProperties))
85239
+ throw new Error("Invalid CodeSpecProperties returned in the CodeSpec");
85240
+ const codeSpec = _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.CodeSpec.createFromJson(this._iModel, _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Id64.fromString(codeSpecResult.Id), codeSpecResult.Name, jsonProperties);
85241
+ return codeSpec;
85196
85242
  }
85197
85243
  /** Look up a CodeSpec by Id.
85198
85244
  * @param codeSpecId The Id of the CodeSpec to load
@@ -85200,13 +85246,11 @@ class SnapshotConnection extends IModelConnection {
85200
85246
  * @throws [[IModelError]] if the Id is invalid or if no CodeSpec with that Id could be found.
85201
85247
  */
85202
85248
  async getById(codeSpecId) {
85249
+ if (codeSpecId === "")
85250
+ throw new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelError(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.IModelStatus.NotFound, "CodeSpec not found");
85203
85251
  if (!_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Id64.isValid(codeSpecId))
85204
85252
  throw new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelError(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.IModelStatus.InvalidId, "Invalid codeSpecId", () => ({ codeSpecId }));
85205
- await this._loadAllCodeSpecs(); // ensure all codeSpecs have been downloaded
85206
- const found = this._loaded.find((codeSpec) => codeSpec.id === codeSpecId);
85207
- if (!found)
85208
- throw new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelError(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.IModelStatus.NotFound, "CodeSpec not found");
85209
- return found;
85253
+ return this._loadCodeSpec({ id: codeSpecId });
85210
85254
  }
85211
85255
  /** Look up a CodeSpec by name.
85212
85256
  * @param name The name of the CodeSpec to load
@@ -85214,11 +85258,9 @@ class SnapshotConnection extends IModelConnection {
85214
85258
  * @throws [[IModelError]] if no CodeSpec with the specified name could be found.
85215
85259
  */
85216
85260
  async getByName(name) {
85217
- await this._loadAllCodeSpecs(); // ensure all codeSpecs have been downloaded
85218
- const found = this._loaded.find((codeSpec) => codeSpec.name === name);
85219
- if (!found)
85261
+ if (name === "")
85220
85262
  throw new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelError(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.IModelStatus.NotFound, "CodeSpec not found");
85221
- return found;
85263
+ return this._loadCodeSpec({ name });
85222
85264
  }
85223
85265
  }
85224
85266
  IModelConnection.CodeSpecs = CodeSpecs;
@@ -186382,7 +186424,6 @@ class BSplineSurface3d extends BSpline2dNd {
186382
186424
  getPointGridJSON() {
186383
186425
  const result = {
186384
186426
  points: _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_7__.Point3dArray.unpackNumbersToNestedArraysIJK(this.coffs, 3, this.numPolesUV(0)),
186385
- weighStyle: WeightStyle.WeightsAlreadyAppliedToCoordinates, // @deprecated in 4.x - will not be removed until after 2026-06-13. Use weightStyle instead.
186386
186427
  weightStyle: WeightStyle.UnWeighted,
186387
186428
  numCartesianDimensions: 3,
186388
186429
  };
@@ -186795,7 +186836,6 @@ class BSplineSurface3dH extends BSpline2dNd {
186795
186836
  const result = {
186796
186837
  points: _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_7__.Point3dArray.unpackNumbersToNestedArraysIJK(this.coffs, 4, this.numPolesUV(0)),
186797
186838
  numCartesianDimensions: 3,
186798
- weighStyle: WeightStyle.WeightsAlreadyAppliedToCoordinates, // @deprecated in 4.x - will not be removed until after 2026-06-13. Use weightStyle instead.
186799
186839
  weightStyle: WeightStyle.WeightsAlreadyAppliedToCoordinates,
186800
186840
  };
186801
186841
  return result;
@@ -197809,6 +197849,17 @@ class CurveChain extends CurveCollection {
197809
197849
  else
197810
197850
  return undefined;
197811
197851
  }
197852
+ /**
197853
+ * Whether the chain start and end points are defined and within tolerance.
197854
+ * * Does not check for planarity or degeneracy.
197855
+ * @param tolerance optional distance tolerance (default is [[Geometry.smallMetricDistance]])
197856
+ * @param xyOnly if true, ignore z coordinate (default is `false`)
197857
+ */
197858
+ isPhysicallyClosedCurve(tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_6__.Geometry.smallMetricDistance, xyOnly = false) {
197859
+ const p0 = this.startPoint();
197860
+ const p1 = this.endPoint();
197861
+ return p0 !== undefined && p1 !== undefined && (xyOnly ? p0.isAlmostEqualXY(p1, tolerance) : p0.isAlmostEqual(p1, tolerance));
197862
+ }
197812
197863
  /**
197813
197864
  * Return the start point and derivative of the first child of the curve chain.
197814
197865
  * * For queries interior to the chain, use [[CurveChainWithDistanceIndex.fractionToPointAndDerivative]].
@@ -198539,11 +198590,12 @@ class CurveFactory {
198539
198590
  * * This only succeeds if the two arcs are part of identical complete arcs and end of `arcA` matches the beginning of `arcB`.
198540
198591
  * @param arcA first arc, modified in place.
198541
198592
  * @param arcB second arc, unmodified.
198542
- * @param allowReversed whether to consolidate even when second arc is reversed.
198593
+ * @param allowReversed whether to consolidate even when second arc is reversed (default is `false`).
198594
+ * @param tolerance optional coordinate tolerance for point equality (default is `Geometry.smallMetricDistance`).
198543
198595
  * @returns whether `arcA` was modified.
198544
198596
  */
198545
- static appendToArcInPlace(arcA, arcB, allowReverse = false) {
198546
- if (arcA.center.isAlmostEqual(arcB.center)) {
198597
+ static appendToArcInPlace(arcA, arcB, allowReverse = false, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
198598
+ if (arcA.center.isAlmostEqual(arcB.center, tolerance)) {
198547
198599
  const sweepSign = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.split3WaySign(arcA.sweep.sweepRadians * arcB.sweep.sweepRadians, -1, 0, 1);
198548
198600
  // evaluate derivatives wrt radians (not fraction!), but adjust direction for sweep signs
198549
198601
  const endA = arcA.angleToPointAndDerivative(arcA.sweep.fractionToAngle(1.0));
@@ -198552,14 +198604,14 @@ class CurveFactory {
198552
198604
  const startB = arcB.angleToPointAndDerivative(arcB.sweep.fractionToAngle(0.0));
198553
198605
  if (arcB.sweep.sweepRadians < 0)
198554
198606
  startB.direction.scaleInPlace(-1.0);
198555
- if (endA.isAlmostEqual(startB)) {
198607
+ if (endA.isAlmostEqual(startB, tolerance)) {
198556
198608
  arcA.sweep.setStartEndRadians(arcA.sweep.startRadians, arcA.sweep.startRadians + arcA.sweep.sweepRadians + sweepSign * arcB.sweep.sweepRadians);
198557
198609
  return true;
198558
198610
  }
198559
198611
  // Also ok if negated tangent
198560
198612
  if (allowReverse) {
198561
198613
  startB.direction.scaleInPlace(-1.0);
198562
- if (endA.isAlmostEqual(startB)) {
198614
+ if (endA.isAlmostEqual(startB, tolerance)) {
198563
198615
  arcA.sweep.setStartEndRadians(arcA.sweep.startRadians, arcA.sweep.startRadians + arcA.sweep.sweepRadians - sweepSign * arcB.sweep.sweepRadians);
198564
198616
  return true;
198565
198617
  }
@@ -199106,7 +199158,12 @@ class CurveLocationDetail {
199106
199158
  setIntervalRole(value) {
199107
199159
  this.intervalRole = value;
199108
199160
  }
199109
- /** Set the (optional) fraction1 and point1, using direct assignment (capture!) to point1. */
199161
+ /** Set the `fraction` and `point`, using direct assignment (capture!) to `point`. */
199162
+ captureFractionPoint(fraction, point) {
199163
+ this.fraction = fraction;
199164
+ this.point = point;
199165
+ }
199166
+ /** Set the (optional) `fraction1` and `point1`, using direct assignment (capture!) to `point1`. */
199110
199167
  captureFraction1Point1(fraction1, point1) {
199111
199168
  this.fraction1 = fraction1;
199112
199169
  this.point1 = point1;
@@ -200326,6 +200383,17 @@ class CurvePrimitive extends _GeometryQuery__WEBPACK_IMPORTED_MODULE_1__.Geometr
200326
200383
  endPoint(result) {
200327
200384
  return this.fractionToPoint(1.0, result);
200328
200385
  }
200386
+ /**
200387
+ * Whether the start and end points are defined and within tolerance.
200388
+ * * Does not check for planarity or degeneracy.
200389
+ * @param tolerance optional distance tolerance (default is [[Geometry.smallMetricDistance]])
200390
+ * @param xyOnly if true, ignore z coordinate (default is `false`)
200391
+ */
200392
+ isPhysicallyClosedCurve(tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallMetricDistance, xyOnly = false) {
200393
+ const p0 = this.startPoint();
200394
+ const p1 = this.endPoint();
200395
+ return p0 !== undefined && p1 !== undefined && (xyOnly ? p0.isAlmostEqualXY(p1, tolerance) : p0.isAlmostEqual(p1, tolerance));
200396
+ }
200329
200397
  /**
200330
200398
  * Attach StrokeCountMap structure to this primitive (and recursively to any children)
200331
200399
  * * Base class implementation (here) gets the simple count from computeStrokeCountForOptions and attaches it.
@@ -200813,6 +200881,10 @@ class LineSegment3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePr
200813
200881
  get point1Ref() {
200814
200882
  return this._point1;
200815
200883
  }
200884
+ /** Return a copy of the start and end points in an array. */
200885
+ get points() {
200886
+ return [this._point0.clone(), this._point1.clone()];
200887
+ }
200816
200888
  /** A LineSegment3d extends along its infinite line. */
200817
200889
  get isExtensibleFractionSpace() {
200818
200890
  return true;
@@ -202593,8 +202665,7 @@ class LineString3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePri
202593
202665
  this.addResolvedPoint(localA.index, localA.fraction, result._points);
202594
202666
  for (let index = index0; index <= index1; index++) {
202595
202667
  if (this._points.isIndexValid(index)) {
202596
- this._points.getPoint3dAtUncheckedPointIndex(index, LineString3d._workPointA);
202597
- result._points.push(LineString3d._workPointA);
202668
+ result._points.pushFromGrowableXYZArray(this._points, index);
202598
202669
  }
202599
202670
  }
202600
202671
  this.addResolvedPoint(localB.index, localB.fraction, result._points);
@@ -202606,9 +202677,22 @@ class LineString3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePri
202606
202677
  return _LineSegment3d__WEBPACK_IMPORTED_MODULE_15__.LineSegment3d.create(this._points.getPoint3dAtCheckedPointIndex(index), this._points.getPoint3dAtCheckedPointIndex(index + 1), result);
202607
202678
  return undefined;
202608
202679
  }
202680
+ /**
202681
+ * Whether the start and end points are defined and within tolerance.
202682
+ * * Does not check for planarity or degeneracy.
202683
+ * @param tolerance optional distance tolerance (default is [[Geometry.smallMetricDistance]])
202684
+ * @param xyOnly if true, ignore z coordinate (default is `false`)
202685
+ */
202686
+ isPhysicallyClosedCurve(tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance, xyOnly = false) {
202687
+ if (!this._points.length)
202688
+ return false;
202689
+ if (xyOnly)
202690
+ return this._points.almostEqualXYIndexIndex(0, this._points.length - 1, tolerance); // we know the indices are valid
202691
+ return this._points.almostEqualIndexIndex(0, this._points.length - 1, tolerance);
202692
+ }
202609
202693
  /** Returns true if first and last points are within metric tolerance. */
202610
202694
  get isPhysicallyClosed() {
202611
- return this._points.length > 0 && _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(this._points.distanceIndexIndex(0, this._points.length - 1));
202695
+ return this.isPhysicallyClosedCurve();
202612
202696
  }
202613
202697
  /**
202614
202698
  * Evaluate strokes at fractions indicated in a StrokeCountMap.
@@ -203789,7 +203873,7 @@ class ConsolidateAdjacentCurvePrimitivesContext extends _geometry3d_GeometryHand
203789
203873
  const numOriginal = children.length;
203790
203874
  const points = [];
203791
203875
  let numAccept = 0;
203792
- // i0 <=i < i1 is a range of child indices.
203876
+ // i0 <= i < i1 is a range of child indices.
203793
203877
  // numAccept is the number of children accepted (contiguously at front of children)
203794
203878
  for (let i0 = 0; i0 < numOriginal;) {
203795
203879
  const basePrimitive = g.children[i0];
@@ -203847,7 +203931,7 @@ class ConsolidateAdjacentCurvePrimitivesContext extends _geometry3d_GeometryHand
203847
203931
  const nextPrimitive = g.children[i0];
203848
203932
  if (!(nextPrimitive instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_7__.Arc3d))
203849
203933
  break;
203850
- if (!_CurveFactory__WEBPACK_IMPORTED_MODULE_8__.CurveFactory.appendToArcInPlace(basePrimitive, nextPrimitive)) // TODO: use this._options.duplicatePointTolerance
203934
+ if (!_CurveFactory__WEBPACK_IMPORTED_MODULE_8__.CurveFactory.appendToArcInPlace(basePrimitive, nextPrimitive, false, this._options.duplicatePointTolerance))
203851
203935
  break;
203852
203936
  }
203853
203937
  // i0 has already advanced
@@ -203860,8 +203944,32 @@ class ConsolidateAdjacentCurvePrimitivesContext extends _geometry3d_GeometryHand
203860
203944
  }
203861
203945
  g.children.length = numAccept;
203862
203946
  }
203863
- handlePath(g) { return this.handleCurveChain(g); }
203864
- handleLoop(g) { return this.handleCurveChain(g); }
203947
+ handlePath(g) {
203948
+ return this.handleCurveChain(g);
203949
+ }
203950
+ handleLoop(g) {
203951
+ this.handleCurveChain(g);
203952
+ if (g.children.length > 1 && this._options.consolidateLoopSeam) {
203953
+ const lastChild = g.children[g.children.length - 1];
203954
+ const firstChild = g.children[0];
203955
+ if ((lastChild instanceof _LineSegment3d__WEBPACK_IMPORTED_MODULE_2__.LineSegment3d || lastChild instanceof _LineString3d__WEBPACK_IMPORTED_MODULE_3__.LineString3d) && (firstChild instanceof _LineSegment3d__WEBPACK_IMPORTED_MODULE_2__.LineSegment3d || firstChild instanceof _LineString3d__WEBPACK_IMPORTED_MODULE_3__.LineString3d)) {
203956
+ if (this._options.consolidateLinearGeometry && !this._options.disableLinearCompression) {
203957
+ const lastPoints = lastChild.points;
203958
+ lastPoints.pop(); // the original start point survives as an interior point in the new first primitive
203959
+ g.children[0] = _LineString3d__WEBPACK_IMPORTED_MODULE_3__.LineString3d.createPoints([...lastPoints, ...firstChild.points]);
203960
+ g.children.pop();
203961
+ }
203962
+ }
203963
+ else if (lastChild instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_7__.Arc3d && firstChild instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_7__.Arc3d) {
203964
+ if (this._options.consolidateCompatibleArcs) {
203965
+ if (_CurveFactory__WEBPACK_IMPORTED_MODULE_8__.CurveFactory.appendToArcInPlace(lastChild, firstChild, false, this._options.duplicatePointTolerance)) {
203966
+ g.children[0] = lastChild;
203967
+ g.children.pop();
203968
+ }
203969
+ }
203970
+ }
203971
+ }
203972
+ }
203865
203973
  handleParityRegion(g) {
203866
203974
  for (const child of g.children)
203867
203975
  child.dispatchToGeometryHandler(this);
@@ -204290,16 +204398,19 @@ __webpack_require__.r(__webpack_exports__);
204290
204398
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
204291
204399
  /* harmony export */ PlanarSubdivision: () => (/* binding */ PlanarSubdivision)
204292
204400
  /* harmony export */ });
204293
- /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
204294
- /* harmony import */ var _topology_Graph__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../topology/Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
204295
- /* harmony import */ var _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../topology/HalfEdgeGraphSearch */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphSearch.js");
204296
- /* harmony import */ var _topology_Merging__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../topology/Merging */ "../../core/geometry/lib/esm/topology/Merging.js");
204297
- /* harmony import */ var _Arc3d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Arc3d */ "../../core/geometry/lib/esm/curve/Arc3d.js");
204298
- /* harmony import */ var _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../CurveLocationDetail */ "../../core/geometry/lib/esm/curve/CurveLocationDetail.js");
204299
- /* harmony import */ var _LineSegment3d__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
204300
- /* harmony import */ var _LineString3d__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
204301
- /* harmony import */ var _Loop__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
204302
- /* harmony import */ var _RegionOps__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../RegionOps */ "../../core/geometry/lib/esm/curve/RegionOps.js");
204401
+ /* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
204402
+ /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
204403
+ /* harmony import */ var _topology_Graph__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../topology/Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
204404
+ /* harmony import */ var _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../topology/HalfEdgeGraphSearch */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphSearch.js");
204405
+ /* harmony import */ var _topology_Merging__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../topology/Merging */ "../../core/geometry/lib/esm/topology/Merging.js");
204406
+ /* harmony import */ var _Arc3d__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Arc3d */ "../../core/geometry/lib/esm/curve/Arc3d.js");
204407
+ /* harmony import */ var _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../CurveLocationDetail */ "../../core/geometry/lib/esm/curve/CurveLocationDetail.js");
204408
+ /* harmony import */ var _LineSegment3d__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
204409
+ /* harmony import */ var _LineString3d__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
204410
+ /* harmony import */ var _Loop__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
204411
+ /* harmony import */ var _ParityRegion__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../ParityRegion */ "../../core/geometry/lib/esm/curve/ParityRegion.js");
204412
+ /* harmony import */ var _RegionOps__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../RegionOps */ "../../core/geometry/lib/esm/curve/RegionOps.js");
204413
+ /* harmony import */ var _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../RegionOpsClassificationSweeps */ "../../core/geometry/lib/esm/curve/RegionOpsClassificationSweeps.js");
204303
204414
  /*---------------------------------------------------------------------------------------------
204304
204415
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
204305
204416
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -204314,6 +204425,9 @@ __webpack_require__.r(__webpack_exports__);
204314
204425
 
204315
204426
 
204316
204427
 
204428
+
204429
+
204430
+
204317
204431
  /** @packageDocumentation
204318
204432
  * @module Curve
204319
204433
  */
@@ -204356,19 +204470,19 @@ class MapCurvePrimitiveToCurveLocationDetailPairArray {
204356
204470
  * added to the graph because it isn't in the `primitiveToPair` map. By splitting such a missing primitive in two, we
204357
204471
  * introduce two intersections for each half, which allows the primitive to be represented in the map.
204358
204472
  */
204359
- splitAndAppendMissingClosedPrimitives(primitives, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
204473
+ splitAndAppendMissingClosedPrimitives(primitives, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance) {
204360
204474
  for (const p of primitives) {
204361
204475
  let closedCurveSplitCandidate = false;
204362
- if (p instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_1__.Arc3d)
204476
+ if (p instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_2__.Arc3d)
204363
204477
  closedCurveSplitCandidate = p.sweep.isFullCircle;
204364
- else if (!(p instanceof _LineSegment3d__WEBPACK_IMPORTED_MODULE_2__.LineSegment3d) && !(p instanceof _LineString3d__WEBPACK_IMPORTED_MODULE_3__.LineString3d)) // TODO: probably should do this for all types. Lots of spline-type primitives can be closed.
204478
+ else if (!(p instanceof _LineSegment3d__WEBPACK_IMPORTED_MODULE_3__.LineSegment3d) && !(p instanceof _LineString3d__WEBPACK_IMPORTED_MODULE_4__.LineString3d)) // TODO: probably should do this for all types. Lots of spline-type primitives can be closed.
204365
204479
  closedCurveSplitCandidate = p.startPoint().isAlmostEqualXY(p.endPoint(), tolerance);
204366
204480
  if (closedCurveSplitCandidate && !this.primitiveToPair.has(p)) {
204367
204481
  const p0 = p.clonePartialCurve(0.0, 0.5);
204368
204482
  const p1 = p.clonePartialCurve(0.5, 1.0);
204369
204483
  if (p0 && p1) {
204370
- this.insertPair(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetailPair.createCapture(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetail.createCurveEvaluatedFraction(p0, 0.0), _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetail.createCurveEvaluatedFraction(p1, 1.0)));
204371
- this.insertPair(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetailPair.createCapture(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetail.createCurveEvaluatedFraction(p0, 1.0), _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetail.createCurveEvaluatedFraction(p1, 0.0)));
204484
+ this.insertPair(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetailPair.createCapture(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetail.createCurveEvaluatedFraction(p0, 0.0), _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetail.createCurveEvaluatedFraction(p1, 1.0)));
204485
+ this.insertPair(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetailPair.createCapture(_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetail.createCurveEvaluatedFraction(p0, 1.0), _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetail.createCurveEvaluatedFraction(p1, 0.0)));
204372
204486
  }
204373
204487
  }
204374
204488
  }
@@ -204382,7 +204496,7 @@ class PlanarSubdivision {
204382
204496
  * Create a graph from an array of curves, and an array of the curves' precomputed intersections.
204383
204497
  * Z-coordinates are ignored.
204384
204498
  */
204385
- static assembleHalfEdgeGraph(primitives, allPairs, mergeTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
204499
+ static assembleHalfEdgeGraph(primitives, allPairs, mergeTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance) {
204386
204500
  // map from key CurvePrimitive to CurveLocationDetailPair
204387
204501
  const detailByPrimitive = new MapCurvePrimitiveToCurveLocationDetailPairArray();
204388
204502
  for (const pair of allPairs)
@@ -204391,7 +204505,7 @@ class PlanarSubdivision {
204391
204505
  // otherwise, these single-primitive loops are missing from the graph
204392
204506
  detailByPrimitive.splitAndAppendMissingClosedPrimitives(primitives, mergeTolerance);
204393
204507
  }
204394
- const graph = new _topology_Graph__WEBPACK_IMPORTED_MODULE_5__.HalfEdgeGraph();
204508
+ const graph = new _topology_Graph__WEBPACK_IMPORTED_MODULE_6__.HalfEdgeGraph();
204395
204509
  for (const entry of detailByPrimitive.primitiveToPair.entries()) {
204396
204510
  const p = entry[0];
204397
204511
  // convert each interval intersection into two isolated intersections
@@ -204399,12 +204513,12 @@ class PlanarSubdivision {
204399
204513
  if (!detailPair.detailA.hasFraction1)
204400
204514
  return [...accumulator, detailPair];
204401
204515
  const detail = getDetailOnCurve(detailPair, p);
204402
- const detail0 = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetail.createCurveFractionPoint(p, detail.fraction, detail.point);
204403
- const detail1 = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetail.createCurveFractionPoint(p, detail.fraction1, detail.point1);
204516
+ const detail0 = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetail.createCurveFractionPoint(p, detail.fraction, detail.point);
204517
+ const detail1 = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetail.createCurveFractionPoint(p, detail.fraction1, detail.point1);
204404
204518
  return [
204405
204519
  ...accumulator,
204406
- _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetailPair.createCapture(detail0, detail0),
204407
- _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetailPair.createCapture(detail1, detail1),
204520
+ _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetailPair.createCapture(detail0, detail0),
204521
+ _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetailPair.createCapture(detail1, detail1),
204408
204522
  ];
204409
204523
  }, []);
204410
204524
  // lexical sort on p intersection fraction
@@ -204416,12 +204530,12 @@ class PlanarSubdivision {
204416
204530
  let last = { point: p.startPoint(), fraction: 0.0 };
204417
204531
  for (const detailPair of details) {
204418
204532
  const detail = getDetailOnCurve(detailPair, p);
204419
- const detailFraction = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.restrictToInterval(detail.fraction, 0, 1); // truncate fraction, but don't snap point; clustering happens later
204533
+ const detailFraction = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.restrictToInterval(detail.fraction, 0, 1); // truncate fraction, but don't snap point; clustering happens later
204420
204534
  last = this.addHalfEdge(graph, p, last.point, last.fraction, detail.point, detailFraction, mergeTolerance);
204421
204535
  }
204422
204536
  this.addHalfEdge(graph, p, last.point, last.fraction, p.endPoint(), 1.0, mergeTolerance);
204423
204537
  }
204424
- _topology_Merging__WEBPACK_IMPORTED_MODULE_6__.HalfEdgeGraphMerge.clusterAndMergeXYTheta(graph, (he) => he.sortAngle);
204538
+ _topology_Merging__WEBPACK_IMPORTED_MODULE_7__.HalfEdgeGraphMerge.clusterAndMergeXYTheta(graph, (he) => he.sortAngle);
204425
204539
  return graph;
204426
204540
  }
204427
204541
  /**
@@ -204435,11 +204549,13 @@ class PlanarSubdivision {
204435
204549
  * @param fraction1 end fraction
204436
204550
  * @returns end point and fraction, or start point and fraction if no action
204437
204551
  */
204438
- static addHalfEdge(graph, p, point0, fraction0, point1, fraction1, mergeTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
204552
+ static addHalfEdge(graph, p, point0, fraction0, point1, fraction1, mergeTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance) {
204439
204553
  if (point0.isAlmostEqualXY(point1, mergeTolerance))
204440
204554
  return { point: point0, fraction: fraction0 };
204441
204555
  const halfEdge = graph.createEdgeXYAndZ(point0, 0, point1, 0);
204442
- const detail01 = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_4__.CurveLocationDetail.createCurveEvaluatedFractionFraction(p, fraction0, fraction1);
204556
+ if (p.parent && p.parent instanceof _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_8__.RegionGroupMember && p.parent.parentGroup.groupOpType === _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_8__.RegionGroupOpType.NonBounding)
204557
+ halfEdge.setMaskAroundEdge(_topology_Graph__WEBPACK_IMPORTED_MODULE_6__.HalfEdgeMask.BRIDGE_EDGE);
204558
+ const detail01 = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetail.createCurveEvaluatedFractionFraction(p, fraction0, fraction1);
204443
204559
  const mate = halfEdge.edgeMate;
204444
204560
  halfEdge.edgeTag = detail01;
204445
204561
  halfEdge.sortData = 1.0;
@@ -204457,7 +204573,7 @@ class PlanarSubdivision {
204457
204573
  * @returns the area (forced to zero if within tolerance)
204458
204574
  */
204459
204575
  static collectSignedLoop(loop, outLoops, zeroAreaTolerance = 1.0e-10, isSliverFace) {
204460
- let area = isSliverFace ? 0.0 : _RegionOps__WEBPACK_IMPORTED_MODULE_7__.RegionOps.computeXYArea(loop);
204576
+ let area = isSliverFace ? 0.0 : _RegionOps__WEBPACK_IMPORTED_MODULE_9__.RegionOps.computeXYArea(loop);
204461
204577
  if (area === undefined)
204462
204578
  area = 0;
204463
204579
  if (Math.abs(area) < zeroAreaTolerance)
@@ -204471,41 +204587,115 @@ class PlanarSubdivision {
204471
204587
  outLoops.slivers.push(loop);
204472
204588
  return area;
204473
204589
  }
204474
- static createLoopInFace(faceSeed, announce) {
204475
- let he = faceSeed;
204476
- const loop = _Loop__WEBPACK_IMPORTED_MODULE_8__.Loop.create();
204477
- do {
204478
- const detail = he.edgeTag;
204479
- if (detail) {
204480
- let curve;
204481
- if (he.sortData > 0)
204482
- curve = detail.curve.clonePartialCurve(detail.fraction, detail.fraction1);
204483
- else
204484
- curve = detail.curve.clonePartialCurve(detail.fraction1, detail.fraction);
204485
- if (curve) {
204486
- if (announce !== undefined)
204487
- announce(he, curve, loop);
204488
- loop.tryAddChild(curve);
204590
+ /** Extract geometric info from a topological edge. */
204591
+ static extractGeometryFromEdge(edge) {
204592
+ if (edge.sortData !== undefined && edge.edgeTag && edge.edgeTag instanceof _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetail) {
204593
+ const detail = edge.edgeTag;
204594
+ if (detail.curve && detail.fraction1 !== undefined) {
204595
+ const reversed = edge.sortData < 0;
204596
+ return { detail, reversed };
204597
+ }
204598
+ }
204599
+ return undefined;
204600
+ }
204601
+ /** Create the geometry for a topological edge. */
204602
+ static createCurveInEdge(edge) {
204603
+ const info = this.extractGeometryFromEdge(edge);
204604
+ if (info) {
204605
+ if (info.reversed)
204606
+ return info.detail.curve.clonePartialCurve(info.detail.fraction1, info.detail.fraction);
204607
+ return info.detail.curve.clonePartialCurve(info.detail.fraction, info.detail.fraction1);
204608
+ }
204609
+ return undefined;
204610
+ }
204611
+ /**
204612
+ * Create a [[Loop]] for the given face or super face.
204613
+ * @param face a node in the face loop, or an array of HalfEdges that comprise a loop (e.g., a super face).
204614
+ * @param announce optional callback invoked on each edge/curve of the face/Loop.
204615
+ * @param compress whether to consolidate adjacent curves in the output Loop (default `false`).
204616
+ * If `announce` is provided, no compression is performed, as edges and curves would no longer be in 1-1 correspondence.
204617
+ */
204618
+ static createLoopInFace(face, announce, compress = false) {
204619
+ if (announce)
204620
+ compress = false;
204621
+ const loop = _Loop__WEBPACK_IMPORTED_MODULE_10__.Loop.create();
204622
+ const addEdgeCurve = (he) => {
204623
+ const curve = this.createCurveInEdge(he);
204624
+ if (curve) {
204625
+ announce?.(he, curve, loop);
204626
+ loop.tryAddChild(curve);
204627
+ }
204628
+ };
204629
+ if (Array.isArray(face))
204630
+ face.forEach(addEdgeCurve);
204631
+ else
204632
+ face.announceEdgesInFace(addEdgeCurve);
204633
+ if (compress) {
204634
+ const options = new _RegionOps__WEBPACK_IMPORTED_MODULE_9__.ConsolidateAdjacentCurvePrimitivesOptions();
204635
+ options.consolidateLoopSeam = true;
204636
+ _RegionOps__WEBPACK_IMPORTED_MODULE_9__.RegionOps.consolidateAdjacentPrimitives(loop, options);
204637
+ }
204638
+ if (loop.isPhysicallyClosedCurve(undefined, true))
204639
+ return loop;
204640
+ (0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.assert)(false, "createLoopInFace: face is not physically closed");
204641
+ return undefined;
204642
+ }
204643
+ /**
204644
+ * Create a [[Loop]] or [[ParityRegion]] for the given face.
204645
+ * * A ParityRegion is created for a split-washer type face by removing bridge edges.
204646
+ * @param face a node in the face loop.
204647
+ * @param bridgeMask mask preset on bridge edges (default is `HalfEdgeMask.BRIDGE_EDGE`).
204648
+ * @param visitMask mask to use for visiting edges in the face loop (default is `HalfEdgeMask.VISITED`).
204649
+ */
204650
+ static createLoopOrParityRegionInFace(face, bridgeMask = _topology_Graph__WEBPACK_IMPORTED_MODULE_6__.HalfEdgeMask.BRIDGE_EDGE, visitMask = _topology_Graph__WEBPACK_IMPORTED_MODULE_6__.HalfEdgeMask.VISITED) {
204651
+ let region;
204652
+ if (face.isSplitWasherFace(bridgeMask)) {
204653
+ const loops = [];
204654
+ const loopEdges = [];
204655
+ const bridgeStack = [face.findMaskAroundFace(bridgeMask, true)];
204656
+ const announceEdge = (he) => { he.setMask(visitMask); loopEdges.push(he); };
204657
+ const announceBridge = (he) => { if (!he.isMaskSet(visitMask))
204658
+ bridgeStack.push(he); };
204659
+ face.clearMaskAroundFace(visitMask);
204660
+ let bridge;
204661
+ while (undefined !== (bridge = bridgeStack.pop())) {
204662
+ bridge.setMask(visitMask);
204663
+ const loopSeed = bridge.findMaskAroundFace(bridgeMask, false); // advance to next loop
204664
+ if (loopSeed) {
204665
+ if (loopSeed.isMaskSet(visitMask))
204666
+ continue;
204667
+ loopEdges.length = 0;
204668
+ if (loopSeed.announceEdgesInSuperFace(bridgeMask, announceEdge, announceBridge)) {
204669
+ const loop = this.createLoopInFace(loopEdges, undefined, true);
204670
+ if (loop) {
204671
+ loops.push(loop);
204672
+ continue;
204673
+ }
204674
+ }
204489
204675
  }
204490
204676
  }
204491
- he = he.faceSuccessor;
204492
- } while (he !== faceSeed);
204493
- return loop;
204677
+ region = _RegionOps__WEBPACK_IMPORTED_MODULE_9__.RegionOps.sortOuterAndHoleLoopsXY(loops);
204678
+ region = _RegionOps__WEBPACK_IMPORTED_MODULE_9__.RegionOps.simplifyRegion(region);
204679
+ }
204680
+ else {
204681
+ region = this.createLoopInFace(face, undefined, true);
204682
+ }
204683
+ return (region && (region instanceof _Loop__WEBPACK_IMPORTED_MODULE_10__.Loop || region instanceof _ParityRegion__WEBPACK_IMPORTED_MODULE_11__.ParityRegion)) ? region : undefined;
204494
204684
  }
204495
- // Return true if there are only two edges in the face loop, and their start curvatures are the same.
204685
+ /** Return true if there are only two edges in the face loop, and their start curvatures are the same. */
204496
204686
  static isNullFace(he) {
204497
204687
  const faceHasTwoEdges = (he.faceSuccessor.faceSuccessor === he);
204498
204688
  let faceIsBanana = false;
204499
204689
  if (faceHasTwoEdges) {
204500
- const c0 = _topology_Merging__WEBPACK_IMPORTED_MODULE_6__.HalfEdgeGraphMerge.curvatureSortKey(he);
204501
- const c1 = _topology_Merging__WEBPACK_IMPORTED_MODULE_6__.HalfEdgeGraphMerge.curvatureSortKey(he.faceSuccessor.edgeMate);
204502
- if (!_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(c0, c1)) // default tol!
204690
+ const c0 = _topology_Merging__WEBPACK_IMPORTED_MODULE_7__.HalfEdgeGraphMerge.curvatureSortKey(he);
204691
+ const c1 = _topology_Merging__WEBPACK_IMPORTED_MODULE_7__.HalfEdgeGraphMerge.curvatureSortKey(he.faceSuccessor.edgeMate);
204692
+ if (!_Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(c0, c1)) // default tol!
204503
204693
  faceIsBanana = true; // heuristic: we could also check end curvatures, and/or higher derivatives...
204504
204694
  }
204505
204695
  return faceHasTwoEdges && !faceIsBanana;
204506
204696
  }
204507
- // Look across edge mates (possibly several) for a nonnull mate face.
204508
- static nonNullEdgeMate(_graph, e) {
204697
+ /** Look across edge mates (possibly several) for a non-null mate face. */
204698
+ static getNonNullEdgeMate(_graph, e) {
204509
204699
  if (this.isNullFace(e))
204510
204700
  return undefined;
204511
204701
  let e1 = e.edgeMate;
@@ -204517,7 +204707,7 @@ class PlanarSubdivision {
204517
204707
  return e1;
204518
204708
  }
204519
204709
  static collectSignedLoopSetsInHalfEdgeGraph(graph, zeroAreaTolerance = 1.0e-10) {
204520
- const q = _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_9__.HalfEdgeGraphSearch.collectConnectedComponentsWithExteriorParityMasks(graph, undefined);
204710
+ const q = _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_12__.HalfEdgeGraphSearch.collectConnectedComponentsWithExteriorParityMasks(graph, undefined);
204521
204711
  const result = [];
204522
204712
  const edgeMap = new Map();
204523
204713
  for (const faceSeeds of q) {
@@ -204527,15 +204717,15 @@ class PlanarSubdivision {
204527
204717
  const isNullFace = this.isNullFace(faceSeed);
204528
204718
  const loop = this.createLoopInFace(faceSeed, (he, curveC, loopC) => {
204529
204719
  if (!isNullFace) {
204530
- const mate = this.nonNullEdgeMate(graph, he);
204720
+ const mate = this.getNonNullEdgeMate(graph, he);
204531
204721
  if (mate !== undefined) {
204532
204722
  const e = edgeMap.get(mate);
204533
204723
  if (e === undefined) {
204534
204724
  // Record this as loopA,edgeA of a shared edge to be completed later from the other side of the edge
204535
- const e1 = new _Loop__WEBPACK_IMPORTED_MODULE_8__.LoopCurveLoopCurve(loopC, curveC, undefined, undefined);
204725
+ const e1 = new _Loop__WEBPACK_IMPORTED_MODULE_10__.LoopCurveLoopCurve(loopC, curveC, undefined, undefined);
204536
204726
  edgeMap.set(he, e1);
204537
204727
  }
204538
- else if (e instanceof _Loop__WEBPACK_IMPORTED_MODULE_8__.LoopCurveLoopCurve) {
204728
+ else if (e instanceof _Loop__WEBPACK_IMPORTED_MODULE_10__.LoopCurveLoopCurve) {
204539
204729
  e.setB(loopC, curveC);
204540
204730
  edges.push(e);
204541
204731
  edgeMap.delete(mate);
@@ -204543,7 +204733,8 @@ class PlanarSubdivision {
204543
204733
  }
204544
204734
  }
204545
204735
  });
204546
- this.collectSignedLoop(loop, componentAreas, zeroAreaTolerance, isNullFace);
204736
+ if (loop)
204737
+ this.collectSignedLoop(loop, componentAreas, zeroAreaTolerance, isNullFace);
204547
204738
  }
204548
204739
  componentAreas.edges = edges;
204549
204740
  result.push(componentAreas);
@@ -204591,11 +204782,12 @@ __webpack_require__.r(__webpack_exports__);
204591
204782
  /* harmony export */ StrokeCountSection: () => (/* binding */ StrokeCountSection)
204592
204783
  /* harmony export */ });
204593
204784
  /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
204594
- /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
204595
- /* harmony import */ var _CurveCollection__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../CurveCollection */ "../../core/geometry/lib/esm/curve/CurveCollection.js");
204785
+ /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
204786
+ /* harmony import */ var _CurveCollection__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../CurveCollection */ "../../core/geometry/lib/esm/curve/CurveCollection.js");
204596
204787
  /* harmony import */ var _LineString3d__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
204597
- /* harmony import */ var _Loop__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
204598
- /* harmony import */ var _ParityRegion__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../ParityRegion */ "../../core/geometry/lib/esm/curve/ParityRegion.js");
204788
+ /* harmony import */ var _Loop__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
204789
+ /* harmony import */ var _ParityRegion__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../ParityRegion */ "../../core/geometry/lib/esm/curve/ParityRegion.js");
204790
+ /* harmony import */ var _UnionRegion__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../UnionRegion */ "../../core/geometry/lib/esm/curve/UnionRegion.js");
204599
204791
  /* harmony import */ var _StrokeCountMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./StrokeCountMap */ "../../core/geometry/lib/esm/curve/Query/StrokeCountMap.js");
204600
204792
  /*---------------------------------------------------------------------------------------------
204601
204793
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
@@ -204611,6 +204803,7 @@ __webpack_require__.r(__webpack_exports__);
204611
204803
 
204612
204804
 
204613
204805
 
204806
+
204614
204807
  // cspell:word remapa
204615
204808
  /**
204616
204809
  * abstract methods for callbacks during sweeps of collections of StrokeCount Structures.
@@ -204741,6 +204934,7 @@ class StrokeCountMapVisitorApplyMaxCurveLength extends StrokeCountMapMultipassVi
204741
204934
  * * `parent` = parent CurveCollection.
204742
204935
  *
204743
204936
  * An instance is normally created with either a `Path` or `Loop` as the parent.
204937
+ * @internal
204744
204938
  */
204745
204939
  class StrokeCountChain {
204746
204940
  maps;
@@ -204756,7 +204950,7 @@ class StrokeCountChain {
204756
204950
  this.maps = [];
204757
204951
  this.options = options;
204758
204952
  }
204759
- static createForCurveChain(chain, options) {
204953
+ static create(chain, options) {
204760
204954
  const result = new StrokeCountChain(chain, options);
204761
204955
  result.parent = chain;
204762
204956
  // A chain can only contain primitives !!!!
@@ -204827,16 +205021,24 @@ class StrokeCountSection {
204827
205021
  * construct array of arrays of `StrokeCountMap`s
204828
205022
  * @param parent
204829
205023
  */
204830
- static createForParityRegionOrChain(parent, options) {
205024
+ static create(parent, options) {
204831
205025
  const result = new StrokeCountSection(parent);
204832
- if (parent instanceof _ParityRegion__WEBPACK_IMPORTED_MODULE_3__.ParityRegion) {
205026
+ const appendCurveChain = (chain) => result.chains.push(StrokeCountChain.create(chain, options));
205027
+ const appendParityRegion = (region) => { for (const child of region.children)
205028
+ appendCurveChain(child); };
205029
+ if (parent instanceof _UnionRegion__WEBPACK_IMPORTED_MODULE_3__.UnionRegion) {
204833
205030
  for (const child of parent.children) {
204834
- const p = StrokeCountChain.createForCurveChain(child, options);
204835
- result.chains.push(p);
205031
+ if (child instanceof _ParityRegion__WEBPACK_IMPORTED_MODULE_4__.ParityRegion)
205032
+ appendParityRegion(child);
205033
+ else
205034
+ appendCurveChain(child);
204836
205035
  }
204837
205036
  }
204838
- else if (parent instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_4__.CurveChain) {
204839
- result.chains.push(StrokeCountChain.createForCurveChain(parent, options));
205037
+ else if (parent instanceof _ParityRegion__WEBPACK_IMPORTED_MODULE_4__.ParityRegion) {
205038
+ appendParityRegion(parent);
205039
+ }
205040
+ else if (parent instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_5__.CurveChain) {
205041
+ appendCurveChain(parent);
204840
205042
  }
204841
205043
  return result;
204842
205044
  }
@@ -204915,11 +205117,12 @@ class StrokeCountSection {
204915
205117
  for (let chainIndex = 0; chainIndex < numChainPerSection; chainIndex++) {
204916
205118
  const numPrimitive = sections[0].chains[chainIndex].maps.length;
204917
205119
  for (let primitiveIndex = 0; primitiveIndex < numPrimitive; primitiveIndex++) {
204918
- if (sections[0].chains[chainIndex].maps[primitiveIndex].componentData) {
204919
- const numComponent = sections[0].chains[chainIndex].maps[primitiveIndex].componentData.length;
204920
- for (let i = 0; i < numComponent; i++)
205120
+ const numComponent = sections[0].chains[chainIndex].maps[primitiveIndex].componentData?.length ?? 0;
205121
+ if (numComponent > 0) {
205122
+ for (let i = 0; i < numComponent; i++) {
204921
205123
  if (!this.applyMultipassVisitorCallbackNoComponents(sections, chainIndex, primitiveIndex, i, callback))
204922
205124
  return false;
205125
+ }
204923
205126
  }
204924
205127
  else {
204925
205128
  if (!this.applyMultipassVisitorCallbackNoComponents(sections, chainIndex, primitiveIndex, undefined, callback))
@@ -204967,11 +205170,11 @@ class StrokeCountSection {
204967
205170
  return this.chains[0].getStrokes();
204968
205171
  }
204969
205172
  else {
204970
- const region = _ParityRegion__WEBPACK_IMPORTED_MODULE_3__.ParityRegion.create();
205173
+ const region = _ParityRegion__WEBPACK_IMPORTED_MODULE_4__.ParityRegion.create();
204971
205174
  for (const c of this.chains) {
204972
205175
  const strokes = c.getStrokes();
204973
205176
  if (strokes instanceof _LineString3d__WEBPACK_IMPORTED_MODULE_2__.LineString3d)
204974
- region.tryAddChild(_Loop__WEBPACK_IMPORTED_MODULE_5__.Loop.create(strokes));
205177
+ region.tryAddChild(_Loop__WEBPACK_IMPORTED_MODULE_6__.Loop.create(strokes));
204975
205178
  }
204976
205179
  return region;
204977
205180
  }
@@ -204993,8 +205196,8 @@ class StrokeCountSection {
204993
205196
  if (strokeB instanceof _LineString3d__WEBPACK_IMPORTED_MODULE_2__.LineString3d) {
204994
205197
  if (strokeA.numPoints() === strokeB.numPoints()) {
204995
205198
  const n = strokeA.numPoints();
204996
- const pointA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
204997
- const pointB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
205199
+ const pointA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
205200
+ const pointB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
204998
205201
  const allPointA = strokeA.packedPoints;
204999
205202
  const allPointB = strokeB.packedPoints;
205000
205203
  for (let i = 0; i < n; i++) {
@@ -205006,8 +205209,8 @@ class StrokeCountSection {
205006
205209
  }
205007
205210
  }
205008
205211
  }
205009
- else if (strokeA instanceof _ParityRegion__WEBPACK_IMPORTED_MODULE_3__.ParityRegion) {
205010
- if (strokeB instanceof _ParityRegion__WEBPACK_IMPORTED_MODULE_3__.ParityRegion) {
205212
+ else if (strokeA instanceof _ParityRegion__WEBPACK_IMPORTED_MODULE_4__.ParityRegion) {
205213
+ if (strokeB instanceof _ParityRegion__WEBPACK_IMPORTED_MODULE_4__.ParityRegion) {
205011
205214
  const childrenA = strokeA.children;
205012
205215
  const childrenB = strokeB.children;
205013
205216
  const n = childrenA.length;
@@ -205020,8 +205223,8 @@ class StrokeCountSection {
205020
205223
  }
205021
205224
  }
205022
205225
  }
205023
- else if (strokeA instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_4__.CurveChain) {
205024
- if (strokeB instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_4__.CurveChain) {
205226
+ else if (strokeA instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_5__.CurveChain) {
205227
+ if (strokeB instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_5__.CurveChain) {
205025
205228
  const childrenA = strokeA.children;
205026
205229
  const childrenB = strokeB.children;
205027
205230
  const n = childrenA.length;
@@ -205224,10 +205427,11 @@ __webpack_require__.r(__webpack_exports__);
205224
205427
  /* harmony import */ var _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../geometry3d/GeometryHandler */ "../../core/geometry/lib/esm/geometry3d/GeometryHandler.js");
205225
205428
  /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
205226
205429
  /* harmony import */ var _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../geometry4d/MomentData */ "../../core/geometry/lib/esm/geometry4d/MomentData.js");
205227
- /* harmony import */ var _LineString3d__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
205430
+ /* harmony import */ var _LineString3d__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
205228
205431
  /* harmony import */ var _Loop__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
205432
+ /* harmony import */ var _ParityRegion__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./ParityRegion */ "../../core/geometry/lib/esm/curve/ParityRegion.js");
205229
205433
  /* harmony import */ var _RegionOps__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./RegionOps */ "../../core/geometry/lib/esm/curve/RegionOps.js");
205230
- /* harmony import */ var _StrokeOptions__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./StrokeOptions */ "../../core/geometry/lib/esm/curve/StrokeOptions.js");
205434
+ /* harmony import */ var _StrokeOptions__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./StrokeOptions */ "../../core/geometry/lib/esm/curve/StrokeOptions.js");
205231
205435
  /*---------------------------------------------------------------------------------------------
205232
205436
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
205233
205437
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -205240,6 +205444,7 @@ __webpack_require__.r(__webpack_exports__);
205240
205444
 
205241
205445
 
205242
205446
 
205447
+
205243
205448
  /**
205244
205449
  * Implementation class for computing XY area moments.
205245
205450
  * @internal
@@ -205295,7 +205500,7 @@ class RegionMomentsXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
205295
205500
  segment.endPoint(this._point1);
205296
205501
  momentData.accumulateTriangleMomentsXY(undefined, this._point0, this._point1);
205297
205502
  }
205298
- /** Accumulate integrals from origin to all primitives in the chain. */
205503
+ /** Accumulate integrals from origin to all primitives in the loop. */
205299
205504
  handleLoop(loop) {
205300
205505
  const momentData = this._activeMomentData = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_3__.MomentData.create();
205301
205506
  momentData.needOrigin = false;
@@ -205305,7 +205510,7 @@ class RegionMomentsXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
205305
205510
  return momentData;
205306
205511
  }
205307
205512
  handleAnyRegion(region) {
205308
- // guarantee there is no overlapping children
205513
+ // guarantee there are no overlapping children and parity loops have been properly oriented
205309
205514
  const merged = _RegionOps__WEBPACK_IMPORTED_MODULE_4__.RegionOps.regionBooleanXY(region, undefined, _RegionOps__WEBPACK_IMPORTED_MODULE_4__.RegionBinaryOpType.Union);
205310
205515
  if (!merged)
205311
205516
  return undefined;
@@ -205315,7 +205520,9 @@ class RegionMomentsXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
205315
205520
  for (const child of merged.children) {
205316
205521
  const childMoments = child.dispatchToGeometryHandler(this);
205317
205522
  if (childMoments) {
205318
- const sign0 = childMoments.signFactor(1.0);
205523
+ // parity region hole sums subtract; all other regions add
205524
+ const scale = (merged instanceof _ParityRegion__WEBPACK_IMPORTED_MODULE_6__.ParityRegion && childMoments.quantitySum < 0) ? -1.0 : 1.0;
205525
+ const sign0 = childMoments.signFactor(scale);
205319
205526
  summedMoments.accumulateProducts(childMoments, sign0);
205320
205527
  }
205321
205528
  }
@@ -205333,7 +205540,7 @@ class RegionMomentsXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
205333
205540
  getStrokeOptions() {
205334
205541
  if (this._strokeOptions)
205335
205542
  return this._strokeOptions;
205336
- const options = _StrokeOptions__WEBPACK_IMPORTED_MODULE_6__.StrokeOptions.createForCurves();
205543
+ const options = _StrokeOptions__WEBPACK_IMPORTED_MODULE_7__.StrokeOptions.createForCurves();
205337
205544
  // this is unusually fine for stroking, but appropriate for sum.
205338
205545
  options.angleTol = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createDegrees(5.0);
205339
205546
  this._strokeOptions = options;
@@ -205344,7 +205551,7 @@ class RegionMomentsXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
205344
205551
  * * Stroke the curve and accumulate stroke array.
205345
205552
  */
205346
205553
  handleCurvePrimitive(cp) {
205347
- const strokes = _LineString3d__WEBPACK_IMPORTED_MODULE_7__.LineString3d.create();
205554
+ const strokes = _LineString3d__WEBPACK_IMPORTED_MODULE_8__.LineString3d.create();
205348
205555
  const options = this.getStrokeOptions();
205349
205556
  cp.emitStrokes(strokes, options);
205350
205557
  this.handleLineString3d(strokes);
@@ -205386,27 +205593,28 @@ __webpack_require__.r(__webpack_exports__);
205386
205593
  /* harmony import */ var _geometry3d_IndexedXYZCollection__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../geometry3d/IndexedXYZCollection */ "../../core/geometry/lib/esm/geometry3d/IndexedXYZCollection.js");
205387
205594
  /* harmony import */ var _geometry3d_Point3dArrayCarrier__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ../geometry3d/Point3dArrayCarrier */ "../../core/geometry/lib/esm/geometry3d/Point3dArrayCarrier.js");
205388
205595
  /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
205389
- /* harmony import */ var _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ../geometry3d/PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
205596
+ /* harmony import */ var _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ../geometry3d/PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
205390
205597
  /* harmony import */ var _geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ../geometry3d/PolylineCompressionByEdgeOffset */ "../../core/geometry/lib/esm/geometry3d/PolylineCompressionByEdgeOffset.js");
205391
- /* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
205598
+ /* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
205392
205599
  /* harmony import */ var _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../geometry3d/Ray3d */ "../../core/geometry/lib/esm/geometry3d/Ray3d.js");
205393
205600
  /* harmony import */ var _geometry3d_SortablePolygon__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ../geometry3d/SortablePolygon */ "../../core/geometry/lib/esm/geometry3d/SortablePolygon.js");
205394
205601
  /* harmony import */ var _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ../geometry3d/Transform */ "../../core/geometry/lib/esm/geometry3d/Transform.js");
205395
205602
  /* harmony import */ var _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../geometry4d/MomentData */ "../../core/geometry/lib/esm/geometry4d/MomentData.js");
205396
205603
  /* harmony import */ var _polyface_PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../polyface/PolyfaceBuilder */ "../../core/geometry/lib/esm/polyface/PolyfaceBuilder.js");
205397
- /* harmony import */ var _topology_Graph__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../topology/Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
205398
- /* harmony import */ var _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../topology/HalfEdgeGraphSearch */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphSearch.js");
205399
- /* harmony import */ var _topology_Merging__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ../topology/Merging */ "../../core/geometry/lib/esm/topology/Merging.js");
205604
+ /* harmony import */ var _topology_Graph__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../topology/Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
205605
+ /* harmony import */ var _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../topology/HalfEdgeGraphSearch */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphSearch.js");
205606
+ /* harmony import */ var _topology_Merging__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ../topology/Merging */ "../../core/geometry/lib/esm/topology/Merging.js");
205400
205607
  /* harmony import */ var _topology_Triangulation__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../topology/Triangulation */ "../../core/geometry/lib/esm/topology/Triangulation.js");
205401
205608
  /* harmony import */ var _CurveCollection__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./CurveCollection */ "../../core/geometry/lib/esm/curve/CurveCollection.js");
205402
- /* harmony import */ var _CurveCurve__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./CurveCurve */ "../../core/geometry/lib/esm/curve/CurveCurve.js");
205609
+ /* harmony import */ var _CurveCurve__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./CurveCurve */ "../../core/geometry/lib/esm/curve/CurveCurve.js");
205403
205610
  /* harmony import */ var _CurveOps__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./CurveOps */ "../../core/geometry/lib/esm/curve/CurveOps.js");
205404
205611
  /* harmony import */ var _CurvePrimitive__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./CurvePrimitive */ "../../core/geometry/lib/esm/curve/CurvePrimitive.js");
205405
205612
  /* harmony import */ var _CurveWireMomentsXYZ__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./CurveWireMomentsXYZ */ "../../core/geometry/lib/esm/curve/CurveWireMomentsXYZ.js");
205406
- /* harmony import */ var _GeometryQuery__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./GeometryQuery */ "../../core/geometry/lib/esm/curve/GeometryQuery.js");
205613
+ /* harmony import */ var _GeometryQuery__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ./GeometryQuery */ "../../core/geometry/lib/esm/curve/GeometryQuery.js");
205407
205614
  /* harmony import */ var _internalContexts_ChainCollectorContext__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./internalContexts/ChainCollectorContext */ "../../core/geometry/lib/esm/curve/internalContexts/ChainCollectorContext.js");
205408
205615
  /* harmony import */ var _internalContexts_PolygonOffsetContext__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./internalContexts/PolygonOffsetContext */ "../../core/geometry/lib/esm/curve/internalContexts/PolygonOffsetContext.js");
205409
205616
  /* harmony import */ var _internalContexts_TransferWithSplitArcs__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ./internalContexts/TransferWithSplitArcs */ "../../core/geometry/lib/esm/curve/internalContexts/TransferWithSplitArcs.js");
205617
+ /* harmony import */ var _LineSegment3d__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
205410
205618
  /* harmony import */ var _LineString3d__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
205411
205619
  /* harmony import */ var _Loop__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
205412
205620
  /* harmony import */ var _OffsetOptions__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./OffsetOptions */ "../../core/geometry/lib/esm/curve/OffsetOptions.js");
@@ -205415,7 +205623,7 @@ __webpack_require__.r(__webpack_exports__);
205415
205623
  /* harmony import */ var _Query_ConsolidateAdjacentPrimitivesContext__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ./Query/ConsolidateAdjacentPrimitivesContext */ "../../core/geometry/lib/esm/curve/Query/ConsolidateAdjacentPrimitivesContext.js");
205416
205624
  /* harmony import */ var _Query_CurveSplitContext__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./Query/CurveSplitContext */ "../../core/geometry/lib/esm/curve/Query/CurveSplitContext.js");
205417
205625
  /* harmony import */ var _Query_InOutTests__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./Query/InOutTests */ "../../core/geometry/lib/esm/curve/Query/InOutTests.js");
205418
- /* harmony import */ var _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./Query/PlanarSubdivision */ "../../core/geometry/lib/esm/curve/Query/PlanarSubdivision.js");
205626
+ /* harmony import */ var _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./Query/PlanarSubdivision */ "../../core/geometry/lib/esm/curve/Query/PlanarSubdivision.js");
205419
205627
  /* harmony import */ var _RegionMomentsXY__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./RegionMomentsXY */ "../../core/geometry/lib/esm/curve/RegionMomentsXY.js");
205420
205628
  /* harmony import */ var _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./RegionOpsClassificationSweeps */ "../../core/geometry/lib/esm/curve/RegionOpsClassificationSweeps.js");
205421
205629
  /* harmony import */ var _UnionRegion__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./UnionRegion */ "../../core/geometry/lib/esm/curve/UnionRegion.js");
@@ -205464,6 +205672,7 @@ __webpack_require__.r(__webpack_exports__);
205464
205672
 
205465
205673
 
205466
205674
 
205675
+
205467
205676
 
205468
205677
 
205469
205678
  /**
@@ -205765,16 +205974,17 @@ class RegionOps {
205765
205974
  * @param loopsB second set of loops (treated as a union)
205766
205975
  * @param operation indicates Union, Intersection, Parity, AMinusB, or BMinusA
205767
205976
  * @param mergeTolerance absolute distance tolerance for merging loops
205768
- * @returns a region resulting from merging input loops and the boolean operation. May contain bridge edges added
205769
- * to connect interior loops to exterior loops.
205977
+ * @returns a region resulting from merging input loops and the boolean operation.
205770
205978
  */
205771
205979
  static regionBooleanXY(loopsA, loopsB, operation, mergeTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistance) {
205772
- let result;
205980
+ const result = _UnionRegion__WEBPACK_IMPORTED_MODULE_14__.UnionRegion.create();
205773
205981
  const context = _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__.RegionBooleanContext.create(_RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__.RegionGroupOpType.Union, _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__.RegionGroupOpType.Union);
205774
205982
  context.addMembers(loopsA, loopsB);
205775
205983
  context.annotateAndMergeCurvesInGraph(mergeTolerance);
205984
+ const visitMask = context.graph.grabMask(false);
205776
205985
  const range = context.groupA.range().union(context.groupB.range());
205777
205986
  const areaTol = this.computeXYAreaTolerance(range, mergeTolerance);
205987
+ const bridgeMask = _topology_Graph__WEBPACK_IMPORTED_MODULE_15__.HalfEdgeMask.BRIDGE_EDGE;
205778
205988
  context.runClassificationSweep(operation, (_graph, face, faceType, area) => {
205779
205989
  // ignore danglers and null faces, but not 2-edge "banana" faces with nonzero area
205780
205990
  if (face.countEdgesAroundFace() < 2)
@@ -205782,15 +205992,13 @@ class RegionOps {
205782
205992
  if (Math.abs(area) < areaTol)
205783
205993
  return;
205784
205994
  if (faceType === 1) {
205785
- const loop = _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_15__.PlanarSubdivision.createLoopInFace(face);
205786
- if (loop) {
205787
- if (!result)
205788
- result = _UnionRegion__WEBPACK_IMPORTED_MODULE_14__.UnionRegion.create();
205789
- result.tryAddChild(loop);
205790
- }
205995
+ const loopOrParityRegion = _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_16__.PlanarSubdivision.createLoopOrParityRegionInFace(face, bridgeMask, visitMask);
205996
+ if (loopOrParityRegion)
205997
+ result.tryAddChild(loopOrParityRegion);
205791
205998
  }
205792
205999
  });
205793
- return result ? this.simplifyRegion(result) : undefined;
206000
+ context.graph.dropMask(visitMask);
206001
+ return this.simplifyRegion(result);
205794
206002
  }
205795
206003
  /**
205796
206004
  * Return a polyface whose facets are a boolean operation between the input regions.
@@ -205823,7 +206031,7 @@ class RegionOps {
205823
206031
  const graph = _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__.RegionOpsFaceToFaceSearch.doBinaryBooleanBetweenMultiLoopInputs(inputA, _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__.RegionGroupOpType.Union, operation, inputB, _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__.RegionGroupOpType.Union, true);
205824
206032
  if (!graph)
205825
206033
  return undefined;
205826
- const loopEdges = _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_16__.HalfEdgeGraphSearch.collectExtendedBoundaryLoopsInGraph(graph, _topology_Graph__WEBPACK_IMPORTED_MODULE_17__.HalfEdgeMask.EXTERIOR);
206034
+ const loopEdges = _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_17__.HalfEdgeGraphSearch.collectExtendedBoundaryLoopsInGraph(graph, _topology_Graph__WEBPACK_IMPORTED_MODULE_15__.HalfEdgeMask.EXTERIOR);
205827
206035
  const allLoops = [];
205828
206036
  for (const graphLoop of loopEdges) {
205829
206037
  const points = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_18__.GrowableXYZArray();
@@ -206105,19 +206313,45 @@ class RegionOps {
206105
206313
  }
206106
206314
  return _geometry3d_SortablePolygon__WEBPACK_IMPORTED_MODULE_33__.SortablePolygon.sortAsAnyRegion(loopAndArea);
206107
206315
  }
206316
+ /**
206317
+ * Collect inputs that are nominally closed: regions, and physically closed curves.
206318
+ * * Physically closed input curves are each returned wrapped in a Loop to facilitate xy-algorithms,
206319
+ * but outside this limited context, these Loops only makes sense if they are planar.
206320
+ */
206321
+ static collectRegionsAndClosedPrimitives(curves, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistance) {
206322
+ const regions = [];
206323
+ if (!Array.isArray(curves))
206324
+ curves = [curves];
206325
+ for (const curve of curves) {
206326
+ if (curve instanceof _Loop__WEBPACK_IMPORTED_MODULE_8__.Loop || curve instanceof _ParityRegion__WEBPACK_IMPORTED_MODULE_9__.ParityRegion || curve instanceof _UnionRegion__WEBPACK_IMPORTED_MODULE_14__.UnionRegion) {
206327
+ regions.push(curve);
206328
+ }
206329
+ else if (curve instanceof _Path__WEBPACK_IMPORTED_MODULE_24__.Path) {
206330
+ if (curve.isPhysicallyClosedCurve(tolerance))
206331
+ regions.push(_Loop__WEBPACK_IMPORTED_MODULE_8__.Loop.create(...curve.children));
206332
+ }
206333
+ else if (curve instanceof _CurvePrimitive__WEBPACK_IMPORTED_MODULE_27__.CurvePrimitive) {
206334
+ if (curve.isPhysicallyClosedCurve(tolerance))
206335
+ regions.push(_Loop__WEBPACK_IMPORTED_MODULE_8__.Loop.create(curve));
206336
+ }
206337
+ }
206338
+ return regions;
206339
+ }
206108
206340
  /**
206109
206341
  * Find all xy-areas bounded by the unstructured, possibly intersecting curves.
206110
206342
  * * For best results, input curves should be parallel to the xy-plane, as z-coordinates are ignored.
206111
- * * A common use case of this method is to assemble the bounding "exterior" loop (or loops) containing the
206112
- * input curves. Note that "holes" implied by inputs are _not_ preserved in output.
206113
- * * This method does not add bridge edges to connect outer loops to inner loops. Each disconnected loop,
206114
- * regardless of its containment, is returned as its own SignedLoops object. Pre-process with [[regionBooleanXY]]
206115
- * to add bridge edges so that [[constructAllXYRegionLoops]] will return outer and inner loops in the same
206116
- * SignedLoops object.
206117
- * @param curvesAndRegions Any collection of curves. Each Loop/ParityRegion/UnionRegion contributes its curve
206118
- * primitives, stripped of parity context. This means holes are _not_ preserved in output.
206343
+ * * "Holes" implied/bounded by inputs are _not_ preserved/discovered in output; in particular [[ParityRegion]]
206344
+ * hole loops are treated like any other positive area loops.
206345
+ * * A common use case of this method is to assemble the bounding negative-area "exterior" loop for each connected
206346
+ * component of input curves. Passing `addBridges = true` decreases the number of connected components for nested
206347
+ * input [[Loop]]s, and thus increases the likelihood of returning exactly one exterior loop. (This is why the
206348
+ * default value for `addBridges` is `true`.)
206349
+ * @param curvesAndRegions Any collection of curves. Each [[AnyRegion]] contributes its children _stripped of
206350
+ * parity context_.
206119
206351
  * @param tolerance optional distance tolerance for coincidence.
206120
- * @returns array of [[SignedLoops]], each entry of which describes the faces in a single connected component:
206352
+ * @param addBridges whether to add line segments to connect nested input [[Loop]]s (default is `true`). When `false`,
206353
+ * no line segments are added to the input curves, but the number of output components may be greater than expected.
206354
+ * @returns array of [[SignedLoops]], each entry of which describes the areas bounded by a single connected component:
206121
206355
  * * `positiveAreaLoops` contains "interior" loops, _including holes in ParityRegion input_. These loops have
206122
206356
  * positive area and counterclockwise orientation.
206123
206357
  * * `negativeAreaLoops` contains (probably just one) "exterior" loop which is ordered clockwise.
@@ -206125,14 +206359,25 @@ class RegionOps {
206125
206359
  * * `edges` contains a [[LoopCurveLoopCurve]] object for each component edge, collecting both loops adjacent
206126
206360
  * to the edge and a constituent curve in each.
206127
206361
  */
206128
- static constructAllXYRegionLoops(curvesAndRegions, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistance) {
206362
+ static constructAllXYRegionLoops(curvesAndRegions, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistance, addBridges = true) {
206129
206363
  let primitives = RegionOps.collectCurvePrimitives(curvesAndRegions, undefined, true, true);
206130
206364
  primitives = _internalContexts_TransferWithSplitArcs__WEBPACK_IMPORTED_MODULE_34__.TransferWithSplitArcs.clone(_CurveCollection__WEBPACK_IMPORTED_MODULE_25__.BagOfCurves.create(...primitives)).children;
206131
206365
  const range = this.curveArrayRange(primitives);
206132
206366
  const areaTol = this.computeXYAreaTolerance(range, tolerance);
206133
- const intersections = _CurveCurve__WEBPACK_IMPORTED_MODULE_35__.CurveCurve.allIntersectionsAmongPrimitivesXY(primitives, tolerance);
206134
- const graph = _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_15__.PlanarSubdivision.assembleHalfEdgeGraph(primitives, intersections, tolerance);
206135
- return _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_15__.PlanarSubdivision.collectSignedLoopSetsInHalfEdgeGraph(graph, areaTol);
206367
+ if (addBridges) { // generate a temp graph to extract its bridge edges
206368
+ const context = _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__.RegionBooleanContext.create(_RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__.RegionGroupOpType.Union, _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__.RegionGroupOpType.Union);
206369
+ const regions = this.collectRegionsAndClosedPrimitives(curvesAndRegions, tolerance);
206370
+ context.addMembers(regions, undefined);
206371
+ context.annotateAndMergeCurvesInGraph(tolerance);
206372
+ context.graph.announceEdges((_graph, edge) => {
206373
+ if (edge.isMaskSet(_topology_Graph__WEBPACK_IMPORTED_MODULE_15__.HalfEdgeMask.BRIDGE_EDGE))
206374
+ primitives.push(_LineSegment3d__WEBPACK_IMPORTED_MODULE_35__.LineSegment3d.create(edge.getPoint3d(), edge.faceSuccessor.getPoint3d()));
206375
+ return true;
206376
+ });
206377
+ }
206378
+ const intersections = _CurveCurve__WEBPACK_IMPORTED_MODULE_36__.CurveCurve.allIntersectionsAmongPrimitivesXY(primitives, tolerance);
206379
+ const graph = _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_16__.PlanarSubdivision.assembleHalfEdgeGraph(primitives, intersections, tolerance);
206380
+ return _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_16__.PlanarSubdivision.collectSignedLoopSetsInHalfEdgeGraph(graph, areaTol);
206136
206381
  }
206137
206382
  /**
206138
206383
  * Collect all `CurvePrimitives` in loosely typed input.
@@ -206188,12 +206433,12 @@ class RegionOps {
206188
206433
  * @param worldToLocal transform to apply to data before computing its range
206189
206434
  */
206190
206435
  static curveArrayRange(data, worldToLocal) {
206191
- const range = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_36__.Range3d.create();
206192
- if (data instanceof _GeometryQuery__WEBPACK_IMPORTED_MODULE_37__.GeometryQuery)
206436
+ const range = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_37__.Range3d.create();
206437
+ if (data instanceof _GeometryQuery__WEBPACK_IMPORTED_MODULE_38__.GeometryQuery)
206193
206438
  data.extendRange(range, worldToLocal);
206194
206439
  else if (Array.isArray(data)) {
206195
206440
  for (const c of data) {
206196
- if (c instanceof _GeometryQuery__WEBPACK_IMPORTED_MODULE_37__.GeometryQuery)
206441
+ if (c instanceof _GeometryQuery__WEBPACK_IMPORTED_MODULE_38__.GeometryQuery)
206197
206442
  c.extendRange(range, worldToLocal);
206198
206443
  else if (c instanceof _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d)
206199
206444
  range.extendPoint(c, worldToLocal);
@@ -206229,7 +206474,7 @@ class RegionOps {
206229
206474
  for (const polygon of polygons)
206230
206475
  writablePolygons.push(_geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_18__.GrowableXYZArray.create(polygon));
206231
206476
  }
206232
- const sortedPolygons = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_38__.PolygonOps.sortOuterAndHoleLoopsXY(writablePolygons);
206477
+ const sortedPolygons = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_39__.PolygonOps.sortOuterAndHoleLoopsXY(writablePolygons);
206233
206478
  if (sortedPolygons.length === 1) { // below requires exactly one outer loop!
206234
206479
  if (graph = _topology_Triangulation__WEBPACK_IMPORTED_MODULE_11__.Triangulator.createTriangulatedGraphFromLoops(sortedPolygons[0]))
206235
206480
  _topology_Triangulation__WEBPACK_IMPORTED_MODULE_11__.Triangulator.flipTriangles(graph);
@@ -206312,7 +206557,7 @@ class RegionOps {
206312
206557
  if (!graph)
206313
206558
  return undefined;
206314
206559
  if (options?.maximizeConvexFacets)
206315
- _topology_Merging__WEBPACK_IMPORTED_MODULE_39__.HalfEdgeGraphOps.expandConvexFaces(graph);
206560
+ _topology_Merging__WEBPACK_IMPORTED_MODULE_40__.HalfEdgeGraphOps.expandConvexFaces(graph);
206316
206561
  return _polyface_PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_12__.PolyfaceBuilder.graphToPolyface(graph, options);
206317
206562
  }
206318
206563
  /**
@@ -206326,10 +206571,10 @@ class RegionOps {
206326
206571
  if (!graph)
206327
206572
  return undefined;
206328
206573
  if (maximize)
206329
- _topology_Merging__WEBPACK_IMPORTED_MODULE_39__.HalfEdgeGraphOps.expandConvexFaces(graph);
206574
+ _topology_Merging__WEBPACK_IMPORTED_MODULE_40__.HalfEdgeGraphOps.expandConvexFaces(graph);
206330
206575
  const convexPolygons = [];
206331
206576
  graph.announceFaceLoops((_graph, seed) => {
206332
- if (!seed.isMaskSet(_topology_Graph__WEBPACK_IMPORTED_MODULE_17__.HalfEdgeMask.EXTERIOR))
206577
+ if (!seed.isMaskSet(_topology_Graph__WEBPACK_IMPORTED_MODULE_15__.HalfEdgeMask.EXTERIOR))
206333
206578
  convexPolygons.push(_geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_18__.GrowableXYZArray.create(seed.collectAroundFace((node) => { return node.getPoint3d(); })));
206334
206579
  return true;
206335
206580
  });
@@ -206354,9 +206599,11 @@ class ConsolidateAdjacentCurvePrimitivesOptions {
206354
206599
  consolidateLinearGeometry = true;
206355
206600
  /** True to consolidate contiguous compatible arcs into a single Arc3d. */
206356
206601
  consolidateCompatibleArcs = true;
206602
+ /** True to consolidate the first and last primitives of a [[Loop]], allowing the start/end point to change. */
206603
+ consolidateLoopSeam = false;
206357
206604
  /** Disable LineSegment3d and LineString3d point compression. */
206358
206605
  disableLinearCompression = false;
206359
- /** Tolerance for collapsing identical points (if `!disableLinearCompression`). */
206606
+ /** Tolerance for detecting identical points. */
206360
206607
  duplicatePointTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistance;
206361
206608
  /** Tolerance for removing interior colinear points (if `!disableLinearCompression`). */
206362
206609
  colinearPointTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistance;
@@ -206378,6 +206625,7 @@ __webpack_require__.r(__webpack_exports__);
206378
206625
  /* harmony export */ GraphComponentArray: () => (/* binding */ GraphComponentArray),
206379
206626
  /* harmony export */ RegionBooleanContext: () => (/* binding */ RegionBooleanContext),
206380
206627
  /* harmony export */ RegionGroup: () => (/* binding */ RegionGroup),
206628
+ /* harmony export */ RegionGroupMember: () => (/* binding */ RegionGroupMember),
206381
206629
  /* harmony export */ RegionGroupOpType: () => (/* binding */ RegionGroupOpType),
206382
206630
  /* harmony export */ RegionOpsFaceToFaceSearch: () => (/* binding */ RegionOpsFaceToFaceSearch)
206383
206631
  /* harmony export */ });
@@ -206390,15 +206638,15 @@ __webpack_require__.r(__webpack_exports__);
206390
206638
  /* harmony import */ var _topology_Merging__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../topology/Merging */ "../../core/geometry/lib/esm/topology/Merging.js");
206391
206639
  /* harmony import */ var _topology_RegularizeFace__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../topology/RegularizeFace */ "../../core/geometry/lib/esm/topology/RegularizeFace.js");
206392
206640
  /* harmony import */ var _Arc3d__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./Arc3d */ "../../core/geometry/lib/esm/curve/Arc3d.js");
206393
- /* harmony import */ var _CurveCurve__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./CurveCurve */ "../../core/geometry/lib/esm/curve/CurveCurve.js");
206394
- /* harmony import */ var _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./CurveLocationDetail */ "../../core/geometry/lib/esm/curve/CurveLocationDetail.js");
206641
+ /* harmony import */ var _CurveCurve__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./CurveCurve */ "../../core/geometry/lib/esm/curve/CurveCurve.js");
206642
+ /* harmony import */ var _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./CurveLocationDetail */ "../../core/geometry/lib/esm/curve/CurveLocationDetail.js");
206395
206643
  /* harmony import */ var _GeometryQuery__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./GeometryQuery */ "../../core/geometry/lib/esm/curve/GeometryQuery.js");
206396
206644
  /* harmony import */ var _internalContexts_PlaneAltitudeRangeContext__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./internalContexts/PlaneAltitudeRangeContext */ "../../core/geometry/lib/esm/curve/internalContexts/PlaneAltitudeRangeContext.js");
206397
206645
  /* harmony import */ var _internalContexts_TransferWithSplitArcs__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./internalContexts/TransferWithSplitArcs */ "../../core/geometry/lib/esm/curve/internalContexts/TransferWithSplitArcs.js");
206398
206646
  /* harmony import */ var _LineSegment3d__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
206399
206647
  /* harmony import */ var _Loop__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
206400
206648
  /* harmony import */ var _ParityRegion__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./ParityRegion */ "../../core/geometry/lib/esm/curve/ParityRegion.js");
206401
- /* harmony import */ var _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./Query/PlanarSubdivision */ "../../core/geometry/lib/esm/curve/Query/PlanarSubdivision.js");
206649
+ /* harmony import */ var _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./Query/PlanarSubdivision */ "../../core/geometry/lib/esm/curve/Query/PlanarSubdivision.js");
206402
206650
  /* harmony import */ var _RegionOps__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./RegionOps */ "../../core/geometry/lib/esm/curve/RegionOps.js");
206403
206651
  /* harmony import */ var _UnionRegion__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./UnionRegion */ "../../core/geometry/lib/esm/curve/UnionRegion.js");
206404
206652
  /*---------------------------------------------------------------------------------------------
@@ -206902,6 +207150,94 @@ class RegionBooleanContext {
206902
207150
  this.extraGeometry.addMember(bridgeLine, true);
206903
207151
  }
206904
207152
  }
207153
+ /**
207154
+ * Simplify the graph by removing bridge edges that do not serve to connect inner and outer loops, i.e.:
207155
+ * * the bridge edge is dangling
207156
+ * * the bridge edge is adjacent to multiple faces
207157
+ * * the bridge edge is adjacent to a negative area face
207158
+ * @returns the number of extraneous bridge edges removed from the graph.
207159
+ */
207160
+ removeExtraneousBridgeEdges() {
207161
+ const toHeal = [];
207162
+ const interiorBridges = [];
207163
+ // lambda test for boundary edge. Relies only on face loop orientation. Doesn't use HalfEdgeMasks!
207164
+ const isExteriorEdge = (node) => {
207165
+ if (this.faceAreaFunction(node) < 0.0)
207166
+ return true;
207167
+ if (!node.findAroundFace(node.edgeMate))
207168
+ return this.faceAreaFunction(node.edgeMate) < 0.0;
207169
+ return false;
207170
+ };
207171
+ // isolate dangling bridges, bridges separating different faces, and "exterior" bridges in the negative area face
207172
+ this.graph.announceEdges((_graph, node) => {
207173
+ if (node.edgeTag !== undefined) {
207174
+ if (node.edgeTag instanceof _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_16__.CurveLocationDetail) {
207175
+ if (node.edgeTag.curve) {
207176
+ if (node.edgeTag.curve.parent instanceof RegionGroupMember) {
207177
+ if (node.edgeTag.curve.parent.parentGroup === this.extraGeometry) {
207178
+ if (node.isDangling || node.edgeMate.isDangling || !node.findAroundFace(node.edgeMate) || this.faceAreaFunction(node) < 0.0) {
207179
+ toHeal.push(node.vertexSuccessor);
207180
+ toHeal.push(node.edgeMate.vertexSuccessor);
207181
+ node.isolateEdge();
207182
+ }
207183
+ else {
207184
+ interiorBridges.push(node);
207185
+ }
207186
+ }
207187
+ }
207188
+ }
207189
+ }
207190
+ }
207191
+ return true;
207192
+ });
207193
+ // At this point, all bridges that were exterior are isolated, but this may have caused formerly
207194
+ // interior bridges to become exterior. Now we successively isolate exterior bridges until none remain.
207195
+ let numIsolatedThisPass;
207196
+ do {
207197
+ numIsolatedThisPass = 0;
207198
+ for (const node of interiorBridges) {
207199
+ if (!node.isIsolatedEdge && isExteriorEdge(node)) {
207200
+ toHeal.push(node.vertexSuccessor);
207201
+ toHeal.push(node.edgeMate.vertexSuccessor);
207202
+ node.isolateEdge();
207203
+ numIsolatedThisPass++;
207204
+ }
207205
+ }
207206
+ } while (numIsolatedThisPass > 0);
207207
+ // lambda to extend the detail interval on a side of a healed edge
207208
+ const mergeDetails = (he, newFraction, newPoint) => {
207209
+ if (he && he.edgeTag instanceof _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_16__.CurveLocationDetail && he.sortData !== undefined && newFraction !== undefined && newPoint) {
207210
+ if (he.sortData > 0)
207211
+ he.edgeTag.captureFraction1Point1(newFraction, newPoint);
207212
+ else
207213
+ he.edgeTag.captureFractionPoint(newFraction, newPoint);
207214
+ }
207215
+ };
207216
+ // At this point all removable bridges are isolated. Clean up their original vertex loops, if possible.
207217
+ for (const doomedA of toHeal) {
207218
+ const doomedB = doomedA.vertexSuccessor;
207219
+ if ( // are the geometries mergeable?
207220
+ doomedA !== doomedB &&
207221
+ doomedA.edgeTag instanceof _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_16__.CurveLocationDetail && doomedA.sortData !== undefined &&
207222
+ doomedB.edgeTag instanceof _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_16__.CurveLocationDetail && doomedB.sortData !== undefined &&
207223
+ doomedA.edgeTag.curve === doomedB.edgeTag.curve &&
207224
+ doomedA.edgeTag.hasFraction1 && doomedB.edgeTag.hasFraction1 &&
207225
+ doomedA.sortData * doomedB.sortData < 0 &&
207226
+ ((doomedA.sortData > 0 && _Geometry__WEBPACK_IMPORTED_MODULE_7__.Geometry.isSmallRelative(doomedA.edgeTag.fraction - doomedB.edgeTag.fraction1)) ||
207227
+ (doomedA.sortData < 0 && _Geometry__WEBPACK_IMPORTED_MODULE_7__.Geometry.isSmallRelative(doomedA.edgeTag.fraction1 - doomedB.edgeTag.fraction)))) {
207228
+ const survivorA = _topology_Graph__WEBPACK_IMPORTED_MODULE_0__.HalfEdge.healEdge(doomedA, false);
207229
+ if (survivorA) {
207230
+ const endFractionA = (doomedA.sortData > 0) ? doomedA.edgeTag.fraction1 : doomedA.edgeTag.fraction;
207231
+ const endPointA = (doomedA.sortData > 0) ? doomedA.edgeTag.point1 : doomedA.edgeTag.point;
207232
+ mergeDetails(survivorA, endFractionA, endPointA);
207233
+ const endFractionB = (doomedB.sortData > 0) ? doomedB.edgeTag.fraction1 : doomedB.edgeTag.fraction;
207234
+ const endPointB = (doomedB.sortData > 0) ? doomedB.edgeTag.point1 : doomedB.edgeTag.point;
207235
+ mergeDetails(survivorA.edgeMate, endFractionB, endPointB);
207236
+ }
207237
+ }
207238
+ }
207239
+ return this.graph.deleteIsolatedEdges();
207240
+ }
206905
207241
  /**
206906
207242
  * Markup and assembly steps for geometry in the RegionGroups.
206907
207243
  * * Annotate connection from group to curves.
@@ -206923,10 +207259,11 @@ class RegionBooleanContext {
206923
207259
  }
206924
207260
  }
206925
207261
  }
206926
- const intersections = _CurveCurve__WEBPACK_IMPORTED_MODULE_16__.CurveCurve.allIntersectionsAmongPrimitivesXY(allPrimitives, mergeTolerance);
206927
- const graph = _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_17__.PlanarSubdivision.assembleHalfEdgeGraph(allPrimitives, intersections, mergeTolerance);
207262
+ const intersections = _CurveCurve__WEBPACK_IMPORTED_MODULE_17__.CurveCurve.allIntersectionsAmongPrimitivesXY(allPrimitives, mergeTolerance);
207263
+ const graph = _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_18__.PlanarSubdivision.assembleHalfEdgeGraph(allPrimitives, intersections, mergeTolerance);
206928
207264
  this.graph = graph;
206929
207265
  this.faceAreaFunction = faceAreaFromCurvedEdgeData;
207266
+ this.removeExtraneousBridgeEdges();
206930
207267
  }
206931
207268
  _announceFaceFunction;
206932
207269
  /**
@@ -207014,7 +207351,7 @@ class RegionBooleanContext {
207014
207351
  const data = node.edgeTag;
207015
207352
  if (data instanceof RegionGroupMember)
207016
207353
  return updateRegionGroupMemberState(data);
207017
- if (data instanceof _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_18__.CurveLocationDetail) {
207354
+ if (data instanceof _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_16__.CurveLocationDetail) {
207018
207355
  // We trust that the caller has linked from the graph node to a curve which has a RegionGroupMember as its parent.
207019
207356
  const member = data.curve.parent;
207020
207357
  if (member instanceof RegionGroupMember)
@@ -208784,23 +209121,23 @@ class CurveCurveCloseApproachXY extends _geometry3d_GeometryHandler__WEBPACK_IMP
208784
209121
  let reversed = false;
208785
209122
  const uu = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.hypotenuseSquaredXY(ux, uy);
208786
209123
  if (hab0 * hab0 <= maxDistanceSquared * uu) { // test distance of b0 to u
208787
- const fractionA = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.dotProductXYXY(ux, uy, e00x, e00y) / uu;
209124
+ const fractionA = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.safeDivideFraction(_Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.dotProductXYXY(ux, uy, e00x, e00y), uu, 0.0);
208788
209125
  if (this.updatePointToSegmentDistance(0, b0, a0, a1, fractionA, maxDistanceSquared, closestApproach))
208789
209126
  reversed = true;
208790
209127
  }
208791
209128
  if (hab1 * hab1 <= maxDistanceSquared * uu) { // test distance of b1 to u
208792
- const fractionA = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.dotProductXYXY(ux, uy, e01x, e01y) / uu;
209129
+ const fractionA = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.safeDivideFraction(_Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.dotProductXYXY(ux, uy, e01x, e01y), uu, 0.0);
208793
209130
  if (this.updatePointToSegmentDistance(1, b1, a0, a1, fractionA, maxDistanceSquared, closestApproach))
208794
209131
  reversed = true;
208795
209132
  }
208796
209133
  const vv = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.hypotenuseSquaredXY(vx, vy);
208797
209134
  if (hba0 * hba0 <= maxDistanceSquared * vv) { // test distance of a0 to v
208798
- const fractionB = -_Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.dotProductXYXY(vx, vy, e00x, e00y) / vv;
209135
+ const fractionB = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.safeDivideFraction(-_Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.dotProductXYXY(vx, vy, e00x, e00y), vv, 0.0);
208799
209136
  if (this.updatePointToSegmentDistance(0, a0, b0, b1, fractionB, maxDistanceSquared, closestApproach))
208800
209137
  reversed = false;
208801
209138
  }
208802
209139
  if (hba1 * hba1 <= maxDistanceSquared * vv) { // test distance of a1 to v
208803
- const fractionB = -_Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.dotProductXYXY(vx, vy, e10x, e10y) / vv;
209140
+ const fractionB = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.safeDivideFraction(-_Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.dotProductXYXY(vx, vy, e10x, e10y), vv, 0.0);
208804
209141
  if (this.updatePointToSegmentDistance(1, a1, b0, b1, fractionB, maxDistanceSquared, closestApproach))
208805
209142
  reversed = false;
208806
209143
  }
@@ -208878,7 +209215,7 @@ class CurveCurveCloseApproachXY extends _geometry3d_GeometryHandler__WEBPACK_IMP
208878
209215
  return undefined;
208879
209216
  }
208880
209217
  /**
208881
- * Find the closest approach between `pointA` and `cpB`. Add the approach if it's within `fB0` and `fB1`.
209218
+ * Find the closest xy approach between `pointA` and `cpB`. Add the approach if it's within `fB0` and `fB1`.
208882
209219
  * * Does not test the endpoints of `cpB`.
208883
209220
  * * The only types supported for `cpB` are Arc3d, LineSegment3d, and LineString3d.
208884
209221
  * * If `cpB` is a LineString3d, then the interval `[fB0, fB1]` must correspond to a segment of the line string.
@@ -208903,7 +209240,7 @@ class CurveCurveCloseApproachXY extends _geometry3d_GeometryHandler__WEBPACK_IMP
208903
209240
  }
208904
209241
  }
208905
209242
  /**
208906
- * Compute intersection of two line segments.
209243
+ * Compute closest xy approach of two line segments.
208907
209244
  * Filter by extension rules.
208908
209245
  * Record with fraction mapping.
208909
209246
  * * The fraction mappings allow portions of a linestring to be passed here.
@@ -217179,7 +217516,7 @@ class AngleSweep {
217179
217516
  result.setStartEndRadians(startRadians, endRadians);
217180
217517
  return result;
217181
217518
  }
217182
- /** Return the angle obtained by subtracting radians from this angle. */
217519
+ /** Return the AngleSweep obtained by subtracting radians from the start and end angles of this sweep. */
217183
217520
  cloneMinusRadians(radians) {
217184
217521
  return new AngleSweep(this._radians0 - radians, this._radians1 - radians);
217185
217522
  }
@@ -218870,7 +219207,7 @@ __webpack_require__.r(__webpack_exports__);
218870
219207
  * For the equator circle, phi=0, cos(phi) = 1, sin(phi)=0
218871
219208
  * f = u * cos(theta) + v * sin(theta).
218872
219209
  * with derivative
218873
- * df / dTheta = = u * sin(theta) + v * cos(theta)
219210
+ * df / dTheta = - u * sin(theta) + v * cos(theta)
218874
219211
  * whose zero is tan(theta) = v/u
218875
219212
  * (and that has two solutions 180 degrees apart)
218876
219213
  * Then with that theta let A = u * cos(theta) + v * sin(theta)
@@ -223526,6 +223863,7 @@ class IndexedXYZCollection {
223526
223863
  * @param index0 index of first point
223527
223864
  * @param index1 index of second point
223528
223865
  * @param tolerance max coordinate difference to be considered equal. For exact test, pass 0. Defaults to `Geometry.smallMetricDistance`.
223866
+ * @returns whether the points are equal within tolerance, or `undefined` if either index is invalid.
223529
223867
  */
223530
223868
  almostEqualIndexIndex(index0, index1, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance) {
223531
223869
  if (index0 < 0 || index0 >= this.length || index1 < 0 || index1 >= this.length)
@@ -223534,6 +223872,19 @@ class IndexedXYZCollection {
223534
223872
  && _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.getYAtUncheckedPointIndex(index0), this.getYAtUncheckedPointIndex(index1), tolerance)
223535
223873
  && _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.getZAtUncheckedPointIndex(index0), this.getZAtUncheckedPointIndex(index1), tolerance);
223536
223874
  }
223875
+ /**
223876
+ * Test whether the xy-coordinates of the indexed points are equal within tolerance. The z-coordinates are ignored.
223877
+ * @param index0 index of first point
223878
+ * @param index1 index of second point
223879
+ * @param tolerance max coordinate difference to be considered equal. For exact test, pass 0. Defaults to `Geometry.smallMetricDistance`.
223880
+ * @returns whether the xy-coordinates of the points are equal within tolerance, or `undefined` if either index is invalid.
223881
+ */
223882
+ almostEqualXYIndexIndex(index0, index1, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance) {
223883
+ if (index0 < 0 || index0 >= this.length || index1 < 0 || index1 >= this.length)
223884
+ return undefined;
223885
+ return _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.getXAtUncheckedPointIndex(index0), this.getXAtUncheckedPointIndex(index1), tolerance)
223886
+ && _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.getYAtUncheckedPointIndex(index0), this.getYAtUncheckedPointIndex(index1), tolerance);
223887
+ }
223537
223888
  }
223538
223889
  /**
223539
223890
  * abstract base class extends IndexedXYZCollection, adding methods to push, peek, and pop, and rewrite.
@@ -236072,13 +236423,11 @@ class Ray3d {
236072
236423
  return new Ray3d(_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.createZero(), _Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.createZero());
236073
236424
  }
236074
236425
  /**
236075
- * Test for nearly equal Ray3d objects.
236076
- * * This tests for near equality of origin and direction -- i.e. member-by-member comparison.
236077
- * * Use [[isAlmostEqualPointSet]] to allow origins to be anywhere along the common ray and to have to allow the
236078
- * directions to be scaled or opposing.
236426
+ * Test for nearly equal Ray3d objects by comparing their origin and direction members.
236427
+ * @see [[isAlmostEqualPointSet]] to test for rays on the same infinite line.
236079
236428
  */
236080
- isAlmostEqual(other) {
236081
- return this.origin.isAlmostEqual(other.origin) && this.direction.isAlmostEqual(other.direction);
236429
+ isAlmostEqual(other, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance) {
236430
+ return this.origin.isAlmostEqual(other.origin, tolerance) && this.direction.isAlmostEqual(other.direction, tolerance);
236082
236431
  }
236083
236432
  /**
236084
236433
  * Return the dot product of the ray's direction vector with a vector from the ray origin
@@ -236106,27 +236455,19 @@ class Ray3d {
236106
236455
  return this.origin.plusScaled(this.direction, this.pointToFraction(spacePoint));
236107
236456
  }
236108
236457
  /**
236109
- * Test for nearly equal rays, allowing origin float and direction scaling.
236110
- * * Use [[isAlmostEqual]] to require member-by-member comparison.
236458
+ * Test for rays that describe the same infinite line.
236459
+ * @see [[isAlmostEqual]] for member-by-member comparison.
236111
236460
  */
236112
- isAlmostEqualPointSet(other) {
236113
- /**
236114
- * This function tests two rays to determine if they define the same infinite lines.
236115
- * So the origins can be different as long as they are on the infinite line (they can
236116
- * "float") but the directions must be parallel or antiparallel.
236117
- */
236118
- if (!this.direction.isParallelTo(other.direction, true))
236461
+ isAlmostEqualPointSet(other, options) {
236462
+ if (!this.direction.isParallelTo(other.direction, true, false, options))
236119
236463
  return false;
236120
- /**
236121
- * In exact math, we consider a ray to have an infinite line as direction (not a finite vector).
236122
- * Therefore, in exact math it is not possible for one origin to be on the other ray but not vice
236123
- * versa. However, we test both ways because first check may pass due to round-off errors.
236124
- */
236464
+ const tol2 = options?.distanceSquaredTol ?? _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistanceSquared;
236465
+ // theoretically, one test below is sufficient, but perform both in case the first passes because of round-off
236125
236466
  let workPoint = this.projectPointToRay(other.origin);
236126
- if (!other.origin.isAlmostEqualMetric(workPoint))
236467
+ if (other.origin.distanceSquared(workPoint) > tol2)
236127
236468
  return false;
236128
236469
  workPoint = other.projectPointToRay(this.origin);
236129
- if (!this.origin.isAlmostEqualMetric(workPoint))
236470
+ if (this.origin.distanceSquared(workPoint) > tol2)
236130
236471
  return false;
236131
236472
  return true;
236132
236473
  }
@@ -236821,19 +237162,24 @@ __webpack_require__.r(__webpack_exports__);
236821
237162
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
236822
237163
  /* harmony export */ SortablePolygon: () => (/* binding */ SortablePolygon)
236823
237164
  /* harmony export */ });
236824
- /* harmony import */ var _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../curve/CurveCollection */ "../../core/geometry/lib/esm/curve/CurveCollection.js");
236825
- /* harmony import */ var _curve_CurvePrimitive__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../curve/CurvePrimitive */ "../../core/geometry/lib/esm/curve/CurvePrimitive.js");
236826
- /* harmony import */ var _curve_LineString3d__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../curve/LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
236827
- /* harmony import */ var _curve_Loop__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../curve/Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
236828
- /* harmony import */ var _curve_ParityRegion__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../curve/ParityRegion */ "../../core/geometry/lib/esm/curve/ParityRegion.js");
236829
- /* harmony import */ var _curve_RegionOps__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../curve/RegionOps */ "../../core/geometry/lib/esm/curve/RegionOps.js");
236830
- /* harmony import */ var _curve_UnionRegion__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../curve/UnionRegion */ "../../core/geometry/lib/esm/curve/UnionRegion.js");
236831
- /* harmony import */ var _IndexedXYZCollection__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./IndexedXYZCollection */ "../../core/geometry/lib/esm/geometry3d/IndexedXYZCollection.js");
236832
- /* harmony import */ var _PolygonOps__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
237165
+ /* harmony import */ var _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../curve/CurveCollection */ "../../core/geometry/lib/esm/curve/CurveCollection.js");
237166
+ /* harmony import */ var _curve_CurvePrimitive__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../curve/CurvePrimitive */ "../../core/geometry/lib/esm/curve/CurvePrimitive.js");
237167
+ /* harmony import */ var _curve_LineString3d__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../curve/LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
237168
+ /* harmony import */ var _curve_Loop__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../curve/Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
237169
+ /* harmony import */ var _curve_ParityRegion__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../curve/ParityRegion */ "../../core/geometry/lib/esm/curve/ParityRegion.js");
237170
+ /* harmony import */ var _curve_RegionOps__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../curve/RegionOps */ "../../core/geometry/lib/esm/curve/RegionOps.js");
237171
+ /* harmony import */ var _curve_UnionRegion__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../curve/UnionRegion */ "../../core/geometry/lib/esm/curve/UnionRegion.js");
237172
+ /* harmony import */ var _IndexedXYZCollection__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./IndexedXYZCollection */ "../../core/geometry/lib/esm/geometry3d/IndexedXYZCollection.js");
237173
+ /* harmony import */ var _Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
237174
+ /* harmony import */ var _PolygonOps__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
237175
+ /* harmony import */ var _Ray3d__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Ray3d */ "../../core/geometry/lib/esm/geometry3d/Ray3d.js");
236833
237176
  /*---------------------------------------------------------------------------------------------
236834
237177
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
236835
237178
  * See LICENSE.md in the project root for license terms and full copyright notice.
236836
237179
  *--------------------------------------------------------------------------------------------*/
237180
+ /** @packageDocumentation
237181
+ * @module CartesianGeometry
237182
+ */
236837
237183
 
236838
237184
 
236839
237185
 
@@ -236843,14 +237189,38 @@ __webpack_require__.r(__webpack_exports__);
236843
237189
 
236844
237190
 
236845
237191
 
236846
- /** abstract base class for area-related queries of a loop.
236847
- * * subclasses have particular logic for `Loop` and polygon data.
237192
+
237193
+
237194
+ /** Abstract base class for area-related queries of an xy-loop.
237195
+ * * Subclasses have particular logic for `Loop` and polygon data.
236848
237196
  * @internal
236849
237197
  */
236850
237198
  class SimpleRegionCarrier {
237199
+ /** Fractions for interior point search. */
237200
+ searchFractions = [0.2349, 0.4142, 0.6587, 0.8193];
237201
+ /**
237202
+ * Given a region boundary tangent, construct a point interior to the region.
237203
+ * @param ray point and tangent on an edge of the region (modified on return)
237204
+ */
237205
+ constructInteriorPoint(ray) {
237206
+ ray.direction.z = 0.0;
237207
+ if (!ray.direction.normalizeInPlace())
237208
+ return undefined; // loop has zero length edge, or a vertical (gap) edge
237209
+ ray.direction.rotate90CCWXY(ray.direction);
237210
+ if (this.signedArea < 0.0)
237211
+ ray.direction.scaleInPlace(-1.0); // aim toward the region interior
237212
+ const refDistance = Math.sqrt(Math.abs(this.signedArea));
237213
+ const candidatePoint = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
237214
+ for (let fraction = 1.0e-5; fraction < 3; fraction *= 5.0) {
237215
+ ray.fractionToPoint(fraction * refDistance, candidatePoint);
237216
+ if (1 === this.classifyPointXY(candidatePoint))
237217
+ return candidatePoint;
237218
+ }
237219
+ return undefined;
237220
+ }
236851
237221
  }
236852
237222
  /**
236853
- * Implement `LoopCarrier` queries with the area as a polygon carried in an `IndexedReadWriteXYZCollection`
237223
+ * Implement `SimpleRegionCarrier` queries with the area as a polygon carried in an `IndexedReadWriteXYZCollection`.
236854
237224
  */
236855
237225
  class PolygonCarrier extends SimpleRegionCarrier {
236856
237226
  data;
@@ -236859,7 +237229,7 @@ class PolygonCarrier extends SimpleRegionCarrier {
236859
237229
  constructor(data) {
236860
237230
  super();
236861
237231
  this.data = data;
236862
- this._signedArea = _PolygonOps__WEBPACK_IMPORTED_MODULE_0__.PolygonOps.areaXY(data);
237232
+ this._signedArea = _PolygonOps__WEBPACK_IMPORTED_MODULE_1__.PolygonOps.areaXY(data);
236863
237233
  }
236864
237234
  /**
236865
237235
  * classify xy parts of point wrt this loop.
@@ -236867,22 +237237,22 @@ class PolygonCarrier extends SimpleRegionCarrier {
236867
237237
  * @internal
236868
237238
  */
236869
237239
  classifyPointXY(xy) {
236870
- return _PolygonOps__WEBPACK_IMPORTED_MODULE_0__.PolygonOps.classifyPointInPolygonXY(xy.x, xy.y, this.data);
237240
+ return _PolygonOps__WEBPACK_IMPORTED_MODULE_1__.PolygonOps.classifyPointInPolygonXY(xy.x, xy.y, this.data);
236871
237241
  }
236872
- /** Return some point "inside"
236873
- * NEEDS WORK: this returns a point ON --
236874
- */
237242
+ /** Return some point "inside". */
236875
237243
  getAnyInteriorPoint() {
236876
237244
  for (let childIndex = 0; childIndex < this.data.length; childIndex++) {
236877
- const q = this.constructInteriorPointNearEdge(childIndex, 0.2349);
236878
- if (q !== undefined)
236879
- return q;
237245
+ for (const fraction of this.searchFractions) {
237246
+ const q = this.constructInteriorPointNearEdge(childIndex, fraction);
237247
+ if (q !== undefined)
237248
+ return q;
237249
+ }
236880
237250
  }
236881
237251
  return undefined;
236882
237252
  }
236883
237253
  grabPolygon() { return this.data; }
236884
237254
  grabLoop() {
236885
- return _curve_Loop__WEBPACK_IMPORTED_MODULE_1__.Loop.createPolygon(this.data);
237255
+ return _curve_Loop__WEBPACK_IMPORTED_MODULE_2__.Loop.createPolygon(this.data);
236886
237256
  }
236887
237257
  reverseForAreaSign(targetSign) {
236888
237258
  if (targetSign * this._signedArea < 0.0) {
@@ -236892,27 +237262,14 @@ class PolygonCarrier extends SimpleRegionCarrier {
236892
237262
  }
236893
237263
  constructInteriorPointNearEdge(edgeIndex, fractionAlong) {
236894
237264
  if (edgeIndex + 1 < this.data.length) {
236895
- const point0 = this.data.getPoint3dAtUncheckedPointIndex(edgeIndex);
236896
- const point1 = this.data.getPoint3dAtUncheckedPointIndex(edgeIndex + 1);
236897
- const vector = point0.vectorTo(point1);
236898
- const point = point0.interpolate(fractionAlong, point1);
236899
- vector.rotate90CCWXY(vector);
236900
- if (vector.normalizeInPlace()) {
236901
- if (this._signedArea < 0)
236902
- vector.scaleInPlace(-1.0);
236903
- const refDistance = Math.sqrt(Math.abs(this._signedArea));
236904
- for (let fraction = 1.0e-5; fraction < 3; fraction *= 5.0) {
236905
- const candidatePoint = point.plusScaled(vector, fraction * refDistance);
236906
- if (1 === this.classifyPointXY(candidatePoint))
236907
- return candidatePoint;
236908
- }
236909
- }
237265
+ const ray = _Ray3d__WEBPACK_IMPORTED_MODULE_3__.Ray3d.createCapture(this.data.interpolateIndexIndex(edgeIndex, fractionAlong, edgeIndex + 1), this.data.vectorIndexIndex(edgeIndex, edgeIndex + 1));
237266
+ return this.constructInteriorPoint(ray);
236910
237267
  }
236911
237268
  return undefined;
236912
237269
  }
236913
237270
  }
236914
237271
  /**
236915
- * Implement `LoopCarrier` queries with the area as a strongly typed `Loop`
237272
+ * Implement `SimpleRegionCarrier` queries with the area as a strongly typed `Loop`.
236916
237273
  */
236917
237274
  class LoopCarrier extends SimpleRegionCarrier {
236918
237275
  data;
@@ -236921,7 +237278,7 @@ class LoopCarrier extends SimpleRegionCarrier {
236921
237278
  constructor(data) {
236922
237279
  super();
236923
237280
  this.data = data;
236924
- const areaMoments = _curve_RegionOps__WEBPACK_IMPORTED_MODULE_2__.RegionOps.computeXYAreaMoments(data);
237281
+ const areaMoments = _curve_RegionOps__WEBPACK_IMPORTED_MODULE_4__.RegionOps.computeXYAreaMoments(data);
236925
237282
  this._signedArea = areaMoments !== undefined ? areaMoments.quantitySum : 0.0;
236926
237283
  }
236927
237284
  /**
@@ -236930,41 +237287,32 @@ class LoopCarrier extends SimpleRegionCarrier {
236930
237287
  * @internal
236931
237288
  */
236932
237289
  classifyPointXY(xy) {
236933
- return _curve_RegionOps__WEBPACK_IMPORTED_MODULE_2__.RegionOps.testPointInOnOutRegionXY(this.data, xy.x, xy.y);
237290
+ return _curve_RegionOps__WEBPACK_IMPORTED_MODULE_4__.RegionOps.testPointInOnOutRegionXY(this.data, xy.x, xy.y);
236934
237291
  }
236935
237292
  constructInteriorPointNearChild(childIndex, fractionAlong) {
236936
237293
  if (childIndex < this.data.children.length) {
236937
- const primitive = this.data.children[childIndex];
236938
- const ray = primitive.fractionToPointAndUnitTangent(fractionAlong);
236939
- ray.direction.rotate90CCWXY(ray.direction);
236940
- if (this._signedArea < 0.0)
236941
- ray.direction.scaleInPlace(-1.0);
236942
- const refDistance = Math.sqrt(Math.abs(this._signedArea));
236943
- for (let fraction = 1.0e-5; fraction < 3; fraction *= 5.0) {
236944
- const candidatePoint = ray.fractionToPoint(fraction * refDistance);
236945
- if (1 === this.classifyPointXY(candidatePoint))
236946
- return candidatePoint;
236947
- }
237294
+ const ray = this.data.children[childIndex].fractionToPointAndDerivative(fractionAlong);
237295
+ return this.constructInteriorPoint(ray);
236948
237296
  }
236949
237297
  return undefined;
236950
237298
  }
236951
- /** Return some point "inside"
236952
- * NEEDS WORK: this returns a point ON --
236953
- */
237299
+ /** Return some point "inside". */
236954
237300
  getAnyInteriorPoint() {
236955
237301
  for (let childIndex = 0; childIndex < this.data.children.length; childIndex++) {
236956
- const q = this.constructInteriorPointNearChild(childIndex, 0.2349);
236957
- if (q !== undefined)
236958
- return q;
237302
+ for (const fraction of this.searchFractions) {
237303
+ const q = this.constructInteriorPointNearChild(childIndex, fraction);
237304
+ if (q !== undefined)
237305
+ return q;
237306
+ }
236959
237307
  }
236960
237308
  return undefined;
236961
237309
  }
236962
237310
  grabPolygon() {
236963
237311
  const strokes = this.data.cloneStroked();
236964
- if (strokes instanceof _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_3__.CurveChain) {
236965
- const linestring = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_4__.LineString3d.create();
237312
+ if (strokes instanceof _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_5__.CurveChain) {
237313
+ const linestring = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_6__.LineString3d.create();
236966
237314
  for (const child of strokes.children) {
236967
- if (child instanceof _curve_CurvePrimitive__WEBPACK_IMPORTED_MODULE_5__.CurvePrimitive) {
237315
+ if (child instanceof _curve_CurvePrimitive__WEBPACK_IMPORTED_MODULE_7__.CurvePrimitive) {
236968
237316
  child.emitStrokes(linestring);
236969
237317
  }
236970
237318
  }
@@ -236983,7 +237331,7 @@ class LoopCarrier extends SimpleRegionCarrier {
236983
237331
  }
236984
237332
  }
236985
237333
  /**
236986
- * A `SortablePolygon` carries a (single) loop with data useful for sorting for inner-outer structure.
237334
+ * A `SortablePolygon` carries a (single) xy-loop with data useful for sorting for inner-outer structure.
236987
237335
  * @internal
236988
237336
  */
236989
237337
  class SortablePolygon {
@@ -236999,7 +237347,7 @@ class SortablePolygon {
236999
237347
  * @param loop Loop to capture.
237000
237348
  */
237001
237349
  constructor(loop, range) {
237002
- if (loop instanceof _IndexedXYZCollection__WEBPACK_IMPORTED_MODULE_6__.IndexedReadWriteXYZCollection)
237350
+ if (loop instanceof _IndexedXYZCollection__WEBPACK_IMPORTED_MODULE_8__.IndexedReadWriteXYZCollection)
237003
237351
  this._loopCarrier = new PolygonCarrier(loop);
237004
237352
  else
237005
237353
  this._loopCarrier = new LoopCarrier(loop);
@@ -237104,7 +237452,7 @@ class SortablePolygon {
237104
237452
  const childData = loops[childIndex];
237105
237453
  if (childData.parentIndex === candidateIndex) {
237106
237454
  if (candidateParityRegion === undefined) {
237107
- candidateParityRegion = _curve_ParityRegion__WEBPACK_IMPORTED_MODULE_7__.ParityRegion.create();
237455
+ candidateParityRegion = _curve_ParityRegion__WEBPACK_IMPORTED_MODULE_9__.ParityRegion.create();
237108
237456
  candidateParityRegion.tryAddChild(candidateLoop);
237109
237457
  childData._loopCarrier.reverseForAreaSign(-1.0);
237110
237458
  candidateParityRegion.tryAddChild(childData._loopCarrier.grabLoop());
@@ -237129,7 +237477,7 @@ class SortablePolygon {
237129
237477
  if (regions.length === 1)
237130
237478
  return regions[0];
237131
237479
  else {
237132
- const unionRegion = _curve_UnionRegion__WEBPACK_IMPORTED_MODULE_8__.UnionRegion.create();
237480
+ const unionRegion = _curve_UnionRegion__WEBPACK_IMPORTED_MODULE_10__.UnionRegion.create();
237133
237481
  for (const region of regions)
237134
237482
  unionRegion.tryAddChild(region);
237135
237483
  return unionRegion;
@@ -250814,7 +251162,7 @@ class PolyfaceBuilder extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
250814
251162
  /** Construct facets for a rotational sweep. */
250815
251163
  addRotationalSweep(surface) {
250816
251164
  const contour = surface.getSweepContourRef();
250817
- const section0 = _curve_Query_StrokeCountChain__WEBPACK_IMPORTED_MODULE_16__.StrokeCountSection.createForParityRegionOrChain(contour.getCurves(), this._options);
251165
+ const section0 = _curve_Query_StrokeCountChain__WEBPACK_IMPORTED_MODULE_16__.StrokeCountSection.create(contour.getCurves(), this._options);
250818
251166
  const baseStrokes = section0.getStrokes();
250819
251167
  // ensure sweep is positive for buildRotationalNormalsInLineStrings
250820
251168
  const axis = surface.cloneAxisRay();
@@ -250964,7 +251312,7 @@ class PolyfaceBuilder extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
250964
251312
  /** Add facets from the linear sweep. */
250965
251313
  addLinearSweep(surface) {
250966
251314
  const contour = surface.getCurvesRef();
250967
- const section0 = _curve_Query_StrokeCountChain__WEBPACK_IMPORTED_MODULE_16__.StrokeCountSection.createForParityRegionOrChain(contour, this._options);
251315
+ const section0 = _curve_Query_StrokeCountChain__WEBPACK_IMPORTED_MODULE_16__.StrokeCountSection.create(contour, this._options);
250968
251316
  const stroke0 = section0.getStrokes();
250969
251317
  const sweepVector = surface.cloneSweepVector();
250970
251318
  const sweepTransform = _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_9__.Transform.createTranslation(sweepVector);
@@ -250986,7 +251334,7 @@ class PolyfaceBuilder extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
250986
251334
  let stroke1;
250987
251335
  const sectionMaps = [];
250988
251336
  for (const contour of contours)
250989
- sectionMaps.push(_curve_Query_StrokeCountChain__WEBPACK_IMPORTED_MODULE_16__.StrokeCountSection.createForParityRegionOrChain(contour.curves, this._options));
251337
+ sectionMaps.push(_curve_Query_StrokeCountChain__WEBPACK_IMPORTED_MODULE_16__.StrokeCountSection.create(contour.curves, this._options));
250990
251338
  if (_curve_Query_StrokeCountChain__WEBPACK_IMPORTED_MODULE_16__.StrokeCountSection.enforceStrokeCountCompatibility(sectionMaps)) {
250991
251339
  _curve_Query_StrokeCountChain__WEBPACK_IMPORTED_MODULE_16__.StrokeCountSection.enforceCompatibleDistanceSums(sectionMaps);
250992
251340
  for (let i = 0; i < contours.length; i++) {
@@ -272521,7 +272869,7 @@ class Sphere extends _SolidPrimitive__WEBPACK_IMPORTED_MODULE_0__.SolidPrimitive
272521
272869
  const sinTheta = Math.sin(thetaRadians);
272522
272870
  const sinPhi = Math.sin(phiRadians);
272523
272871
  const cosPhi = Math.cos(phiRadians);
272524
- return _geometry3d_Plane3dByOriginAndVectors__WEBPACK_IMPORTED_MODULE_11__.Plane3dByOriginAndVectors.createOriginAndVectors(this._localToWorld.multiplyXYZ(cosTheta * cosPhi, sinTheta * cosPhi, sinPhi), this._localToWorld.matrix.multiplyXYZ(-fTheta * sinTheta, fTheta * cosTheta, 0), // !!! note cosTheta term is omitted -- scale is wrong, but remains non-zero at poles.
272872
+ return _geometry3d_Plane3dByOriginAndVectors__WEBPACK_IMPORTED_MODULE_11__.Plane3dByOriginAndVectors.createOriginAndVectors(this._localToWorld.multiplyXYZ(cosTheta * cosPhi, sinTheta * cosPhi, sinPhi), this._localToWorld.matrix.multiplyXYZ(-fTheta * sinTheta, fTheta * cosTheta, 0), // NOTE: cosPhi scale is omitted, so the u-derivative scale is wrong but at least at the poles it's nonzero
272525
272873
  this._localToWorld.matrix.multiplyXYZ(-fPhi * cosTheta * sinPhi, -fPhi * sinTheta * sinPhi, fPhi * cosPhi), result);
272526
272874
  }
272527
272875
  /**
@@ -272776,7 +273124,7 @@ class SweepContour {
272776
273124
  /**
272777
273125
  * Emit facets to a function.
272778
273126
  * This method may cache and reuse facets over multiple calls.
272779
- * @param announce callback to receive the facet set.
273127
+ * @param announce callback to receive the facet set. Called only once (if facets exist).
272780
273128
  * @param options how to stroke the contour.
272781
273129
  */
272782
273130
  announceFacets(announce, options) {
@@ -273542,13 +273890,14 @@ __webpack_require__.r(__webpack_exports__);
273542
273890
  /* harmony export */ HalfEdgeGraph: () => (/* binding */ HalfEdgeGraph),
273543
273891
  /* harmony export */ HalfEdgeMask: () => (/* binding */ HalfEdgeMask)
273544
273892
  /* harmony export */ });
273545
- /* harmony import */ var _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../curve/LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
273546
- /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
273547
- /* harmony import */ var _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../geometry3d/Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
273548
- /* harmony import */ var _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../geometry3d/Point2dVector2d */ "../../core/geometry/lib/esm/geometry3d/Point2dVector2d.js");
273549
- /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
273550
- /* harmony import */ var _numerics_SmallSystem__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../numerics/SmallSystem */ "../../core/geometry/lib/esm/numerics/SmallSystem.js");
273551
- /* harmony import */ var _MaskManager__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./MaskManager */ "../../core/geometry/lib/esm/topology/MaskManager.js");
273893
+ /* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
273894
+ /* harmony import */ var _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../curve/LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
273895
+ /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
273896
+ /* harmony import */ var _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../geometry3d/Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
273897
+ /* harmony import */ var _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../geometry3d/Point2dVector2d */ "../../core/geometry/lib/esm/geometry3d/Point2dVector2d.js");
273898
+ /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
273899
+ /* harmony import */ var _numerics_SmallSystem__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../numerics/SmallSystem */ "../../core/geometry/lib/esm/numerics/SmallSystem.js");
273900
+ /* harmony import */ var _MaskManager__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./MaskManager */ "../../core/geometry/lib/esm/topology/MaskManager.js");
273552
273901
  /*---------------------------------------------------------------------------------------------
273553
273902
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
273554
273903
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -273563,9 +273912,9 @@ __webpack_require__.r(__webpack_exports__);
273563
273912
 
273564
273913
 
273565
273914
 
273915
+
273566
273916
  // import { GraphChecker } from "../test/topology/Graph.test"; // used for debugging
273567
273917
  /* eslint-disable @typescript-eslint/no-this-alias */
273568
- // cspell:word CONSTU CONSTV USEAM VSEAM internaldocs
273569
273918
  /**
273570
273919
  * * Each node of the graph has a mask member.
273571
273920
  * * The mask member is a number which is used as set of single bit boolean values.
@@ -273580,14 +273929,6 @@ __webpack_require__.r(__webpack_exports__);
273580
273929
  */
273581
273930
  var HalfEdgeMask;
273582
273931
  (function (HalfEdgeMask) {
273583
- // REMARK: Various mask names are COMMENTED here for reference to native legacy code.
273584
- // CONSTU_MASK = 0x00000004,
273585
- // CONSTV_MASK = 0x00000008,
273586
- // USEAM_MASK = 0x00000010,
273587
- // VSEAM_MASK = 0x00000020,
273588
- // BOUNDARY_VERTEX_MASK = 0x00000040,
273589
- // PRIMARY_VERTEX_MASK = 0x00000080,
273590
- // DIRECTED_EDGE_MASK = 0x00000100,
273591
273932
  /**
273592
273933
  * Mask commonly set consistently around exterior faces.
273593
273934
  * * A boundary edge with interior to one side, exterior to the other, will have EXTERIOR only on the outside.
@@ -273610,22 +273951,22 @@ var HalfEdgeMask;
273610
273951
  * BOUNDARY_EDGE nor EXTERIOR_EDGE.
273611
273952
  */
273612
273953
  HalfEdgeMask[HalfEdgeMask["PRIMARY_EDGE"] = 4] = "PRIMARY_EDGE";
273613
- /** Mask used for low level searches to identify previously-visited nodes. */
273614
- HalfEdgeMask[HalfEdgeMask["VISITED"] = 16] = "VISITED";
273954
+ /** Mask set on both sides of a bridge edge added by algorithms to join loops. */
273955
+ HalfEdgeMask[HalfEdgeMask["BRIDGE_EDGE"] = 8] = "BRIDGE_EDGE";
273956
+ /** Mask set on both sides of an edge added during graph regularization. */
273957
+ HalfEdgeMask[HalfEdgeMask["REGULARIZED_EDGE"] = 16] = "REGULARIZED_EDGE";
273615
273958
  /** Mask applied to triangles by earcut triangulator. */
273616
273959
  HalfEdgeMask[HalfEdgeMask["TRIANGULATED_FACE"] = 256] = "TRIANGULATED_FACE";
273617
273960
  /** Mask applied in a face with 2 edges. */
273618
273961
  HalfEdgeMask[HalfEdgeMask["NULL_FACE"] = 512] = "NULL_FACE";
273962
+ /** Temporary mask used for low level searches to identify previously-visited nodes. */
273963
+ HalfEdgeMask[HalfEdgeMask["VISITED"] = 65536] = "VISITED";
273619
273964
  /** No mask bits. */
273620
273965
  HalfEdgeMask[HalfEdgeMask["NULL_MASK"] = 0] = "NULL_MASK";
273621
273966
  /** The "upper 12" bits of 32 bit integer reserved for grab/drop. */
273622
273967
  HalfEdgeMask[HalfEdgeMask["ALL_GRAB_DROP_MASKS"] = 4293918720] = "ALL_GRAB_DROP_MASKS";
273623
273968
  /** All mask bits */
273624
273969
  HalfEdgeMask[HalfEdgeMask["ALL_MASK"] = 4294967295] = "ALL_MASK";
273625
- // informal convention on preassigned mask bit numbers:
273626
- // byte0 (EXTERIOR, BOUNDARY_EDGE, PRIMARY_EDGE) -- edge properties
273627
- // byte1 (VISITED, VISIT_A, WORK_MASK0, WORK_MASK1) -- temp masks for algorithms.
273628
- // byte2 (TRIANGULATED_FACE, NULL_FACE) -- face properties.
273629
273970
  })(HalfEdgeMask || (HalfEdgeMask = {}));
273630
273971
  /**
273631
273972
  * A HalfEdge is "one side of an edge" in a structure of faces, edges and vertices. From a node there are
@@ -273821,6 +274162,37 @@ class HalfEdge {
273821
274162
  }
273822
274163
  return newA;
273823
274164
  }
274165
+ /**
274166
+ * Reverse of [[splitEdge]]: remove the vertex at `doomed` and merge its two incident edges.
274167
+ * @param doomed one of two nodes added by [[splitEdge]]. These nodes should form a vertex loop of two nodes.
274168
+ * On successful return this node and its mate are isolated.
274169
+ * @param checkParallel whether to check that the doomed edge and the preceding edge in its face loop are parallel.
274170
+ * When passing `true` the assumption is that edge geometry is linear. If nonlinear edge geometry is attached, the
274171
+ * caller should a) verify that the geometry on either side of the doomed vertex can be merged, and if so, they
274172
+ * should b) call this method passing `false`, and c) adjust the geometry of the returned edge and its edge mate
274173
+ * as appropriate.
274174
+ * @returns the former (surviving) face predecessor of `doomed`, or undefined if the edge can't be healed.
274175
+ */
274176
+ static healEdge(doomed, checkParallel = true) {
274177
+ if (doomed.isIsolatedEdge)
274178
+ return undefined;
274179
+ const doomed1 = doomed.vertexSuccessor;
274180
+ if (doomed1.vertexSuccessor !== doomed)
274181
+ return undefined; // v-loop not a 2-cycle
274182
+ if (checkParallel && !doomed.vectorToFaceSuccessor().isParallelTo(doomed.facePredecessor.vectorToFaceSuccessor(), false, true))
274183
+ return undefined; // removing this vertex does not leave a straight edge behind
274184
+ const fPred = doomed.facePredecessor;
274185
+ const fSucc = doomed.faceSuccessor;
274186
+ const fPred1 = doomed1.facePredecessor;
274187
+ const fSucc1 = doomed1.faceSuccessor;
274188
+ this.setFaceLinks(fPred, fSucc);
274189
+ this.setFaceLinks(fPred1, fSucc1);
274190
+ this.setEdgeMates(fPred, fPred1);
274191
+ this.setFaceLinks(doomed, doomed1);
274192
+ this.setFaceLinks(doomed1, doomed);
274193
+ this.setEdgeMates(doomed, doomed1);
274194
+ return fPred;
274195
+ }
273824
274196
  /**
273825
274197
  * Create a new sliver face "inside" an existing edge.
273826
274198
  * * This creates two nodes that are each face predecessor and successor to the other.
@@ -273848,14 +274220,14 @@ class HalfEdge {
273848
274220
  newB.copyDataFrom(baseB, true, true, false, false);
273849
274221
  return newA;
273850
274222
  }
273851
- /** Edge property masks. */
274223
+ /** Masks copied when an edge is split. */
273852
274224
  static _edgePropertyMasks = [
273853
- HalfEdgeMask.BOUNDARY_EDGE, HalfEdgeMask.EXTERIOR, HalfEdgeMask.PRIMARY_EDGE, HalfEdgeMask.NULL_FACE,
274225
+ HalfEdgeMask.EXTERIOR, HalfEdgeMask.BOUNDARY_EDGE, HalfEdgeMask.PRIMARY_EDGE, HalfEdgeMask.BRIDGE_EDGE, HalfEdgeMask.REGULARIZED_EDGE, HalfEdgeMask.NULL_FACE
273854
274226
  ];
273855
274227
  /**
273856
274228
  * Copy "edge based" content of `fromNode` to `toNode`:
273857
274229
  * * edgeTag
273858
- * * masks EXTERIOR, BOUNDARY_EDGE, NULL_FACE, PRIMARY_EDGE
274230
+ * * edge masks
273859
274231
  */
273860
274232
  static transferEdgeProperties(fromNode, toNode) {
273861
274233
  toNode.edgeTag = fromNode.edgeTag;
@@ -274028,7 +274400,7 @@ class HalfEdge {
274028
274400
  /**
274029
274401
  * Returns the number of nodes that match (or do not match) the given mask value around this face loop.
274030
274402
  * @param mask the mask to check.
274031
- * @param value true for mask match and false for mask not match.
274403
+ * @param value true for mask match and false for mask not match. Default is `true`.
274032
274404
  */
274033
274405
  countMaskAroundFace(mask, value = true) {
274034
274406
  let count = 0;
@@ -274075,16 +274447,17 @@ class HalfEdge {
274075
274447
  }
274076
274448
  /**
274077
274449
  * Returns the first node that matches (or does not match) the given mask value around this vertex loop, starting
274078
- * with the instance node and proceeding via vertex successors.
274450
+ * with the instance node and proceeding via `vertexSuccessor`.
274079
274451
  * @param mask the mask to check.
274080
- * @param value true for mask match and false for mask not match.
274452
+ * @param value true for mask match and false for mask not match. Default is `true`.
274453
+ * @param reverse if true, search in reverse order via `vertexPredecessor`. Default is `false`.
274081
274454
  */
274082
- findMaskAroundVertex(mask, value = true) {
274455
+ findMaskAroundVertex(mask, value = true, reverse = false) {
274083
274456
  let node = this;
274084
274457
  do {
274085
274458
  if (node.isMaskSet(mask) === value)
274086
274459
  return node;
274087
- node = node.vertexSuccessor;
274460
+ node = reverse ? node.vertexPredecessor : node.vertexSuccessor;
274088
274461
  } while (node !== this);
274089
274462
  return undefined;
274090
274463
  }
@@ -274092,7 +274465,7 @@ class HalfEdge {
274092
274465
  * Returns the first node that matches (or does not match) the given mask value around this face loop, starting
274093
274466
  * with the instance node and proceeding via face successors.
274094
274467
  * @param mask the mask to check.
274095
- * @param value true for mask match and false for mask not match.
274468
+ * @param value true for mask match and false for mask not match. Default is `true`.
274096
274469
  */
274097
274470
  findMaskAroundFace(mask, value = true) {
274098
274471
  let node = this;
@@ -274204,6 +274577,10 @@ class HalfEdge {
274204
274577
  predA._faceSuccessor = nodeB;
274205
274578
  }
274206
274579
  }
274580
+ /** Return whether the edge is dangling at its base. */
274581
+ get isDangling() {
274582
+ return this.edgeMate.faceSuccessor === this;
274583
+ }
274207
274584
  /**
274208
274585
  * Pinch this half edge out of its base vertex loop.
274209
274586
  * @return the surviving HalfEdge in the vertex loop or `undefined` if the instance HalfEdge is already dangling.
@@ -274273,17 +274650,17 @@ class HalfEdge {
274273
274650
  }
274274
274651
  /** Return Vector2d from `this` to face successor (with only xy coordinates). */
274275
274652
  vectorToFaceSuccessorXY(result) {
274276
- return _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_0__.Vector2d.create(this.faceSuccessor.x - this.x, this.faceSuccessor.y - this.y, result);
274653
+ return _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_1__.Vector2d.create(this.faceSuccessor.x - this.x, this.faceSuccessor.y - this.y, result);
274277
274654
  }
274278
274655
  /** Return Vector3d from `this` to face successor. */
274279
274656
  vectorToFaceSuccessor(result) {
274280
274657
  const other = this.faceSuccessor;
274281
- return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(other.x - this.x, other.y - this.y, other.z - this.z, result);
274658
+ return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(other.x - this.x, other.y - this.y, other.z - this.z, result);
274282
274659
  }
274283
274660
  /** Return Vector3d from `this` to face successor. */
274284
274661
  vectorToFacePredecessor(result) {
274285
274662
  const other = this.facePredecessor;
274286
- return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(other.x - this.x, other.y - this.y, other.z - this.z, result);
274663
+ return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(other.x - this.x, other.y - this.y, other.z - this.z, result);
274287
274664
  }
274288
274665
  /**
274289
274666
  * Test if `spaceNode` is in the sector of `sectorNode`.
@@ -274334,15 +274711,15 @@ class HalfEdge {
274334
274711
  }
274335
274712
  /** Returns 2D cross product of vectors from `base` to `targetA` and from `base` to `targetB`. */
274336
274713
  static crossProductXYToTargets(base, targetA, targetB) {
274337
- return _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.crossProductXYXY(targetA.x - base.x, targetA.y - base.y, targetB.x - base.x, targetB.y - base.y);
274714
+ return _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.crossProductXYXY(targetA.x - base.x, targetA.y - base.y, targetB.x - base.x, targetB.y - base.y);
274338
274715
  }
274339
274716
  /** Returns 2D dot product of vectors from `baseA` to `targetA` and from `baseB` to `targetB`. */
274340
274717
  static dotProductNodeToNodeVectorsXY(baseA, targetA, baseB, targetB) {
274341
- return _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.dotProductXYXY(targetA.x - baseA.x, targetA.y - baseA.y, targetB.x - baseB.x, targetB.y - baseB.y);
274718
+ return _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.dotProductXYXY(targetA.x - baseA.x, targetA.y - baseA.y, targetB.x - baseB.x, targetB.y - baseB.y);
274342
274719
  }
274343
274720
  /** Return 2D cross product of vectors from `nodeA` to `nodeB` and from `nodeB` to `nodeC`. */
274344
274721
  static crossProductXYAlongChain(nodeA, nodeB, nodeC) {
274345
- return _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.crossProductXYXY(nodeB.x - nodeA.x, nodeB.y - nodeA.y, nodeC.x - nodeB.x, nodeC.y - nodeB.y);
274722
+ return _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.crossProductXYXY(nodeB.x - nodeA.x, nodeB.y - nodeA.y, nodeC.x - nodeB.x, nodeC.y - nodeB.y);
274346
274723
  }
274347
274724
  /**
274348
274725
  * Compute whether the sector defined by the chain of nodes is convex.
@@ -274379,7 +274756,7 @@ class HalfEdge {
274379
274756
  */
274380
274757
  isSectorConvex(signedAreaTol) {
274381
274758
  if (signedAreaTol === undefined)
274382
- signedAreaTol = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallMetricDistanceSquared * this.signedFaceArea();
274759
+ signedAreaTol = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistanceSquared * this.signedFaceArea();
274383
274760
  return HalfEdge.isSectorConvex(this.facePredecessor, this, this.faceSuccessor, signedAreaTol);
274384
274761
  }
274385
274762
  /**
@@ -274391,7 +274768,7 @@ class HalfEdge {
274391
274768
  * `Geometry.smallMetricDistanceSquared`. Pass 0 to skip toleranced computation.
274392
274769
  * @returns true iff this face is convex.
274393
274770
  */
274394
- isFaceConvex(tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallMetricDistanceSquared) {
274771
+ isFaceConvex(tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistanceSquared) {
274395
274772
  let node = this;
274396
274773
  const signedAreaTol = tolerance > 0.0 ? tolerance * node.signedFaceArea() : 0.0;
274397
274774
  do {
@@ -274407,7 +274784,10 @@ class HalfEdge {
274407
274784
  this.yankFromVertexLoop();
274408
274785
  mate.yankFromVertexLoop();
274409
274786
  }
274410
- /** Specify whether this edge is isolated from the rest of the graph. */
274787
+ /**
274788
+ * Specify whether this edge is isolated from the rest of the graph.
274789
+ * * Both edge mates of an isolated edge return true for [[isDangling]].
274790
+ */
274411
274791
  get isIsolatedEdge() {
274412
274792
  return this === this.vertexSuccessor && this.edgeMate === this.edgeMate.vertexSuccessor;
274413
274793
  }
@@ -274437,7 +274817,7 @@ class HalfEdge {
274437
274817
  static sectorSweepRadiansXYZ(node, normal) {
274438
274818
  const suc = node.faceSuccessor;
274439
274819
  const pred = node.facePredecessor;
274440
- return _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__.Angle.orientedRadiansBetweenVectorsXYZ(suc.x - node.x, suc.y - node.y, suc.z - node.z, pred.x - node.x, pred.y - node.y, pred.z - node.z, normal.x, normal.y, normal.z, true);
274820
+ return _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_4__.Angle.orientedRadiansBetweenVectorsXYZ(suc.x - node.x, suc.y - node.y, suc.z - node.z, pred.x - node.x, pred.y - node.y, pred.z - node.z, normal.x, normal.y, normal.z, true);
274441
274821
  }
274442
274822
  /** Returns true if the face has positive area in xy parts. */
274443
274823
  static testFacePositiveAreaXY(node) {
@@ -274449,11 +274829,76 @@ class HalfEdge {
274449
274829
  }
274450
274830
  /** Return distance between xy coordinates of `this` and `other` node. */
274451
274831
  distanceXY(other) {
274452
- return _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.distanceXYXY(this.x, this.y, other.x, other.y);
274832
+ return _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.distanceXYXY(this.x, this.y, other.x, other.y);
274453
274833
  }
274454
274834
  /** Return distance between xyz coordinates of `this` and `other` node. */
274455
274835
  distanceXYZ(other) {
274456
- return _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.distanceXYZXYZ(this.x, this.y, this.z, other.x, other.y, other.z);
274836
+ return _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.distanceXYZXYZ(this.x, this.y, this.z, other.x, other.y, other.z);
274837
+ }
274838
+ /**
274839
+ * Search around the instance's face loop for nodes with the specified mask value.
274840
+ * * Returned nodes satisfy `node.isMaskSet(mask) === value`.
274841
+ * @param mask target mask.
274842
+ * @param value target boolean value for mask on half edges (default `true`).
274843
+ * @param result optional array to be cleared, populated with masked nodes, and returned.
274844
+ * @return array of masked half edges
274845
+ */
274846
+ collectMaskedEdgesAroundFace(mask, value = true, result) {
274847
+ if (result === undefined)
274848
+ result = [];
274849
+ else
274850
+ result.length = 0;
274851
+ let node = this;
274852
+ do {
274853
+ if (node.isMaskSet(mask) === value)
274854
+ result.push(node);
274855
+ node = node.faceSuccessor;
274856
+ } while (node !== this);
274857
+ return result;
274858
+ }
274859
+ /**
274860
+ * Announce edges in the face loop, starting with the instance and proceeding in a `faceSuccessor` traversal.
274861
+ * @param announceEdge function to call at each edge
274862
+ */
274863
+ announceEdgesInFace(announceEdge) {
274864
+ let node = this;
274865
+ do {
274866
+ announceEdge(node);
274867
+ node = node.faceSuccessor;
274868
+ } while (node !== this);
274869
+ }
274870
+ /**
274871
+ * Announce edges in the super face loop, starting with the instance.
274872
+ * * A super face admits a `faceSuccessor` traversal, where the next edge at the far vertex is the first one lacking `skipMask` in a `vertexPredecessor` traversal.
274873
+ * @param skipMask mask on edges to skip.
274874
+ * @param announceEdge function to call at each edge that is not skipped.
274875
+ * @param announceSkipped optional function to call at each edge that is skipped.
274876
+ * @return whether a super face was found. Specifically, if a vertex loop has all edges with `skipMask` set, the return value is `false`.
274877
+ */
274878
+ announceEdgesInSuperFace(skipMask, announceEdge, announceSkipped) {
274879
+ const maxIter = 1000; // safeguard against infinite loops
274880
+ let iter = 0;
274881
+ const findNextNodeAroundVertex = (he) => {
274882
+ let vNode = he;
274883
+ do {
274884
+ if (!vNode.isMaskSet(skipMask))
274885
+ return vNode;
274886
+ announceSkipped?.(vNode);
274887
+ vNode = vNode.vertexPredecessor;
274888
+ } while (vNode !== he);
274889
+ return undefined;
274890
+ };
274891
+ const firstNode = findNextNodeAroundVertex(this);
274892
+ if (!firstNode)
274893
+ return false;
274894
+ let node = firstNode;
274895
+ do {
274896
+ announceEdge(node);
274897
+ node = findNextNodeAroundVertex(node.faceSuccessor);
274898
+ if (!node)
274899
+ return false;
274900
+ } while (node !== firstNode && iter++ < maxIter);
274901
+ return iter < maxIter;
274457
274902
  }
274458
274903
  /**
274459
274904
  * Evaluate `f(node)` at each node around `this` node's face loop. Collect the function values.
@@ -274594,7 +275039,7 @@ class HalfEdge {
274594
275039
  */
274595
275040
  fractionToPoint2d(fraction, result) {
274596
275041
  const suc = this.faceSuccessor;
274597
- return _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_0__.Point2d.create(this.x + (suc.x - this.x) * fraction, this.y + (suc.y - this.y) * fraction, result);
275042
+ return _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_1__.Point2d.create(this.x + (suc.x - this.x) * fraction, this.y + (suc.y - this.y) * fraction, result);
274598
275043
  }
274599
275044
  /**
274600
275045
  * Interpolate xyz coordinates between `this` node and its face successor.
@@ -274603,7 +275048,7 @@ class HalfEdge {
274603
275048
  */
274604
275049
  fractionToPoint3d(fraction, result) {
274605
275050
  const suc = this.faceSuccessor;
274606
- return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(this.x + (suc.x - this.x) * fraction, this.y + (suc.y - this.y) * fraction, this.z + (suc.z - this.z) * fraction, result);
275051
+ return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(this.x + (suc.x - this.x) * fraction, this.y + (suc.y - this.y) * fraction, this.z + (suc.z - this.z) * fraction, result);
274607
275052
  }
274608
275053
  /**
274609
275054
  * Interpolate xy coordinates at `fractionAlong` between this node and its face successor. Then shift perpendicular
@@ -274616,25 +275061,25 @@ class HalfEdge {
274616
275061
  const suc = this.faceSuccessor;
274617
275062
  const dx = suc.x - this.x;
274618
275063
  const dy = suc.y - this.y;
274619
- return _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_0__.Point2d.create(this.x + dx * fractionAlong - dy * fractionPerpendicular, this.y + dy * fractionAlong + dx * fractionPerpendicular, result);
275064
+ return _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_1__.Point2d.create(this.x + dx * fractionAlong - dy * fractionPerpendicular, this.y + dy * fractionAlong + dx * fractionPerpendicular, result);
274620
275065
  }
274621
275066
  /** Return the 3d coordinates at this half edge. */
274622
275067
  getPoint3d(result) {
274623
- return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(this.x, this.y, this.z, result);
275068
+ return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(this.x, this.y, this.z, result);
274624
275069
  }
274625
275070
  /** Return the 2d coordinates at this half edge. */
274626
275071
  getPoint2d(result) {
274627
- return _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_0__.Point2d.create(this.x, this.y, result);
275072
+ return _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_1__.Point2d.create(this.x, this.y, result);
274628
275073
  }
274629
275074
  /** Return a 3d vector from start to end of this half edge. */
274630
275075
  getVector3dAlongEdge(result) {
274631
275076
  const suc = this.faceSuccessor;
274632
- return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(suc.x - this.x, suc.y - this.y, suc.z - this.z, result);
275077
+ return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(suc.x - this.x, suc.y - this.y, suc.z - this.z, result);
274633
275078
  }
274634
275079
  /** Return a 2d vector from start to end of this half edge. */
274635
275080
  getVector2dAlongEdge(result) {
274636
275081
  const suc = this.faceSuccessor;
274637
- return _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_0__.Vector2d.create(suc.x - this.x, suc.y - this.y, result);
275082
+ return _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_1__.Vector2d.create(suc.x - this.x, suc.y - this.y, result);
274638
275083
  }
274639
275084
  /**
274640
275085
  * Return the interpolated x coordinate between `this` node and its face successor.
@@ -274672,12 +275117,12 @@ class HalfEdge {
274672
275117
  const nodeA1 = nodeA0.faceSuccessor;
274673
275118
  const nodeB1 = nodeB0.faceSuccessor;
274674
275119
  if (!result)
274675
- result = _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_0__.Vector2d.create();
275120
+ result = _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_1__.Vector2d.create();
274676
275121
  // To find the fraction of intersection (ta,tb), you need to solve these 2 equations:
274677
275122
  // (nodeA1.x - nodeA0.x)ta + (nodeB0.x - nodeB1.x)tb = nodeB0.x - nodeA0.x
274678
275123
  // (nodeA1.y - nodeA0.y)ta + (nodeB0.y - nodeB1.y)tb = nodeB0.y - nodeA0.y
274679
275124
  // Proof can be found at geometry/internaldocs/Graph.md
274680
- if (_numerics_SmallSystem__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))
275125
+ if (_numerics_SmallSystem__WEBPACK_IMPORTED_MODULE_5__.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))
274681
275126
  return result;
274682
275127
  return undefined;
274683
275128
  }
@@ -274691,13 +275136,13 @@ class HalfEdge {
274691
275136
  static horizontalScanFraction(node0, y) {
274692
275137
  const node1 = node0.faceSuccessor;
274693
275138
  const dy = node1.y - node0.y;
274694
- if (_Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.isSameCoordinate(y, node0.y) && _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.isSameCoordinate(y, node1.y))
275139
+ if (_Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.isSameCoordinate(y, node0.y) && _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.isSameCoordinate(y, node1.y))
274695
275140
  return node0;
274696
- if (_Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.isSameCoordinate(dy, 0.0))
275141
+ if (_Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.isSameCoordinate(dy, 0.0))
274697
275142
  return undefined;
274698
275143
  // parametric equation of line is (1-t)y0 + ty1 which is equal to y at the intersection so
274699
275144
  // (1-t)y0 + ty1 = y or t = (y-y0)/(y1-y0)
274700
- return _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.conditionalDivideFraction(y - node0.y, dy);
275145
+ return _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.conditionalDivideFraction(y - node0.y, dy);
274701
275146
  }
274702
275147
  /**
274703
275148
  * Compute fractional position (inside 0..1) of the intersection of a horizontal line with an edge.
@@ -274709,11 +275154,11 @@ class HalfEdge {
274709
275154
  static horizontalScanFraction01(node0, y) {
274710
275155
  const node1 = node0.faceSuccessor;
274711
275156
  const dy = node1.y - node0.y;
274712
- if (_Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.isSameCoordinate(y, node0.y) && _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.isSameCoordinate(y, node1.y))
275157
+ if (_Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.isSameCoordinate(y, node0.y) && _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.isSameCoordinate(y, node1.y))
274713
275158
  return undefined;
274714
- if (_Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.isSameCoordinate(dy, 0.0))
275159
+ if (_Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.isSameCoordinate(dy, 0.0))
274715
275160
  return undefined;
274716
- const fraction = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.conditionalDivideFraction(y - node0.y, dy);
275161
+ const fraction = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.conditionalDivideFraction(y - node0.y, dy);
274717
275162
  if (fraction !== undefined && fraction >= 0.0 && fraction <= 1.0)
274718
275163
  return fraction;
274719
275164
  return undefined;
@@ -274732,16 +275177,37 @@ class HalfEdge {
274732
275177
  this.y = source.y;
274733
275178
  this.z = source.z;
274734
275179
  }
274735
- if (copyVertexData) {
275180
+ if (copyVertexData)
274736
275181
  this.i = source.i;
274737
- }
274738
- if (copyEdgeData) {
275182
+ if (copyEdgeData)
274739
275183
  HalfEdge.transferEdgeProperties(source, this);
274740
- this.edgeTag = source.edgeTag;
274741
- }
274742
- if (copyFaceData) {
275184
+ if (copyFaceData)
274743
275185
  this.faceTag = source.faceTag;
275186
+ }
275187
+ /**
275188
+ * Is the instance's face loop a split-washer type face?
275189
+ * * A split-washer face contains at least one bridge edge.
275190
+ * * A bridge edge and its edge mate have the same `bridgeMask` and live in the same face loop.
275191
+ * * By connecting hole/outer loops with bridge edges, a split-washer face can represent a parity region.
275192
+ * @param bridgeMask mask preset on bridge edges (default is [[HalfEdgeMask.BRIDGE_EDGE]]).
275193
+ */
275194
+ isSplitWasherFace(bridgeMask = HalfEdgeMask.BRIDGE_EDGE) {
275195
+ if (!this.countMaskAroundFace(HalfEdgeMask.BRIDGE_EDGE))
275196
+ return false;
275197
+ const bridges = new _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.OrderedSet((a, b) => a.id - b.id);
275198
+ let node = this;
275199
+ do {
275200
+ if (node.isMaskSet(bridgeMask))
275201
+ bridges.add(node);
275202
+ node = node.faceSuccessor;
275203
+ } while (node !== this);
275204
+ if (bridges.size === 0)
275205
+ return false;
275206
+ for (const bridge of bridges) {
275207
+ if (!bridges.has(bridge.edgeMate) || !bridge.edgeMate.isMaskSet(bridgeMask))
275208
+ return false;
274744
275209
  }
275210
+ return true;
274745
275211
  }
274746
275212
  }
274747
275213
  /**
@@ -274757,11 +275223,11 @@ class HalfEdgeGraph {
274757
275223
  _numNodesCreated = 0;
274758
275224
  constructor() {
274759
275225
  this.allHalfEdges = [];
274760
- this._maskManager = _MaskManager__WEBPACK_IMPORTED_MODULE_5__.MaskManager.create(HalfEdgeMask.ALL_GRAB_DROP_MASKS);
275226
+ this._maskManager = _MaskManager__WEBPACK_IMPORTED_MODULE_6__.MaskManager.create(HalfEdgeMask.ALL_GRAB_DROP_MASKS);
274761
275227
  }
274762
275228
  /**
274763
275229
  * Ask for a mask (from the graph's free pool) for caller's use.
274764
- * * Optionally clear the mask throughout the graph.
275230
+ * @param clearInAllHalfEdges optionally clear the mask throughout the graph (default `true`).
274765
275231
  */
274766
275232
  grabMask(clearInAllHalfEdges = true) {
274767
275233
  const mask = this._maskManager.grabMask();
@@ -274927,7 +275393,7 @@ class HalfEdgeGraph {
274927
275393
  const segments = [];
274928
275394
  for (const node of this.allHalfEdges) {
274929
275395
  if (node.id < node.edgeMate.id)
274930
- 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)));
275396
+ segments.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_7__.LineSegment3d.create(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(node.x, node.y), _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(node.faceSuccessor.x, node.faceSuccessor.y)));
274931
275397
  }
274932
275398
  return segments;
274933
275399
  }
@@ -275415,8 +275881,8 @@ class HalfEdgeGraphSearch {
275415
275881
  * pattern starting at the seed face, with each successive concentric ring of faces at constant topological
275416
275882
  * distance from the seed face receiving the opposite parity state of the previous ring.
275417
275883
  * @param parityMask (optional) mask to apply to the first face and faces that share the same parity as the
275418
- * first face, as determined by the parity rule. If this is `NULL_MASK`, there is no record of parity. If
275419
- * (non-null) parity mask is given, on return it is entirely set or entirely clear around each face.
275884
+ * first face, as determined by the parity rule. If this is `NULL_MASK` (default), there is no record of parity.
275885
+ * If (non-null) parity mask is given, on return it is entirely set or entirely clear around each face.
275420
275886
  * @returns the components of the graph, each component represented by an array of nodes, one node per face
275421
275887
  * of the component. In other words, entry [i][j] is a HalfEdge in the j_th face loop of the i_th component.
275422
275888
  */
@@ -278174,8 +278640,9 @@ class RegularizationContext {
278174
278640
  if (nodeA1 !== undefined && nodeB1 !== undefined) {
278175
278641
  _Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.pinch(nodeA1, nodeC);
278176
278642
  _Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.pinch(nodeB1, nodeC.edgeMate);
278643
+ nodeC.setMaskAroundEdge(_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdgeMask.REGULARIZED_EDGE);
278177
278644
  if (RegularizationContext.announceEdge)
278178
- RegularizationContext.announceEdge(this.graph, nodeA, nodeB, direction);
278645
+ RegularizationContext.announceEdge(this.graph, nodeC, nodeC.edgeMate, direction);
278179
278646
  return nodeC;
278180
278647
  }
278181
278648
  return undefined;
@@ -301358,10 +301825,10 @@ class Settings {
301358
301825
  });
301359
301826
  }
301360
301827
  toString() {
301361
- return `Configurations:
301362
- oidc client id: ${this.oidcClientId},
301363
- oidc scopes: ${this.oidcScopes},
301364
- applicationId: ${this.gprid},
301828
+ return `Configurations:
301829
+ oidc client id: ${this.oidcClientId},
301830
+ oidc scopes: ${this.oidcScopes},
301831
+ applicationId: ${this.gprid},
301365
301832
  log level: ${this.logLevel}`;
301366
301833
  }
301367
301834
  }
@@ -314171,7 +314638,7 @@ var loadLanguages = instance.loadLanguages;
314171
314638
  /***/ ((module) => {
314172
314639
 
314173
314640
  "use strict";
314174
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.1.0-dev.52","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs && npm run -s build:esm && npm run -s webpackWorkers && npm run -s copy:workers","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module 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","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","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-inline-config -c extraction.eslint.config.js \\"./src/**/*.ts\\" 1>&2","lint":"eslint \\"./src/**/*.ts\\" 1>&2","lint-fix":"eslint --fix -f visualstudio \\"./src/**/*.ts\\" 1>&2","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run webpackTestWorker && vitest --run","cover":"npm run webpackTestWorker && vitest --run","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":{"@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/eslint-plugin":"5.0.0-dev.1","@types/chai-as-promised":"^7","@types/sinon":"^17.0.2","@vitest/browser":"^3.0.6","@vitest/coverage-v8":"^3.0.6","cpx2":"^8.0.0","eslint":"^9.13.0","glob":"^10.3.12","playwright":"~1.47.1","rimraf":"^6.0.1","sinon":"^17.0.2","source-map-loader":"^5.0.0","typescript":"~5.6.2","typemoq":"^2.1.0","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/cloud-agnostic-core":"^2.2.4","@itwin/object-storage-core":"^2.3.0","@itwin/core-i18n":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^3.1.6","@loaders.gl/draco":"^3.1.6","fuse.js":"^3.3.0","wms-capabilities":"0.4.0"}}');
314641
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.1.0-dev.54","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs && npm run -s build:esm && npm run -s webpackWorkers && npm run -s copy:workers","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module 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","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","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-inline-config -c extraction.eslint.config.js \\"./src/**/*.ts\\" 1>&2","lint":"eslint \\"./src/**/*.ts\\" 1>&2","lint-fix":"eslint --fix -f visualstudio \\"./src/**/*.ts\\" 1>&2","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run webpackTestWorker && vitest --run","cover":"npm run webpackTestWorker && vitest --run","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":{"@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/eslint-plugin":"5.0.0-dev.1","@types/chai-as-promised":"^7","@types/sinon":"^17.0.2","@vitest/browser":"^3.0.6","@vitest/coverage-v8":"^3.0.6","cpx2":"^8.0.0","eslint":"^9.13.0","glob":"^10.3.12","playwright":"~1.47.1","rimraf":"^6.0.1","sinon":"^17.0.2","source-map-loader":"^5.0.0","typescript":"~5.6.2","typemoq":"^2.1.0","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/cloud-agnostic-core":"^2.2.4","@itwin/object-storage-core":"^2.3.0","@itwin/core-i18n":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^3.1.6","@loaders.gl/draco":"^3.1.6","fuse.js":"^3.3.0","wms-capabilities":"0.4.0"}}');
314175
314642
 
314176
314643
  /***/ })
314177
314644