@itwin/ecschema-rpcinterface-tests 5.0.0-dev.113 → 5.0.0-dev.114

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.
@@ -174902,25 +174902,48 @@ class InteractiveTool extends Tool {
174902
174902
  return foundProperty;
174903
174903
  throw new Error(`property not found: ${propertyName}`);
174904
174904
  }
174905
- /** Override to return the property that is disabled/enabled if the supplied property is a lock property.
174905
+ /** Override to return the property that is locked by the supplied property if it is a lock property.
174906
+ * Used to enable/disable the returned property according to the current lock state.
174907
+ * @note Only applicable when [[getToolSettingLockProperty]] is not being used automatically enable the lock on a change of value.
174906
174908
  * @see [[changeToolSettingPropertyValue]]
174907
174909
  * @public
174908
174910
  */
174909
174911
  getToolSettingPropertyLocked(_property) {
174910
174912
  return undefined;
174911
174913
  }
174914
+ /** Override to return the lock property associated with the supplied non-lock property.
174915
+ * Used to enable the lock property after the value of the supplied property is changed.
174916
+ * @see [[changeToolSettingPropertyValue]]
174917
+ * @beta
174918
+ */
174919
+ getToolSettingLockProperty(_property) {
174920
+ return undefined;
174921
+ }
174912
174922
  /** Helper method for responding to a tool setting property value change by updating saved settings.
174913
174923
  * @see [[applyToolSettingPropertyChange]]
174914
174924
  * @see [[getToolSettingPropertyLocked]] to return the corresponding locked property, if any.
174925
+ * @see [[getToolSettingLockProperty]] to return the corresponding property's lock property, if any.
174915
174926
  * @public
174916
174927
  */
174917
174928
  changeToolSettingPropertyValue(syncItem) {
174918
174929
  const property = this.getToolSettingPropertyByName(syncItem.propertyName);
174919
174930
  if (!this.saveToolSettingPropertyValue(property, syncItem.value))
174920
174931
  return false;
174921
- const lockedProperty = this.getToolSettingPropertyLocked(property);
174922
- if (undefined !== lockedProperty)
174923
- this.syncToolSettingPropertyValue(lockedProperty, !property.value);
174932
+ // Either enable lock when corresponding property value changes, or enable/disable property according to value of lock...
174933
+ const lockProperty = this.getToolSettingLockProperty(property);
174934
+ if (undefined !== lockProperty) {
174935
+ if (!lockProperty.value) {
174936
+ this.saveToolSettingPropertyValue(lockProperty, { value: true });
174937
+ this.syncToolSettingPropertyValue(lockProperty);
174938
+ }
174939
+ }
174940
+ else {
174941
+ const propertyToLock = this.getToolSettingPropertyLocked(property);
174942
+ if (undefined !== propertyToLock) {
174943
+ if (undefined === this.getToolSettingLockProperty(propertyToLock))
174944
+ this.syncToolSettingPropertyValue(propertyToLock, !property.value);
174945
+ }
174946
+ }
174924
174947
  return true;
174925
174948
  }
174926
174949
  /** Helper method to establish initial values for tool setting properties from saved settings.
@@ -180994,7 +181017,7 @@ class SetupCameraTool extends _PrimitiveTool__WEBPACK_IMPORTED_MODULE_17__.Primi
180994
181017
  _cameraHeightProperty;
180995
181018
  get cameraHeightProperty() {
180996
181019
  if (!this._cameraHeightProperty)
180997
- this._cameraHeightProperty = new _itwin_appui_abstract__WEBPACK_IMPORTED_MODULE_3__.DialogProperty(new _properties_LengthDescription__WEBPACK_IMPORTED_MODULE_8__.LengthDescription("cameraHeight", ViewTool.translate("SetupCamera.Labels.CameraHeight")), 0.0, undefined, !this.useCameraHeight);
181020
+ this._cameraHeightProperty = new _itwin_appui_abstract__WEBPACK_IMPORTED_MODULE_3__.DialogProperty(new _properties_LengthDescription__WEBPACK_IMPORTED_MODULE_8__.LengthDescription("cameraHeight", ViewTool.translate("SetupCamera.Labels.CameraHeight")), 0.0);
180998
181021
  return this._cameraHeightProperty;
180999
181022
  }
181000
181023
  get cameraHeight() { return this.cameraHeightProperty.value; }
@@ -181010,62 +181033,23 @@ class SetupCameraTool extends _PrimitiveTool__WEBPACK_IMPORTED_MODULE_17__.Primi
181010
181033
  _targetHeightProperty;
181011
181034
  get targetHeightProperty() {
181012
181035
  if (!this._targetHeightProperty)
181013
- this._targetHeightProperty = new _itwin_appui_abstract__WEBPACK_IMPORTED_MODULE_3__.DialogProperty(new _properties_LengthDescription__WEBPACK_IMPORTED_MODULE_8__.LengthDescription("targetHeight", ViewTool.translate("SetupCamera.Labels.TargetHeight")), 0.0, undefined, !this.useTargetHeight);
181036
+ this._targetHeightProperty = new _itwin_appui_abstract__WEBPACK_IMPORTED_MODULE_3__.DialogProperty(new _properties_LengthDescription__WEBPACK_IMPORTED_MODULE_8__.LengthDescription("targetHeight", ViewTool.translate("SetupCamera.Labels.TargetHeight")), 0.0);
181014
181037
  return this._targetHeightProperty;
181015
181038
  }
181016
181039
  get targetHeight() { return this.targetHeightProperty.value; }
181017
181040
  set targetHeight(value) { this.targetHeightProperty.value = value; }
181018
- syncCameraHeightState() {
181019
- const specs = _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.quantityFormatter.getSpecsByName(this.cameraHeightProperty.description.kindOfQuantityName ?? "AecUnits.LENGTH");
181020
- this.cameraHeightProperty.displayValue = specs ? specs.formatterSpec.applyFormatting(this.cameraHeight) : this.cameraHeight.toFixed(2);
181021
- this.cameraHeightProperty.isDisabled = !this.useCameraHeight;
181022
- this.syncToolSettingsProperties([this.cameraHeightProperty.syncItem]);
181023
- }
181024
- syncTargetHeightState() {
181025
- const specs = _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.quantityFormatter.getSpecsByName(this.targetHeightProperty.description.kindOfQuantityName ?? "AecUnits.LENGTH");
181026
- this.targetHeightProperty.displayValue = specs ? specs.formatterSpec.applyFormatting(this.targetHeight) : this.targetHeight.toFixed(2);
181027
- this.targetHeightProperty.isDisabled = !this.useTargetHeight;
181028
- this.syncToolSettingsProperties([this.targetHeightProperty.syncItem]);
181041
+ getToolSettingLockProperty(property) {
181042
+ if (property === this.cameraHeightProperty)
181043
+ return this.useCameraHeightProperty;
181044
+ else if (property === this.targetHeightProperty)
181045
+ return this.useTargetHeightProperty;
181046
+ return undefined;
181029
181047
  }
181030
181048
  async applyToolSettingPropertyChange(updatedValue) {
181031
- if (updatedValue.propertyName === this.useCameraHeightProperty.name) {
181032
- this.useCameraHeight = updatedValue.value.value;
181033
- _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.toolAdmin.toolSettingsState.saveToolSettingProperty(this.toolId, this.useCameraHeightProperty.item);
181034
- this.syncCameraHeightState();
181035
- }
181036
- else if (updatedValue.propertyName === this.useTargetHeightProperty.name) {
181037
- this.useTargetHeight = updatedValue.value.value;
181038
- _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.toolAdmin.toolSettingsState.saveToolSettingProperty(this.toolId, this.useTargetHeightProperty.item);
181039
- this.syncTargetHeightState();
181040
- }
181041
- else if (updatedValue.propertyName === this.cameraHeightProperty.name) {
181042
- this.cameraHeight = updatedValue.value.value;
181043
- _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.toolAdmin.toolSettingsState.saveToolSettingProperty(this.toolId, this.cameraHeightProperty.item);
181044
- }
181045
- else if (updatedValue.propertyName === this.targetHeightProperty.name) {
181046
- this.targetHeight = updatedValue.value.value;
181047
- _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.toolAdmin.toolSettingsState.saveToolSettingProperty(this.toolId, this.targetHeightProperty.item);
181048
- }
181049
- return true;
181049
+ return this.changeToolSettingPropertyValue(updatedValue);
181050
181050
  }
181051
181051
  supplyToolSettingsProperties() {
181052
- // load latest values from session
181053
- _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.toolAdmin.toolSettingsState.getInitialToolSettingValues(this.toolId, [
181054
- this.useCameraHeightProperty.name, this.useTargetHeightProperty.name, this.cameraHeightProperty.name, this.targetHeightProperty.name,
181055
- ])
181056
- ?.forEach((value) => {
181057
- if (value.propertyName === this.useCameraHeightProperty.name)
181058
- this.useCameraHeightProperty.dialogItemValue = value.value;
181059
- else if (value.propertyName === this.cameraHeightProperty.name)
181060
- this.cameraHeightProperty.dialogItemValue = value.value;
181061
- else if (value.propertyName === this.useTargetHeightProperty.name)
181062
- this.useTargetHeightProperty.dialogItemValue = value.value;
181063
- else if (value.propertyName === this.targetHeightProperty.name)
181064
- this.targetHeightProperty.dialogItemValue = value.value;
181065
- });
181066
- // ensure controls are enabled/disabled base on current lock property state
181067
- this.targetHeightProperty.isDisabled = !this.useTargetHeight;
181068
- this.cameraHeightProperty.isDisabled = !this.useCameraHeight;
181052
+ this.initializeToolSettingPropertyValues([this.useCameraHeightProperty, this.useTargetHeightProperty, this.cameraHeightProperty, this.targetHeightProperty]);
181069
181053
  const cameraHeightLock = this.useCameraHeightProperty.toDialogItem({ rowPriority: 1, columnIndex: 0 });
181070
181054
  const targetHeightLock = this.useTargetHeightProperty.toDialogItem({ rowPriority: 2, columnIndex: 0 });
181071
181055
  const toolSettings = new Array();
@@ -189656,11 +189640,11 @@ class ClipPlane extends _geometry3d_Plane3d__WEBPACK_IMPORTED_MODULE_0__.Plane3d
189656
189640
  get inwardNormalRef() {
189657
189641
  return this._inwardNormal;
189658
189642
  }
189659
- /** Return the "interior" property bit */
189643
+ /** Return the "interior" property flag. Interpretation of this flag is algorithm-specific. */
189660
189644
  get interior() {
189661
189645
  return this._interior;
189662
189646
  }
189663
- /** Return the "invisible" property bit. */
189647
+ /** Return the "invisible" property flag. Interpretation of this flag is algorithm-specific. */
189664
189648
  get invisible() {
189665
189649
  return this._invisible;
189666
189650
  }
@@ -189879,7 +189863,7 @@ class ClipPlane extends _geometry3d_Plane3d__WEBPACK_IMPORTED_MODULE_0__.Plane3d
189879
189863
  this._distanceFromOrigin = this._inwardNormal.dotProduct(plane.getOriginRef());
189880
189864
  return true;
189881
189865
  }
189882
- /** Set the invisible flag. Interpretation of this is up to the use code algorithms. */
189866
+ /** Set the invisible flag. Interpretation of this flag is algorithm-specific. */
189883
189867
  setInvisible(invisible) {
189884
189868
  this._invisible = invisible;
189885
189869
  }
@@ -190023,8 +190007,12 @@ class ClipPlane extends _geometry3d_Plane3d__WEBPACK_IMPORTED_MODULE_0__.Plane3d
190023
190007
  }
190024
190008
  /** Project a point in space to the plane. */
190025
190009
  projectPointToPlane(spacePoint, result) {
190026
- const d = -this.altitude(spacePoint);
190027
- return spacePoint.plusXYZ(d * this._inwardNormal.x, d * this._inwardNormal.y, d * this._inwardNormal.z, result);
190010
+ return this.projectXYZToPlane(spacePoint.x, spacePoint.y, spacePoint.z, result);
190011
+ }
190012
+ /** Return the projection of (x,y,z) onto the plane. */
190013
+ projectXYZToPlane(x, y, z, result) {
190014
+ const scale = -this.altitudeXYZ(x, y, z);
190015
+ return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(x + scale * this._inwardNormal.x, y + scale * this._inwardNormal.y, z + scale * this._inwardNormal.z, result);
190028
190016
  }
190029
190017
  }
190030
190018
 
@@ -192323,8 +192311,8 @@ __webpack_require__.r(__webpack_exports__);
192323
192311
  /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
192324
192312
  /* harmony import */ var _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../geometry3d/PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
192325
192313
  /* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
192326
- /* harmony import */ var _polyface_Polyface__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../polyface/Polyface */ "../../core/geometry/lib/esm/polyface/Polyface.js");
192327
- /* harmony import */ var _polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../polyface/PolyfaceQuery */ "../../core/geometry/lib/esm/polyface/PolyfaceQuery.js");
192314
+ /* harmony import */ var _polyface_Polyface__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../polyface/Polyface */ "../../core/geometry/lib/esm/polyface/Polyface.js");
192315
+ /* harmony import */ var _polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../polyface/PolyfaceQuery */ "../../core/geometry/lib/esm/polyface/PolyfaceQuery.js");
192328
192316
  /* harmony import */ var _ClipPlane__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ClipPlane */ "../../core/geometry/lib/esm/clipping/ClipPlane.js");
192329
192317
  /* harmony import */ var _ClipUtils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ClipUtils */ "../../core/geometry/lib/esm/clipping/ClipUtils.js");
192330
192318
  /*---------------------------------------------------------------------------------------------
@@ -193064,29 +193052,18 @@ class ConvexClipPlaneSet {
193064
193052
  static createConvexPolyface(convexMesh, result) {
193065
193053
  result = this.createEmpty(result);
193066
193054
  let vol = 0;
193067
- let myMesh;
193068
- let myVisitor;
193069
- if (convexMesh instanceof _polyface_Polyface__WEBPACK_IMPORTED_MODULE_10__.Polyface) {
193070
- myMesh = convexMesh;
193071
- myVisitor = convexMesh.createVisitor(0);
193072
- }
193073
- else {
193074
- myMesh = convexMesh.clientPolyface();
193075
- myVisitor = convexMesh;
193076
- }
193077
- if (myMesh && myVisitor) {
193078
- if (_polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_11__.PolyfaceQuery.isPolyfaceClosedByEdgePairing(myMesh))
193079
- vol = _polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_11__.PolyfaceQuery.sumTetrahedralVolumes(myVisitor);
193080
- const scale = vol > 0.0 ? -1.0 : 1.0; // point clipper normals inward if mesh normals point outward
193081
- const normal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create();
193082
- const plane = _geometry3d_Plane3dByOriginAndUnitNormal__WEBPACK_IMPORTED_MODULE_1__.Plane3dByOriginAndUnitNormal.createXYPlane();
193083
- myVisitor.reset();
193084
- while (myVisitor.moveToNextFacet()) {
193085
- if (undefined !== _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_7__.PolygonOps.areaNormalGo(myVisitor.point, normal)) {
193086
- normal.scaleInPlace(scale);
193087
- if (undefined !== _geometry3d_Plane3dByOriginAndUnitNormal__WEBPACK_IMPORTED_MODULE_1__.Plane3dByOriginAndUnitNormal.create(myVisitor.point.front(), normal, plane))
193088
- result.addPlaneToConvexSet(plane);
193089
- }
193055
+ if (_polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_10__.PolyfaceQuery.isPolyfaceClosedByEdgePairing(convexMesh))
193056
+ vol = _polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_10__.PolyfaceQuery.sumTetrahedralVolumes(convexMesh);
193057
+ const scale = vol > 0.0 ? -1.0 : 1.0; // point clipper normals inward if mesh normals point outward
193058
+ const normal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create();
193059
+ const plane = _geometry3d_Plane3dByOriginAndUnitNormal__WEBPACK_IMPORTED_MODULE_1__.Plane3dByOriginAndUnitNormal.createXYPlane();
193060
+ const visitor = convexMesh instanceof _polyface_Polyface__WEBPACK_IMPORTED_MODULE_11__.Polyface ? convexMesh.createVisitor(0) : convexMesh;
193061
+ visitor.setNumWrap(0);
193062
+ for (visitor.reset(); visitor.moveToNextFacet();) {
193063
+ if (undefined !== _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_7__.PolygonOps.areaNormalGo(visitor.point, normal)) {
193064
+ normal.scaleInPlace(scale);
193065
+ if (undefined !== _geometry3d_Plane3dByOriginAndUnitNormal__WEBPACK_IMPORTED_MODULE_1__.Plane3dByOriginAndUnitNormal.create(visitor.point.front(), normal, plane))
193066
+ result.addPlaneToConvexSet(plane);
193090
193067
  }
193091
193068
  }
193092
193069
  return { clipper: result, volume: vol };
@@ -193681,7 +193658,7 @@ __webpack_require__.r(__webpack_exports__);
193681
193658
  /* harmony export */ BSplineWrapMode: () => (/* reexport safe */ _bspline_KnotVector__WEBPACK_IMPORTED_MODULE_108__.BSplineWrapMode),
193682
193659
  /* harmony export */ BagOfCurves: () => (/* reexport safe */ _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_64__.BagOfCurves),
193683
193660
  /* harmony export */ BarycentricTriangle: () => (/* reexport safe */ _geometry3d_BarycentricTriangle__WEBPACK_IMPORTED_MODULE_3__.BarycentricTriangle),
193684
- /* harmony export */ BentleyGeometryFlatBuffer: () => (/* reexport safe */ _serialization_BentleyGeometryFlatBuffer__WEBPACK_IMPORTED_MODULE_131__.BentleyGeometryFlatBuffer),
193661
+ /* harmony export */ BentleyGeometryFlatBuffer: () => (/* reexport safe */ _serialization_BentleyGeometryFlatBuffer__WEBPACK_IMPORTED_MODULE_132__.BentleyGeometryFlatBuffer),
193685
193662
  /* harmony export */ Bezier1dNd: () => (/* reexport safe */ _bspline_Bezier1dNd__WEBPACK_IMPORTED_MODULE_98__.Bezier1dNd),
193686
193663
  /* harmony export */ BezierCoffs: () => (/* reexport safe */ _numerics_BezierPolynomials__WEBPACK_IMPORTED_MODULE_51__.BezierCoffs),
193687
193664
  /* harmony export */ BezierCurve3d: () => (/* reexport safe */ _bspline_BezierCurve3d__WEBPACK_IMPORTED_MODULE_100__.BezierCurve3d),
@@ -193701,7 +193678,7 @@ __webpack_require__.r(__webpack_exports__);
193701
193678
  /* harmony export */ ClipStepAction: () => (/* reexport safe */ _clipping_ClipUtils__WEBPACK_IMPORTED_MODULE_44__.ClipStepAction),
193702
193679
  /* harmony export */ ClipUtilities: () => (/* reexport safe */ _clipping_ClipUtils__WEBPACK_IMPORTED_MODULE_44__.ClipUtilities),
193703
193680
  /* harmony export */ ClipVector: () => (/* reexport safe */ _clipping_ClipVector__WEBPACK_IMPORTED_MODULE_43__.ClipVector),
193704
- /* harmony export */ ClippedPolyfaceBuilders: () => (/* reexport safe */ _polyface_PolyfaceClip__WEBPACK_IMPORTED_MODULE_121__.ClippedPolyfaceBuilders),
193681
+ /* harmony export */ ClippedPolyfaceBuilders: () => (/* reexport safe */ _polyface_PolyfaceClip__WEBPACK_IMPORTED_MODULE_122__.ClippedPolyfaceBuilders),
193705
193682
  /* harmony export */ ClusterableArray: () => (/* reexport safe */ _numerics_ClusterableArray__WEBPACK_IMPORTED_MODULE_52__.ClusterableArray),
193706
193683
  /* harmony export */ Complex: () => (/* reexport safe */ _numerics_Complex__WEBPACK_IMPORTED_MODULE_53__.Complex),
193707
193684
  /* harmony export */ Cone: () => (/* reexport safe */ _solid_Cone__WEBPACK_IMPORTED_MODULE_89__.Cone),
@@ -193729,9 +193706,9 @@ __webpack_require__.r(__webpack_exports__);
193729
193706
  /* harmony export */ CurveSearchStatus: () => (/* reexport safe */ _curve_CurveLocationDetail__WEBPACK_IMPORTED_MODULE_66__.CurveSearchStatus),
193730
193707
  /* harmony export */ CutLoop: () => (/* reexport safe */ _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_27__.CutLoop),
193731
193708
  /* harmony export */ CutLoopMergeContext: () => (/* reexport safe */ _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_27__.CutLoopMergeContext),
193732
- /* harmony export */ DeepCompare: () => (/* reexport safe */ _serialization_DeepCompare__WEBPACK_IMPORTED_MODULE_128__.DeepCompare),
193709
+ /* harmony export */ DeepCompare: () => (/* reexport safe */ _serialization_DeepCompare__WEBPACK_IMPORTED_MODULE_129__.DeepCompare),
193733
193710
  /* harmony export */ DirectSpiral3d: () => (/* reexport safe */ _curve_spiral_DirectSpiral3d__WEBPACK_IMPORTED_MODULE_85__.DirectSpiral3d),
193734
- /* harmony export */ DuplicateFacetClusterSelector: () => (/* reexport safe */ _polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_120__.DuplicateFacetClusterSelector),
193711
+ /* harmony export */ DuplicateFacetClusterSelector: () => (/* reexport safe */ _polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_121__.DuplicateFacetClusterSelector),
193735
193712
  /* harmony export */ Ellipsoid: () => (/* reexport safe */ _geometry3d_Ellipsoid__WEBPACK_IMPORTED_MODULE_5__.Ellipsoid),
193736
193713
  /* harmony export */ EllipsoidPatch: () => (/* reexport safe */ _geometry3d_Ellipsoid__WEBPACK_IMPORTED_MODULE_5__.EllipsoidPatch),
193737
193714
  /* harmony export */ EllipticalArcApproximationOptions: () => (/* reexport safe */ _curve_Arc3d__WEBPACK_IMPORTED_MODULE_59__.EllipticalArcApproximationOptions),
@@ -193746,18 +193723,19 @@ __webpack_require__.r(__webpack_exports__);
193746
193723
  /* harmony export */ Geometry: () => (/* reexport safe */ _Geometry__WEBPACK_IMPORTED_MODULE_36__.Geometry),
193747
193724
  /* harmony export */ GeometryHandler: () => (/* reexport safe */ _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODULE_8__.GeometryHandler),
193748
193725
  /* harmony export */ GeometryQuery: () => (/* reexport safe */ _curve_GeometryQuery__WEBPACK_IMPORTED_MODULE_71__.GeometryQuery),
193749
- /* harmony export */ GriddedRaggedRange2dSet: () => (/* reexport safe */ _polyface_multiclip_GriddedRaggedRange2dSet__WEBPACK_IMPORTED_MODULE_116__.GriddedRaggedRange2dSet),
193750
- /* harmony export */ GriddedRaggedRange2dSetWithOverflow: () => (/* reexport safe */ _polyface_multiclip_GriddedRaggedRange2dSetWithOverflow__WEBPACK_IMPORTED_MODULE_117__.GriddedRaggedRange2dSetWithOverflow),
193726
+ /* harmony export */ GriddedRaggedRange2dSet: () => (/* reexport safe */ _polyface_multiclip_GriddedRaggedRange2dSet__WEBPACK_IMPORTED_MODULE_117__.GriddedRaggedRange2dSet),
193727
+ /* harmony export */ GriddedRaggedRange2dSetWithOverflow: () => (/* reexport safe */ _polyface_multiclip_GriddedRaggedRange2dSetWithOverflow__WEBPACK_IMPORTED_MODULE_118__.GriddedRaggedRange2dSetWithOverflow),
193751
193728
  /* harmony export */ GrowableBlockedArray: () => (/* reexport safe */ _geometry3d_GrowableBlockedArray__WEBPACK_IMPORTED_MODULE_9__.GrowableBlockedArray),
193752
193729
  /* harmony export */ GrowableFloat64Array: () => (/* reexport safe */ _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_10__.GrowableFloat64Array),
193753
193730
  /* harmony export */ GrowableXYArray: () => (/* reexport safe */ _geometry3d_GrowableXYArray__WEBPACK_IMPORTED_MODULE_11__.GrowableXYArray),
193754
193731
  /* harmony export */ GrowableXYZArray: () => (/* reexport safe */ _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_12__.GrowableXYZArray),
193755
- /* harmony export */ IModelJson: () => (/* reexport safe */ _serialization_IModelJsonSchema__WEBPACK_IMPORTED_MODULE_127__.IModelJson),
193732
+ /* harmony export */ IModelJson: () => (/* reexport safe */ _serialization_IModelJsonSchema__WEBPACK_IMPORTED_MODULE_128__.IModelJson),
193756
193733
  /* harmony export */ IndexedCollectionInterval: () => (/* reexport safe */ _geometry3d_IndexedCollectionInterval__WEBPACK_IMPORTED_MODULE_13__.IndexedCollectionInterval),
193734
+ /* harmony export */ IndexedEdgeMatcher: () => (/* reexport safe */ _polyface_IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_114__.IndexedEdgeMatcher),
193757
193735
  /* harmony export */ IndexedPolyface: () => (/* reexport safe */ _polyface_Polyface__WEBPACK_IMPORTED_MODULE_112__.IndexedPolyface),
193758
- /* harmony export */ IndexedPolyfaceSubsetVisitor: () => (/* reexport safe */ _polyface_IndexedPolyfaceVisitor__WEBPACK_IMPORTED_MODULE_114__.IndexedPolyfaceSubsetVisitor),
193759
- /* harmony export */ IndexedPolyfaceVisitor: () => (/* reexport safe */ _polyface_IndexedPolyfaceVisitor__WEBPACK_IMPORTED_MODULE_114__.IndexedPolyfaceVisitor),
193760
- /* harmony export */ IndexedPolyfaceWalker: () => (/* reexport safe */ _polyface_IndexedPolyfaceWalker__WEBPACK_IMPORTED_MODULE_115__.IndexedPolyfaceWalker),
193736
+ /* harmony export */ IndexedPolyfaceSubsetVisitor: () => (/* reexport safe */ _polyface_IndexedPolyfaceVisitor__WEBPACK_IMPORTED_MODULE_115__.IndexedPolyfaceSubsetVisitor),
193737
+ /* harmony export */ IndexedPolyfaceVisitor: () => (/* reexport safe */ _polyface_IndexedPolyfaceVisitor__WEBPACK_IMPORTED_MODULE_115__.IndexedPolyfaceVisitor),
193738
+ /* harmony export */ IndexedPolyfaceWalker: () => (/* reexport safe */ _polyface_IndexedPolyfaceWalker__WEBPACK_IMPORTED_MODULE_116__.IndexedPolyfaceWalker),
193761
193739
  /* harmony export */ IndexedReadWriteXYZCollection: () => (/* reexport safe */ _geometry3d_IndexedXYZCollection__WEBPACK_IMPORTED_MODULE_15__.IndexedReadWriteXYZCollection),
193762
193740
  /* harmony export */ IndexedXYCollection: () => (/* reexport safe */ _geometry3d_IndexedXYCollection__WEBPACK_IMPORTED_MODULE_14__.IndexedXYCollection),
193763
193741
  /* harmony export */ IndexedXYZCollection: () => (/* reexport safe */ _geometry3d_IndexedXYZCollection__WEBPACK_IMPORTED_MODULE_15__.IndexedXYZCollection),
@@ -193771,7 +193749,7 @@ __webpack_require__.r(__webpack_exports__);
193771
193749
  /* harmony export */ KnotVector: () => (/* reexport safe */ _bspline_KnotVector__WEBPACK_IMPORTED_MODULE_108__.KnotVector),
193772
193750
  /* harmony export */ LineSegment3d: () => (/* reexport safe */ _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_72__.LineSegment3d),
193773
193751
  /* harmony export */ LineString3d: () => (/* reexport safe */ _curve_LineString3d__WEBPACK_IMPORTED_MODULE_73__.LineString3d),
193774
- /* harmony export */ LineString3dRangeTreeContext: () => (/* reexport safe */ _polyface_RangeTree_LineString3dRangeTreeContext__WEBPACK_IMPORTED_MODULE_123__.LineString3dRangeTreeContext),
193752
+ /* harmony export */ LineString3dRangeTreeContext: () => (/* reexport safe */ _polyface_RangeTree_LineString3dRangeTreeContext__WEBPACK_IMPORTED_MODULE_124__.LineString3dRangeTreeContext),
193775
193753
  /* harmony export */ LinearSweep: () => (/* reexport safe */ _solid_LinearSweep__WEBPACK_IMPORTED_MODULE_90__.LinearSweep),
193776
193754
  /* harmony export */ LongitudeLatitudeNumber: () => (/* reexport safe */ _geometry3d_LongitudeLatitudeAltitude__WEBPACK_IMPORTED_MODULE_2__.LongitudeLatitudeNumber),
193777
193755
  /* harmony export */ Loop: () => (/* reexport safe */ _curve_Loop__WEBPACK_IMPORTED_MODULE_74__.Loop),
@@ -193784,7 +193762,7 @@ __webpack_require__.r(__webpack_exports__);
193784
193762
  /* harmony export */ NonConvexFacetLocationDetail: () => (/* reexport safe */ _polyface_FacetLocationDetail__WEBPACK_IMPORTED_MODULE_113__.NonConvexFacetLocationDetail),
193785
193763
  /* harmony export */ NullGeometryHandler: () => (/* reexport safe */ _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODULE_8__.NullGeometryHandler),
193786
193764
  /* harmony export */ NumberArray: () => (/* reexport safe */ _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_24__.NumberArray),
193787
- /* harmony export */ OffsetMeshOptions: () => (/* reexport safe */ _polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_120__.OffsetMeshOptions),
193765
+ /* harmony export */ OffsetMeshOptions: () => (/* reexport safe */ _polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_121__.OffsetMeshOptions),
193788
193766
  /* harmony export */ OffsetOptions: () => (/* reexport safe */ _curve_OffsetOptions__WEBPACK_IMPORTED_MODULE_75__.OffsetOptions),
193789
193767
  /* harmony export */ Order2Bezier: () => (/* reexport safe */ _numerics_BezierPolynomials__WEBPACK_IMPORTED_MODULE_51__.Order2Bezier),
193790
193768
  /* harmony export */ Order3Bezier: () => (/* reexport safe */ _numerics_BezierPolynomials__WEBPACK_IMPORTED_MODULE_51__.Order3Bezier),
@@ -193807,17 +193785,17 @@ __webpack_require__.r(__webpack_exports__);
193807
193785
  /* harmony export */ Point3dArray: () => (/* reexport safe */ _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_24__.Point3dArray),
193808
193786
  /* harmony export */ Point3dArrayCarrier: () => (/* reexport safe */ _geometry3d_Point3dArrayCarrier__WEBPACK_IMPORTED_MODULE_25__.Point3dArrayCarrier),
193809
193787
  /* harmony export */ Point3dArrayPolygonOps: () => (/* reexport safe */ _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_27__.Point3dArrayPolygonOps),
193810
- /* harmony export */ Point3dArrayRangeTreeContext: () => (/* reexport safe */ _polyface_RangeTree_Point3dArrayRangeTreeContext__WEBPACK_IMPORTED_MODULE_122__.Point3dArrayRangeTreeContext),
193788
+ /* harmony export */ Point3dArrayRangeTreeContext: () => (/* reexport safe */ _polyface_RangeTree_Point3dArrayRangeTreeContext__WEBPACK_IMPORTED_MODULE_123__.Point3dArrayRangeTreeContext),
193811
193789
  /* harmony export */ Point4d: () => (/* reexport safe */ _geometry4d_Point4d__WEBPACK_IMPORTED_MODULE_47__.Point4d),
193812
193790
  /* harmony export */ Point4dArray: () => (/* reexport safe */ _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_24__.Point4dArray),
193813
193791
  /* harmony export */ PointString3d: () => (/* reexport safe */ _curve_PointString3d__WEBPACK_IMPORTED_MODULE_80__.PointString3d),
193814
193792
  /* harmony export */ Polyface: () => (/* reexport safe */ _polyface_Polyface__WEBPACK_IMPORTED_MODULE_112__.Polyface),
193815
193793
  /* harmony export */ PolyfaceAuxData: () => (/* reexport safe */ _polyface_AuxData__WEBPACK_IMPORTED_MODULE_109__.PolyfaceAuxData),
193816
- /* harmony export */ PolyfaceBuilder: () => (/* reexport safe */ _polyface_PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_118__.PolyfaceBuilder),
193817
- /* harmony export */ PolyfaceClip: () => (/* reexport safe */ _polyface_PolyfaceClip__WEBPACK_IMPORTED_MODULE_121__.PolyfaceClip),
193818
- /* harmony export */ PolyfaceData: () => (/* reexport safe */ _polyface_PolyfaceData__WEBPACK_IMPORTED_MODULE_119__.PolyfaceData),
193819
- /* harmony export */ PolyfaceQuery: () => (/* reexport safe */ _polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_120__.PolyfaceQuery),
193820
- /* harmony export */ PolyfaceRangeTreeContext: () => (/* reexport safe */ _polyface_RangeTree_PolyfaceRangeTreeContext__WEBPACK_IMPORTED_MODULE_124__.PolyfaceRangeTreeContext),
193794
+ /* harmony export */ PolyfaceBuilder: () => (/* reexport safe */ _polyface_PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_119__.PolyfaceBuilder),
193795
+ /* harmony export */ PolyfaceClip: () => (/* reexport safe */ _polyface_PolyfaceClip__WEBPACK_IMPORTED_MODULE_122__.PolyfaceClip),
193796
+ /* harmony export */ PolyfaceData: () => (/* reexport safe */ _polyface_PolyfaceData__WEBPACK_IMPORTED_MODULE_120__.PolyfaceData),
193797
+ /* harmony export */ PolyfaceQuery: () => (/* reexport safe */ _polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_121__.PolyfaceQuery),
193798
+ /* harmony export */ PolyfaceRangeTreeContext: () => (/* reexport safe */ _polyface_RangeTree_PolyfaceRangeTreeContext__WEBPACK_IMPORTED_MODULE_125__.PolyfaceRangeTreeContext),
193821
193799
  /* harmony export */ PolygonLocation: () => (/* reexport safe */ _Geometry__WEBPACK_IMPORTED_MODULE_36__.PolygonLocation),
193822
193800
  /* harmony export */ PolygonLocationDetail: () => (/* reexport safe */ _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_27__.PolygonLocationDetail),
193823
193801
  /* harmony export */ PolygonLocationDetailPair: () => (/* reexport safe */ _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_27__.PolygonLocationDetailPair),
@@ -193840,23 +193818,24 @@ __webpack_require__.r(__webpack_exports__);
193840
193818
  /* harmony export */ RegionOps: () => (/* reexport safe */ _curve_RegionOps__WEBPACK_IMPORTED_MODULE_79__.RegionOps),
193841
193819
  /* harmony export */ RotationalSweep: () => (/* reexport safe */ _solid_RotationalSweep__WEBPACK_IMPORTED_MODULE_91__.RotationalSweep),
193842
193820
  /* harmony export */ RuledSweep: () => (/* reexport safe */ _solid_RuledSweep__WEBPACK_IMPORTED_MODULE_92__.RuledSweep),
193843
- /* harmony export */ Sample: () => (/* reexport safe */ _serialization_GeometrySamples__WEBPACK_IMPORTED_MODULE_129__.Sample),
193821
+ /* harmony export */ Sample: () => (/* reexport safe */ _serialization_GeometrySamples__WEBPACK_IMPORTED_MODULE_130__.Sample),
193844
193822
  /* harmony export */ Segment1d: () => (/* reexport safe */ _geometry3d_Segment1d__WEBPACK_IMPORTED_MODULE_31__.Segment1d),
193845
- /* harmony export */ SerializationHelpers: () => (/* reexport safe */ _serialization_SerializationHelpers__WEBPACK_IMPORTED_MODULE_130__.SerializationHelpers),
193823
+ /* harmony export */ SerializationHelpers: () => (/* reexport safe */ _serialization_SerializationHelpers__WEBPACK_IMPORTED_MODULE_131__.SerializationHelpers),
193846
193824
  /* harmony export */ SmallSystem: () => (/* reexport safe */ _numerics_SmallSystem__WEBPACK_IMPORTED_MODULE_57__.SmallSystem),
193847
193825
  /* harmony export */ SmoothTransformBetweenFrusta: () => (/* reexport safe */ _geometry3d_FrustumAnimation__WEBPACK_IMPORTED_MODULE_7__.SmoothTransformBetweenFrusta),
193848
193826
  /* harmony export */ SolidPrimitive: () => (/* reexport safe */ _solid_SolidPrimitive__WEBPACK_IMPORTED_MODULE_93__.SolidPrimitive),
193849
- /* harmony export */ SpacePolygonTriangulation: () => (/* reexport safe */ _topology_SpaceTriangulation__WEBPACK_IMPORTED_MODULE_126__.SpacePolygonTriangulation),
193827
+ /* harmony export */ SortableEdge: () => (/* reexport safe */ _polyface_IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_114__.SortableEdge),
193828
+ /* harmony export */ SpacePolygonTriangulation: () => (/* reexport safe */ _topology_SpaceTriangulation__WEBPACK_IMPORTED_MODULE_127__.SpacePolygonTriangulation),
193850
193829
  /* harmony export */ Sphere: () => (/* reexport safe */ _solid_Sphere__WEBPACK_IMPORTED_MODULE_94__.Sphere),
193851
193830
  /* harmony export */ StandardViewIndex: () => (/* reexport safe */ _Geometry__WEBPACK_IMPORTED_MODULE_36__.StandardViewIndex),
193852
- /* harmony export */ SteppedIndexFunctionFactory: () => (/* reexport safe */ _serialization_GeometrySamples__WEBPACK_IMPORTED_MODULE_129__.SteppedIndexFunctionFactory),
193831
+ /* harmony export */ SteppedIndexFunctionFactory: () => (/* reexport safe */ _serialization_GeometrySamples__WEBPACK_IMPORTED_MODULE_130__.SteppedIndexFunctionFactory),
193853
193832
  /* harmony export */ StringifiedClipVector: () => (/* reexport safe */ _clipping_ClipVector__WEBPACK_IMPORTED_MODULE_43__.StringifiedClipVector),
193854
193833
  /* harmony export */ StrokeCountMap: () => (/* reexport safe */ _curve_Query_StrokeCountMap__WEBPACK_IMPORTED_MODULE_87__.StrokeCountMap),
193855
193834
  /* harmony export */ StrokeOptions: () => (/* reexport safe */ _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_82__.StrokeOptions),
193856
193835
  /* harmony export */ SweepContour: () => (/* reexport safe */ _solid_SweepContour__WEBPACK_IMPORTED_MODULE_95__.SweepContour),
193857
- /* harmony export */ SweepLineStringToFacetsOptions: () => (/* reexport safe */ _polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_120__.SweepLineStringToFacetsOptions),
193858
- /* harmony export */ TaggedNumericConstants: () => (/* reexport safe */ _polyface_TaggedNumericData__WEBPACK_IMPORTED_MODULE_125__.TaggedNumericConstants),
193859
- /* harmony export */ TaggedNumericData: () => (/* reexport safe */ _polyface_TaggedNumericData__WEBPACK_IMPORTED_MODULE_125__.TaggedNumericData),
193836
+ /* harmony export */ SweepLineStringToFacetsOptions: () => (/* reexport safe */ _polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_121__.SweepLineStringToFacetsOptions),
193837
+ /* harmony export */ TaggedNumericConstants: () => (/* reexport safe */ _polyface_TaggedNumericData__WEBPACK_IMPORTED_MODULE_126__.TaggedNumericConstants),
193838
+ /* harmony export */ TaggedNumericData: () => (/* reexport safe */ _polyface_TaggedNumericData__WEBPACK_IMPORTED_MODULE_126__.TaggedNumericData),
193860
193839
  /* harmony export */ TorusPipe: () => (/* reexport safe */ _solid_TorusPipe__WEBPACK_IMPORTED_MODULE_96__.TorusPipe),
193861
193840
  /* harmony export */ Transform: () => (/* reexport safe */ _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_32__.Transform),
193862
193841
  /* harmony export */ TransitionSpiral3d: () => (/* reexport safe */ _curve_spiral_TransitionSpiral3d__WEBPACK_IMPORTED_MODULE_83__.TransitionSpiral3d),
@@ -193992,24 +193971,25 @@ __webpack_require__.r(__webpack_exports__);
193992
193971
  /* harmony import */ var _polyface_FacetFaceData__WEBPACK_IMPORTED_MODULE_111__ = __webpack_require__(/*! ./polyface/FacetFaceData */ "../../core/geometry/lib/esm/polyface/FacetFaceData.js");
193993
193972
  /* harmony import */ var _polyface_Polyface__WEBPACK_IMPORTED_MODULE_112__ = __webpack_require__(/*! ./polyface/Polyface */ "../../core/geometry/lib/esm/polyface/Polyface.js");
193994
193973
  /* harmony import */ var _polyface_FacetLocationDetail__WEBPACK_IMPORTED_MODULE_113__ = __webpack_require__(/*! ./polyface/FacetLocationDetail */ "../../core/geometry/lib/esm/polyface/FacetLocationDetail.js");
193995
- /* harmony import */ var _polyface_IndexedPolyfaceVisitor__WEBPACK_IMPORTED_MODULE_114__ = __webpack_require__(/*! ./polyface/IndexedPolyfaceVisitor */ "../../core/geometry/lib/esm/polyface/IndexedPolyfaceVisitor.js");
193996
- /* harmony import */ var _polyface_IndexedPolyfaceWalker__WEBPACK_IMPORTED_MODULE_115__ = __webpack_require__(/*! ./polyface/IndexedPolyfaceWalker */ "../../core/geometry/lib/esm/polyface/IndexedPolyfaceWalker.js");
193997
- /* harmony import */ var _polyface_multiclip_GriddedRaggedRange2dSet__WEBPACK_IMPORTED_MODULE_116__ = __webpack_require__(/*! ./polyface/multiclip/GriddedRaggedRange2dSet */ "../../core/geometry/lib/esm/polyface/multiclip/GriddedRaggedRange2dSet.js");
193998
- /* harmony import */ var _polyface_multiclip_GriddedRaggedRange2dSetWithOverflow__WEBPACK_IMPORTED_MODULE_117__ = __webpack_require__(/*! ./polyface/multiclip/GriddedRaggedRange2dSetWithOverflow */ "../../core/geometry/lib/esm/polyface/multiclip/GriddedRaggedRange2dSetWithOverflow.js");
193999
- /* harmony import */ var _polyface_PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_118__ = __webpack_require__(/*! ./polyface/PolyfaceBuilder */ "../../core/geometry/lib/esm/polyface/PolyfaceBuilder.js");
194000
- /* harmony import */ var _polyface_PolyfaceData__WEBPACK_IMPORTED_MODULE_119__ = __webpack_require__(/*! ./polyface/PolyfaceData */ "../../core/geometry/lib/esm/polyface/PolyfaceData.js");
194001
- /* harmony import */ var _polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_120__ = __webpack_require__(/*! ./polyface/PolyfaceQuery */ "../../core/geometry/lib/esm/polyface/PolyfaceQuery.js");
194002
- /* harmony import */ var _polyface_PolyfaceClip__WEBPACK_IMPORTED_MODULE_121__ = __webpack_require__(/*! ./polyface/PolyfaceClip */ "../../core/geometry/lib/esm/polyface/PolyfaceClip.js");
194003
- /* harmony import */ var _polyface_RangeTree_Point3dArrayRangeTreeContext__WEBPACK_IMPORTED_MODULE_122__ = __webpack_require__(/*! ./polyface/RangeTree/Point3dArrayRangeTreeContext */ "../../core/geometry/lib/esm/polyface/RangeTree/Point3dArrayRangeTreeContext.js");
194004
- /* harmony import */ var _polyface_RangeTree_LineString3dRangeTreeContext__WEBPACK_IMPORTED_MODULE_123__ = __webpack_require__(/*! ./polyface/RangeTree/LineString3dRangeTreeContext */ "../../core/geometry/lib/esm/polyface/RangeTree/LineString3dRangeTreeContext.js");
194005
- /* harmony import */ var _polyface_RangeTree_PolyfaceRangeTreeContext__WEBPACK_IMPORTED_MODULE_124__ = __webpack_require__(/*! ./polyface/RangeTree/PolyfaceRangeTreeContext */ "../../core/geometry/lib/esm/polyface/RangeTree/PolyfaceRangeTreeContext.js");
194006
- /* harmony import */ var _polyface_TaggedNumericData__WEBPACK_IMPORTED_MODULE_125__ = __webpack_require__(/*! ./polyface/TaggedNumericData */ "../../core/geometry/lib/esm/polyface/TaggedNumericData.js");
194007
- /* harmony import */ var _topology_SpaceTriangulation__WEBPACK_IMPORTED_MODULE_126__ = __webpack_require__(/*! ./topology/SpaceTriangulation */ "../../core/geometry/lib/esm/topology/SpaceTriangulation.js");
194008
- /* harmony import */ var _serialization_IModelJsonSchema__WEBPACK_IMPORTED_MODULE_127__ = __webpack_require__(/*! ./serialization/IModelJsonSchema */ "../../core/geometry/lib/esm/serialization/IModelJsonSchema.js");
194009
- /* harmony import */ var _serialization_DeepCompare__WEBPACK_IMPORTED_MODULE_128__ = __webpack_require__(/*! ./serialization/DeepCompare */ "../../core/geometry/lib/esm/serialization/DeepCompare.js");
194010
- /* harmony import */ var _serialization_GeometrySamples__WEBPACK_IMPORTED_MODULE_129__ = __webpack_require__(/*! ./serialization/GeometrySamples */ "../../core/geometry/lib/esm/serialization/GeometrySamples.js");
194011
- /* harmony import */ var _serialization_SerializationHelpers__WEBPACK_IMPORTED_MODULE_130__ = __webpack_require__(/*! ./serialization/SerializationHelpers */ "../../core/geometry/lib/esm/serialization/SerializationHelpers.js");
194012
- /* harmony import */ var _serialization_BentleyGeometryFlatBuffer__WEBPACK_IMPORTED_MODULE_131__ = __webpack_require__(/*! ./serialization/BentleyGeometryFlatBuffer */ "../../core/geometry/lib/esm/serialization/BentleyGeometryFlatBuffer.js");
193974
+ /* harmony import */ var _polyface_IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_114__ = __webpack_require__(/*! ./polyface/IndexedEdgeMatcher */ "../../core/geometry/lib/esm/polyface/IndexedEdgeMatcher.js");
193975
+ /* harmony import */ var _polyface_IndexedPolyfaceVisitor__WEBPACK_IMPORTED_MODULE_115__ = __webpack_require__(/*! ./polyface/IndexedPolyfaceVisitor */ "../../core/geometry/lib/esm/polyface/IndexedPolyfaceVisitor.js");
193976
+ /* harmony import */ var _polyface_IndexedPolyfaceWalker__WEBPACK_IMPORTED_MODULE_116__ = __webpack_require__(/*! ./polyface/IndexedPolyfaceWalker */ "../../core/geometry/lib/esm/polyface/IndexedPolyfaceWalker.js");
193977
+ /* harmony import */ var _polyface_multiclip_GriddedRaggedRange2dSet__WEBPACK_IMPORTED_MODULE_117__ = __webpack_require__(/*! ./polyface/multiclip/GriddedRaggedRange2dSet */ "../../core/geometry/lib/esm/polyface/multiclip/GriddedRaggedRange2dSet.js");
193978
+ /* harmony import */ var _polyface_multiclip_GriddedRaggedRange2dSetWithOverflow__WEBPACK_IMPORTED_MODULE_118__ = __webpack_require__(/*! ./polyface/multiclip/GriddedRaggedRange2dSetWithOverflow */ "../../core/geometry/lib/esm/polyface/multiclip/GriddedRaggedRange2dSetWithOverflow.js");
193979
+ /* harmony import */ var _polyface_PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_119__ = __webpack_require__(/*! ./polyface/PolyfaceBuilder */ "../../core/geometry/lib/esm/polyface/PolyfaceBuilder.js");
193980
+ /* harmony import */ var _polyface_PolyfaceData__WEBPACK_IMPORTED_MODULE_120__ = __webpack_require__(/*! ./polyface/PolyfaceData */ "../../core/geometry/lib/esm/polyface/PolyfaceData.js");
193981
+ /* harmony import */ var _polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_121__ = __webpack_require__(/*! ./polyface/PolyfaceQuery */ "../../core/geometry/lib/esm/polyface/PolyfaceQuery.js");
193982
+ /* harmony import */ var _polyface_PolyfaceClip__WEBPACK_IMPORTED_MODULE_122__ = __webpack_require__(/*! ./polyface/PolyfaceClip */ "../../core/geometry/lib/esm/polyface/PolyfaceClip.js");
193983
+ /* harmony import */ var _polyface_RangeTree_Point3dArrayRangeTreeContext__WEBPACK_IMPORTED_MODULE_123__ = __webpack_require__(/*! ./polyface/RangeTree/Point3dArrayRangeTreeContext */ "../../core/geometry/lib/esm/polyface/RangeTree/Point3dArrayRangeTreeContext.js");
193984
+ /* harmony import */ var _polyface_RangeTree_LineString3dRangeTreeContext__WEBPACK_IMPORTED_MODULE_124__ = __webpack_require__(/*! ./polyface/RangeTree/LineString3dRangeTreeContext */ "../../core/geometry/lib/esm/polyface/RangeTree/LineString3dRangeTreeContext.js");
193985
+ /* harmony import */ var _polyface_RangeTree_PolyfaceRangeTreeContext__WEBPACK_IMPORTED_MODULE_125__ = __webpack_require__(/*! ./polyface/RangeTree/PolyfaceRangeTreeContext */ "../../core/geometry/lib/esm/polyface/RangeTree/PolyfaceRangeTreeContext.js");
193986
+ /* harmony import */ var _polyface_TaggedNumericData__WEBPACK_IMPORTED_MODULE_126__ = __webpack_require__(/*! ./polyface/TaggedNumericData */ "../../core/geometry/lib/esm/polyface/TaggedNumericData.js");
193987
+ /* harmony import */ var _topology_SpaceTriangulation__WEBPACK_IMPORTED_MODULE_127__ = __webpack_require__(/*! ./topology/SpaceTriangulation */ "../../core/geometry/lib/esm/topology/SpaceTriangulation.js");
193988
+ /* harmony import */ var _serialization_IModelJsonSchema__WEBPACK_IMPORTED_MODULE_128__ = __webpack_require__(/*! ./serialization/IModelJsonSchema */ "../../core/geometry/lib/esm/serialization/IModelJsonSchema.js");
193989
+ /* harmony import */ var _serialization_DeepCompare__WEBPACK_IMPORTED_MODULE_129__ = __webpack_require__(/*! ./serialization/DeepCompare */ "../../core/geometry/lib/esm/serialization/DeepCompare.js");
193990
+ /* harmony import */ var _serialization_GeometrySamples__WEBPACK_IMPORTED_MODULE_130__ = __webpack_require__(/*! ./serialization/GeometrySamples */ "../../core/geometry/lib/esm/serialization/GeometrySamples.js");
193991
+ /* harmony import */ var _serialization_SerializationHelpers__WEBPACK_IMPORTED_MODULE_131__ = __webpack_require__(/*! ./serialization/SerializationHelpers */ "../../core/geometry/lib/esm/serialization/SerializationHelpers.js");
193992
+ /* harmony import */ var _serialization_BentleyGeometryFlatBuffer__WEBPACK_IMPORTED_MODULE_132__ = __webpack_require__(/*! ./serialization/BentleyGeometryFlatBuffer */ "../../core/geometry/lib/esm/serialization/BentleyGeometryFlatBuffer.js");
194013
193993
  /*---------------------------------------------------------------------------------------------
194014
193994
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
194015
193995
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -194263,6 +194243,7 @@ __webpack_require__.r(__webpack_exports__);
194263
194243
 
194264
194244
 
194265
194245
 
194246
+
194266
194247
 
194267
194248
 
194268
194249
  /***/ }),
@@ -194446,15 +194427,26 @@ class EllipticalArcApproximationOptions {
194446
194427
  * Circular or elliptic arc.
194447
194428
  * * The angle to point equation is:
194448
194429
  * * `X = center + cos(theta) * vector0 + sin(theta) * vector90`
194449
- * * When the two vectors are perpendicular and have equal length, it is a true circle.
194450
- * * Non-perpendicular vectors are always elliptic.
194451
- * * Vectors of unequal length are always elliptic.
194452
- * * To create an ellipse in the common "major and minor axis" form of an ellipse:
194453
- * * vector0 is the vector from the center to the major axis extreme.
194454
- * * vector90 is the vector from the center to the minor axis extreme.
194430
+ * * The arc's `sweep` determines the range of theta values (angles). In particular:
194431
+ * * The point at `theta = n*360` degrees is `center + vector0` for any integer n.
194432
+ * * The point at `theta = 90 + n*360` degrees is `center + vector90` for any integer n.
194433
+ * * The arc's `sweep` _together with_ `vector0` and `vector90` determine the arc's orientation:
194434
+ * * If `sweep.startDegrees < sweep.endDegrees`, the arc's orientation is counterclockwise with respect to its
194435
+ * `perpendicularVector` (i.e., looking at the arc from the head of this vector).
194436
+ * * Similarly, if `sweep.startDegrees > sweep.endDegrees`, the arc's orientation is clockwise with respect to
194437
+ * its `perpendicularVector`.
194438
+ * * The arc's orientation is _always_ counterclockwise with respect to its `binormalVector`.
194439
+ * * When `vector0` and `vector90` are perpendicular and have equal length, the arc is circular.
194440
+ * * When they are non-perpendicular, the arc is always elliptic.
194441
+ * * When they have unequal length, the arc is always elliptic.
194442
+ * * To create an ellipse in standard major-minor axis form:
194443
+ * * `vector0` is the vector from the center to the major axis extreme.
194444
+ * * `vector90` is the vector from the center to the minor axis extreme.
194455
194445
  * * Note that constructing these vectors to the extreme points makes them perpendicular.
194456
- * * The method toScaledMatrix3d() can be called to convert the unrestricted vector0, vector90 to perpendicular form.
194457
- * * The unrestricted form is much easier to work with for common calculations: stroking, projection to 2d, intersection with plane.
194446
+ * * The method [[Arc3d.toScaledMatrix3d]] can be called to convert an arc with unrestricted `vector0` and `vector90`
194447
+ * to an arc in standard major-minor axis form.
194448
+ * * The unrestricted form is much easier to work with for common calculations: stroking, projection to 2d,
194449
+ * intersection with plane.
194458
194450
  * @public
194459
194451
  */
194460
194452
  class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive {
@@ -194465,7 +194457,7 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
194465
194457
  return other instanceof Arc3d;
194466
194458
  }
194467
194459
  _center;
194468
- _matrix; // columns are [vector0, vector90, unitNormal]
194460
+ _matrix; // columns are [vector0, vector90, unit normal]
194469
194461
  _sweep; // sweep limits
194470
194462
  static _workPointA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create();
194471
194463
  static _workPointB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create();
@@ -194480,21 +194472,27 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
194480
194472
  set center(center) {
194481
194473
  this._center.setFrom(center);
194482
194474
  }
194483
- /** Read property for (reference to) center. */
194475
+ /** Read property for (reference to) the arc center. */
194484
194476
  get centerRef() {
194485
194477
  return this._center;
194486
194478
  }
194487
- /** Read property for (clone of) vector0. */
194479
+ /**
194480
+ * Read property for (clone of) the x-column of the arc matrix.
194481
+ * * This vector determines the point on the arc corresponding to angles n*360 degrees.
194482
+ */
194488
194483
  get vector0() {
194489
194484
  return this._matrix.columnX();
194490
194485
  }
194491
- /** Read property for (clone of) vector90. */
194486
+ /**
194487
+ * Read property for (clone of) the y-column of the arc matrix.
194488
+ * * This vector determines the point on the arc corresponding to angles 90 + n*360 degrees.
194489
+ */
194492
194490
  get vector90() {
194493
194491
  return this._matrix.columnY();
194494
194492
  }
194495
194493
  /**
194496
194494
  * Compute an arc binormal vector with arbitrary length.
194497
- * * The arc parameterization is counter-clockwise with respect to this vector.
194495
+ * * The arc parameterization is counterclockwise with respect to this vector.
194498
194496
  * * This vector is parallel to [[perpendicularVector]] and possibly opposite.
194499
194497
  */
194500
194498
  binormalVector(result) {
@@ -194502,17 +194500,18 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
194502
194500
  return plane.vectorU.crossProduct(plane.vectorV, result);
194503
194501
  }
194504
194502
  /**
194505
- * Read property for (clone of) plane normal, with arbitrary length.
194506
- * * Does not take arc sweep direction into account. See also [[binormalVector]].
194503
+ * Read property for (clone of) the z-column of the arc matrix.
194504
+ * * This vector is nominally the normalized cross product: `vector0 x vector90`.
194505
+ * * To compute a vector with respect to which the arc sweep is counterclockwise, use [[binormalVector]].
194507
194506
  */
194508
194507
  get perpendicularVector() {
194509
194508
  return this._matrix.columnZ();
194510
194509
  }
194511
- /** Read property for (clone of) matrix of vector0, vector90, unit normal. */
194510
+ /** Return a clone of the arc matrix. */
194512
194511
  matrixClone() {
194513
194512
  return this._matrix.clone();
194514
194513
  }
194515
- /** Read property for (reference to) matrix of vector0, vector90, unit normal. */
194514
+ /** Read property for (reference to) the arc matrix. */
194516
194515
  get matrixRef() {
194517
194516
  return this._matrix;
194518
194517
  }
@@ -194527,17 +194526,14 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
194527
194526
  get isExtensibleFractionSpace() {
194528
194527
  return true;
194529
194528
  }
194530
- // constructor copies the pointers
194529
+ /** Constructor. Captures the inputs. */
194531
194530
  constructor(center, matrix, sweep) {
194532
194531
  super();
194533
194532
  this._center = center;
194534
194533
  this._matrix = matrix;
194535
194534
  this._sweep = sweep.clampToFullCircle(sweep);
194536
194535
  }
194537
- /**
194538
- * Return a clone of the arc, with transform applied.
194539
- * @param transform
194540
- */
194536
+ /** Return a clone of the arc, with transform applied. */
194541
194537
  cloneTransformed(transform) {
194542
194538
  const c = this.clone();
194543
194539
  c.tryTransformInPlace(transform);
@@ -194546,7 +194542,7 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
194546
194542
  /**
194547
194543
  * Redefine the arc with (captured references to) given data.
194548
194544
  * @param center arc center.
194549
- * @param matrix matrix with columns vector0, vector 90, and their unit cross product.
194545
+ * @param matrix matrix with columns vector0, vector90, and their unit cross product.
194550
194546
  * @param sweep angle sweep.
194551
194547
  */
194552
194548
  setRefs(center, matrix, sweep) {
@@ -194557,7 +194553,7 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
194557
194553
  /**
194558
194554
  * Redefine the arc with (clones of) given data.
194559
194555
  * @param center arc center.
194560
- * @param matrix matrix with columns vector0, vector 90, and their unit cross product.
194556
+ * @param matrix matrix with columns vector0, vector90, and their unit cross product.
194561
194557
  * @param sweep angle sweep.
194562
194558
  */
194563
194559
  set(center, matrix, sweep) {
@@ -194576,7 +194572,7 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
194576
194572
  /**
194577
194573
  * Create an arc, capturing references to center, matrix and sweep.
194578
194574
  * @param center center point.
194579
- * @param matrix matrix with columns vector0, vector90, and unit cross product.
194575
+ * @param matrix matrix with columns vector0, vector90, and their unit cross product.
194580
194576
  * @param sweep sweep limits.
194581
194577
  * @param result optional preallocated result.
194582
194578
  */
@@ -194590,9 +194586,10 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
194590
194586
  /**
194591
194587
  * Create an arc from center, x column to be scaled, and y column to be scaled.
194592
194588
  * @param center center of ellipse.
194593
- * @param matrix matrix whose x and y columns are scaled by radius0 and radius90.
194594
- * @param radius0 radius in x direction.
194595
- * @param radius90 radius in y direction.
194589
+ * @param matrix the x-column and y-column of this matrix are scaled by `radius0` and `radius90` to define the
194590
+ * arc's `vector0` and `vector90`.
194591
+ * @param radius0 radius along `vector0`.
194592
+ * @param radius90 radius along `vector90`.
194596
194593
  * @param sweep sweep limits.
194597
194594
  * @param result optional preallocated result.
194598
194595
  */
@@ -194602,10 +194599,10 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
194602
194599
  return Arc3d.create(center, vector0.scale(radius0, vector0), vector90.scale(radius90, vector90), sweep, result);
194603
194600
  }
194604
194601
  /**
194605
- * Create a (full circular) arc from center, normal and radius.
194606
- * @param center center of ellipse. If undefined, center at 000.
194602
+ * Create a full circle from center, normal and radius.
194603
+ * @param center center of circle. If undefined, use 000.
194607
194604
  * @param normal normal vector.
194608
- * @param radius radius in x direction.
194605
+ * @param radius radius of the circle.
194609
194606
  * @param result optional preallocated result.
194610
194607
  */
194611
194608
  static createCenterNormalRadius(center, normal, radius, result) {
@@ -194613,7 +194610,7 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
194613
194610
  return Arc3d.createScaledXYColumns(center, frame, radius, radius, undefined, result);
194614
194611
  }
194615
194612
  /**
194616
- * Create an arc by center with vectors to points at 0 and 90 degrees in parameter space.
194613
+ * Create an elliptical arc by center with vectors to points at 0 and 90 degrees in parameter space.
194617
194614
  * @param center arc center.
194618
194615
  * @param vector0 vector to 0 degrees (commonly major axis).
194619
194616
  * @param vector90 vector to 90 degree point (commonly minor axis).
@@ -194930,10 +194927,13 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
194930
194927
  curveLength() {
194931
194928
  return this.curveLengthBetweenFractions(0, 1);
194932
194929
  }
194933
- // !! misspelled Gauss in the published static !! Declare it ok.
194934
- // cspell::word Guass
194935
- /** Gauss point quadrature count for evaluating curve length. (The number of intervals is adjusted to the arc sweep). */
194930
+ /**
194931
+ * Gauss point quadrature count for evaluating curve length. (The number of intervals is adjusted to the arc sweep).
194932
+ * @deprecated in 5.0. Use correct spelling quadratureGaussCount.
194933
+ */
194936
194934
  static quadratureGuassCount = 5;
194935
+ /** Gauss point quadrature count for evaluating curve length. (The number of intervals is adjusted to the arc sweep). */
194936
+ static quadratureGaussCount = 5;
194937
194937
  /** In quadrature for arc length, use this interval (divided by quickEccentricity). */
194938
194938
  static quadratureIntervalAngleDegrees = 10.0;
194939
194939
  /**
@@ -194960,7 +194960,7 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
194960
194960
  numInterval = 400;
194961
194961
  if (numInterval < 1)
194962
194962
  numInterval = 1;
194963
- return super.curveLengthWithFixedIntervalCountQuadrature(f0, f1, numInterval, Arc3d.quadratureGuassCount);
194963
+ return super.curveLengthWithFixedIntervalCountQuadrature(f0, f1, numInterval, Arc3d.quadratureGaussCount);
194964
194964
  }
194965
194965
  /**
194966
194966
  * Return an approximate (but easy to compute) arc length.
@@ -196938,6 +196938,20 @@ class CurveCollection extends _GeometryQuery__WEBPACK_IMPORTED_MODULE_0__.Geomet
196938
196938
  projectedParameterRange(ray, lowHigh) {
196939
196939
  return _internalContexts_PlaneAltitudeRangeContext__WEBPACK_IMPORTED_MODULE_9__.PlaneAltitudeRangeContext.findExtremeFractionsAlongDirection(this, ray, lowHigh);
196940
196940
  }
196941
+ /** Return the immediate parent of the input curve in the instance, or undefined if it is not a descendant. */
196942
+ findParentOfDescendant(descendant) {
196943
+ for (const child of this.children) {
196944
+ if (child === descendant)
196945
+ return this;
196946
+ if (child instanceof CurveCollection) {
196947
+ const parent = child.findParentOfDescendant(descendant);
196948
+ if (parent)
196949
+ return parent;
196950
+ }
196951
+ }
196952
+ return undefined;
196953
+ }
196954
+ ;
196941
196955
  }
196942
196956
  /**
196943
196957
  * Shared base class for use by both open and closed paths.
@@ -199942,6 +199956,7 @@ __webpack_require__.r(__webpack_exports__);
199942
199956
 
199943
199957
 
199944
199958
 
199959
+ // cspell:words CCWXY
199945
199960
  /**
199946
199961
  * A LineSegment3d is:
199947
199962
  * * A 3d line segment represented by its start and end coordinates
@@ -202915,11 +202930,12 @@ __webpack_require__.r(__webpack_exports__);
202915
202930
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
202916
202931
  /* harmony export */ ConsolidateAdjacentCurvePrimitivesContext: () => (/* binding */ ConsolidateAdjacentCurvePrimitivesContext)
202917
202932
  /* harmony export */ });
202933
+ /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
202918
202934
  /* harmony import */ var _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../geometry3d/GeometryHandler */ "../../core/geometry/lib/esm/geometry3d/GeometryHandler.js");
202919
- /* harmony import */ var _geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../geometry3d/PolylineCompressionByEdgeOffset */ "../../core/geometry/lib/esm/geometry3d/PolylineCompressionByEdgeOffset.js");
202935
+ /* harmony import */ var _geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../geometry3d/PolylineCompressionByEdgeOffset */ "../../core/geometry/lib/esm/geometry3d/PolylineCompressionByEdgeOffset.js");
202920
202936
  /* harmony import */ var _geometry3d_PolylineOps__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../geometry3d/PolylineOps */ "../../core/geometry/lib/esm/geometry3d/PolylineOps.js");
202921
- /* harmony import */ var _Arc3d__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Arc3d */ "../../core/geometry/lib/esm/curve/Arc3d.js");
202922
- /* harmony import */ var _CurveFactory__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../CurveFactory */ "../../core/geometry/lib/esm/curve/CurveFactory.js");
202937
+ /* harmony import */ var _Arc3d__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Arc3d */ "../../core/geometry/lib/esm/curve/Arc3d.js");
202938
+ /* harmony import */ var _CurveFactory__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../CurveFactory */ "../../core/geometry/lib/esm/curve/CurveFactory.js");
202923
202939
  /* harmony import */ var _LineSegment3d__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
202924
202940
  /* harmony import */ var _LineString3d__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
202925
202941
  /* harmony import */ var _RegionOps__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../RegionOps */ "../../core/geometry/lib/esm/curve/RegionOps.js");
@@ -202938,6 +202954,7 @@ __webpack_require__.r(__webpack_exports__);
202938
202954
 
202939
202955
 
202940
202956
 
202957
+
202941
202958
  /**
202942
202959
  * * Implementation class for ConsolidateAdjacentCurvePrimitives.
202943
202960
  *
@@ -202979,12 +202996,19 @@ class ConsolidateAdjacentCurvePrimitivesContext extends _geometry3d_GeometryHand
202979
202996
  break;
202980
202997
  }
202981
202998
  }
202982
- if (points.length > 1) {
202999
+ if (points.length <= 1) {
203000
+ g.children[numAccept++] = basePrimitive;
203001
+ }
203002
+ else if (this._options.disableLinearCompression) {
203003
+ const pointsDeduped = _geometry3d_PolylineOps__WEBPACK_IMPORTED_MODULE_4__.PolylineOps.compressShortEdges(points, _Geometry__WEBPACK_IMPORTED_MODULE_5__.Geometry.smallFloatingPoint); // remove only exact duplicate interior points
203004
+ g.children[numAccept++] = _LineString3d__WEBPACK_IMPORTED_MODULE_3__.LineString3d.createPoints(pointsDeduped);
203005
+ }
203006
+ else { // compress points
202983
203007
  const compressedPointsA = _geometry3d_PolylineOps__WEBPACK_IMPORTED_MODULE_4__.PolylineOps.compressShortEdges(points, this._options.duplicatePointTolerance);
202984
203008
  const compressedPointsB = _geometry3d_PolylineOps__WEBPACK_IMPORTED_MODULE_4__.PolylineOps.compressByPerpendicularDistance(compressedPointsA, this._options.colinearPointTolerance);
202985
203009
  if (i0 === 0 && i1 === numOriginal) {
202986
203010
  // points is the entire curve, and the curve is closed. Maybe the first and last segments are colinear.
202987
- _geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_5__.PolylineCompressionContext.compressColinearWrapInPlace(compressedPointsB, this._options.duplicatePointTolerance, this._options.colinearPointTolerance);
203011
+ _geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_6__.PolylineCompressionContext.compressColinearWrapInPlace(compressedPointsB, this._options.duplicatePointTolerance, this._options.colinearPointTolerance);
202988
203012
  }
202989
203013
  if (compressedPointsB.length < 2) {
202990
203014
  // Collapsed to a point? Make a single point linestring
@@ -202997,19 +203021,16 @@ class ConsolidateAdjacentCurvePrimitivesContext extends _geometry3d_GeometryHand
202997
203021
  g.children[numAccept++] = _LineString3d__WEBPACK_IMPORTED_MODULE_3__.LineString3d.createPoints(compressedPointsB);
202998
203022
  }
202999
203023
  }
203000
- else {
203001
- g.children[numAccept++] = basePrimitive;
203002
- }
203003
203024
  i0 = i1;
203004
203025
  }
203005
- else if (this._options.consolidateCompatibleArcs && basePrimitive instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_6__.Arc3d) {
203026
+ else if (this._options.consolidateCompatibleArcs && basePrimitive instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_7__.Arc3d) {
203006
203027
  // subsume subsequent arcs into basePrimitive.
203007
203028
  // always accept base primitive.
203008
203029
  for (; ++i0 < g.children.length;) {
203009
203030
  const nextPrimitive = g.children[i0];
203010
- if (!(nextPrimitive instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_6__.Arc3d))
203031
+ if (!(nextPrimitive instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_7__.Arc3d))
203011
203032
  break;
203012
- if (!_CurveFactory__WEBPACK_IMPORTED_MODULE_7__.CurveFactory.appendToArcInPlace(basePrimitive, nextPrimitive))
203033
+ if (!_CurveFactory__WEBPACK_IMPORTED_MODULE_8__.CurveFactory.appendToArcInPlace(basePrimitive, nextPrimitive)) // TODO: use this._options.duplicatePointTolerance
203013
203034
  break;
203014
203035
  }
203015
203036
  // i0 has already advanced
@@ -203512,13 +203533,18 @@ class MapCurvePrimitiveToCurveLocationDetailPairArray {
203512
203533
  if (primitiveB)
203513
203534
  this.insertPrimitiveToPair(primitiveB, pair);
203514
203535
  }
203515
- /** Split closed missing primitives in half and add new intersection pairs */
203536
+ /**
203537
+ * Split closed missing primitives in half and add new intersection pairs.
203538
+ * * When bridge edges aren't included in the primitives array, a closed primitive with no intersections will not be
203539
+ * added to the graph because it isn't in the `primitiveToPair` map. By splitting such a missing primitive in two, we
203540
+ * introduce two intersections for each half, which allows the primitive to be represented in the map.
203541
+ */
203516
203542
  splitAndAppendMissingClosedPrimitives(primitives, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
203517
203543
  for (const p of primitives) {
203518
203544
  let closedCurveSplitCandidate = false;
203519
203545
  if (p instanceof _Arc3d__WEBPACK_IMPORTED_MODULE_1__.Arc3d)
203520
203546
  closedCurveSplitCandidate = p.sweep.isFullCircle;
203521
- else if (!(p instanceof _LineSegment3d__WEBPACK_IMPORTED_MODULE_2__.LineSegment3d) && !(p instanceof _LineString3d__WEBPACK_IMPORTED_MODULE_3__.LineString3d))
203547
+ 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.
203522
203548
  closedCurveSplitCandidate = p.startPoint().isAlmostEqualXY(p.endPoint(), tolerance);
203523
203549
  if (closedCurveSplitCandidate && !this.primitiveToPair.has(p)) {
203524
203550
  const p0 = p.clonePartialCurve(0.0, 0.5);
@@ -204637,13 +204663,14 @@ var RegionBinaryOpType;
204637
204663
  })(RegionBinaryOpType || (RegionBinaryOpType = {}));
204638
204664
  /**
204639
204665
  * Class `RegionOps` has static members for calculations on regions (areas).
204640
- * * Regions are represented by these `CurveCollection` subclasses:
204641
- * * `Loop` -- a single loop
204642
- * * `ParityRegion` -- a collection of loops, interpreted by parity rules.
204643
- * The common "One outer loop and many Inner loops" is a parity region.
204644
- * * `UnionRegion` -- a collection of `Loop` and `ParityRegion` objects understood as a (probably disjoint) union.
204645
- * * **NOTE:** Most of the methods in this class ignore z-coordinates, so callers should ensure that input geometry has
204646
- * been rotated parallel to the xy-plane.
204666
+ * * Regions are represented by these [[CurveCollection]] subclasses:
204667
+ * * [[Loop]] -- a single loop
204668
+ * * [[ParityRegion]] -- a collection of loops, interpreted by parity rules.
204669
+ * The common "One outer loop and many inner loops" is a parity region.
204670
+ * * [[UnionRegion]] -- a collection of `Loop` and `ParityRegion` objects understood as a (probably disjoint) union.
204671
+ * * Most of the methods in this class:
204672
+ * * Ignore z-coordinates, so callers should ensure that input geometry has been rotated parallel to the xy-plane.
204673
+ * * Assume consistent Loop orientation: "solid" Loops are counterclockwise; "hole" Loops are clockwise.
204647
204674
  * @public
204648
204675
  */
204649
204676
  class RegionOps {
@@ -204674,8 +204701,15 @@ class RegionOps {
204674
204701
  }
204675
204702
  /**
204676
204703
  * Return a (signed) xy area for a region.
204704
+ <<<<<<< HEAD
204677
204705
  * * The area is negative if and only if the region is oriented clockwise with respect to the positive z-axis.
204678
204706
  * @param root any Loop, ParityRegion, or UnionRegion.
204707
+ =======
204708
+ * * The input region should lie in a plane parallel to the xy-plane, as z-coords will be ignored.
204709
+ * * For a non-self-intersecting Loop, the returned area is negative if and only if the Loop is oriented clockwise
204710
+ * with respect to the positive z-axis.
204711
+ * @param region any [[Loop]], [[ParityRegion]], or [[UnionRegion]].
204712
+ >>>>>>> 168574b454 (Utilize `PolyfaceData.edgeMateIndex` to speed up some `Polyface` methods (#8095))
204679
204713
  */
204680
204714
  static computeXYArea(root) {
204681
204715
  const handler = new _RegionMomentsXY__WEBPACK_IMPORTED_MODULE_0__.RegionMomentsXY();
@@ -204817,10 +204851,11 @@ class RegionOps {
204817
204851
  }
204818
204852
  /**
204819
204853
  * Return areas defined by a boolean operation.
204820
- * * If there are multiple regions in loopsA, they are treated as a union.
204821
- * * If there are multiple regions in loopsB, they are treated as a union.
204822
- * @param loopsA first set of loops
204823
- * @param loopsB second set of loops
204854
+ * @note For best results, input regions should have correctly oriented loops. See [[sortOuterAndHoleLoopsXY]].
204855
+ * @note A common use case of this method is to convert a region with overlapping children into one with
204856
+ * non-overlapping children: `regionOut = RegionOps.regionBooleanXY(regionIn, undefined, RegionBinaryOpType.Union)`.
204857
+ * @param loopsA first set of loops (treated as a union)
204858
+ * @param loopsB second set of loops (treated as a union)
204824
204859
  * @param operation indicates Union, Intersection, Parity, AMinusB, or BMinusA
204825
204860
  * @param mergeTolerance absolute distance tolerance for merging loops
204826
204861
  * @returns a region resulting from merging input loops and the boolean operation. May contain bridge edges added
@@ -205138,14 +205173,15 @@ class RegionOps {
205138
205173
  curves.dispatchToGeometryHandler(context);
205139
205174
  }
205140
205175
  /**
205141
- * Reverse and reorder loops in the xy-plane for consistency and containment.
205142
- * @param loops multiple loops in any order and orientation, z-coordinates ignored
205176
+ * Reverse and reorder loops in the xy-plane for consistent orientation and containment.
205177
+ * @param loops multiple loops in any order and orientation, z-coordinates ignored.
205178
+ * * For best results, all overlaps should be containments, i.e., loop boundaries can touch, but should not cross.
205143
205179
  * @returns a region that captures the input pointers. This region is a:
205144
- * * `Loop` if there is exactly one input loop. It is oriented counterclockwise.
205145
- * * `ParityRegion` if input consists of exactly one outer loop with at least one hole loop.
205180
+ * * [[Loop]] if there is exactly one input loop. It is oriented counterclockwise.
205181
+ * * [[ParityRegion]] if input consists of exactly one outer loop with at least one hole loop.
205146
205182
  * Its first child is an outer loop oriented counterclockwise; all subsequent children are holes oriented
205147
205183
  * clockwise.
205148
- * * `UnionRegion` if any other input configuration. Its children are individually ordered/oriented as in
205184
+ * * [[UnionRegion]] if any other input configuration. Its children are individually ordered/oriented as in
205149
205185
  * the above cases.
205150
205186
  * @see [[PolygonOps.sortOuterAndHoleLoopsXY]]
205151
205187
  */
@@ -205165,14 +205201,14 @@ class RegionOps {
205165
205201
  * Find all xy-areas bounded by the unstructured, possibly intersecting curves.
205166
205202
  * * For best results, input curves should be parallel to the xy-plane, as z-coordinates are ignored.
205167
205203
  * * A common use case of this method is to assemble the bounding "exterior" loop (or loops) containing the
205168
- * input curves.
205204
+ * input curves. Note that "holes" implied by inputs are _not_ preserved in output.
205169
205205
  * * This method does not add bridge edges to connect outer loops to inner loops. Each disconnected loop,
205170
205206
  * regardless of its containment, is returned as its own SignedLoops object. Pre-process with [[regionBooleanXY]]
205171
205207
  * to add bridge edges so that [[constructAllXYRegionLoops]] will return outer and inner loops in the same
205172
205208
  * SignedLoops object.
205173
205209
  * @param curvesAndRegions Any collection of curves. Each Loop/ParityRegion/UnionRegion contributes its curve
205174
- * primitives.
205175
- * @param tolerance optional distance tolerance for coincidence
205210
+ * primitives, stripped of parity context. This means holes are _not_ preserved in output.
205211
+ * @param tolerance optional distance tolerance for coincidence.
205176
205212
  * @returns array of [[SignedLoops]], each entry of which describes the faces in a single connected component:
205177
205213
  * * `positiveAreaLoops` contains "interior" loops, _including holes in ParityRegion input_. These loops have
205178
205214
  * positive area and counterclockwise orientation.
@@ -205335,12 +205371,10 @@ class RegionOps {
205335
205371
  }
205336
205372
  /**
205337
205373
  * Facet the region according to stroke options.
205374
+ * @note For best results, [[UnionRegion]] input should consist of non-overlapping children. See [[regionBooleanXY]].
205375
+ * @note For best results, [[ParityRegion]] input should be correctly oriented. See [[sortOuterAndHoleLoopsXY]].
205338
205376
  * @param region a closed xy-planar region, possibly with holes.
205339
205377
  * * The z-coordinates of the region are ignored. Caller is responsible for rotating the region into plane local coordinates beforehand, and reversing the rotation afterwards.
205340
- * * For best results, `UnionRegion` input should consist of non-overlapping children.
205341
- * Caller can ensure this by passing in `region = RegionOps.regionBooleanXY(unionRegion, undefined, RegionBinaryOpType.Union)`.
205342
- * * For best results, `ParityRegion` input should be correctly oriented (holes have opposite orientation to their containing loop).
205343
- * Caller can ensure this for non-intersecting loops by passing in `region = RegionOps.sortOuterAndHoleLoopsXY(loops)`.
205344
205378
  * @param options primarily how to stroke the region boundary, but also how to facet the region interior.
205345
205379
  * * By default, a triangulation is returned, but if `options.maximizeConvexFacets === true`, edges between coplanar triangles are removed to return maximally convex facets.
205346
205380
  * @returns facets for the region, or undefined if facetting failed
@@ -205403,17 +205437,19 @@ function pushToInOnOutArrays(curve, select, arrayNegative, array0, arrayPositive
205403
205437
  array0.push(curve);
205404
205438
  }
205405
205439
  /**
205406
- * * Options to control method `RegionOps.consolidateAdjacentPrimitives`
205440
+ * * Options to control method `RegionOps.consolidateAdjacentPrimitives`.
205407
205441
  * @public
205408
205442
  */
205409
205443
  class ConsolidateAdjacentCurvePrimitivesOptions {
205410
- /** True to consolidate adjacent linear geometry into a single LineString3d */
205444
+ /** True to consolidate adjacent linear geometry into a single LineString3d. */
205411
205445
  consolidateLinearGeometry = true;
205412
- /** True to consolidate contiguous compatible arcs into a single Arc3d */
205446
+ /** True to consolidate contiguous compatible arcs into a single Arc3d. */
205413
205447
  consolidateCompatibleArcs = true;
205414
- /** Tolerance for collapsing identical points */
205448
+ /** Disable LineSegment3d and LineString3d point compression. */
205449
+ disableLinearCompression = false;
205450
+ /** Tolerance for collapsing identical points (if `!disableLinearCompression`). */
205415
205451
  duplicatePointTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallMetricDistance;
205416
- /** Tolerance for removing interior colinear points. */
205452
+ /** Tolerance for removing interior colinear points (if `!disableLinearCompression`). */
205417
205453
  colinearPointTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallMetricDistance;
205418
205454
  }
205419
205455
 
@@ -216039,17 +216075,20 @@ __webpack_require__.r(__webpack_exports__);
216039
216075
  /**
216040
216076
  * An `AngleSweep` is a pair of angles at start and end of an interval.
216041
216077
  *
216042
- * * For stroking purposes, the "included interval" is all angles numerically reached
216043
- * by theta = start + f*(end-start), where f is between 0 and 1.
216044
- * * This stroking formula is simple numbers -- 2PI shifts are not involved.
216045
- * * 2PI shifts do become important in the reverse mapping of an angle to a fraction.
216046
- * * If "start < end" the angle proceeds CCW around the unit circle.
216047
- * * If "end < start" the angle proceeds CW around the unit circle.
216048
- * * Angles beyond 360 are fine as endpoints.
216049
- * * (350,370) covers the same unit angles as (-10,10).
216050
- * * (370,350) covers the same unit angles as (10,-10).
216051
- * * math details related fraction API can be found at docs/learning/geometry/Angle.md
216052
- * * Visualization can be found at https://www.itwinjs.org/sandbox/SaeedTorabi/AngleSweep
216078
+ * * For stroking purposes, the "included interval" is all angles numerically reached
216079
+ * by `theta = start + f * (end - start)`, where `0 <= f <= 1`.
216080
+ * * This stroking formula is simple numbers -- 2PI shifts are not involved.
216081
+ * * 2PI shifts do become important in the reverse mapping of an angle to a fraction.
216082
+ * * Angles greater than 360 and less than 0 are fine as endpoints.
216083
+ * * An AngleSweep determines orientation only _in concert with a reference vector_, e.g., a plane normal like (0,0,1).
216084
+ * * Be careful reading orientation from an AngleSweep without a reference vector!
216085
+ * * If "start < end" the angles in the sweep proceed counterclockwise around the reference vector.
216086
+ * * If "start > end" the angles in the sweep proceed clockwise around the reference vector.
216087
+ * * (350,370) covers the same angles as (-10,10), and both sweeps are counterclockwise around the reference vector.
216088
+ * * (370,350) covers the same angles as (10,-10), and both sweeps are clockwise around the reference vector.
216089
+ * * (370,350) covers the same angles as (-10,10), but the sweeps have opposite orientation.
216090
+ * * Math details can be found at docs/learning/geometry/Angle.md .
216091
+ * * Visualization can be found at https://www.itwinjs.org/sandbox/SaeedTorabi/AngleSweep .
216053
216092
  * @public
216054
216093
  */
216055
216094
  class AngleSweep {
@@ -221675,8 +221714,12 @@ class GrowableXYZArray extends _IndexedXYZCollection__WEBPACK_IMPORTED_MODULE_0_
221675
221714
  }
221676
221715
  }
221677
221716
  /** get range of points. */
221678
- getRange(transform) {
221679
- const range = _Range__WEBPACK_IMPORTED_MODULE_5__.Range3d.createNull();
221717
+ getRange(transform, result) {
221718
+ let range = result;
221719
+ if (range)
221720
+ range.setNull();
221721
+ else
221722
+ range = _Range__WEBPACK_IMPORTED_MODULE_5__.Range3d.createNull();
221680
221723
  this.extendRange(range, transform);
221681
221724
  return range;
221682
221725
  }
@@ -222029,6 +222072,20 @@ class GrowableXYZArray extends _IndexedXYZCollection__WEBPACK_IMPORTED_MODULE_0_
222029
222072
  this._data[i + componentIndex] = q;
222030
222073
  }
222031
222074
  }
222075
+ /**
222076
+ * Pass the (x,y,z) of each point to a function which returns a replacement for the point.
222077
+ * * @param func function to be called as `func(x,y,z)`, returning a replacement point.
222078
+ */
222079
+ mapPoint(func) {
222080
+ const n = this._data.length;
222081
+ let q;
222082
+ for (let i = 0; i + 2 < n; i += 3) {
222083
+ q = func(this._data[i], this._data[i + 1], this._data[i + 2]);
222084
+ this._data[i] = q.x;
222085
+ this._data[i + 1] = q.y;
222086
+ this._data[i + 2] = q.z;
222087
+ }
222088
+ }
222032
222089
  }
222033
222090
 
222034
222091
 
@@ -222364,13 +222421,17 @@ class IndexedXYZCollection {
222364
222421
  return (i % this.length);
222365
222422
  }
222366
222423
  /** Return the range of the points. */
222367
- getRange() {
222368
- const range = _Range__WEBPACK_IMPORTED_MODULE_2__.Range3d.createNull();
222424
+ getRange(transform, result) {
222425
+ let range = result;
222426
+ if (range)
222427
+ range.setNull();
222428
+ else
222429
+ range = _Range__WEBPACK_IMPORTED_MODULE_2__.Range3d.createNull();
222369
222430
  const n = this.length;
222370
222431
  const point = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
222371
222432
  for (let i = 0; i < n; i++) {
222372
222433
  this.getPoint3dAtUncheckedPointIndex(i, point);
222373
- range.extendPoint(point);
222434
+ range.extendPoint(point, transform);
222374
222435
  }
222375
222436
  return range;
222376
222437
  }
@@ -225845,7 +225906,12 @@ class Plane3d {
225845
225906
  * * Classes with a purely implicit equation of their plane can accept the default implementation
225846
225907
  */
225847
225908
  getAnyPointOnPlane(result) {
225848
- return this.projectPointToPlane(_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(0, 0, 0), result);
225909
+ return this.projectXYZToPlane(0, 0, 0, result);
225910
+ }
225911
+ /** Return the projection of (x,y,z) onto the plane. */
225912
+ projectXYZToPlane(x, y, z, result) {
225913
+ const point = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(x, y, z, result);
225914
+ return this.projectPointToPlane(point, point);
225849
225915
  }
225850
225916
  }
225851
225917
 
@@ -226190,7 +226256,12 @@ class Plane3dByOriginAndUnitNormal extends _Plane3d__WEBPACK_IMPORTED_MODULE_0__
226190
226256
  }
226191
226257
  /** Return the projection of spacePoint onto the plane. */
226192
226258
  projectPointToPlane(spacePoint, result) {
226193
- return spacePoint.plusScaled(this._normal, -this._normal.dotProductStartEnd(this._origin, spacePoint), result);
226259
+ return this.projectXYZToPlane(spacePoint.x, spacePoint.y, spacePoint.z, result);
226260
+ }
226261
+ /** Return the projection of (x,y,z) onto the plane. */
226262
+ projectXYZToPlane(x, y, z, result) {
226263
+ const scale = -this._normal.dotProductStartEndXYZ(this._origin, x, y, z);
226264
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(x + scale * this._normal.x, y + scale * this._normal.y, z + scale * this._normal.z, result);
226194
226265
  }
226195
226266
  /**
226196
226267
  * Returns true if spacePoint is within distance tolerance of the plane.
@@ -226573,30 +226644,38 @@ class Plane3dByOriginAndVectors extends _Plane3d__WEBPACK_IMPORTED_MODULE_0__.Pl
226573
226644
  }
226574
226645
  /**
226575
226646
  * Return the projection of spacePoint onto the plane.
226576
- * If the plane is degenerate to a ray, project to the ray.
226577
- * If the plane is degenerate to its origin, return the point
226647
+ * * If the plane is degenerate to a ray, project to the ray.
226648
+ * * If the plane is degenerate to its origin, return the point.
226578
226649
  */
226579
226650
  projectPointToPlane(spacePoint, result) {
226651
+ return this.projectXYZToPlane(spacePoint.x, spacePoint.y, spacePoint.z, result);
226652
+ }
226653
+ /**
226654
+ * Return the projection of (x,y,z) onto the plane.
226655
+ * * If the plane is degenerate to a ray, project to the ray.
226656
+ * * If the plane is degenerate to its origin, return the point.
226657
+ */
226658
+ projectXYZToPlane(x, y, z, result) {
226580
226659
  const unitNormal = this.vectorU.unitCrossProduct(this.vectorV);
226581
226660
  if (unitNormal !== undefined) {
226582
- const w = unitNormal.dotProductStartEnd(this.origin, spacePoint);
226583
- return spacePoint.plusScaled(unitNormal, -w, result);
226661
+ const scale = -unitNormal.dotProductStartEndXYZ(this.origin, x, y, z);
226662
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(x + scale * unitNormal.x, y + scale * unitNormal.y, z + scale * unitNormal.z, result);
226584
226663
  }
226585
- // uh oh. vectorU and vectorV are colinear or zero.
226586
- // project to ray defined by the longer one, or just to origin.
226664
+ // vectorU and vectorV are colinear or zero.
226665
+ // Project to ray defined by the longer one, or just to origin.
226587
226666
  const dotUU = this.vectorU.magnitudeSquared();
226588
226667
  const dotVV = this.vectorV.magnitudeSquared();
226589
226668
  if (dotUU >= dotVV) {
226590
- const dotUW = this.vectorU.dotProductStartEnd(this.origin, spacePoint);
226669
+ const dotUW = this.vectorU.dotProductStartEndXYZ(this.origin, x, y, z);
226591
226670
  const f = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.conditionalDivideCoordinate(dotUW, dotUU, 0.0);
226592
226671
  if (f !== undefined)
226593
- return spacePoint.plusScaled(this.vectorU, f, result);
226672
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(x + f * this.vectorU.x, y + f * this.vectorU.y, z + f * this.vectorU.z, result);
226594
226673
  }
226595
226674
  else {
226596
- const dotVW = this.vectorV.dotProductStartEnd(this.origin, spacePoint);
226675
+ const dotVW = this.vectorV.dotProductStartEndXYZ(this.origin, x, y, z);
226597
226676
  const f = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.conditionalDivideCoordinate(dotVW, dotVV, 0.0);
226598
226677
  if (f !== undefined)
226599
- return spacePoint.plusScaled(this.vectorV, f, result);
226678
+ return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(x + f * this.vectorV.x, y + f * this.vectorV.y, z + f * this.vectorV.z, result);
226600
226679
  }
226601
226680
  return this.origin.clone(result);
226602
226681
  }
@@ -229048,7 +229127,7 @@ class Vector3d extends XYZ {
229048
229127
  /**
229049
229128
  * Return the (strongly-typed) angle from this vector to vectorB, using only the xy parts.
229050
229129
  * * The returned angle is between -180 and 180 degrees.
229051
- * * Use `planarAngleTo` and `signedAngleTo` to return an angle measured in a specific plane.
229130
+ * * Use [[planarAngleTo]] and [[signedAngleTo]] to return an angle measured in a specific plane.
229052
229131
  * @param vectorB target vector.
229053
229132
  */
229054
229133
  angleToXY(vectorB) {
@@ -229061,7 +229140,7 @@ class Vector3d extends XYZ {
229061
229140
  * * If the cross product of `this` vector and `vectorB` lies on the same side of the plane as `vectorW`,
229062
229141
  * this function returns `radiansTo(vectorB)`; otherwise, it returns `-radiansTo(vectorB)`.
229063
229142
  * * `vectorW` does not have to be perpendicular to the plane.
229064
- * * Use `planarRadiansTo` to measure the angle between vectors that are projected to another plane.
229143
+ * * Use [[planarRadiansTo]] to measure the angle between vectors that are projected to another plane.
229065
229144
  * @param vectorB target vector.
229066
229145
  * @param vectorW determines the side of the plane in which the returned angle is measured
229067
229146
  */
@@ -229081,7 +229160,7 @@ class Vector3d extends XYZ {
229081
229160
  * * If the cross product of this vector and vectorB lies on the same side of the plane as vectorW,
229082
229161
  * this function returns `angleTo(vectorB)`; otherwise, it returns `-angleTo(vectorB)`.
229083
229162
  * * `vectorW` does not have to be perpendicular to the plane.
229084
- * * Use `planarAngleTo` to measure the angle between vectors that are projected to another plane.
229163
+ * * Use [[planarAngleTo]] to measure the angle between vectors that are projected to another plane.
229085
229164
  * @param vectorB target vector.
229086
229165
  * @param vectorW determines the side of the plane in which the returned angle is measured
229087
229166
  */
@@ -229344,9 +229423,9 @@ class NumberArray {
229344
229423
  return a;
229345
229424
  }
229346
229425
  /**
229347
- * Return an array with indicated start and end points, maximum step size internally
229348
- * @param low low value
229349
- * @param high high value
229426
+ * Return an array with indicated start and end points, and maximum step size.
229427
+ * @param low first value in returned array
229428
+ * @param high last value in returned array
229350
229429
  * @param step max permitted step
229351
229430
  */
229352
229431
  static createArrayWithMaxStepSize(low, high, step) {
@@ -229537,13 +229616,32 @@ class NumberArray {
229537
229616
  */
229538
229617
  class Point2dArray {
229539
229618
  /** Return true if arrays have same length and matching coordinates. */
229540
- static isAlmostEqual(dataA, dataB) {
229619
+ static isAlmostEqual(dataA, dataB, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
229541
229620
  if (dataA && dataB) {
229542
- if (dataA.length !== dataB.length)
229543
- return false;
229544
- for (let i = 0; i < dataA.length; i++) {
229545
- if (!dataA[i].isAlmostEqual(dataB[i]))
229621
+ if (dataA instanceof Float64Array && dataB instanceof Float64Array) {
229622
+ if (dataA.length !== dataB.length)
229623
+ return false;
229624
+ for (let i = 0; i < dataA.length; i++)
229625
+ if (!_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(dataA[i], dataB[i], tolerance))
229626
+ return false;
229627
+ }
229628
+ else if (Array.isArray(dataA) && Array.isArray(dataB)) {
229629
+ if (dataA.length !== dataB.length)
229546
229630
  return false;
229631
+ for (let i = 0; i < dataA.length; i++)
229632
+ if (!dataA[i].isAlmostEqual(dataB[i], tolerance))
229633
+ return false;
229634
+ }
229635
+ else { // different types
229636
+ const points = dataA instanceof Float64Array ? dataB : dataA;
229637
+ const numbers = dataA instanceof Float64Array ? dataA : dataB;
229638
+ if (numbers.length !== points.length * 2)
229639
+ return false;
229640
+ for (let iPoint = 0; iPoint < points.length; ++iPoint) {
229641
+ if (!_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(points[iPoint].x, numbers[2 * iPoint], tolerance) ||
229642
+ !_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(points[iPoint].y, numbers[2 * iPoint + 1], tolerance))
229643
+ return false;
229644
+ }
229547
229645
  }
229548
229646
  return true;
229549
229647
  }
@@ -229580,13 +229678,34 @@ class Point2dArray {
229580
229678
  */
229581
229679
  class Vector3dArray {
229582
229680
  /** Return true if arrays have same length and matching coordinates. */
229583
- static isAlmostEqual(dataA, dataB) {
229681
+ static isAlmostEqual(dataA, dataB, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
229584
229682
  if (dataA && dataB) {
229585
- if (dataA.length !== dataB.length)
229586
- return false;
229587
- for (let i = 0; i < dataA.length; i++)
229588
- if (!dataA[i].isAlmostEqual(dataB[i]))
229683
+ if (dataA instanceof Float64Array && dataB instanceof Float64Array) {
229684
+ if (dataA.length !== dataB.length)
229685
+ return false;
229686
+ for (let i = 0; i < dataA.length; i++)
229687
+ if (!_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(dataA[i], dataB[i], tolerance))
229688
+ return false;
229689
+ }
229690
+ else if (Array.isArray(dataA) && Array.isArray(dataB)) {
229691
+ if (dataA.length !== dataB.length)
229692
+ return false;
229693
+ for (let i = 0; i < dataA.length; i++)
229694
+ if (!dataA[i].isAlmostEqual(dataB[i], tolerance))
229695
+ return false;
229696
+ }
229697
+ else { // different types
229698
+ const points = dataA instanceof Float64Array ? dataB : dataA;
229699
+ const numbers = dataA instanceof Float64Array ? dataA : dataB;
229700
+ if (numbers.length !== points.length * 3)
229589
229701
  return false;
229702
+ for (let iPoint = 0; iPoint < points.length; ++iPoint) {
229703
+ if (!_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(points[iPoint].x, numbers[3 * iPoint], tolerance) ||
229704
+ !_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(points[iPoint].y, numbers[3 * iPoint + 1], tolerance) ||
229705
+ !_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(points[iPoint].z, numbers[3 * iPoint + 2], tolerance))
229706
+ return false;
229707
+ }
229708
+ }
229590
229709
  return true;
229591
229710
  }
229592
229711
  return (dataA === undefined && dataB === undefined);
@@ -229705,20 +229824,20 @@ class Point4dArray {
229705
229824
  }
229706
229825
  }
229707
229826
  /** Test arrays for near equality of all corresponding numeric values, treated as coordinates. */
229708
- static isAlmostEqual(dataA, dataB) {
229827
+ static isAlmostEqual(dataA, dataB, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
229709
229828
  if (dataA && dataB) {
229710
229829
  if (dataA instanceof Float64Array && dataB instanceof Float64Array) {
229711
229830
  if (dataA.length !== dataB.length)
229712
229831
  return false;
229713
229832
  for (let i = 0; i < dataA.length; i++)
229714
- if (!_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(dataA[i], dataB[i]))
229833
+ if (!_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(dataA[i], dataB[i], tolerance))
229715
229834
  return false;
229716
229835
  }
229717
229836
  else if (Array.isArray(dataA) && Array.isArray(dataB)) {
229718
229837
  if (dataA.length !== dataB.length)
229719
229838
  return false;
229720
229839
  for (let i = 0; i < dataA.length; i++)
229721
- if (!dataA[i].isAlmostEqual(dataB[i]))
229840
+ if (!dataA[i].isAlmostEqual(dataB[i], tolerance))
229722
229841
  return false;
229723
229842
  }
229724
229843
  else { // different types
@@ -229727,10 +229846,10 @@ class Point4dArray {
229727
229846
  if (numbers.length !== points.length * 4)
229728
229847
  return false;
229729
229848
  for (let iPoint = 0; iPoint < points.length; ++iPoint) {
229730
- if (!_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(points[iPoint].x, numbers[4 * iPoint]) ||
229731
- !_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(points[iPoint].y, numbers[4 * iPoint + 1]) ||
229732
- !_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(points[iPoint].z, numbers[4 * iPoint + 2]) ||
229733
- !_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(points[iPoint].w, numbers[4 * iPoint + 3]))
229849
+ if (!_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(points[iPoint].x, numbers[4 * iPoint], tolerance) ||
229850
+ !_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(points[iPoint].y, numbers[4 * iPoint + 1], tolerance) ||
229851
+ !_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(points[iPoint].z, numbers[4 * iPoint + 2], tolerance) ||
229852
+ !_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(points[iPoint].w, numbers[4 * iPoint + 3], tolerance))
229734
229853
  return false;
229735
229854
  }
229736
229855
  }
@@ -229970,20 +230089,20 @@ class Point3dArray {
229970
230089
  }
229971
230090
  }
229972
230091
  /** Test arrays for near equality of all corresponding numeric values, treated as coordinates. */
229973
- static isAlmostEqual(dataA, dataB) {
230092
+ static isAlmostEqual(dataA, dataB, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
229974
230093
  if (dataA && dataB) {
229975
230094
  if (dataA instanceof Float64Array && dataB instanceof Float64Array) {
229976
230095
  if (dataA.length !== dataB.length)
229977
230096
  return false;
229978
230097
  for (let i = 0; i < dataA.length; i++)
229979
- if (!_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(dataA[i], dataB[i]))
230098
+ if (!_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(dataA[i], dataB[i], tolerance))
229980
230099
  return false;
229981
230100
  }
229982
230101
  else if (Array.isArray(dataA) && Array.isArray(dataB)) {
229983
230102
  if (dataA.length !== dataB.length)
229984
230103
  return false;
229985
230104
  for (let i = 0; i < dataA.length; i++)
229986
- if (!dataA[i].isAlmostEqual(dataB[i]))
230105
+ if (!dataA[i].isAlmostEqual(dataB[i], tolerance))
229987
230106
  return false;
229988
230107
  }
229989
230108
  else { // different types
@@ -229992,9 +230111,9 @@ class Point3dArray {
229992
230111
  if (numbers.length !== points.length * 3)
229993
230112
  return false;
229994
230113
  for (let iPoint = 0; iPoint < points.length; ++iPoint) {
229995
- if (!_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(points[iPoint].x, numbers[3 * iPoint]) ||
229996
- !_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(points[iPoint].y, numbers[3 * iPoint + 1]) ||
229997
- !_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(points[iPoint].z, numbers[3 * iPoint + 2]))
230114
+ if (!_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(points[iPoint].x, numbers[3 * iPoint], tolerance) ||
230115
+ !_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(points[iPoint].y, numbers[3 * iPoint + 1], tolerance) ||
230116
+ !_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSameCoordinate(points[iPoint].z, numbers[3 * iPoint + 2], tolerance))
229998
230117
  return false;
229999
230118
  }
230000
230119
  }
@@ -231292,6 +231411,41 @@ class PolygonOps {
231292
231411
  }
231293
231412
  }
231294
231413
  }
231414
+ /**
231415
+ * Compute the signed volume of the truncated prism between a facet and a plane.
231416
+ * * Useful for parallel algorithms.
231417
+ * @param facetPoints input 3D polygon; on return the points are projected onto the plane. Wraparound point is optional.
231418
+ * @param plane infinite plane bounding volume between the facet and (virtual) side facets perpendicular to the plane (unmodified).
231419
+ * @param options optional flags and pre-allocated temporary storage.
231420
+ * @returns computed data for this facet:
231421
+ * * `volume6`: six times the signed volume of the truncated prism between the facet and the plane.
231422
+ * * `area2`: two times the signed area of the facet's projection onto the plane.
231423
+ * * `origin`: origin of the facet used to accumulate area moments.
231424
+ * * `products`: raw accumulated second moment area products of the facet's projection onto the plane.
231425
+ * @see [[PolyfaceQuery.sumVolumeBetweenFacetsAndPlane]]
231426
+ */
231427
+ static volumeBetweenPolygonAndPlane(facetPoints, plane, options) {
231428
+ let origin;
231429
+ let products;
231430
+ let singleProjectedFacetAreaTimes2 = 0.0;
231431
+ let signedTruncatedPrismVolumeTimes6 = 0.0;
231432
+ const h0 = facetPoints.evaluateUncheckedIndexPlaneAltitude(0, plane);
231433
+ for (let i = 1; i + 1 < facetPoints.length; i++) {
231434
+ const triangleNormal = facetPoints.crossProductIndexIndexIndex(0, i, i + 1, options?.workVector);
231435
+ const hA = facetPoints.evaluateUncheckedIndexPlaneAltitude(i, plane);
231436
+ const hB = facetPoints.evaluateUncheckedIndexPlaneAltitude(i + 1, plane);
231437
+ const signedProjectedTriangleAreaTimes2 = triangleNormal.dotProductXYZ(plane.normalX(), plane.normalY(), plane.normalZ());
231438
+ singleProjectedFacetAreaTimes2 += signedProjectedTriangleAreaTimes2;
231439
+ signedTruncatedPrismVolumeTimes6 += signedProjectedTriangleAreaTimes2 * (h0 + hA + hB);
231440
+ }
231441
+ if (!options?.skipMoments) {
231442
+ origin = facetPoints.getPoint3dAtUncheckedPointIndex(0, options?.workPoint0);
231443
+ products = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_4__.Matrix4d.createZero(options?.workMatrix);
231444
+ facetPoints.mapPoint((x, y, z) => plane.projectXYZToPlane(x, y, z, options?.workPoint1));
231445
+ PolygonOps.addSecondMomentAreaProducts(facetPoints, origin, products);
231446
+ }
231447
+ return { volume6: signedTruncatedPrismVolumeTimes6, area2: singleProjectedFacetAreaTimes2, origin, products };
231448
+ }
231295
231449
  /** Test the direction of turn at the vertices of the polygon, ignoring z-coordinates.
231296
231450
  * * For a polygon without self-intersections and successive colinear edges, this is a convexity and orientation test: all positive is convex and counterclockwise, all negative is convex and clockwise.
231297
231451
  * * Beware that a polygon which turns through more than a full turn can cross itself and close, but is not convex.
@@ -231445,8 +231599,9 @@ class PolygonOps {
231445
231599
  return numReverse;
231446
231600
  }
231447
231601
  /**
231448
- * Reverse and reorder loops in the xy-plane for consistency and containment.
231449
- * @param loops multiple polygons in any order and orientation, z-coordinates ignored
231602
+ * Reverse and reorder loops in the xy-plane for consistent orientation and containment.
231603
+ * @param loops multiple polygons in any order and orientation, z-coordinates ignored.
231604
+ * * For best results, all overlaps should be containments, i.e., loop boundaries can touch, but should not cross.
231450
231605
  * @returns array of arrays of polygons that capture the input pointers. In each first level array:
231451
231606
  * * The first polygon is an outer loop, oriented counterclockwise.
231452
231607
  * * Any subsequent polygons are holes of the outer loop, oriented clockwise.
@@ -232489,17 +232644,21 @@ class PolylineCompressionContext {
232489
232644
  context.acceptPointByIndex(indexA);
232490
232645
  context.recursiveCompressByChordErrorGo(indexA, indexB);
232491
232646
  }
232492
- /** Copy points from source to dest, omitting those too close to predecessor.
232493
- * * First and last points are always preserved.
232647
+ /**
232648
+ * Return a simplified subset of given points, omitting a point if very close to its predecessor.
232649
+ * * This is a local search, with a single pass over the data.
232650
+ * * First and last points are always retained.
232651
+ * @param data input points
232652
+ * @param maxEdgeLength length of largest edge to be compressed out
232494
232653
  */
232495
- static compressInPlaceByShortEdgeLength(data, edgeLength) {
232654
+ static compressInPlaceByShortEdgeLength(data, maxEdgeLength) {
232496
232655
  const n = data.length;
232497
232656
  if (n < 2)
232498
232657
  return;
232499
232658
  let lastAcceptedIndex = 0;
232500
232659
  // back up from final point ..
232501
232660
  let indexB = n - 1;
232502
- while (indexB > 0 && data.distanceIndexIndex(indexB - 1, n - 1) < edgeLength)
232661
+ while (indexB > 0 && data.distanceIndexIndex(indexB - 1, n - 1) <= maxEdgeLength)
232503
232662
  indexB--;
232504
232663
  if (indexB === 0) {
232505
232664
  // Theres only one point there.
@@ -232512,7 +232671,7 @@ class PolylineCompressionContext {
232512
232671
  let candidateIndex = lastAcceptedIndex + 1;
232513
232672
  while (candidateIndex <= indexB) {
232514
232673
  const d = data.distanceIndexIndex(lastAcceptedIndex, candidateIndex);
232515
- if (d >= edgeLength) {
232674
+ if (d > maxEdgeLength) {
232516
232675
  data.moveIndexToIndex(candidateIndex, lastAcceptedIndex + 1);
232517
232676
  lastAcceptedIndex++;
232518
232677
  }
@@ -232520,10 +232679,13 @@ class PolylineCompressionContext {
232520
232679
  }
232521
232680
  data.length = lastAcceptedIndex + 1;
232522
232681
  }
232523
- /** Copy points from source to dest, omitting those too close to predecessor.
232524
- * * First and last points are always preserved.
232682
+ /**
232683
+ * Return a simplified subset of given points, omitting the middle of three successive points if the triangle they form is small.
232684
+ * * This is a local search, with a single pass over the data.
232685
+ * @param data input points
232686
+ * @param maxTriangleArea area of largest triangle to compress
232525
232687
  */
232526
- static compressInPlaceBySmallTriangleArea(data, triangleArea) {
232688
+ static compressInPlaceBySmallTriangleArea(data, maxTriangleArea) {
232527
232689
  const n = data.length;
232528
232690
  if (n < 3)
232529
232691
  return;
@@ -232531,7 +232693,7 @@ class PolylineCompressionContext {
232531
232693
  const cross = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create();
232532
232694
  for (let i1 = 1; i1 + 1 < n; i1++) {
232533
232695
  data.crossProductIndexIndexIndex(lastAcceptedIndex, i1, i1 + 1, cross);
232534
- if (0.5 * cross.magnitude() > triangleArea) {
232696
+ if (0.5 * cross.magnitude() > maxTriangleArea) {
232535
232697
  data.moveIndexToIndex(i1, ++lastAcceptedIndex);
232536
232698
  }
232537
232699
  }
@@ -232672,10 +232834,11 @@ class PolylineOps {
232672
232834
  return _PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_1__.PolylineCompressionContext.compressPoint3dArrayByChordError(source, chordTolerance);
232673
232835
  }
232674
232836
  /**
232675
- * Return a simplified subset of given points, omitting points if very close to their neighbors.
232837
+ * Return a simplified subset of given points, omitting a point if very close to its predecessor.
232676
232838
  * * This is a local search, with a single pass over the data.
232839
+ * * First and last points are always retained.
232677
232840
  * @param source input points
232678
- * @param maxEdgeLength
232841
+ * @param maxEdgeLength length of largest edge to be compressed out
232679
232842
  * @see [[GrowableXYZArray.cloneCompressed]]
232680
232843
  */
232681
232844
  static compressShortEdges(source, maxEdgeLength) {
@@ -232684,10 +232847,10 @@ class PolylineOps {
232684
232847
  return dest.getPoint3dArray();
232685
232848
  }
232686
232849
  /**
232687
- * Return a simplified subset of given points, omitting points of the triangle with adjacent points is small.
232850
+ * Return a simplified subset of given points, omitting the middle of three successive points if the triangle they form is small.
232688
232851
  * * This is a local search, with a single pass over the data.
232689
232852
  * @param source input points
232690
- * @param maxEdgeLength
232853
+ * @param maxTriangleArea area of largest triangle to compress
232691
232854
  */
232692
232855
  static compressSmallTriangles(source, maxTriangleArea) {
232693
232856
  const dest = _GrowableXYZArray__WEBPACK_IMPORTED_MODULE_2__.GrowableXYZArray.create(source);
@@ -235186,41 +235349,29 @@ class Ray3d {
235186
235349
  */
235187
235350
  intersectionWithTriangle(vertex0, vertex1, vertex2, distanceTol, parameterTol, result) {
235188
235351
  /**
235189
- * Suppose ray is shown by "rayOrigin + t*rayVector" and barycentric coordinate of point
235352
+ * Let (w,u,v) be the barycentric coordinates of point P wrt the triangle (v0,v1,v2), such that
235190
235353
  * P = w*v0 + u*v1 + v*v2 = (1-u-v)*v0 + u*v1 + v*v2 = v0 + u*(v1-v0) + v*(v2-v0)
235191
235354
  *
235192
- * Then if ray intersects triangle at a point we have
235355
+ * Then if the ray given by rayOrigin + t*rayVector intersects the triangle at P, we have
235193
235356
  * v0 + u*(v1-v0) + v*(v2-v0) = rayOrigin + t*rayVector
235194
- * or
235195
- * -t*rayVector + u*(v1-v0) + v*(v2-v0) = rayOrigin - v0
235196
235357
  *
235197
235358
  * This equation can be reformulated as the following linear system:
235198
235359
  *
235199
235360
  * [ | | | ] [t] [ | ]
235200
235361
  * [-rayVector v1-v0 v2-v0] [u] = [rayOrigin - v0]
235201
- * [ | | | ] [v] [ | ]
235202
- *
235203
- * Then to find t, u, and v use Cramer's Rule and also the fact that if matrix A = [c1,c2,c3], then
235204
- * det(A) = c1.(c2 x c3) which leads to
235205
- *
235206
- * t = [(rayOrigin - v0).((v1-v0) x (v2-v0))] / [-rayVector.((v1-v0) x (v2-v0))]
235207
- * u = [-rayVector.((rayOrigin - v0) x (v2-v0))] / [-rayVector.((v1-v0) x (v2-v0))]
235208
- * v = [-rayVector.((v1-v0) x (rayOrigin - v0))] / [-rayVector.((v1-v0) x (v2-v0))]
235362
+ * [ | | | ] [v] [ | ]
235209
235363
  *
235210
- * Now note that swapping any 2 vectors c_i and c_j in formula c1.(c2 x c3) negates it. For example:
235211
- * c1.(c2 x c3) = -c3.(c2 x c1) = c2.(c3 x c1)
235364
+ * Then to find t, u, and v, use Cramer's Rule, the formulation of matrix determinant as column triple product,
235365
+ * and the fact that swapping any 2 vectors in the triple product negates it:
235212
235366
  *
235213
- * This leads to the final formulas used in the following code:
235214
- * t = [(v2-v0).((rayOrigin - v0) x (v1-v0))] / [(v1-v0).(rayVector x (v2-v0))]
235215
- * u = [(rayOrigin - v0).(rayVector x (v2-v0))] / [(v1-v0).(rayVector x (v2-v0))]
235216
- * v = [-rayVector.((rayOrigin - v0) x (v1-v0))] / [(v1-v0).(rayVector x (v2-v0))]
235367
+ * t = (v2-v0).(rayOrigin - v0) x (v1-v0) / (v1-v0).rayVector x (v2-v0)
235368
+ * u = (rayOrigin - v0).rayVector x (v2-v0) / (v1-v0).rayVector x (v2-v0)
235369
+ * v = -rayVector.(rayOrigin - v0) x (v1-v0) / (v1-v0).rayVector x (v2-v0)
235217
235370
  *
235218
- * Note that we should verify 0 <= u,v,w <= 1. To do so we only need to check 0 <= u <= 1, 0 <= v, and u+v <= 1.
235219
- * That's because w = 1-(u+v) and if we have those 4 checks, it's guaranteed that v <= 1 and 0 <= u+v and so
235220
- * 0 <= w <= 1.
235371
+ * Note that we verify 0 <= u,v,w <= 1. To do so we only need to check 0 <= u <= 1, 0 <= v, and u+v <= 1:
235372
+ * these 4 checks guarantee that v <= 1 and 0 <= u+v, and so with w = 1-(u+v), we have 0 <= w <= 1.
235221
235373
  *
235222
- * More info be found at
235223
- * https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
235374
+ * More info be found at https://en.wikipedia.org/wiki/Moller-Trumbore_intersection_algorithm.
235224
235375
  */
235225
235376
  if (distanceTol === undefined || distanceTol < 0) // we explicitly allow zero tolerance
235226
235377
  distanceTol = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance;
@@ -236263,27 +236414,46 @@ class Transform {
236263
236414
  return result;
236264
236415
  }
236265
236416
  /**
236266
- * Create a Transform such that its `matrix` part is rigid.
236267
- * @see [[Matrix3d.createRigidFromColumns]] for details of how the matrix is created to be rigid.
236417
+ * Create a Transform with given origin and a rigid matrix constructed from two column vectors.
236418
+ * @param origin origin of the local coordinate system. Default is the global origin (zero).
236419
+ * @param vectorX first axis passed into `Matrix3d.createRigidFromColumns`.
236420
+ * @param vectorY second axis passed into `Matrix3d.createRigidFromColumns`.
236421
+ * @param axisOrder order of axis construction in `Matrix3d.createRigidFromColumns(vectorX, vectorY, axisOrder)`.
236422
+ * @param result optional pre-allocated result to populate and return.
236423
+ * @returns localToWorld transform for a local coordinate system with given origin and ordered axes, or `undefined`
236424
+ * if the rigid matrix could not be created.
236425
+ * @see [[Matrix3d.createRigidFromColumns]]
236268
236426
  */
236269
236427
  static createRigidFromOriginAndColumns(origin, vectorX, vectorY, axisOrder, result) {
236270
- const matrix = _Matrix3d__WEBPACK_IMPORTED_MODULE_2__.Matrix3d.createRigidFromColumns(vectorX, vectorY, axisOrder, result ? result._matrix : undefined);
236428
+ const matrix = _Matrix3d__WEBPACK_IMPORTED_MODULE_2__.Matrix3d.createRigidFromColumns(vectorX, vectorY, axisOrder, result?._matrix);
236271
236429
  if (!matrix)
236272
236430
  return undefined;
236273
236431
  if (result) {
236274
- // result._matrix was already modified to become rigid via createRigidFromColumns
236275
236432
  result._origin.setFrom(origin);
236276
236433
  return result;
236277
236434
  }
236278
- /**
236279
- * We don't want to pass "origin" to createRefs because createRefs does not clone "origin". That means if "origin"
236280
- * is changed via Transform at any point, the initial "origin" passed by the user is also changed. To avoid that,
236281
- * we pass "undefined" to createRefs so that it allocates a new point which then we set it to the "origin" which
236282
- * is passed by user in the next line.
236283
- */
236284
- result = Transform.createRefs(undefined, matrix);
236285
- result._origin.setFromPoint3d(origin);
236286
- return result;
236435
+ return Transform.createRefs(origin?.cloneAsPoint3d(), matrix);
236436
+ }
236437
+ /**
236438
+ * Create a Transform with given origin and a rigid matrix constructed from one column vector.
236439
+ * @param origin origin of the local coordinate system. Default is the global origin (zero).
236440
+ * @param vector direction of the axis of the local coordinate system indicated by the first letter of `axisOrder`.
236441
+ * @param axisOrder order of axis construction in `Matrix3d.createRigidHeadsUp(vector, axisOrder)`. Default value
236442
+ * is `AxisOrder.ZXY`, which means the z-column of the returned Transform is in the direction of `vector`.
236443
+ * @param result optional pre-allocated result to populate and return.
236444
+ * @returns localToWorld transform for a local coordinate system with given origin and axis, or `undefined`
236445
+ * if the rigid matrix could not be created.
236446
+ * @see [[Matrix3d.createRigidHeadsUp]]
236447
+ */
236448
+ static createRigidFromOriginAndVector(origin, vector, axisOrder = _Geometry__WEBPACK_IMPORTED_MODULE_0__.AxisOrder.ZXY, result) {
236449
+ const matrix = _Matrix3d__WEBPACK_IMPORTED_MODULE_2__.Matrix3d.createRigidHeadsUp(vector, axisOrder, result?._matrix);
236450
+ if (!matrix)
236451
+ return undefined;
236452
+ if (result) {
236453
+ result._origin.setFrom(origin);
236454
+ return result;
236455
+ }
236456
+ return Transform.createRefs(origin?.cloneAsPoint3d(), matrix);
236287
236457
  }
236288
236458
  /**
236289
236459
  * Create a Transform with the specified `matrix`. Compute an `origin` (different from the given `fixedPoint`)
@@ -238840,11 +239010,11 @@ class Point4d extends _geometry3d_Plane3d__WEBPACK_IMPORTED_MODULE_0__.Plane3d {
238840
239010
  return result;
238841
239011
  }
238842
239012
  /** Near-equality test, using `Geometry.isSameCoordinate` on all 4 x,y,z,w */
238843
- isAlmostEqual(other) {
238844
- return _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.x, other.x)
238845
- && _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.y, other.y)
238846
- && _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.z, other.z)
238847
- && _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.w, other.w);
239013
+ isAlmostEqual(other, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance) {
239014
+ return _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.x, other.x, tolerance)
239015
+ && _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.y, other.y, tolerance)
239016
+ && _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.z, other.z, tolerance)
239017
+ && _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.w, other.w, tolerance);
238848
239018
  }
238849
239019
  /**
238850
239020
  * Test for same coordinate by direct x,y,z,w args
@@ -238853,11 +239023,11 @@ class Point4d extends _geometry3d_Plane3d__WEBPACK_IMPORTED_MODULE_0__.Plane3d {
238853
239023
  * @param z z to test
238854
239024
  * @param w w to test
238855
239025
  */
238856
- isAlmostEqualXYZW(x, y, z, w) {
238857
- return _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.x, x)
238858
- && _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.y, y)
238859
- && _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.z, z)
238860
- && _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.w, w);
239026
+ isAlmostEqualXYZW(x, y, z, w, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance) {
239027
+ return _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.x, x, tolerance)
239028
+ && _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.y, y, tolerance)
239029
+ && _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.z, z, tolerance)
239030
+ && _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSameCoordinate(this.w, w, tolerance);
238861
239031
  }
238862
239032
  /**
238863
239033
  * Convert an Angle to a JSON object.
@@ -239092,13 +239262,17 @@ class Point4d extends _geometry3d_Plane3d__WEBPACK_IMPORTED_MODULE_0__.Plane3d {
239092
239262
  * * If the xyz part of `this` are all zero, (a clone of) `spacePoint` is returned.
239093
239263
  */
239094
239264
  projectPointToPlane(spacePoint, result) {
239095
- const h = this.altitude(spacePoint);
239265
+ return this.projectXYZToPlane(spacePoint.x, spacePoint.y, spacePoint.z, result);
239266
+ }
239267
+ /** Return the projection of (x,y,z) onto the plane. */
239268
+ projectXYZToPlane(x, y, z, result) {
239269
+ const h = this.altitudeXYZ(x, y, z);
239096
239270
  const nn = this.magnitudeSquaredXYZ();
239097
239271
  // this unusual tol is needed so that toPlane3dByOriginAndUnitNormal agrees with its original implementation
239098
239272
  const alpha = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.conditionalDivideCoordinate(-h, nn, _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.largeFractionResult * _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.largeFractionResult);
239099
239273
  if (alpha === undefined)
239100
- return spacePoint.clone(result);
239101
- return spacePoint.plusXYZ(alpha * this.x, alpha * this.y, alpha * this.z, result);
239274
+ return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(x, y, z, result);
239275
+ return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(x + alpha * this.x, y + alpha * this.y, z + alpha * this.z, result);
239102
239276
  }
239103
239277
  /** scale all components (including w!!) */
239104
239278
  scale(scale, result) {
@@ -246348,7 +246522,7 @@ class FacetOrientationFixup {
246348
246522
  return this._facetOrientation[facetIndex];
246349
246523
  }
246350
246524
  /**
246351
- * RETURN FALSE IF ANY EDGE HAS 3 ORE MORE FACETS
246525
+ * RETURN FALSE IF ANY EDGE HAS 3 OR MORE FACETS
246352
246526
  */
246353
246527
  setupUnoriented() {
246354
246528
  this._edges.sort();
@@ -246806,97 +246980,107 @@ __webpack_require__.r(__webpack_exports__);
246806
246980
  * @module Polyface
246807
246981
  */
246808
246982
  /**
246809
- * * For boundary sorting, an edge is a (packed!) Float64Array.
246810
- * * Fixed entry positions are:
246811
- * * [0] is start vertex index (in CCW order around its facet)
246812
- * * [1] is end vertex index (in CCW order around its facet)
246813
- * * [2] is facet index (or another number to associate with this edge).
246983
+ * Represent an [[IndexedPolyface]] edge as:
246984
+ * * vertex start index and vertex end index (CCW order around its facet)
246985
+ * * an additional number to associate with the edge (e.g., facet index)
246986
+ * @public
246814
246987
  */
246815
- class SortableEdge extends Float64Array {
246988
+ class SortableEdge {
246989
+ _v;
246990
+ _a;
246991
+ /** Constructor. */
246992
+ constructor(startVertex, endVertex, facetIndex) {
246993
+ this._v = [startVertex, endVertex];
246994
+ this._a = facetIndex;
246995
+ }
246996
+ /** Clone the edge. */
246997
+ clone() {
246998
+ return new SortableEdge(this._v[0], this._v[1], this._a);
246999
+ }
246816
247000
  /** Return the vertex index that appears first in the order stored. */
246817
- get vertexIndexA() {
246818
- return this[0];
247001
+ get startVertex() {
247002
+ return this._v[0];
246819
247003
  }
246820
247004
  /** Return the vertex index that appears second in the order stored. */
246821
- get vertexIndexB() {
246822
- return this[1];
247005
+ get endVertex() {
247006
+ return this._v[1];
246823
247007
  }
246824
247008
  /**
246825
247009
  * Return the facet index.
246826
247010
  * * This value is carried along during matching. Typically it is a facet index, but it does not have to be.
246827
247011
  */
246828
247012
  get facetIndex() {
246829
- return this[2];
247013
+ return this._a;
246830
247014
  }
246831
- /** return true if vertexIndexA is less than vertexIndexB. */
247015
+ /** return true if `startVertex` is less than `endVertex`. */
246832
247016
  get isLowHigh() {
246833
- return this[0] < this[1];
247017
+ return this._v[0] < this._v[1];
246834
247018
  }
246835
247019
  /** Return the vertex index with lower numeric value. */
246836
- get lowVertexIndex() {
246837
- return this[0] < this[1] ? this[0] : this[1];
247020
+ get lowVertex() {
247021
+ return this.isLowHigh ? this._v[0] : this._v[1];
246838
247022
  }
246839
247023
  /** Return the vertex index with higher numeric value. */
246840
- get highVertexIndex() {
246841
- return this[0] > this[1] ? this[0] : this[1];
247024
+ get highVertex() {
247025
+ return this.isLowHigh ? this._v[1] : this._v[0];
246842
247026
  }
246843
- /** Return true if the vertices edgeA and edgeB are the same vertex indices in opposite order. */
247027
+ /** Return true if edgeA and edgeB traverse the same edge in the same direction. */
247028
+ static areSameEdge(edgeA, edgeB) {
247029
+ return edgeA._v[0] === edgeB._v[0] && edgeA._v[1] === edgeB._v[1];
247030
+ }
247031
+ /** Return true if edgeA and edgeB traverse the same edge in opposite directions. */
246844
247032
  static areDirectedPartners(edgeA, edgeB) {
246845
- return edgeA[0] === edgeB[1] && edgeA[1] === edgeB[0];
247033
+ return edgeA._v[0] === edgeB._v[1] && edgeA._v[1] === edgeB._v[0];
246846
247034
  }
246847
- /** Return true if the vertices edgeA and edgeB are the same vertex indices with no consideration of order. */
247035
+ /** Return true if edgeA and edgeB traverse the same edge in the same or opposite directions. */
246848
247036
  static areUndirectedPartners(edgeA, edgeB) {
246849
- return (edgeA[0] === edgeB[0] && edgeA[1] === edgeB[1]) || ((edgeA[0] === edgeB[1] && edgeA[1] === edgeB[0]));
247037
+ return this.areSameEdge(edgeA, edgeB) || this.areDirectedPartners(edgeA, edgeB);
246850
247038
  }
246851
247039
  /**
246852
- * Return numeric relationship of edgeA and edgeB:
246853
- * * 1 if they share start and end in the same order.
246854
- * * -1 if they share start and end in reversed order.
247040
+ * Return numeric identifier for the relationship between edgeA and edgeB:
247041
+ * * 1 if they share start and end vertex indices in the same order.
247042
+ * * -1 if they share start and end vertex indices in reversed order.
246855
247043
  * * 0 otherwise.
246856
247044
  */
246857
247045
  static relativeOrientation(edgeA, edgeB) {
246858
- if (edgeA[0] === edgeB[0] && edgeA[1] === edgeB[1])
247046
+ if (this.areSameEdge(edgeA, edgeB))
246859
247047
  return 1;
246860
- if (edgeA[0] === edgeB[1] && edgeA[1] === edgeB[0])
247048
+ if (this.areDirectedPartners(edgeA, edgeB))
246861
247049
  return -1;
246862
247050
  return 0;
246863
247051
  }
247052
+ /** Whether the start and end vertex indices are equal. */
246864
247053
  get isNullEdge() {
246865
- return this[0] === this[1];
247054
+ return this._v[0] === this._v[1];
246866
247055
  }
246867
247056
  /**
246868
247057
  * Lexical comparison of two edges.
246869
- * * If the edges have the same vertex pair (in same or opposite order) they will end up adjacent in a sort.
246870
- * * If the edges have 0 or 1 shared vertex indices, the one with lowest low comes first.
247058
+ * * If the edges have the same vertex index pair (in same or opposite order) they will end up adjacent in a sort.
246871
247059
  * @param edgeA first edge
246872
247060
  * @param edgeB second edge
246873
247061
  */
246874
247062
  static lessThan(edgeA, edgeB) {
246875
247063
  // primary compare is based on indirect indices
246876
- const lowA = edgeA.lowVertexIndex;
246877
- const lowB = edgeB.lowVertexIndex;
247064
+ const lowA = edgeA.lowVertex;
247065
+ const lowB = edgeB.lowVertex;
246878
247066
  if (lowA < lowB)
246879
247067
  return -1;
246880
247068
  if (lowB < lowA)
246881
247069
  return 1;
246882
- const highA = edgeA.highVertexIndex;
246883
- const highB = edgeB.highVertexIndex;
247070
+ const highA = edgeA.highVertex;
247071
+ const highB = edgeB.highVertex;
246884
247072
  if (highA < highB)
246885
247073
  return -1;
246886
247074
  if (highB < highA)
246887
247075
  return 1;
246888
247076
  // undirected indices match ... use directed vertexIndexA
246889
- return edgeA.vertexIndexA - edgeB.vertexIndexA;
246890
- }
246891
- constructor(vertexA, vertexB, facetIndex) {
246892
- super(3);
246893
- this[0] = vertexA;
246894
- this[1] = vertexB;
246895
- this[2] = facetIndex;
247077
+ return edgeA.startVertex - edgeB.startVertex;
246896
247078
  }
247079
+ /** Return the edge data as a JSON array. */
246897
247080
  toJSON() {
246898
- return [this[0], this[1], this[2]];
247081
+ return [this._v[0], this._v[1], this._a];
246899
247082
  }
247083
+ /** Return the edge cluster in JSON format. */
246900
247084
  static clusterToJSON(data) {
246901
247085
  if (data instanceof SortableEdge)
246902
247086
  return data.toJSON();
@@ -246904,6 +247088,7 @@ class SortableEdge extends Float64Array {
246904
247088
  for (const edge of data)
246905
247089
  result.push(edge.toJSON());
246906
247090
  }
247091
+ /** Return the edge cluster array in JSON format. */
246907
247092
  static clusterArrayToJSON(data) {
246908
247093
  const result = [];
246909
247094
  for (const cluster of data)
@@ -246912,11 +247097,14 @@ class SortableEdge extends Float64Array {
246912
247097
  }
246913
247098
  }
246914
247099
  /**
246915
- * An IndexedEdgeMatcher carries an array of edge start & end indices for sorting and subsequent analyses
246916
- * (such as testing for closed mesh).
247100
+ * An IndexedEdgeMatcher carries an array of edge start and end indices for sorting and subsequent analyses,
247101
+ * such as testing for closed mesh.
247102
+ * @public
246917
247103
  */
246918
247104
  class IndexedEdgeMatcher {
247105
+ /** The array of edges to be sorted. */
246919
247106
  edges;
247107
+ /** Constructor. Call [[addEdge]] or [[addPath]] to populate `edges`. */
246920
247108
  constructor() {
246921
247109
  this.edges = [];
246922
247110
  }
@@ -246933,22 +247121,22 @@ class IndexedEdgeMatcher {
246933
247121
  return edge;
246934
247122
  }
246935
247123
  /**
246936
- * Push edges all around a facet, returning to vertexArray[0].
246937
- * @param vertexArray array of vertex indices around facet
246938
- * @param facetIndex value to carry along during matching
247124
+ * Push edges along a path.
247125
+ * * Typically used to add edges around a facet.
247126
+ * @param vertexIndices array of vertex indices along an open or closed path.
247127
+ * @param facetIndex value to set on each edge pushed.
246939
247128
  * @param closeLoop true to add an edge from last to first vertex.
246940
247129
  */
246941
- addPath(vertexArray, facetIndex, closeLoop = true) {
246942
- if (vertexArray.length === 0)
247130
+ addPath(vertexIndices, facetIndex, closeLoop) {
247131
+ if (vertexIndices.length === 0)
246943
247132
  return;
246944
- const m = vertexArray.length - 1;
246945
- for (let i = 0; i < m; i++) {
246946
- this.addEdge(vertexArray[i], vertexArray[i + 1], facetIndex);
246947
- }
247133
+ const m = vertexIndices.length - 1;
247134
+ for (let i = 0; i < m; i++)
247135
+ this.addEdge(vertexIndices[i], vertexIndices[i + 1], facetIndex);
246948
247136
  if (closeLoop)
246949
- this.addEdge(vertexArray[m], vertexArray[0], facetIndex);
247137
+ this.addEdge(vertexIndices[m], vertexIndices[0], facetIndex);
246950
247138
  }
246951
- /** Sort the edge index array. */
247139
+ /** Sort the edges. */
246952
247140
  sort() {
246953
247141
  this.edges.sort((edgeA, edgeB) => SortableEdge.lessThan(edgeA, edgeB));
246954
247142
  }
@@ -246967,20 +247155,18 @@ class IndexedEdgeMatcher {
246967
247155
  }
246968
247156
  }
246969
247157
  /**
246970
- * Sort the edges, and look for three categories of paired edges:
246971
- * * caller must allocate all result arrays of interest.
246972
- * * Any combination of the result arrays may be `undefined`, indicating that category is to be ignored.
246973
- * * Any combination of the result arrays may be aliased as the same target, in which case those to categories are
247158
+ * Sort the edges, and collect up to four categories of edges: manifold pairs, singletons, null edges,
247159
+ * and everything else.
247160
+ * * Caller should allocate arrays of interest.
247161
+ * * Any combination of the arrays may be `undefined`, indicating that category is to be ignored.
247162
+ * * Any combination of the arrays may be aliased as the same target, in which case the aliased categories are
246974
247163
  * merged into the target.
246975
- * * For instance, to ignore manifold pairs and collect all others (singleton, null, and other) as a single array
246976
- * `allOther`, create `const allOther = []` as an empty array and call
246977
- * `sortAndCollectClusters (undefined, allOther, allOther, allOther);`
246978
- * @param manifoldPairs optional array to receive pairs of properly mated SortableEdgePairs, i.e. simple interior
246979
- * edges adjacent to two facets in opposing directions.
246980
- * @param singletons optional array to receive edges that are simple boundary edges.
246981
- * @param nullEdges optional array to receive arrays of null edges (same start and end vertex)
246982
- * @param allOtherClusters optional array to receive arrays in which all the edges are partners in an undirected sense
246983
- * but not a simple directed pair.
247164
+ * * For instance, to ignore manifold pairs and collect all other edges in a single array:
247165
+ * `const foo = []; matcher.sortAndCollectClusters(undefined, foo, foo, foo);`
247166
+ * @param manifoldPairs array to receive pairs of properly mated edges, i.e. mesh interior edges.
247167
+ * @param singletons array to receive edges that have no partner, i.e., mesh boundary edges.
247168
+ * @param nullEdges array to receive arrays of matched null edges, for which start === end vertex index.
247169
+ * @param allOtherClusters array to receive arrays of edges that are partners in an undirected, non-manifold sense.
246984
247170
  */
246985
247171
  sortAndCollectClusters(manifoldPairs, singletons, nullEdges, allOtherClusters) {
246986
247172
  this.sort();
@@ -247001,18 +247187,14 @@ class IndexedEdgeMatcher {
247001
247187
  SortableEdge.areUndirectedPartners(baseEdge, this.edges[index1]); index1++) {
247002
247188
  clusterLength++;
247003
247189
  }
247004
- if (this.edges[index0].isNullEdge) {
247190
+ if (this.edges[index0].isNullEdge)
247005
247191
  this.collectSortableEdgeCluster(index0, index0 + clusterLength, nullEdges);
247006
- }
247007
- else if (clusterLength === 2 && SortableEdge.areDirectedPartners(baseEdge, this.edges[index0 + 1])) {
247192
+ else if (clusterLength === 2 && SortableEdge.areDirectedPartners(baseEdge, this.edges[index0 + 1]))
247008
247193
  this.collectSortableEdgeCluster(index0, index0 + clusterLength, manifoldPairs);
247009
- }
247010
- else if (clusterLength === 1) {
247194
+ else if (clusterLength === 1)
247011
247195
  this.collectSortableEdgeCluster(index0, index0 + 1, singletons);
247012
- }
247013
- else {
247196
+ else
247014
247197
  this.collectSortableEdgeCluster(index0, index0 + clusterLength, allOtherClusters);
247015
- }
247016
247198
  }
247017
247199
  }
247018
247200
  }
@@ -247071,10 +247253,10 @@ class IndexedPolyfaceVisitor extends _PolyfaceData__WEBPACK_IMPORTED_MODULE_0__.
247071
247253
  this.auxData = polyface.data.auxData.createForVisitor();
247072
247254
  if (polyface.data.edgeMateIndex)
247073
247255
  this.edgeMateIndex = [];
247074
- this.reset();
247075
247256
  this._numEdges = 0;
247076
247257
  this._nextFacetIndex = 0;
247077
247258
  this._currentFacetIndex = -1;
247259
+ this.reset();
247078
247260
  }
247079
247261
  /** Return the client polyface object. */
247080
247262
  clientPolyface() {
@@ -247111,11 +247293,14 @@ class IndexedPolyfaceVisitor extends _PolyfaceData__WEBPACK_IMPORTED_MODULE_0__.
247111
247293
  moveToReadIndex(facetIndex) {
247112
247294
  if (!this._polyface.isValidFacetIndex(facetIndex))
247113
247295
  return false;
247114
- this._currentFacetIndex = facetIndex;
247296
+ const numEdges = this._polyface.numEdgeInFacet(facetIndex);
247297
+ if (this._currentFacetIndex !== facetIndex || numEdges + this._numWrap !== this.pointCount) {
247298
+ this._currentFacetIndex = facetIndex;
247299
+ this._numEdges = numEdges;
247300
+ this.resizeAllArrays(this._numEdges + this._numWrap);
247301
+ this.gatherIndexedData(this._polyface.data, this._polyface.facetIndex0(this._currentFacetIndex), this._polyface.facetIndex1(this._currentFacetIndex), this._numWrap);
247302
+ }
247115
247303
  this._nextFacetIndex = facetIndex + 1;
247116
- this._numEdges = this._polyface.numEdgeInFacet(facetIndex);
247117
- this.resizeAllArrays(this._numEdges + this._numWrap);
247118
- this.gatherIndexedData(this._polyface.data, this._polyface.facetIndex0(this._currentFacetIndex), this._polyface.facetIndex1(this._currentFacetIndex), this._numWrap);
247119
247304
  return true;
247120
247305
  }
247121
247306
  /** Advance the iterator to a the 'next' facet in the client polyface. */
@@ -247125,7 +247310,7 @@ class IndexedPolyfaceVisitor extends _PolyfaceData__WEBPACK_IMPORTED_MODULE_0__.
247125
247310
  this._nextFacetIndex++;
247126
247311
  return true;
247127
247312
  }
247128
- /** Reset the iterator to start at the first facet of the polyface. */
247313
+ /** Restart the visitor at the first facet. */
247129
247314
  reset() {
247130
247315
  this.moveToReadIndex(0);
247131
247316
  this._nextFacetIndex = 0; // so immediate moveToNextFacet stays here.
@@ -247224,6 +247409,10 @@ class IndexedPolyfaceVisitor extends _PolyfaceData__WEBPACK_IMPORTED_MODULE_0__.
247224
247409
  this.color.push(_Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.interpolateColor(other.color[index0], fraction, other.color[index1]));
247225
247410
  // TODO: auxData? taggedNumericData?
247226
247411
  }
247412
+ /** Create a visitor for a subset of the facets visitable by the instance. */
247413
+ createSubsetVisitor(facetIndices, numWrap = 0) {
247414
+ return IndexedPolyfaceSubsetVisitor.createSubsetVisitor(this._polyface, facetIndices, numWrap);
247415
+ }
247227
247416
  }
247228
247417
  /**
247229
247418
  * An `IndexedPolyfaceSubsetVisitor` is an `IndexedPolyfaceVisitor` which only visits a subset of facets in the polyface.
@@ -247232,38 +247421,38 @@ class IndexedPolyfaceVisitor extends _PolyfaceData__WEBPACK_IMPORTED_MODULE_0__.
247232
247421
  * @public
247233
247422
  */
247234
247423
  class IndexedPolyfaceSubsetVisitor extends IndexedPolyfaceVisitor {
247235
- _parentFacetIndices; // only undefined during super constructor!
247236
- _currentActiveIndex; // index within _parentFacetIndices, or -1 after construction
247237
- _nextActiveIndex; // index within _parentFacetIndices
247238
- constructor(polyface, activeFacetIndices, numWrap) {
247424
+ _facetIndices;
247425
+ _currentSubsetIndex; // index within _facetIndices, or -1 after construction
247426
+ _nextSubsetIndex; // index within _facetIndices
247427
+ constructor(polyface, facetIndices, numWrap) {
247239
247428
  super(polyface, numWrap);
247240
- this._parentFacetIndices = activeFacetIndices.slice();
247241
- this._currentActiveIndex = -1;
247242
- this._nextActiveIndex = 0;
247429
+ this._facetIndices = facetIndices.slice();
247430
+ this._currentSubsetIndex = -1;
247431
+ this._nextSubsetIndex = 0;
247432
+ this.reset();
247243
247433
  }
247244
247434
  isValidSubsetIndex(index) {
247245
- return (undefined !== this._parentFacetIndices) && index >= 0 && index < this._parentFacetIndices.length;
247435
+ return index >= 0 && index < this._facetIndices.length;
247246
247436
  }
247247
247437
  /**
247248
247438
  * Create a visitor for iterating a subset of the facets of `polyface`.
247249
247439
  * @param polyface reference to the client polyface, supplying facets
247250
- * @param activeFacetIndices array of indices of facets in the client polyface to visit. This array is cloned.
247440
+ * @param facetIndices array of indices of facets in the client polyface to visit. This array is cloned.
247251
247441
  * @param numWrap number of vertices replicated in the visitor arrays to facilitate simpler caller code. Default is zero.
247252
247442
  */
247253
- static createSubsetVisitor(polyface, activeFacetIndices, numWrap = 0) {
247254
- return new IndexedPolyfaceSubsetVisitor(polyface, activeFacetIndices, numWrap);
247443
+ static createSubsetVisitor(polyface, facetIndices, numWrap = 0) {
247444
+ return new IndexedPolyfaceSubsetVisitor(polyface, facetIndices, numWrap);
247255
247445
  }
247256
247446
  /**
247257
247447
  * Advance the iterator to a particular facet in the subset of client polyface facets.
247258
- * @param activeIndex the index of the facet within the subset, not to be confused with the index of the facet within
247259
- * the client polyface.
247448
+ * @param subsetIndex index into the subset array, not to be confused with the client facet index.
247260
247449
  * @return whether the iterator was successfully moved.
247261
247450
  */
247262
- moveToReadIndex(activeIndex) {
247263
- if (this.isValidSubsetIndex(activeIndex)) {
247264
- this._currentActiveIndex = activeIndex;
247265
- this._nextActiveIndex = activeIndex + 1;
247266
- return super.moveToReadIndex(this._parentFacetIndices[activeIndex]);
247451
+ moveToReadIndex(subsetIndex) {
247452
+ if (this.isValidSubsetIndex(subsetIndex)) {
247453
+ this._currentSubsetIndex = subsetIndex;
247454
+ this._nextSubsetIndex = subsetIndex + 1;
247455
+ return super.moveToReadIndex(this._facetIndices[subsetIndex]);
247267
247456
  }
247268
247457
  return false;
247269
247458
  }
@@ -247272,29 +247461,31 @@ class IndexedPolyfaceSubsetVisitor extends IndexedPolyfaceVisitor {
247272
247461
  * @return whether the iterator was successfully moved.
247273
247462
  */
247274
247463
  moveToNextFacet() {
247275
- if (this._nextActiveIndex !== this._currentActiveIndex)
247276
- return this.moveToReadIndex(this._nextActiveIndex);
247277
- this._nextActiveIndex++;
247464
+ if (this._nextSubsetIndex !== this._currentSubsetIndex)
247465
+ return this.moveToReadIndex(this._nextSubsetIndex);
247466
+ this._nextSubsetIndex++;
247278
247467
  return true;
247279
247468
  }
247280
- /** Reset the iterator to start at the first active facet in the subset of client polyface facets. */
247469
+ /** Restart the visitor at the first facet. */
247281
247470
  reset() {
247282
- this.moveToReadIndex(0);
247283
- this._nextActiveIndex = 0; // so immediate moveToNextFacet stays here.
247471
+ if (this._facetIndices) { // avoid crash during super ctor when we aren't yet initialized
247472
+ this.moveToReadIndex(0);
247473
+ this._nextSubsetIndex = 0; // so immediate moveToNextFacet stays here.
247474
+ }
247284
247475
  }
247285
247476
  /**
247286
- * Return the parent facet index of the indicated index within the subset of client polyface facets.
247287
- * @param activeIndex index of the facet within the subset. Default is the active facet.
247288
- * @return valid client polyface facet index, or `undefined` if invalid input index.
247477
+ * Return the client polyface facet index (aka "readIndex") for the given subset index.
247478
+ * @param subsetIndex index into the subset array. Default is the subset index of the currently visited facet.
247479
+ * @return valid client polyface facet index, or `undefined` if invalid subset index.
247289
247480
  */
247290
- parentFacetIndex(activeIndex) {
247291
- if (undefined === activeIndex)
247292
- activeIndex = this._currentActiveIndex;
247293
- return this.isValidSubsetIndex(activeIndex) ? this._parentFacetIndices[activeIndex] : undefined;
247481
+ parentFacetIndex(subsetIndex) {
247482
+ if (undefined === subsetIndex)
247483
+ subsetIndex = this._currentSubsetIndex;
247484
+ return this.isValidSubsetIndex(subsetIndex) ? this._facetIndices[subsetIndex] : undefined;
247294
247485
  }
247295
247486
  /** Return the number of facets this visitor is able to visit. */
247296
247487
  getVisitableFacetCount() {
247297
- return this._parentFacetIndices ? this._parentFacetIndices.length : 0;
247488
+ return this._facetIndices.length;
247298
247489
  }
247299
247490
  /**
247300
247491
  * Create a visitor for those mesh facets with normal in the same half-space as the given vector.
@@ -247394,7 +247585,7 @@ __webpack_require__.r(__webpack_exports__);
247394
247585
  * * The [[previousAroundVertex]] step is clockwise around the vertex.
247395
247586
  * * The `nextAroundFacet` steps for a walker and its [[edgeMate]] are in opposite directions along their shared edge,
247396
247587
  * when that edge is interior. Thus the `edgeMate` step can be seen to iterate an "edge loop" of two locations for an
247397
- * interior edges.
247588
+ * interior edge.
247398
247589
  * * Invalid Walkers:
247399
247590
  * * An invalid walker has undefined [[edgeIndex]]. For these walkers, [[isUndefined]] returns true, and [[isValid]]
247400
247591
  * returns false. Traversal operations on an invalid walker return an invalid walker.
@@ -247408,6 +247599,7 @@ __webpack_require__.r(__webpack_exports__);
247408
247599
  * * Invalid walkers can also occur while traversing a non-manifold mesh. Such meshes feature edge(s) with more than
247409
247600
  * two adjacent facets, or with two adjacent facets that have opposite orientations. These meshes are uncommon, and
247410
247601
  * usually indicate a construction problem.
247602
+ * * Note that a null edge, for which the start and end vertex is the same, does not yield an invalid walker.
247411
247603
  * * See [[buildEdgeMateIndices]] for further description of the topological relations.
247412
247604
  * @public
247413
247605
  */
@@ -247450,6 +247642,10 @@ class IndexedPolyfaceWalker {
247450
247642
  get isUndefined() {
247451
247643
  return this._edgeIndex === undefined;
247452
247644
  }
247645
+ /** Whether the walker is at a null edge, i.e. an edge with no length. */
247646
+ get isNull() {
247647
+ return this.isValid && this._polyface.data.edgeIndexToEdgeMateIndex(this._edgeIndex) === this._edgeIndex;
247648
+ }
247453
247649
  /**
247454
247650
  * Create a walker for a given polyface at an optional edge.
247455
247651
  * @param polyface reference to the client polyface. This reference is captured (the polyface is not copied).
@@ -247492,17 +247688,16 @@ class IndexedPolyfaceWalker {
247492
247688
  }
247493
247689
  /**
247494
247690
  * Create a new IndexedPolyfaceWalker from the instance.
247495
- * * The returned walker refers to the same polyface.
247496
- * * If `edgeIndex` is undefined, the returned walker refers to the same edge as the instance.
247497
- * * If `edgeIndex` is defined and valid, the returned walker refers to this edge.
247498
- * * If `edgeIndex` is defined but invalid, return undefined.
247499
- */
247500
- clone(edgeIndex) {
247501
- if (edgeIndex === undefined)
247502
- edgeIndex = this._edgeIndex;
247503
- if (this._polyface.data.isValidEdgeIndex(edgeIndex))
247504
- return new IndexedPolyfaceWalker(this._polyface, edgeIndex);
247505
- return undefined;
247691
+ * * The returned walker refers to the same polyface and edge as the instance.
247692
+ * @param result optional receiver to modify and return.
247693
+ */
247694
+ clone(result) {
247695
+ if (result) {
247696
+ result._polyface = this._polyface;
247697
+ result._edgeIndex = this._edgeIndex;
247698
+ return result;
247699
+ }
247700
+ return new IndexedPolyfaceWalker(this._polyface, this._edgeIndex);
247506
247701
  }
247507
247702
  /**
247508
247703
  * Load the walker's facet into the given visitor.
@@ -247631,29 +247826,35 @@ class IndexedPolyfaceWalker {
247631
247826
  * Build the edgeMate index array into the polyface's [[PolyfaceData]].
247632
247827
  * After this method:
247633
247828
  * * The array `polyface.data.edgeMateIndex` is defined with the same length as the other PolyfaceData index arrays.
247634
- * * For each interior edge, `polyface.data.edgeIndexToEdgeMateIndex` returns the edgeIndex on the other side of the
247829
+ * * For each interior edge, `polyface.data.edgeIndexToEdgeMateIndex` returns the edge index on the other side of the
247635
247830
  * edge in the adjacent facet.
247636
247831
  * * The conditions for edgeMate matching are:
247637
247832
  * * Given facetIndex f, let `k0 = polyface.facetIndex0(f)` and `k1 = polyface.facetIndex1(f)`.
247638
- * * Every edgeIndex k in the face loop of facet f satisfies `k0 <= k < k1`.
247639
- * * The edge with edgeIndex k starts at the point with index `polyface.data.pointIndex[k]`.
247640
- * * Let kA be an edgeIndex in this range [k0,k1), and let kB be its in-range successor with cyclic wrap, i.e.,
247833
+ * * Every edge index k in the face loop of facet f satisfies `k0 <= k < k1`.
247834
+ * * The edge with edge index k starts at the point with index `polyface.data.pointIndex[k]`.
247835
+ * * Let kA be an edge index in this range [k0,k1), and let kB be its in-range successor with cyclic wrap, i.e.,
247641
247836
  * `kB === (kA + 1 === k1) ? k0 : kA + 1`.
247642
247837
  * * Then `polyface.data.pointIndex[kA]` and `polyface.data.pointIndex[kB]` are the indices of the points at the
247643
247838
  * start and end of an edge of that facet.
247644
- * * We call kA the _edgeIndex_ for that edge, and kB the _edgeIndex_ for the next edge around the facet.
247645
- * * If kA is an interior edge in a 2-manifold mesh with properly oriented facets, then there is an adjacent facet
247646
- * whose face loop contains edgeIndices kC and kD referencing the same edge vertices in reverse order, i.e.,
247839
+ * * We call kA the _edge index_ for that edge, and kB the _edge index_ for the next edge around the facet.
247840
+ * * If kA is a positive-length interior edge in a 2-manifold mesh with properly oriented facets, then there is
247841
+ * an adjacent facet whose face loop contains edge indices kC and kD referencing the same edge vertices in reverse
247842
+ * order, i.e.,
247647
247843
  * * `polyface.data.pointIndex[kA] === polyface.data.pointIndex[kD]`
247648
247844
  * * `polyface.data.pointIndex[kB] === polyface.data.pointIndex[kC]`
247649
- * * Given this relationship, we say that edgeIndices kA and kC are _edge mates_.
247650
- * * A non-interior edge either lies on the boundary of the mesh or is non-manifold (having more than two adjacent
247651
- * facets, or one with the wrong orientation). These edges have no edge mate.
247845
+ * * We call the edge indices kA and kC _edge mates_, denoted in the `edgeMateIndex` array by:
247846
+ * * `polyface.data.edgeMateIndex[kA] === kC`
247847
+ * * `polyface.data.edgeMateIndex[kC] === kA`
247848
+ * * If kA is zero-length interior edge, i.e, it has the same start and end point indices, then we call it a _null
247849
+ * edge_, and its edge mate is itself.
247850
+ * * A non-interior edge either lies on the boundary of the mesh, or is non-manifold (having more than 2 adjacent
247851
+ * facets, or 1 with the wrong orientation). These edges have no edge mate, represented as `undefined` in
247852
+ * the `edgeMateIndex` array.
247652
247853
  * * These conditions define a conventional manifold mesh where each edge of a facet has at most one partner edge with
247653
247854
  * opposite orientation in an adjacent facet.
247654
247855
  * * After calling this method, the caller can construct `IndexedPolyfaceWalker` objects to traverse the mesh by
247655
- * walking across edges, around faces, and around vertices. Let walkerA have edgeIndex value kA. Then with the
247656
- * aforementioned edgeIndices:
247856
+ * walking across edges, around faces, and around vertices. Let walkerA have edge index value kA. Then with the
247857
+ * aforementioned edge indices:
247657
247858
  * * `walkerC = walkerA.edgeMate()` moves across the edge to its other end, at kC.
247658
247859
  * * `walkerB = walkerA.nextAroundFacet()` moves around the facet to the next edge, at kB.
247659
247860
  * * `walkerB.previousAroundFacet()` moves from kB back to kA.
@@ -247668,25 +247869,30 @@ class IndexedPolyfaceWalker {
247668
247869
  const kStart = polyface.facetIndex0(facetIndex);
247669
247870
  const kEnd = polyface.facetIndex1(facetIndex);
247670
247871
  let k0 = kEnd - 1;
247671
- // sneaky: addEdge 3rd arg is edgeIndex k0 instead of facetIndex; it gets carried around during matching
247872
+ // sneaky: addEdge 3rd arg is edge index k0 instead of facetIndex; it gets carried around during matching
247672
247873
  for (let k1 = kStart; k1 < kEnd; k0 = k1, k1++)
247673
247874
  matcher.addEdge(polyface.data.pointIndex[k0], polyface.data.pointIndex[k1], k0);
247674
247875
  }
247675
247876
  const matchedPairs = [];
247676
- const singletons = [];
247677
247877
  const nullEdges = [];
247678
- const allOtherClusters = [];
247679
- matcher.sortAndCollectClusters(matchedPairs, singletons, nullEdges, allOtherClusters);
247878
+ matcher.sortAndCollectClusters(matchedPairs, undefined, nullEdges, undefined);
247680
247879
  const numIndex = polyface.data.pointIndex.length;
247681
247880
  polyface.data.edgeMateIndex = new Array(numIndex);
247682
247881
  for (let i = 0; i < numIndex; i++)
247683
- polyface.data.edgeMateIndex[i] = undefined;
247882
+ polyface.data.edgeMateIndex[i] = undefined; // boundary and non-manifold edges have no mate
247684
247883
  for (const pair of matchedPairs) {
247685
247884
  if (Array.isArray(pair) && pair.length === 2) {
247686
- const k0 = pair[0].facetIndex;
247687
- const k1 = pair[1].facetIndex;
247688
- polyface.data.edgeMateIndex[k0] = k1;
247689
- polyface.data.edgeMateIndex[k1] = k0;
247885
+ const edgeIndex0 = pair[0].facetIndex;
247886
+ const edgeIndex1 = pair[1].facetIndex;
247887
+ polyface.data.edgeMateIndex[edgeIndex0] = edgeIndex1; // paired edges point to each other
247888
+ polyface.data.edgeMateIndex[edgeIndex1] = edgeIndex0;
247889
+ }
247890
+ }
247891
+ for (const nullEdgeOrCluster of nullEdges) {
247892
+ const nullCluster = Array.isArray(nullEdgeOrCluster) ? nullEdgeOrCluster : [nullEdgeOrCluster];
247893
+ for (const nullEdge of nullCluster) {
247894
+ const edgeIndex = nullEdge.facetIndex;
247895
+ polyface.data.edgeMateIndex[edgeIndex] = edgeIndex; // a null edge points to itself
247690
247896
  }
247691
247897
  }
247692
247898
  }
@@ -248373,6 +248579,22 @@ class IndexedPolyface extends Polyface {
248373
248579
  dispatchToGeometryHandler(handler) {
248374
248580
  return handler.handleIndexedPolyface(this);
248375
248581
  }
248582
+ /** If the input accesses an edgeMateIndex array, return it along with the owning IndexedPolyface. */
248583
+ static hasEdgeMateIndex(polyface) {
248584
+ let parent;
248585
+ if (polyface instanceof Polyface) {
248586
+ if (polyface instanceof IndexedPolyface)
248587
+ parent = polyface;
248588
+ }
248589
+ else if (polyface.clientPolyface() && polyface.clientPolyface() instanceof IndexedPolyface)
248590
+ parent = polyface.clientPolyface();
248591
+ if (parent) {
248592
+ const edgeMateIndex = parent.data.edgeMateIndex;
248593
+ if (edgeMateIndex && edgeMateIndex.length > 0 && edgeMateIndex.length === parent.data.indexCount)
248594
+ return { parent, edgeMateIndex };
248595
+ }
248596
+ return undefined;
248597
+ }
248376
248598
  }
248377
248599
 
248378
248600
 
@@ -250283,9 +250505,9 @@ class PolyfaceBuilder extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
250283
250505
  let indexA = -1;
250284
250506
  let indexB = -1;
250285
250507
  for (let i = this._polyface.facetIndex0(edge.facetIndex); i < this._polyface.facetIndex1(edge.facetIndex); ++i) {
250286
- if (edge.vertexIndexA === this._polyface.data.pointIndex[i])
250508
+ if (edge.startVertex === this._polyface.data.pointIndex[i])
250287
250509
  indexA = i;
250288
- else if (edge.vertexIndexB === this._polyface.data.pointIndex[i])
250510
+ else if (edge.endVertex === this._polyface.data.pointIndex[i])
250289
250511
  indexB = i;
250290
250512
  }
250291
250513
  return (indexA < 0 || indexB < 0) ? undefined : { edgeIndexA: indexA, edgeIndexB: indexB };
@@ -250423,7 +250645,7 @@ __webpack_require__.r(__webpack_exports__);
250423
250645
  /* harmony import */ var _curve_UnionRegion__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../curve/UnionRegion */ "../../core/geometry/lib/esm/curve/UnionRegion.js");
250424
250646
  /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
250425
250647
  /* harmony import */ var _geometry3d_FrameBuilder__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../geometry3d/FrameBuilder */ "../../core/geometry/lib/esm/geometry3d/FrameBuilder.js");
250426
- /* harmony import */ var _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../geometry3d/GrowableXYZArray */ "../../core/geometry/lib/esm/geometry3d/GrowableXYZArray.js");
250648
+ /* harmony import */ var _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../geometry3d/GrowableXYZArray */ "../../core/geometry/lib/esm/geometry3d/GrowableXYZArray.js");
250427
250649
  /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
250428
250650
  /* harmony import */ var _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../geometry3d/PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
250429
250651
  /* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
@@ -250431,7 +250653,7 @@ __webpack_require__.r(__webpack_exports__);
250431
250653
  /* harmony import */ var _solid_SweepContour__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../solid/SweepContour */ "../../core/geometry/lib/esm/solid/SweepContour.js");
250432
250654
  /* harmony import */ var _topology_ChainMerge__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../topology/ChainMerge */ "../../core/geometry/lib/esm/topology/ChainMerge.js");
250433
250655
  /* harmony import */ var _multiclip_RangeSearch__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./multiclip/RangeSearch */ "../../core/geometry/lib/esm/polyface/multiclip/RangeSearch.js");
250434
- /* harmony import */ var _Polyface__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Polyface */ "../../core/geometry/lib/esm/polyface/Polyface.js");
250656
+ /* harmony import */ var _Polyface__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Polyface */ "../../core/geometry/lib/esm/polyface/Polyface.js");
250435
250657
  /* harmony import */ var _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./PolyfaceBuilder */ "../../core/geometry/lib/esm/polyface/PolyfaceBuilder.js");
250436
250658
  /* harmony import */ var _PolyfaceQuery__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./PolyfaceQuery */ "../../core/geometry/lib/esm/polyface/PolyfaceQuery.js");
250437
250659
  /*---------------------------------------------------------------------------------------------
@@ -250527,26 +250749,28 @@ class PolyfaceClip {
250527
250749
  * * Return all surviving clip as a new mesh.
250528
250750
  * * WARNING: The new mesh is "points only" -- parameters, normals, etc are not interpolated
250529
250751
  */
250530
- static clipPolyfaceClipPlaneWithClosureFace(polyface, clipper, insideClip = true, buildClosureFaces = true) {
250531
- return this.clipPolyfaceClipPlane(polyface, clipper, insideClip, buildClosureFaces);
250752
+ static clipPolyfaceClipPlaneWithClosureFace(source, clipper, insideClip = true, buildClosureFaces = true) {
250753
+ return this.clipPolyfaceClipPlane(source, clipper, insideClip, buildClosureFaces);
250532
250754
  }
250533
250755
  /** Clip each facet of polyface to the ClipPlane.
250534
250756
  * * Return all surviving clip as a new mesh.
250535
250757
  * * WARNING: The new mesh is "points only" -- parameters, normals, etc are not interpolated
250536
250758
  */
250537
- static clipPolyfaceClipPlane(polyface, clipper, insideClip = true, buildClosureFaces = false) {
250759
+ static clipPolyfaceClipPlane(source, clipper, insideClip = true, buildClosureFaces = false) {
250538
250760
  const builders = ClippedPolyfaceBuilders.create(insideClip, !insideClip, buildClosureFaces);
250539
- this.clipPolyfaceInsideOutside(polyface, clipper, builders);
250761
+ this.clipPolyfaceInsideOutside(source, clipper, builders);
250540
250762
  return builders.claimPolyface(insideClip ? 0 : 1, true);
250541
250763
  }
250542
- /** Clip each facet of polyface to the ClipPlane.
250543
- * * Return surviving clip as a new mesh.
250764
+ /**
250765
+ * Clip each facet to the clipper.
250766
+ * * Return surviving facets as a new mesh.
250544
250767
  * * WARNING: The new mesh is "points only".
250545
250768
  */
250546
- static clipPolyfaceConvexClipPlaneSet(polyface, clipper) {
250547
- const visitor = polyface.createVisitor(0);
250769
+ static clipPolyfaceConvexClipPlaneSet(source, clipper) {
250770
+ const visitor = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface ? source.createVisitor(0) : source;
250771
+ visitor.setNumWrap(0);
250548
250772
  const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_1__.PolyfaceBuilder.create();
250549
- const work = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_4__.GrowableXYZArray(10);
250773
+ const work = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_5__.GrowableXYZArray(10);
250550
250774
  for (visitor.reset(); visitor.moveToNextFacet();) {
250551
250775
  clipper.clipConvexPolygonInPlace(visitor.point, work);
250552
250776
  if (visitor.point.length > 2)
@@ -250554,21 +250778,18 @@ class PolyfaceClip {
250554
250778
  }
250555
250779
  return builder.claimPolyface(true);
250556
250780
  }
250557
- /** Clip each facet of polyface to the the clippers.
250781
+ /** Clip each facet to the clippers.
250558
250782
  * * Add inside, outside fragments to builderA, builderB
250559
250783
  * * This does not consider params, normals, colors. Just points.
250560
250784
  * * outputSelect determines how the clip output is structured
250561
250785
  * * 0 outputs all shards -- this may have many interior edges.
250562
250786
  * * 1 stitches shards together to get cleaner facets.
250563
250787
  */
250564
- static clipPolyfaceUnionOfConvexClipPlaneSetsToBuilders(polyface, allClippers, destination, outputSelector = 1) {
250565
- if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_5__.Polyface) {
250566
- this.clipPolyfaceUnionOfConvexClipPlaneSetsToBuilders(polyface.createVisitor(0), allClippers, destination, outputSelector);
250567
- return;
250568
- }
250788
+ static clipPolyfaceUnionOfConvexClipPlaneSetsToBuilders(source, allClippers, destination, outputSelector = 1) {
250569
250789
  const builderA = destination.builderA;
250570
250790
  const builderB = destination.builderB;
250571
- const visitor = polyface; // alias; we have a visitor now
250791
+ const visitor = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface ? source.createVisitor(0) : source;
250792
+ visitor.setNumWrap(0);
250572
250793
  const cache = new _geometry3d_ReusableObjectCache__WEBPACK_IMPORTED_MODULE_6__.GrowableXYZArrayCache();
250573
250794
  const insideShards = [];
250574
250795
  const outsideShards = [];
@@ -250655,7 +250876,7 @@ class PolyfaceClip {
250655
250876
  static cleanupAndAddRegion(builder, shards, worldToLocal, localToWorld) {
250656
250877
  if (builder !== undefined && shards.length > 0) {
250657
250878
  if (worldToLocal)
250658
- _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_4__.GrowableXYZArray.multiplyTransformInPlace(worldToLocal, shards);
250879
+ _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_5__.GrowableXYZArray.multiplyTransformInPlace(worldToLocal, shards);
250659
250880
  const outsidePieces = _curve_RegionOps__WEBPACK_IMPORTED_MODULE_11__.RegionOps.polygonBooleanXYToLoops(shards, _curve_RegionOps__WEBPACK_IMPORTED_MODULE_11__.RegionBinaryOpType.Union, []);
250660
250881
  if (outsidePieces && outsidePieces.children.length > 0) {
250661
250882
  _curve_RegionOps__WEBPACK_IMPORTED_MODULE_11__.RegionOps.consolidateAdjacentPrimitives(outsidePieces); // source of the T-vertices removed in claimPolyface
@@ -250699,24 +250920,23 @@ class PolyfaceClip {
250699
250920
  }
250700
250921
  return chainContexts;
250701
250922
  }
250702
- /** Clip each facet of polyface to the the clippers.
250923
+ /** Clip each facet to the clippers.
250703
250924
  * * Add inside, outside fragments to builderA, builderB
250704
250925
  * * This does not consider params, normals, colors. Just points.
250705
250926
  * @internal
250706
250927
  */
250707
- static clipPolyfaceConvexClipPlaneSetToBuilders(polyface, clipper, destination) {
250928
+ static clipPolyfaceConvexClipPlaneSetToBuilders(source, clipper, destination) {
250708
250929
  const builderA = destination.builderA;
250709
250930
  const builderB = destination.builderB;
250710
- const visitor = polyface.createVisitor(0);
250931
+ const visitor = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface ? source.createVisitor(0) : source;
250932
+ visitor.setNumWrap(0);
250711
250933
  const cache = new _geometry3d_ReusableObjectCache__WEBPACK_IMPORTED_MODULE_6__.GrowableXYZArrayCache();
250712
250934
  const outsideParts = [];
250713
250935
  for (visitor.reset(); visitor.moveToNextFacet();) {
250714
- // !!! currentCandidates and next candidates are empty at this point !!!
250715
250936
  const insidePart = clipper.clipInsidePushOutside(visitor.point, outsideParts, cache);
250716
250937
  if (insidePart === undefined) {
250717
250938
  // everything is out ... outsideParts might be fragmented. Save only the original polygon
250718
250939
  builderB?.addPolygonGrowableXYZArray(visitor.point);
250719
- cache.dropToCache(insidePart);
250720
250940
  cache.dropAllToCache(outsideParts);
250721
250941
  }
250722
250942
  this.addPolygonToBuilderAndDropToCache(insidePart, builderA, cache);
@@ -250852,15 +251072,16 @@ class PolyfaceClip {
250852
251072
  }
250853
251073
  }
250854
251074
  }
250855
- /** Clip each facet of polyface to the the clippers.
251075
+ /** Clip each facet to the clippers.
250856
251076
  * * Add inside, outside fragments to builderA, builderB
250857
251077
  * * This does not consider params, normals, colors. Just points.
250858
251078
  * @internal
250859
251079
  */
250860
- static clipPolyfaceClipPlaneToBuilders(polyface, clipper, destination) {
251080
+ static clipPolyfaceClipPlaneToBuilders(source, clipper, destination) {
250861
251081
  const builderA = destination.builderA;
250862
251082
  const builderB = destination.builderB;
250863
- const visitor = polyface.createVisitor(0);
251083
+ const visitor = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface ? source.createVisitor(0) : source;
251084
+ visitor.setNumWrap(0);
250864
251085
  const cache = new _geometry3d_ReusableObjectCache__WEBPACK_IMPORTED_MODULE_6__.GrowableXYZArrayCache();
250865
251086
  const inside = cache.grabFromCache();
250866
251087
  const outside = cache.grabFromCache();
@@ -250877,34 +251098,31 @@ class PolyfaceClip {
250877
251098
  cache.dropToCache(inside);
250878
251099
  cache.dropToCache(outside);
250879
251100
  }
250880
- /** Clip each facet of polyface to the ClipPlane or ConvexClipPlaneSet
251101
+ /** Clip each facet to the clipper.
250881
251102
  * * accumulate inside and outside facets -- to destination.builderA and destination.builderB
250882
- * * if `destination.buildClosureFaces` is set, and also build closure facets
250883
- * * This method parses the variant input types and calls a more specific method.
251103
+ * * if `destination.buildClosureFaces` is set, also build closure facets.
251104
+ * * This method parses the variant input types and calls a more specific method.
250884
251105
  * * WARNING: The new mesh is "points only".
250885
251106
  * * outputSelect applies only for UnionOfConvexClipPlaneSets -- see [[PolyfaceClip.clipPolyfaceUnionOfConvexClipPlaneSetsToBuilders]]
250886
251107
  */
250887
- static clipPolyfaceInsideOutside(polyface, clipper, destination, outputSelect = 0) {
250888
- if (clipper instanceof _clipping_ClipPlane__WEBPACK_IMPORTED_MODULE_18__.ClipPlane) {
250889
- this.clipPolyfaceClipPlaneToBuilders(polyface, clipper, destination);
250890
- }
250891
- else if (clipper instanceof _clipping_ConvexClipPlaneSet__WEBPACK_IMPORTED_MODULE_19__.ConvexClipPlaneSet) {
250892
- this.clipPolyfaceConvexClipPlaneSetToBuilders(polyface, clipper, destination);
250893
- }
250894
- else if (clipper instanceof _clipping_UnionOfConvexClipPlaneSets__WEBPACK_IMPORTED_MODULE_20__.UnionOfConvexClipPlaneSets) {
250895
- this.clipPolyfaceUnionOfConvexClipPlaneSetsToBuilders(polyface, clipper, destination, outputSelect);
250896
- }
251108
+ static clipPolyfaceInsideOutside(source, clipper, destination, outputSelect = 0) {
251109
+ if (clipper instanceof _clipping_ClipPlane__WEBPACK_IMPORTED_MODULE_18__.ClipPlane)
251110
+ this.clipPolyfaceClipPlaneToBuilders(source, clipper, destination);
251111
+ else if (clipper instanceof _clipping_ConvexClipPlaneSet__WEBPACK_IMPORTED_MODULE_19__.ConvexClipPlaneSet)
251112
+ this.clipPolyfaceConvexClipPlaneSetToBuilders(source, clipper, destination);
251113
+ else if (clipper instanceof _clipping_UnionOfConvexClipPlaneSets__WEBPACK_IMPORTED_MODULE_20__.UnionOfConvexClipPlaneSets)
251114
+ this.clipPolyfaceUnionOfConvexClipPlaneSetsToBuilders(source, clipper, destination, outputSelect);
250897
251115
  }
250898
- /** Clip each facet of polyface to the ClipPlane or ConvexClipPlaneSet
251116
+ /** Clip each facet to the clipper.
250899
251117
  * * This method parses the variant input types and calls a more specific method.
250900
251118
  * * To get both inside and outside parts, use clipPolyfaceInsideOutside
250901
251119
  * * WARNING: The new mesh is "points only".
250902
251120
  */
250903
- static clipPolyface(polyface, clipper) {
251121
+ static clipPolyface(source, clipper) {
250904
251122
  if (clipper instanceof _clipping_ClipPlane__WEBPACK_IMPORTED_MODULE_18__.ClipPlane)
250905
- return this.clipPolyfaceClipPlane(polyface, clipper);
251123
+ return this.clipPolyfaceClipPlane(source, clipper);
250906
251124
  if (clipper instanceof _clipping_ConvexClipPlaneSet__WEBPACK_IMPORTED_MODULE_19__.ConvexClipPlaneSet)
250907
- return this.clipPolyfaceConvexClipPlaneSet(polyface, clipper);
251125
+ return this.clipPolyfaceConvexClipPlaneSet(source, clipper);
250908
251126
  // (The if tests exhaust the type space -- this line is unreachable.)
250909
251127
  return undefined;
250910
251128
  }
@@ -250918,7 +251136,7 @@ class PolyfaceClip {
250918
251136
  * @returns clipped facets. No other mesh data but vertices appear in output.
250919
251137
  */
250920
251138
  static drapeRegion(mesh, region, sweepVector, options) {
250921
- if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_5__.Polyface)
251139
+ if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
250922
251140
  return this.drapeRegion(mesh.createVisitor(0), region, sweepVector, options);
250923
251141
  const contour = _solid_SweepContour__WEBPACK_IMPORTED_MODULE_16__.SweepContour.createForLinearSweep(region);
250924
251142
  if (!contour)
@@ -250954,10 +251172,11 @@ class PolyfaceClip {
250954
251172
  /** Intersect each facet with the clip plane. (Producing intersection edges.)
250955
251173
  * * Return all edges chained as array of LineString3d.
250956
251174
  */
250957
- static sectionPolyfaceClipPlane(polyface, clipper) {
251175
+ static sectionPolyfaceClipPlane(source, clipper) {
250958
251176
  const chainContext = _topology_ChainMerge__WEBPACK_IMPORTED_MODULE_13__.ChainMergeContext.create();
250959
- const visitor = polyface.createVisitor(0);
250960
- const work = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_4__.GrowableXYZArray(10);
251177
+ const visitor = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface ? source.createVisitor(0) : source;
251178
+ visitor.setNumWrap(0);
251179
+ const work = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_5__.GrowableXYZArray(10);
250961
251180
  const point0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_15__.Point3d.create();
250962
251181
  const point1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_15__.Point3d.create();
250963
251182
  for (visitor.reset(); visitor.moveToNextFacet();) {
@@ -250992,11 +251211,11 @@ class PolyfaceClip {
250992
251211
  visitorA.point.setRange(range);
250993
251212
  searchA.addRange(range, visitorA.currentReadIndex());
250994
251213
  }
250995
- const xyClip = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_4__.GrowableXYZArray(10);
250996
- const workArray = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_4__.GrowableXYZArray(10);
251214
+ const xyClip = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_5__.GrowableXYZArray(10);
251215
+ const workArray = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_5__.GrowableXYZArray(10);
250997
251216
  const xyFrustum = _clipping_ConvexClipPlaneSet__WEBPACK_IMPORTED_MODULE_19__.ConvexClipPlaneSet.createEmpty();
250998
- const below = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_4__.GrowableXYZArray(10);
250999
- const above = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_4__.GrowableXYZArray(10);
251217
+ const below = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_5__.GrowableXYZArray(10);
251218
+ const above = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_5__.GrowableXYZArray(10);
251000
251219
  const planeOfFacet = _clipping_ClipPlane__WEBPACK_IMPORTED_MODULE_18__.ClipPlane.createNormalAndPointXYZXYZ(0, 0, 1, 0, 0, 0);
251001
251220
  const altitudeRange = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_17__.Range1d.createNull();
251002
251221
  for (visitorB.reset(); visitorB.moveToNextFacet();) {
@@ -251872,42 +252091,41 @@ __webpack_require__.r(__webpack_exports__);
251872
252091
  /* harmony export */ });
251873
252092
  /* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
251874
252093
  /* harmony import */ var _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../curve/CurveCollection */ "../../core/geometry/lib/esm/curve/CurveCollection.js");
251875
- /* harmony import */ var _curve_CurveOps__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../curve/CurveOps */ "../../core/geometry/lib/esm/curve/CurveOps.js");
252094
+ /* harmony import */ var _curve_CurveOps__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../curve/CurveOps */ "../../core/geometry/lib/esm/curve/CurveOps.js");
251876
252095
  /* harmony import */ var _curve_internalContexts_MultiChainCollector__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../curve/internalContexts/MultiChainCollector */ "../../core/geometry/lib/esm/curve/internalContexts/MultiChainCollector.js");
251877
252096
  /* harmony import */ var _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../curve/LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
251878
252097
  /* harmony import */ var _curve_LineString3d__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../curve/LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
251879
252098
  /* harmony import */ var _curve_Loop__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../curve/Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
251880
- /* harmony import */ var _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ../curve/StrokeOptions */ "../../core/geometry/lib/esm/curve/StrokeOptions.js");
252099
+ /* harmony import */ var _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ../curve/StrokeOptions */ "../../core/geometry/lib/esm/curve/StrokeOptions.js");
251881
252100
  /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
251882
252101
  /* harmony import */ var _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../geometry3d/Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
251883
- /* harmony import */ var _geometry3d_BarycentricTriangle__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ../geometry3d/BarycentricTriangle */ "../../core/geometry/lib/esm/geometry3d/BarycentricTriangle.js");
251884
- /* harmony import */ var _geometry3d_Point3dArrayCarrier__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ../geometry3d/Point3dArrayCarrier */ "../../core/geometry/lib/esm/geometry3d/Point3dArrayCarrier.js");
252102
+ /* harmony import */ var _geometry3d_BarycentricTriangle__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ../geometry3d/BarycentricTriangle */ "../../core/geometry/lib/esm/geometry3d/BarycentricTriangle.js");
252103
+ /* harmony import */ var _geometry3d_Point3dArrayCarrier__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../geometry3d/Point3dArrayCarrier */ "../../core/geometry/lib/esm/geometry3d/Point3dArrayCarrier.js");
251885
252104
  /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
251886
- /* harmony import */ var _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../geometry3d/PointHelpers */ "../../core/geometry/lib/esm/geometry3d/PointHelpers.js");
252105
+ /* harmony import */ var _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../geometry3d/PointHelpers */ "../../core/geometry/lib/esm/geometry3d/PointHelpers.js");
251887
252106
  /* harmony import */ var _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../geometry3d/PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
251888
- /* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
251889
- /* harmony import */ var _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../geometry3d/Ray3d */ "../../core/geometry/lib/esm/geometry3d/Ray3d.js");
251890
- /* harmony import */ var _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../geometry3d/Transform */ "../../core/geometry/lib/esm/geometry3d/Transform.js");
251891
- /* harmony import */ var _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../geometry4d/Matrix4d */ "../../core/geometry/lib/esm/geometry4d/Matrix4d.js");
251892
- /* harmony import */ var _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../geometry4d/MomentData */ "../../core/geometry/lib/esm/geometry4d/MomentData.js");
252107
+ /* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
252108
+ /* harmony import */ var _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../geometry3d/Ray3d */ "../../core/geometry/lib/esm/geometry3d/Ray3d.js");
252109
+ /* harmony import */ var _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../geometry3d/Transform */ "../../core/geometry/lib/esm/geometry3d/Transform.js");
252110
+ /* harmony import */ var _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../geometry4d/Matrix4d */ "../../core/geometry/lib/esm/geometry4d/Matrix4d.js");
252111
+ /* harmony import */ var _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../geometry4d/MomentData */ "../../core/geometry/lib/esm/geometry4d/MomentData.js");
251893
252112
  /* harmony import */ var _numerics_UnionFind__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../numerics/UnionFind */ "../../core/geometry/lib/esm/numerics/UnionFind.js");
251894
- /* harmony import */ var _topology_ChainMerge__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ../topology/ChainMerge */ "../../core/geometry/lib/esm/topology/ChainMerge.js");
251895
- /* harmony import */ var _topology_Graph__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../topology/Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
251896
- /* harmony import */ var _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ../topology/HalfEdgeGraphFromIndexedLoopsContext */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js");
251897
- /* harmony import */ var _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../topology/HalfEdgeGraphSearch */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphSearch.js");
251898
- /* harmony import */ var _topology_Merging__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../topology/Merging */ "../../core/geometry/lib/esm/topology/Merging.js");
251899
- /* harmony import */ var _topology_SpaceTriangulation__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ../topology/SpaceTriangulation */ "../../core/geometry/lib/esm/topology/SpaceTriangulation.js");
251900
- /* harmony import */ var _FacetLocationDetail__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./FacetLocationDetail */ "../../core/geometry/lib/esm/polyface/FacetLocationDetail.js");
251901
- /* harmony import */ var _FacetOrientation__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ./FacetOrientation */ "../../core/geometry/lib/esm/polyface/FacetOrientation.js");
252113
+ /* harmony import */ var _topology_ChainMerge__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ../topology/ChainMerge */ "../../core/geometry/lib/esm/topology/ChainMerge.js");
252114
+ /* harmony import */ var _topology_Graph__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../topology/Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
252115
+ /* harmony import */ var _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ../topology/HalfEdgeGraphFromIndexedLoopsContext */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js");
252116
+ /* harmony import */ var _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../topology/HalfEdgeGraphSearch */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphSearch.js");
252117
+ /* harmony import */ var _topology_Merging__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../topology/Merging */ "../../core/geometry/lib/esm/topology/Merging.js");
252118
+ /* harmony import */ var _topology_SpaceTriangulation__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../topology/SpaceTriangulation */ "../../core/geometry/lib/esm/topology/SpaceTriangulation.js");
252119
+ /* harmony import */ var _FacetLocationDetail__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./FacetLocationDetail */ "../../core/geometry/lib/esm/polyface/FacetLocationDetail.js");
252120
+ /* harmony import */ var _FacetOrientation__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ./FacetOrientation */ "../../core/geometry/lib/esm/polyface/FacetOrientation.js");
251902
252121
  /* harmony import */ var _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./IndexedEdgeMatcher */ "../../core/geometry/lib/esm/polyface/IndexedEdgeMatcher.js");
251903
- /* harmony import */ var _IndexedPolyfaceVisitor__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./IndexedPolyfaceVisitor */ "../../core/geometry/lib/esm/polyface/IndexedPolyfaceVisitor.js");
251904
- /* harmony import */ var _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ./multiclip/BuildAverageNormalsContext */ "../../core/geometry/lib/esm/polyface/multiclip/BuildAverageNormalsContext.js");
251905
- /* harmony import */ var _multiclip_OffsetMeshContext__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./multiclip/OffsetMeshContext */ "../../core/geometry/lib/esm/polyface/multiclip/OffsetMeshContext.js");
252122
+ /* harmony import */ var _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ./multiclip/BuildAverageNormalsContext */ "../../core/geometry/lib/esm/polyface/multiclip/BuildAverageNormalsContext.js");
252123
+ /* harmony import */ var _multiclip_OffsetMeshContext__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ./multiclip/OffsetMeshContext */ "../../core/geometry/lib/esm/polyface/multiclip/OffsetMeshContext.js");
251906
252124
  /* harmony import */ var _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./multiclip/SweepLineStringToFacetContext */ "../../core/geometry/lib/esm/polyface/multiclip/SweepLineStringToFacetContext.js");
251907
- /* harmony import */ var _multiclip_XYPointBuckets__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./multiclip/XYPointBuckets */ "../../core/geometry/lib/esm/polyface/multiclip/XYPointBuckets.js");
252125
+ /* harmony import */ var _multiclip_XYPointBuckets__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./multiclip/XYPointBuckets */ "../../core/geometry/lib/esm/polyface/multiclip/XYPointBuckets.js");
251908
252126
  /* harmony import */ var _Polyface__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Polyface */ "../../core/geometry/lib/esm/polyface/Polyface.js");
251909
- /* harmony import */ var _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./PolyfaceBuilder */ "../../core/geometry/lib/esm/polyface/PolyfaceBuilder.js");
251910
- /* harmony import */ var _RangeLengthData__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./RangeLengthData */ "../../core/geometry/lib/esm/polyface/RangeLengthData.js");
252127
+ /* harmony import */ var _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./PolyfaceBuilder */ "../../core/geometry/lib/esm/polyface/PolyfaceBuilder.js");
252128
+ /* harmony import */ var _RangeLengthData__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./RangeLengthData */ "../../core/geometry/lib/esm/polyface/RangeLengthData.js");
251911
252129
  /*---------------------------------------------------------------------------------------------
251912
252130
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
251913
252131
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -251951,7 +252169,6 @@ __webpack_require__.r(__webpack_exports__);
251951
252169
 
251952
252170
 
251953
252171
 
251954
-
251955
252172
 
251956
252173
 
251957
252174
  /**
@@ -251979,14 +252196,27 @@ class SweepLineStringToFacetsOptions {
251979
252196
  sideAngle;
251980
252197
  /** Option to assemble lines into chains. */
251981
252198
  assembleChains;
252199
+ /**
252200
+ * Optional searcher object for vertical sweep speedup. If provided, `vectorToEye` must be the positive Z vector.
252201
+ * @example To construct a 5x5 indexed search grid:
252202
+ * ````
252203
+ * const xyRange = Range2d.createFrom(myPolyface.range());
252204
+ * const searcher = GriddedRaggedRange2dSetWithOverflow.create<number>(xyRange, 5, 5)!;
252205
+ * for (const visitor = myPolyface.createVisitor(0); visitor.moveToNextFacet();) {
252206
+ * searcher.addRange(visitor.point.getRange(), visitor.currentReadIndex());
252207
+ * }
252208
+ * ````
252209
+ */
252210
+ searcher;
251982
252211
  /** Constructor. Captures fully-checked parameters from static create method. */
251983
- constructor(vectorToEye, sideAngle, assembleChains, collectOnForwardFacets, collectOnSideFacets, collectOnRearFacets) {
252212
+ constructor(vectorToEye, sideAngle, assembleChains, collectOnForwardFacets, collectOnSideFacets, collectOnRearFacets, searcher) {
251984
252213
  this.vectorToEye = vectorToEye;
251985
252214
  this.sideAngle = sideAngle;
251986
252215
  this.assembleChains = assembleChains;
251987
252216
  this.collectOnForwardFacets = collectOnForwardFacets;
251988
252217
  this.collectOnSideFacets = collectOnSideFacets;
251989
252218
  this.collectOnRearFacets = collectOnRearFacets;
252219
+ this.searcher = searcher;
251990
252220
  }
251991
252221
  /**
251992
252222
  * Create an options structure.
@@ -251995,14 +252225,12 @@ class SweepLineStringToFacetsOptions {
251995
252225
  * * Default `assembleChains` is `true`.
251996
252226
  * * Default `collectOnForwardFacets`, `collectOnSideFacets`, `collectOnRearFacets` are all `true`.
251997
252227
  */
251998
- static create(vectorToEye, sideAngle, assembleChains, collectOnForwardFacets, collectOnSideFacets, collectOnRearFacets) {
251999
- return new SweepLineStringToFacetsOptions(vectorToEye === undefined ? _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.unitZ() : vectorToEye.clone(), sideAngle === undefined ? _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createRadians(_Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallAngleRadians) : sideAngle.clone(), _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.resolveValue(assembleChains, true), _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.resolveValue(collectOnForwardFacets, true), _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.resolveValue(collectOnSideFacets, true), _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.resolveValue(collectOnRearFacets, true));
252228
+ static create(vectorToEye, sideAngle, assembleChains, collectOnForwardFacets, collectOnSideFacets, collectOnRearFacets, searcher) {
252229
+ return new SweepLineStringToFacetsOptions((!vectorToEye || searcher) ? _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.unitZ() : vectorToEye.clone(), sideAngle?.clone() ?? _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createRadians(_Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallAngleRadians), assembleChains ?? true, collectOnForwardFacets ?? true, collectOnSideFacets ?? true, collectOnRearFacets ?? true, searcher);
252000
252230
  }
252001
252231
  /** Return `true` if all outputs are requested. */
252002
252232
  get collectAll() {
252003
- return this.collectOnForwardFacets === true &&
252004
- this.collectOnSideFacets === true &&
252005
- this.collectOnRearFacets === true;
252233
+ return this.collectOnForwardFacets && this.collectOnSideFacets && this.collectOnRearFacets;
252006
252234
  }
252007
252235
  /**
252008
252236
  * Decide if the instance collector flags accept a facet with the given normal.
@@ -252113,21 +252341,21 @@ class PolyfaceQuery {
252113
252341
  * @param source polyface or visitor.
252114
252342
  * @param vectorToEye compute sum of (signed) facet areas projected to a view plane perpendicular to `vectorToEye`.
252115
252343
  * If `vectorToEye` is not provided, actual facet areas are calculated (without any projection).
252116
- * @returns the sum of all facet areas. Return 0 if `source` is `undefined`.
252344
+ * @returns the sum of all facet areas.
252117
252345
  */
252118
252346
  static sumFacetAreas(source, vectorToEye) {
252119
252347
  let sum = 0;
252120
- if (source !== undefined) {
252121
- if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface)
252122
- return PolyfaceQuery.sumFacetAreas(source.createVisitor(1), vectorToEye);
252123
- let unitVectorToEye;
252124
- if (vectorToEye !== undefined)
252125
- unitVectorToEye = vectorToEye.normalize();
252126
- source.reset();
252127
- while (source.moveToNextFacet()) {
252128
- const areaNormal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_8__.PolygonOps.areaNormal(source.point.getPoint3dArray());
252129
- sum += unitVectorToEye ? areaNormal.dotProduct(unitVectorToEye) : areaNormal.magnitude();
252130
- }
252348
+ if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface)
252349
+ source = source.createVisitor(1);
252350
+ else
252351
+ source.setNumWrap(1);
252352
+ let unitVectorToEye;
252353
+ if (vectorToEye !== undefined)
252354
+ unitVectorToEye = vectorToEye.normalize();
252355
+ source.reset();
252356
+ while (source.moveToNextFacet()) {
252357
+ const areaNormal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_8__.PolygonOps.areaNormal(source.point.getPoint3dArray());
252358
+ sum += unitVectorToEye ? areaNormal.dotProduct(unitVectorToEye) : areaNormal.magnitude();
252131
252359
  }
252132
252360
  return sum;
252133
252361
  }
@@ -252161,75 +252389,53 @@ class PolyfaceQuery {
252161
252389
  }
252162
252390
  /**
252163
252391
  * Sum (signed) volumes between facets and a plane.
252164
- * Return a structure with multiple sums:
252165
- * * volume = the sum of (signed) volumes between facets and the plane.
252166
- * * positiveProjectedFacetAreaMoments, negativeProjectedFacetAreaMoments = moment data with centroid, area, and second
252167
- * moments with respect to the centroid.
252168
- */
252169
- static sumVolumeBetweenFacetsAndPlane(source, plane) {
252170
- if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface)
252171
- return PolyfaceQuery.sumVolumeBetweenFacetsAndPlane(source.createVisitor(0), plane);
252172
- const facetOrigin = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create();
252173
- const targetA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create();
252174
- const targetB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create();
252175
- const triangleNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create();
252176
- const planeNormal = plane.getNormalRef();
252177
- let h0, hA, hB;
252178
- let signedVolumeSum = 0.0;
252179
- let signedTriangleArea;
252180
- let singleFacetArea;
252181
- const positiveAreaMomentSums = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_9__.MomentData.create(undefined, true);
252182
- const negativeAreaMomentSums = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_9__.MomentData.create(undefined, true);
252183
- const singleFacetProducts = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_10__.Matrix4d.createZero();
252184
- const projectToPlane = plane.getProjectionToPlane();
252185
- source.reset();
252392
+ * @param source facet set
252393
+ * @param plane infinite plane bounding volume between the input facets and (virtual) side facets perpendicular to the plane.
252394
+ * @param skipMoments whether to skip computation of the area moments. Set to `true` if only volume is needed. Default is `false`.
252395
+ * @returns a structure with multiple sums:
252396
+ * * volume: the sum of (signed) volumes between facets and the plane.
252397
+ * * positiveProjectedFacetAreaMoments, negativeProjectedFacetAreaMoments: area moment data (centroid, signed area,
252398
+ * and second moments with respect to the centroid), separately computed for the input facets that project with
252399
+ * positive/negative area onto the plane.
252400
+ */
252401
+ static sumVolumeBetweenFacetsAndPlane(source, plane, skipMoments) {
252402
+ const visitor = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface ? source.createVisitor(0) : source;
252403
+ visitor.setNumWrap(0);
252404
+ const workPoint0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create();
252405
+ const workPoint1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create();
252406
+ const workVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create();
252407
+ const workMatrix = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__.Matrix4d.createZero();
252408
+ let signedVolumeTimes6 = 0.0;
252409
+ const posSums = skipMoments ? undefined : _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_10__.MomentData.create(undefined, true);
252410
+ const negSums = skipMoments ? undefined : _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_10__.MomentData.create(undefined, true);
252186
252411
  // For each facet:
252187
252412
  // - form triangles from facet origin to each far edge.
252188
- // - sum signed area and volume contributions.
252189
- // each projected area contribution is twice the area of a triangle.
252190
- // each volume contribution is 3 times the actual volume -- (1/3) of the altitude sums was the centroid altitude.
252191
- while (source.moveToNextFacet()) {
252192
- source.point.getPoint3dAtUncheckedPointIndex(0, facetOrigin);
252193
- h0 = plane.altitude(facetOrigin);
252194
- singleFacetArea = 0;
252195
- // within a single facets, the singleFacetArea sum is accumulated with signs of individual triangles.
252196
- // for a non-convex facet, this can be a mixture of positive and negative areas.
252197
- // the absoluteProjectedAreaSum contribution is forced positive after the sum for the facet.
252198
- for (let i = 1; i + 1 < source.point.length; i++) {
252199
- source.point.getPoint3dAtUncheckedPointIndex(i, targetA);
252200
- source.point.getPoint3dAtUncheckedPointIndex(i + 1, targetB);
252201
- facetOrigin.crossProductToPoints(targetA, targetB, triangleNormal);
252202
- hA = plane.altitude(targetA);
252203
- hB = plane.altitude(targetB);
252204
- signedTriangleArea = planeNormal.dotProduct(triangleNormal);
252205
- singleFacetArea += signedTriangleArea;
252206
- signedVolumeSum += signedTriangleArea * (h0 + hA + hB);
252207
- }
252208
- singleFacetProducts.setZero();
252209
- source.point.multiplyTransformInPlace(projectToPlane);
252210
- _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_8__.PolygonOps.addSecondMomentAreaProducts(source.point, facetOrigin, singleFacetProducts);
252211
- if (singleFacetArea > 0) {
252212
- positiveAreaMomentSums.accumulateProductsFromOrigin(facetOrigin, singleFacetProducts, 1.0);
252213
- }
252214
- else {
252215
- negativeAreaMomentSums.accumulateProductsFromOrigin(facetOrigin, singleFacetProducts, 1.0);
252413
+ // - sum signed area and volume contributions (for non-convex facet, signs can be mixed).
252414
+ // - each projected area contribution is twice the area of a triangle.
252415
+ // - each volume contribution is 3 times the actual volume -- a third of the altitude sum is the centroid altitude.
252416
+ const options = { skipMoments, p0: workPoint0, p1: workPoint1, v0: workVector, m0: workMatrix };
252417
+ for (visitor.reset(); visitor.moveToNextFacet();) {
252418
+ const facetData = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_8__.PolygonOps.volumeBetweenPolygonAndPlane(visitor.point, plane, options);
252419
+ signedVolumeTimes6 += facetData.volume6;
252420
+ if (!skipMoments) {
252421
+ (0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.assert)(posSums !== undefined && negSums !== undefined && facetData.origin !== undefined && facetData.products !== undefined);
252422
+ if (facetData.area2 > 0)
252423
+ posSums.accumulateProductsFromOrigin(facetData.origin, facetData.products, 1.0);
252424
+ else
252425
+ negSums.accumulateProductsFromOrigin(facetData.origin, facetData.products, 1.0);
252216
252426
  }
252217
252427
  }
252218
- positiveAreaMomentSums.shiftOriginAndSumsToCentroidOfSums();
252219
- negativeAreaMomentSums.shiftOriginAndSumsToCentroidOfSums();
252220
- const positiveAreaMoments = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_9__.MomentData.inertiaProductsToPrincipalAxes(positiveAreaMomentSums.origin, positiveAreaMomentSums.sums);
252221
- const negativeAreaMoments = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_9__.MomentData.inertiaProductsToPrincipalAxes(negativeAreaMomentSums.origin, negativeAreaMomentSums.sums);
252222
252428
  return {
252223
- volume: signedVolumeSum / 6.0,
252224
- positiveProjectedFacetAreaMoments: positiveAreaMoments,
252225
- negativeProjectedFacetAreaMoments: negativeAreaMoments,
252429
+ volume: signedVolumeTimes6 / 6.0,
252430
+ positiveProjectedFacetAreaMoments: posSums ? _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_10__.MomentData.inertiaProductsToPrincipalAxes(posSums.origin, posSums.sums) : undefined,
252431
+ negativeProjectedFacetAreaMoments: negSums ? _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_10__.MomentData.inertiaProductsToPrincipalAxes(negSums.origin, negSums.sums) : undefined,
252226
252432
  };
252227
252433
  }
252228
252434
  /** Return the inertia products [xx,xy,xz,xw,yw, etc] integrated over all all facets as viewed from origin. */
252229
252435
  static sumFacetSecondAreaMomentProducts(source, origin) {
252230
252436
  if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface)
252231
252437
  return PolyfaceQuery.sumFacetSecondAreaMomentProducts(source.createVisitor(0), origin);
252232
- const products = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_10__.Matrix4d.createZero();
252438
+ const products = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__.Matrix4d.createZero();
252233
252439
  source.reset();
252234
252440
  while (source.moveToNextFacet()) {
252235
252441
  _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_8__.PolygonOps.addSecondMomentAreaProducts(source.point, origin, products);
@@ -252240,7 +252446,7 @@ class PolyfaceQuery {
252240
252446
  static sumFacetSecondVolumeMomentProducts(source, origin) {
252241
252447
  if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface)
252242
252448
  return PolyfaceQuery.sumFacetSecondVolumeMomentProducts(source.createVisitor(0), origin);
252243
- const products = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_10__.Matrix4d.createZero();
252449
+ const products = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__.Matrix4d.createZero();
252244
252450
  source.reset();
252245
252451
  while (source.moveToNextFacet()) {
252246
252452
  _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_8__.PolygonOps.addSecondMomentVolumeProducts(source.point, origin, products);
@@ -252258,7 +252464,7 @@ class PolyfaceQuery {
252258
252464
  if (!origin)
252259
252465
  return undefined;
252260
252466
  const inertiaProducts = PolyfaceQuery.sumFacetSecondAreaMomentProducts(source, origin);
252261
- return _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_9__.MomentData.inertiaProductsToPrincipalAxes(origin, inertiaProducts);
252467
+ return _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_10__.MomentData.inertiaProductsToPrincipalAxes(origin, inertiaProducts);
252262
252468
  }
252263
252469
  /**
252264
252470
  * Compute area moments for the mesh. In the returned MomentData:
@@ -252273,7 +252479,7 @@ class PolyfaceQuery {
252273
252479
  if (!origin)
252274
252480
  return undefined;
252275
252481
  const inertiaProducts = PolyfaceQuery.sumFacetSecondVolumeMomentProducts(source, origin);
252276
- return _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_9__.MomentData.inertiaProductsToPrincipalAxes(origin, inertiaProducts);
252482
+ return _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_10__.MomentData.inertiaProductsToPrincipalAxes(origin, inertiaProducts);
252277
252483
  }
252278
252484
  /**
252279
252485
  * Determine whether all facets are convex.
@@ -252297,7 +252503,7 @@ class PolyfaceQuery {
252297
252503
  * Compute a number summarizing the dihedral angles in the mesh.
252298
252504
  * * A dihedral angle is the signed angle between adjacent facets' normals. This angle is positive when the cross
252299
252505
  * product `normalA x normalB` has the same direction as facetA's traversal of the facets' shared edge.
252300
- * @param source mesh.
252506
+ * @param source facets.
252301
252507
  * @param ignoreBoundaries if `true` ignore simple boundary edges, i.e., allow unclosed meshes. Default is `false`.
252302
252508
  * See [[isConvexByDihedralAngleCount]] for comments about passing true when there are multiple
252303
252509
  * connected components.
@@ -252313,19 +252519,21 @@ class PolyfaceQuery {
252313
252519
  static dihedralAngleSummary(source, ignoreBoundaries = false) {
252314
252520
  // more info can be found at geometry/internaldocs/Polyface.md
252315
252521
  const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_11__.IndexedEdgeMatcher();
252316
- const visitor = source.createVisitor(1);
252317
- visitor.reset();
252318
- // find centroid normals of all facets
252522
+ const vertices = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface ? source.data.point : undefined;
252523
+ const visitor = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface ? source.createVisitor(1) : source;
252524
+ visitor.setNumWrap(1);
252319
252525
  const centroidNormal = [];
252320
252526
  let normalCounter = 0;
252321
- while (visitor.moveToNextFacet()) {
252527
+ for (visitor.reset(); visitor.moveToNextFacet();) {
252322
252528
  const numEdges = visitor.pointCount - 1;
252323
252529
  const normal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_8__.PolygonOps.centroidAreaNormal(visitor.point);
252324
252530
  if (normal === undefined)
252325
252531
  return -2;
252326
252532
  centroidNormal.push(normal);
252327
252533
  for (let i = 0; i < numEdges; i++) {
252328
- edges.addEdge(visitor.clientPointIndex(i), visitor.clientPointIndex(i + 1), normalCounter);
252534
+ const edge = edges.addEdge(visitor.clientPointIndex(i), visitor.clientPointIndex(i + 1), normalCounter);
252535
+ if (!vertices) // decorate if we don't have vertices to query later
252536
+ edge.edgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.createStartEnd(visitor.point.getPoint3dAtUncheckedPointIndex(i), visitor.point.getPoint3dAtUncheckedPointIndex(i + 1));
252329
252537
  }
252330
252538
  normalCounter++;
252331
252539
  }
@@ -252343,11 +252551,16 @@ class PolyfaceQuery {
252343
252551
  let numNegative = 0;
252344
252552
  const edgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create();
252345
252553
  for (const cluster of manifoldClusters) {
252346
- const sideA = cluster[0];
252347
- const sideB = cluster[1];
252348
- if (sideA instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_11__.SortableEdge && sideB instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_11__.SortableEdge
252349
- && source.data.point.vectorIndexIndex(sideA.vertexIndexA, sideA.vertexIndexB, edgeVector)) {
252350
- const dihedralAngle = centroidNormal[sideA.facetIndex].direction.signedAngleTo(centroidNormal[sideB.facetIndex].direction, edgeVector);
252554
+ if (Array.isArray(cluster) && cluster.length === 2) {
252555
+ const sideA = cluster[0];
252556
+ const sideB = cluster[1];
252557
+ if (vertices)
252558
+ vertices.vectorIndexIndex(sideA.startVertex, sideA.endVertex, edgeVector);
252559
+ else
252560
+ edgeVector.setFrom(sideA.edgeVector);
252561
+ const facetNormalA = centroidNormal[sideA.facetIndex].direction;
252562
+ const facetNormalB = centroidNormal[sideB.facetIndex].direction;
252563
+ const dihedralAngle = facetNormalA.signedAngleTo(facetNormalB, edgeVector);
252351
252564
  if (dihedralAngle.isAlmostZero)
252352
252565
  numPlanar++;
252353
252566
  else if (dihedralAngle.radians > 0.0)
@@ -252383,26 +252596,50 @@ class PolyfaceQuery {
252383
252596
  static isConvexByDihedralAngleCount(source, ignoreBoundaries = false) {
252384
252597
  return this.dihedralAngleSummary(source, ignoreBoundaries) > 0;
252385
252598
  }
252599
+ /** Helper function to detect a subset visitor. */
252600
+ static isSubsetVisitor(visitor) {
252601
+ if (visitor instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface)
252602
+ return false;
252603
+ const parentFacetCount = visitor.clientPolyface()?.facetCount;
252604
+ const visitableFacetCount = visitor.getVisitableFacetCount?.();
252605
+ if (parentFacetCount === undefined || visitableFacetCount === undefined)
252606
+ return false;
252607
+ return parentFacetCount > visitableFacetCount;
252608
+ }
252386
252609
  /**
252387
- * Test edges pairing in `source` mesh.
252388
- * * For `allowSimpleBoundaries === false`, a return value of `true` means this is a closed 2-manifold surface.
252389
- * * For `allowSimpleBoundaries === true`, a return value of `true` means this is a 2-manifold surface which may have
252390
- * a boundary, but is still properly matched internally.
252610
+ * Faster version of isPolyfaceManifold for specific input.
252611
+ * @returns whether the mesh is manifold, or undefined if unsuccessful.
252612
+ */
252613
+ static isPolyfaceManifoldFast(source, allowSimpleBoundaries) {
252614
+ if (allowSimpleBoundaries)
252615
+ return undefined; // edgeMateIndex does not distinguish boundary edges from non-manifold edges so we can only speed things up if we search for both
252616
+ if (this.isSubsetVisitor(source))
252617
+ return false; // edgeMateIndex doesn't capture the facet subset boundary
252618
+ const parentData = _Polyface__WEBPACK_IMPORTED_MODULE_7__.IndexedPolyface.hasEdgeMateIndex(source);
252619
+ if (!parentData)
252620
+ return undefined;
252621
+ for (const edgeMate of parentData.edgeMateIndex) {
252622
+ if (edgeMate === undefined)
252623
+ return false; // found a boundary or non-manifold edge
252624
+ }
252625
+ return true; // this is a 2-manifold closed surface
252626
+ }
252627
+ /**
252628
+ * Test edge pairing in `source` mesh.
252391
252629
  * * Any edge with 3 or more adjacent facets triggers `false` return.
252392
- * * Any edge with 2 adjacent facets in the same direction triggers a `false` return.
252630
+ * * Any edge with 2 adjacent facets in the same direction triggers `false` return.
252631
+ * * Null edges are ignored.
252632
+ * @param source facet set to examine
252633
+ * @param allowSimpleBoundaries if `false` (default), a return value of `true` means the facets form a closed
252634
+ * 2-manifold surface; if `true`, a return value of `true` means the facets form a 2-manifold surface which may
252635
+ * have a boundary, but is still properly matched internally.
252393
252636
  */
252394
252637
  static isPolyfaceManifold(source, allowSimpleBoundaries = false) {
252395
- const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_11__.IndexedEdgeMatcher();
252396
- const visitor = source.createVisitor(1);
252397
- visitor.reset();
252398
- while (visitor.moveToNextFacet()) {
252399
- const numEdges = visitor.pointCount - 1;
252400
- for (let i = 0; i < numEdges; i++) {
252401
- edges.addEdge(visitor.clientPointIndex(i), visitor.clientPointIndex(i + 1), visitor.currentReadIndex());
252402
- }
252403
- }
252638
+ const isManifold = this.isPolyfaceManifoldFast(source, allowSimpleBoundaries);
252639
+ if (isManifold !== undefined)
252640
+ return isManifold;
252404
252641
  const badClusters = [];
252405
- edges.sortAndCollectClusters(undefined, allowSimpleBoundaries ? undefined : badClusters, undefined, badClusters);
252642
+ this.createIndexedEdges(source).sortAndCollectClusters(undefined, allowSimpleBoundaries ? undefined : badClusters, undefined, badClusters);
252406
252643
  return badClusters.length === 0;
252407
252644
  }
252408
252645
  /** Test if the facets in `source` occur in perfectly mated pairs, as is required for a closed manifold volume. */
@@ -252410,50 +252647,107 @@ class PolyfaceQuery {
252410
252647
  return this.isPolyfaceManifold(source, false);
252411
252648
  }
252412
252649
  /**
252413
- * Test if the facets in `source` occur in perfectly mated pairs, as is required for a closed manifold volume.
252414
- * If not, extract the boundary edges as lines.
252650
+ * Faster version of announceBoundaryEdges for specific input.
252651
+ * @returns true if successfully announced boundary edges.
252652
+ */
252653
+ static announceBoundaryEdgesFast(source, announceEdge, includeTypical, includeMismatch, includeNull) {
252654
+ if (includeTypical !== includeMismatch)
252655
+ return false; // edgeMateIndex does not distinguish boundary edges from non-manifold edges
252656
+ if (!includeTypical && !includeNull)
252657
+ return true;
252658
+ if (this.isSubsetVisitor(source))
252659
+ return false; // edgeMateIndex doesn't capture the facet subset boundary
252660
+ const parentData = _Polyface__WEBPACK_IMPORTED_MODULE_7__.IndexedPolyface.hasEdgeMateIndex(source);
252661
+ if (!parentData)
252662
+ return false;
252663
+ const pointA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create();
252664
+ const pointB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create();
252665
+ for (let edgeIndex = 0; edgeIndex < parentData.edgeMateIndex.length; edgeIndex++) {
252666
+ const edgeMate = parentData.edgeMateIndex[edgeIndex];
252667
+ const announceBoundaryOrNonManifoldEdge = includeTypical && edgeMate === undefined;
252668
+ const announceNullEdge = includeNull && edgeMate === edgeIndex;
252669
+ if (announceBoundaryOrNonManifoldEdge || announceNullEdge) {
252670
+ const facetIndex = parentData.parent.edgeIndexToFacetIndex(edgeIndex);
252671
+ if (facetIndex !== undefined) { // should always be defined
252672
+ const pointIndexA = parentData.parent.data.pointIndex[edgeIndex];
252673
+ let nextEdgeIndex = edgeIndex + 1;
252674
+ if (nextEdgeIndex >= parentData.parent.facetIndex1(facetIndex))
252675
+ nextEdgeIndex = parentData.parent.facetIndex0(facetIndex);
252676
+ const pointIndexB = parentData.parent.data.pointIndex[nextEdgeIndex];
252677
+ parentData.parent.data.getPoint(pointIndexA, pointA);
252678
+ parentData.parent.data.getPoint(pointIndexB, pointB);
252679
+ announceEdge(pointA, pointB, pointIndexA, pointIndexB, facetIndex);
252680
+ }
252681
+ }
252682
+ }
252683
+ return true;
252684
+ }
252685
+ /**
252686
+ * Announce boundary edges of the facet set as line segments.
252415
252687
  * @param source polyface or visitor.
252416
252688
  * @param announceEdge function to be called with each boundary edge. The announcement is start and end points,
252417
- * start and end indices, and facet index.
252418
- * @param includeTypical true to announce typical boundary edges with a single adjacent facet.
252419
- * @param includeMismatch true to announce edges with more than 2 adjacent facets.
252420
- * @param includeNull true to announce edges with identical start and end vertex indices.
252689
+ * start and end vertex indices, and facet index.
252690
+ * @param includeTypical true to announce typical boundary edges with a single adjacent facet. Default is true.
252691
+ * @param includeMismatch true to announce non-manifold edges (more than 2 adjacent facets, or mismatched
252692
+ * orientations). Default is true.
252693
+ * @param includeNull true to announce edges with identical start and end vertex indices. Default is true.
252694
+ * @see [[announceBoundaryChainsAsLineString3d]] for boundary linestring announcement
252695
+ * @see [[collectBoundaryEdges]] for boundary chain collection
252696
+ * @see [[boundaryEdges]] for boundary edge collection
252421
252697
  */
252422
252698
  static announceBoundaryEdges(source, announceEdge, includeTypical = true, includeMismatch = true, includeNull = true) {
252423
- if (source === undefined || (!includeTypical && !includeMismatch && !includeNull))
252699
+ if (this.announceBoundaryEdgesFast(source, announceEdge, includeTypical, includeMismatch, includeNull))
252424
252700
  return;
252425
- const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_11__.IndexedEdgeMatcher();
252701
+ if (!includeTypical && !includeMismatch && !includeNull)
252702
+ return;
252703
+ const vertices = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface ? source.data.point : undefined;
252426
252704
  const visitor = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface ? source.createVisitor(1) : source;
252427
252705
  visitor.setNumWrap(1);
252428
- visitor.reset();
252429
- while (visitor.moveToNextFacet()) {
252706
+ const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_11__.IndexedEdgeMatcher();
252707
+ for (visitor.reset(); visitor.moveToNextFacet();) {
252430
252708
  const numEdges = visitor.pointCount - 1;
252431
252709
  for (let i = 0; i < numEdges; i++) {
252432
- edges.addEdge(visitor.clientPointIndex(i), visitor.clientPointIndex(i + 1), visitor.currentReadIndex());
252710
+ const edge = edges.addEdge(visitor.clientPointIndex(i), visitor.clientPointIndex(i + 1), visitor.currentReadIndex());
252711
+ if (!vertices) { // decorate if we don't have vertices to query later
252712
+ edge.pointA = visitor.point.getPoint3dAtUncheckedPointIndex(i);
252713
+ edge.pointB = visitor.point.getPoint3dAtUncheckedPointIndex(i + 1);
252714
+ }
252433
252715
  }
252434
252716
  }
252435
252717
  const boundaryEdges = [];
252436
- edges.sortAndCollectClusters(undefined, includeTypical ? boundaryEdges : undefined, includeNull ? boundaryEdges : undefined, includeMismatch ? boundaryEdges : undefined);
252718
+ const typicalEdges = includeTypical ? boundaryEdges : undefined;
252719
+ const nullEdges = includeNull ? boundaryEdges : undefined;
252720
+ const mismatchEdges = includeMismatch ? boundaryEdges : undefined;
252721
+ edges.sortAndCollectClusters(undefined, typicalEdges, nullEdges, mismatchEdges);
252437
252722
  if (boundaryEdges.length === 0)
252438
252723
  return;
252439
- const sourcePolyface = visitor.clientPolyface();
252440
252724
  const pointA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create();
252441
252725
  const pointB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create();
252442
252726
  for (const e of boundaryEdges) {
252443
- const e1 = e instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_11__.SortableEdge ? e : e[0];
252444
- const indexA = e1.vertexIndexA;
252445
- const indexB = e1.vertexIndexB;
252446
- if (sourcePolyface.data.getPoint(indexA, pointA) && sourcePolyface.data.getPoint(indexB, pointB))
252447
- announceEdge(pointA, pointB, indexA, indexB, e1.facetIndex);
252727
+ const e1 = e instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_11__.SortableEdge ? e : e[0]; // only report the first edge in a cluster!
252728
+ const indexA = e1.startVertex;
252729
+ const indexB = e1.endVertex;
252730
+ if (vertices) {
252731
+ vertices.getPoint3dAtUncheckedPointIndex(indexA, pointA);
252732
+ vertices.getPoint3dAtUncheckedPointIndex(indexB, pointB);
252733
+ }
252734
+ else {
252735
+ pointA.setFrom(e1.pointA);
252736
+ pointB.setFrom(e1.pointB);
252737
+ }
252738
+ announceEdge(pointA, pointB, indexA, indexB, e1.facetIndex);
252448
252739
  }
252449
252740
  }
252450
252741
  /**
252451
- * Construct a CurveCollection containing boundary edges.
252452
- * * Each edge is a LineSegment3d.
252742
+ * Collect boundary edges of the facet set as an unordered collection of line segments.
252453
252743
  * @param source polyface or visitor.
252454
- * @param includeTypical true to in include typical boundary edges with a single adjacent facet.
252455
- * @param includeMismatch true to include edges with more than 2 adjacent facets.
252456
- * @param includeNull true to include edges with identical start and end vertex indices.
252744
+ * @param includeTypical true to include typical boundary edges with a single adjacent facet. Default is true.
252745
+ * @param includeMismatch true to include non-manifold edges (more than 2 adjacent facets, or mismatched
252746
+ * orientations). Default is true.
252747
+ * @param includeNull true to include edges with identical start and end vertex indices. Default is true.
252748
+ * @see [[announceBoundaryChainsAsLineString3d]] for boundary linestring announcement
252749
+ * @see [[collectBoundaryEdges]] for boundary chain collection
252750
+ * @see [[announceBoundaryEdges]] for boundary edge announcement
252457
252751
  */
252458
252752
  static boundaryEdges(source, includeTypical = true, includeMismatch = true, includeNull = true) {
252459
252753
  const result = new _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_6__.BagOfCurves();
@@ -252466,33 +252760,32 @@ class PolyfaceQuery {
252466
252760
  return result;
252467
252761
  }
252468
252762
  /**
252469
- * Collect boundary edges.
252470
- * * Return the edges as the simplest collection of chains of line segments.
252763
+ * Collect boundary edges of the facet set as the simplest collection of chains of line segments.
252471
252764
  * @param source polyface or visitor.
252472
- * @param includeTypical true to include typical boundary edges with a single adjacent facet.
252473
- * @param includeMismatch true to include edges with more than 2 adjacent facets.
252474
- * @param includeNull true to include edges with identical start and end vertex indices.
252765
+ * @param includeTypical true to include typical boundary edges with a single adjacent facet. Default is true.
252766
+ * @param includeMismatch true to include non-manifold edges (more than 2 adjacent facets, or mismatched
252767
+ * orientations). Default is true.
252768
+ * @param includeNull true to include edges with identical start and end vertex indices. Default is true.
252769
+ * @see [[announceBoundaryChainsAsLineString3d]] for boundary linestring announcement
252770
+ * @see [[announceBoundaryEdges]] for boundary edge announcement
252771
+ * @see [[boundaryEdges]] for boundary edge collection
252475
252772
  */
252476
252773
  static collectBoundaryEdges(source, includeTypical = true, includeMismatch = true, includeNull = true) {
252477
252774
  const collector = new _curve_internalContexts_MultiChainCollector__WEBPACK_IMPORTED_MODULE_13__.MultiChainCollector(_Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistance, _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistance);
252478
- PolyfaceQuery.announceBoundaryEdges(source, (ptA, ptB) => collector.captureCurve(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_12__.LineSegment3d.create(ptA, ptB)), includeTypical, includeMismatch, includeNull);
252775
+ const announceEdge = (ptA, ptB) => collector.captureCurve(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_12__.LineSegment3d.create(ptA, ptB));
252776
+ PolyfaceQuery.announceBoundaryEdges(source, announceEdge, includeTypical, includeMismatch, includeNull);
252479
252777
  return collector.grabResult(true);
252480
252778
  }
252481
252779
  /**
252482
- * Load all half edges from a mesh to an IndexedEdgeMatcher.
252483
- * @param polyface a mesh or a visitor assumed to have numWrap === 1.
252484
- */
252780
+ * Load an IndexedEdgeMatcher from the edges of a mesh.
252781
+ * @param polyface a mesh or visitor
252782
+ */
252485
252783
  static createIndexedEdges(polyface) {
252486
- if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface)
252487
- return this.createIndexedEdges(polyface.createVisitor(1));
252488
252784
  const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_11__.IndexedEdgeMatcher();
252489
- polyface.reset();
252490
- while (polyface.moveToNextFacet()) {
252491
- const numEdges = polyface.pointCount - 1;
252492
- for (let i = 0; i < numEdges; i++) {
252493
- edges.addEdge(polyface.clientPointIndex(i), polyface.clientPointIndex(i + 1), polyface.currentReadIndex());
252494
- }
252495
- }
252785
+ const visitor = polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface ? polyface.createVisitor(1) : polyface;
252786
+ visitor.setNumWrap(1);
252787
+ for (visitor.reset(); visitor.moveToNextFacet();)
252788
+ edges.addPath(visitor.pointIndex, visitor.currentReadIndex(), false);
252496
252789
  return edges;
252497
252790
  }
252498
252791
  /**
@@ -252528,8 +252821,8 @@ class PolyfaceQuery {
252528
252821
  for (const pair of manifoldEdges) {
252529
252822
  if (!Array.isArray(pair) || pair.length !== 2)
252530
252823
  continue;
252531
- const indexA = pair[0].vertexIndexA;
252532
- const indexB = pair[0].vertexIndexB;
252824
+ const indexA = pair[0].startVertex;
252825
+ const indexB = pair[0].endVertex;
252533
252826
  if (!mesh.data.getPoint(indexA, pointA) || !mesh.data.getPoint(indexB, pointB))
252534
252827
  continue;
252535
252828
  const face0 = analyzeFace(pair[0].facetIndex);
@@ -252704,7 +252997,7 @@ class PolyfaceQuery {
252704
252997
  }
252705
252998
  /**
252706
252999
  * Return the boundary of facets that are facing the eye.
252707
- * @param polyface the indexed polyface
253000
+ * @param source polyface or visitor. Must be capable of constructing a subset visitor.
252708
253001
  * @param visibilitySubset selector among the visible facet sets extracted by partitionFacetIndicesByVisibilityVector
252709
253002
  * * 0 ==> forward facing
252710
253003
  * * 1 ==> rear facing
@@ -252712,21 +253005,29 @@ class PolyfaceQuery {
252712
253005
  * @param vectorToEye the vector to eye
252713
253006
  * @param sideAngleTolerance the tolerance of side angle
252714
253007
  */
252715
- static boundaryOfVisibleSubset(polyface, visibilitySelect, vectorToEye, sideAngleTolerance = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createDegrees(1.0e-3)) {
252716
- const partitionedIndices = this.partitionFacetIndicesByVisibilityVector(polyface, vectorToEye, sideAngleTolerance);
253008
+ static boundaryOfVisibleSubset(source, visibilitySelect, vectorToEye, sideAngleTolerance = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createDegrees(1.0e-3)) {
253009
+ const visitor = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface ? source.createVisitor(0) : source;
253010
+ if (!visitor.createSubsetVisitor)
253011
+ return undefined;
253012
+ const partitionedIndices = this.partitionFacetIndicesByVisibilityVector(source, vectorToEye, sideAngleTolerance);
252717
253013
  if (partitionedIndices[visibilitySelect].length === 0)
252718
253014
  return undefined;
252719
- const visitor = _IndexedPolyfaceVisitor__WEBPACK_IMPORTED_MODULE_16__.IndexedPolyfaceSubsetVisitor.createSubsetVisitor(polyface, partitionedIndices[visibilitySelect], 1);
252720
- return this.boundaryEdges(visitor, true, false, false);
253015
+ const subsetVisitor = visitor.createSubsetVisitor(partitionedIndices[visibilitySelect], 1);
253016
+ return this.boundaryEdges(subsetVisitor, true, false, false);
252721
253017
  }
252722
253018
  /**
252723
- * Search for edges with only 1 adjacent facet.
252724
- * * Accumulate them into chains.
252725
- * * Emit the chains to the `announceChain` callback.
253019
+ * Announce boundary edges of the facet set as linestrings.
253020
+ * * Ignores non-manifold interior edges and null edges.
253021
+ * @param source polyface or visitor.
253022
+ * @param announceChain function to be called with each chain of boundary edges.
253023
+ * @see [[collectBoundaryEdges]] for boundary chain collection
253024
+ * @see [[announceBoundaryEdges]] for boundary edge announcement
253025
+ * @see [[boundaryEdges]] for boundary edge collection
252726
253026
  */
252727
- static announceBoundaryChainsAsLineString3d(mesh, announceChain) {
253027
+ static announceBoundaryChainsAsLineString3d(source, announceChain) {
252728
253028
  const collector = new _curve_internalContexts_MultiChainCollector__WEBPACK_IMPORTED_MODULE_13__.MultiChainCollector(_Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistance); // no planarity tolerance needed
252729
- PolyfaceQuery.announceBoundaryEdges(mesh, (pointA, pointB, _indexA, _indexB) => collector.captureCurve(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_12__.LineSegment3d.create(pointA, pointB)), true, false, false);
253029
+ const announceEdge = (ptA, ptB) => collector.captureCurve(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_12__.LineSegment3d.create(ptA, ptB));
253030
+ PolyfaceQuery.announceBoundaryEdges(source, announceEdge, true, false, false);
252730
253031
  collector.announceChainsAsLineString3d(announceChain);
252731
253032
  }
252732
253033
  /**
@@ -252743,7 +253044,7 @@ class PolyfaceQuery {
252743
253044
  const numFacets = PolyfaceQuery.visitorClientFacetCount(mesh);
252744
253045
  const smoothEdges = PolyfaceQuery.collectEdgesByDihedralAngle(mesh, maxSmoothEdgeAngle);
252745
253046
  const partitions = PolyfaceQuery.partitionFacetIndicesBySortableEdgeClusters(smoothEdges, numFacets);
252746
- const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_17__.PolyfaceBuilder.create();
253047
+ const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create();
252747
253048
  const visitor = mesh;
252748
253049
  const planarPartitions = [];
252749
253050
  const partitionNormals = []; // average normal in each nontrivial partition
@@ -252763,7 +253064,7 @@ class PolyfaceQuery {
252763
253064
  if (_geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_8__.PolygonOps.areaNormalGo(visitor.point, normal))
252764
253065
  averageNormal.addInPlace(normal);
252765
253066
  }
252766
- partitionNormals.push(_geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_18__.Ray3d.createCapture(point0, averageNormal));
253067
+ partitionNormals.push(_geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_17__.Ray3d.createCapture(point0, averageNormal));
252767
253068
  planarPartitions.push(partition);
252768
253069
  }
252769
253070
  }
@@ -252772,8 +253073,8 @@ class PolyfaceQuery {
252772
253073
  (0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.assert)(planarPartitions.length === fragmentPolyfaces.length);
252773
253074
  const gapTolerance = 1.0e-4;
252774
253075
  const planarityTolerance = 1.0e-4;
252775
- const localToWorld = _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_19__.Transform.createIdentity();
252776
- const worldToLocal = _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_19__.Transform.createIdentity();
253076
+ const localToWorld = _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_18__.Transform.createIdentity();
253077
+ const worldToLocal = _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_18__.Transform.createIdentity();
252777
253078
  for (let i = 0; i < fragmentPolyfaces.length; ++i) {
252778
253079
  const fragment = fragmentPolyfaces[i];
252779
253080
  const edges = [];
@@ -252782,7 +253083,7 @@ class PolyfaceQuery {
252782
253083
  edges.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_12__.LineSegment3d.create(pointA, pointB));
252783
253084
  edgeStrings.push([pointA.clone(), pointB.clone()]);
252784
253085
  }, true, false, false);
252785
- const chains = _curve_CurveOps__WEBPACK_IMPORTED_MODULE_20__.CurveOps.collectChains(edges, gapTolerance, planarityTolerance);
253086
+ const chains = _curve_CurveOps__WEBPACK_IMPORTED_MODULE_19__.CurveOps.collectChains(edges, gapTolerance, planarityTolerance);
252786
253087
  if (chains) {
252787
253088
  // avoid FrameBuilder: it can flip the normal of a nonconvex facet!
252788
253089
  partitionNormals[i].toRigidZFrame(localToWorld);
@@ -252792,11 +253093,11 @@ class PolyfaceQuery {
252792
253093
  // But we aren't triangulating here. So if we don't have holes, we can skip regularization
252793
253094
  // to avoid splitting the loop.
252794
253095
  const regularize = !(chains instanceof _curve_Loop__WEBPACK_IMPORTED_MODULE_5__.Loop);
252795
- const graph = _topology_Merging__WEBPACK_IMPORTED_MODULE_21__.HalfEdgeGraphMerge.formGraphFromChains(edgeStrings, regularize, _topology_Graph__WEBPACK_IMPORTED_MODULE_22__.HalfEdgeMask.BOUNDARY_EDGE);
253096
+ const graph = _topology_Merging__WEBPACK_IMPORTED_MODULE_20__.HalfEdgeGraphMerge.formGraphFromChains(edgeStrings, regularize, _topology_Graph__WEBPACK_IMPORTED_MODULE_21__.HalfEdgeMask.BOUNDARY_EDGE);
252796
253097
  if (graph) {
252797
- _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_23__.HalfEdgeGraphSearch.collectConnectedComponentsWithExteriorParityMasks(graph, new _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_23__.HalfEdgeMaskTester(_topology_Graph__WEBPACK_IMPORTED_MODULE_22__.HalfEdgeMask.BOUNDARY_EDGE), _topology_Graph__WEBPACK_IMPORTED_MODULE_22__.HalfEdgeMask.EXTERIOR);
253098
+ _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_22__.HalfEdgeGraphSearch.collectConnectedComponentsWithExteriorParityMasks(graph, new _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_22__.HalfEdgeMaskTester(_topology_Graph__WEBPACK_IMPORTED_MODULE_21__.HalfEdgeMask.BOUNDARY_EDGE), _topology_Graph__WEBPACK_IMPORTED_MODULE_21__.HalfEdgeMask.EXTERIOR);
252798
253099
  // this.purgeNullFaces(HalfEdgeMask.EXTERIOR);
252799
- const polyface1 = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_17__.PolyfaceBuilder.graphToPolyface(graph);
253100
+ const polyface1 = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.graphToPolyface(graph);
252800
253101
  builder.addIndexedPolyface(polyface1, false, localToWorld);
252801
253102
  }
252802
253103
  }
@@ -252822,7 +253123,7 @@ class PolyfaceQuery {
252822
253123
  static fillSimpleHoles(mesh, options, unfilledChains) {
252823
253124
  if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface)
252824
253125
  return this.fillSimpleHoles(mesh.createVisitor(0), options, unfilledChains);
252825
- const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_17__.PolyfaceBuilder.create();
253126
+ const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create();
252826
253127
  const chains = [];
252827
253128
  PolyfaceQuery.announceBoundaryChainsAsLineString3d(mesh, (ls) => { ls.reverseInPlace(); chains.push(ls); });
252828
253129
  for (const c of chains) {
@@ -252832,11 +253133,11 @@ class PolyfaceQuery {
252832
253133
  rejected = true;
252833
253134
  else if (options.maxEdgesAroundHole !== undefined && points.length > options.maxEdgesAroundHole)
252834
253135
  rejected = true;
252835
- else if (options.maxPerimeter !== undefined && _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_24__.Point3dArray.sumEdgeLengths(points, false) > options.maxPerimeter)
253136
+ else if (options.maxPerimeter !== undefined && _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_23__.Point3dArray.sumEdgeLengths(points, false) > options.maxPerimeter)
252836
253137
  rejected = true;
252837
253138
  else if (options.upVector !== undefined && _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_8__.PolygonOps.sumTriangleAreasPerpendicularToUpVector(points, options.upVector) <= 0.0)
252838
253139
  rejected = true;
252839
- if (!rejected && _topology_SpaceTriangulation__WEBPACK_IMPORTED_MODULE_25__.SpacePolygonTriangulation.triangulateSimplestSpaceLoop(points, (_loop, triangles) => {
253140
+ if (!rejected && _topology_SpaceTriangulation__WEBPACK_IMPORTED_MODULE_24__.SpacePolygonTriangulation.triangulateSimplestSpaceLoop(points, (_loop, triangles) => {
252840
253141
  for (const t of triangles)
252841
253142
  builder.addPolygon(t);
252842
253143
  })) {
@@ -252860,13 +253161,13 @@ class PolyfaceQuery {
252860
253161
  }
252861
253162
  polyface.setNumWrap(0);
252862
253163
  const polyfaces = [];
252863
- const options = _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_26__.StrokeOptions.createForFacets();
253164
+ const options = _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_25__.StrokeOptions.createForFacets();
252864
253165
  options.needNormals = polyface.normal !== undefined;
252865
253166
  options.needParams = polyface.param !== undefined;
252866
253167
  options.needColors = polyface.color !== undefined;
252867
253168
  options.needTwoSided = polyface.twoSided;
252868
253169
  for (const partition of partitions) {
252869
- const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_17__.PolyfaceBuilder.create(options);
253170
+ const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create(options);
252870
253171
  polyface.reset();
252871
253172
  for (const facetIndex of partition) {
252872
253173
  polyface.moveToReadIndex(facetIndex);
@@ -252882,12 +253183,12 @@ class PolyfaceQuery {
252882
253183
  return this.cloneFiltered(source.createVisitor(0), filter);
252883
253184
  }
252884
253185
  source.setNumWrap(0);
252885
- const options = _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_26__.StrokeOptions.createForFacets();
253186
+ const options = _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_25__.StrokeOptions.createForFacets();
252886
253187
  options.needNormals = source.normal !== undefined;
252887
253188
  options.needParams = source.param !== undefined;
252888
253189
  options.needColors = source.color !== undefined;
252889
253190
  options.needTwoSided = source.twoSided;
252890
- const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_17__.PolyfaceBuilder.create(options);
253191
+ const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create(options);
252891
253192
  source.reset();
252892
253193
  for (; source.moveToNextFacet();) {
252893
253194
  if (filter(source))
@@ -252899,12 +253200,12 @@ class PolyfaceQuery {
252899
253200
  static cloneWithDanglingEdgesRemoved(source) {
252900
253201
  if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface)
252901
253202
  return this.cloneWithDanglingEdgesRemoved(source.createVisitor(0));
252902
- const options = _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_26__.StrokeOptions.createForFacets();
253203
+ const options = _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_25__.StrokeOptions.createForFacets();
252903
253204
  options.needNormals = source.normal !== undefined;
252904
253205
  options.needParams = source.param !== undefined;
252905
253206
  options.needColors = source.color !== undefined;
252906
253207
  options.needTwoSided = source.twoSided;
252907
- const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_17__.PolyfaceBuilder.create(options);
253208
+ const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create(options);
252908
253209
  // Finds an odd palindrome in data as indexed by indices.
252909
253210
  // An odd palindrome in a face loop corresponds to dangling edges in the face.
252910
253211
  // If one is found, indices is mutated to excise the palindrome (data is untouched).
@@ -253062,7 +253363,7 @@ class PolyfaceQuery {
253062
253363
  * * Input facets are ASSUMED to be convex and planar, and not overlap in the z direction.
253063
253364
  */
253064
253365
  static sweepLineStringToFacetsXYReturnSweptFacets(lineStringPoints, polyface) {
253065
- const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_17__.PolyfaceBuilder.create();
253366
+ const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create();
253066
253367
  this.announceSweepLinestringToConvexPolyfaceXY(lineStringPoints, polyface, (_linestring, _segmentIndex, _polyface, _facetIndex, points) => {
253067
253368
  if (points.length === 4)
253068
253369
  builder.addQuadFacet(points);
@@ -253076,89 +253377,94 @@ class PolyfaceQuery {
253076
253377
  return this.sweepLineStringToFacetsXYReturnSweptFacets(linestringPoints, polyface);
253077
253378
  }
253078
253379
  /**
253079
- * Sweep the line string to intersections with a mesh.
253080
- * * Return collected line segments.
253081
- * * If no options are given, the default sweep direction is the z-axis, and chains are assembled and returned.
253082
- * * See [[SweepLineStringToFacetsOptions]] for input and output options, including filtering by forward/side/rear facets.
253380
+ * Sweep the line string to intersections with a mesh and return collected line segments.
253083
253381
  * * Facets are ASSUMED to be convex and planar, and not overlap in the sweep direction.
253084
- */
253085
- static sweepLineStringToFacets(linestringPoints, polyfaceOrVisitor, options) {
253382
+ * @param points the linestring to drape onto the mesh.
253383
+ * @param source target facet set. For best results, facets should be convex and planar.
253384
+ * @param options input, filtering, search, and output options.
253385
+ * * If `undefined`, the default sweep direction is the positive z-axis, and chains are assembled and returned.
253386
+ * * For faster _vertical_ sweep, a pre-computed range tree can be supplied in `options.searcher`.
253387
+ * * For faster _non-vertical_ sweep, first transform inputs with the inverse of the transform
253388
+ * `T = Transform.createRigidFromOriginAndVector(undefined, options.vectorToEye)`, construct the searcher on these
253389
+ * local facets, call `sweepLineStringToFacets/XY` with these local inputs (and default sweep direction), and lastly,
253390
+ * transform the returned draped linework back to world coordinates with `T`.
253391
+ */
253392
+ static sweepLineStringToFacets(points, source, options) {
253086
253393
  let result = [];
253087
- // setup default options
253088
253394
  if (options === undefined)
253089
- options = SweepLineStringToFacetsOptions.create(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.unitZ(), _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createRadians(_Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallAngleRadians), // tight geometry tolerance for vertical side facets
253090
- true, true, true, true);
253395
+ options = SweepLineStringToFacetsOptions.create();
253091
253396
  let chainContext;
253092
253397
  if (options.assembleChains)
253093
- chainContext = _topology_ChainMerge__WEBPACK_IMPORTED_MODULE_27__.ChainMergeContext.create();
253094
- const context = _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_14__.ClipSweptLineStringContext.create(linestringPoints, options.vectorToEye);
253095
- if (context) {
253096
- let visitor;
253097
- if (polyfaceOrVisitor instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface)
253098
- visitor = polyfaceOrVisitor.createVisitor(0);
253099
- else
253100
- visitor = polyfaceOrVisitor;
253101
- const workNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.createZero();
253102
- for (visitor.reset(); visitor.moveToNextFacet();) {
253103
- if (options.collectFromThisFacetNormal(_geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_8__.PolygonOps.areaNormalGo(visitor.point, workNormal))) {
253104
- context.processPolygon(visitor.point.getArray(), (pointA, pointB) => {
253105
- if (chainContext !== undefined)
253106
- chainContext.addSegment(pointA, pointB);
253107
- else
253108
- result.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_12__.LineSegment3d.create(pointA, pointB));
253109
- });
253398
+ chainContext = _topology_ChainMerge__WEBPACK_IMPORTED_MODULE_26__.ChainMergeContext.create();
253399
+ const addSegment = chainContext ? (ptA, ptB) => chainContext.addSegment(ptA, ptB) : (ptA, ptB) => result.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_12__.LineSegment3d.create(ptA, ptB));
253400
+ const workNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.createZero();
253401
+ const visitor = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface ? source.createVisitor(0) : source;
253402
+ visitor.setNumWrap(0);
253403
+ if (options.searcher && options.vectorToEye.isParallelTo(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.unitZ())) {
253404
+ const searchRange = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_27__.Range3d.createNull();
253405
+ const workPoint0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.createZero();
253406
+ const workPoint1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.createZero();
253407
+ let edgeClipper;
253408
+ const clipEdgeToConvexPolygon = (_facetRange, readIndex) => {
253409
+ if (visitor.moveToReadIndex(readIndex) && (options.collectAll || options.collectFromThisFacetNormal(_geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_8__.PolygonOps.areaNormalGo(visitor.point, workNormal))))
253410
+ edgeClipper?.processPolygon(visitor.point, (ptA, ptB) => addSegment(ptA, ptB));
253411
+ return true;
253412
+ };
253413
+ for (let i = 1; i < points.length; i++) {
253414
+ points.getPoint3dAtUncheckedPointIndex(i - 1, workPoint0);
253415
+ points.getPoint3dAtUncheckedPointIndex(i, workPoint1);
253416
+ if (edgeClipper = _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_14__.EdgeClipData.createPointPointSweep(workPoint0, workPoint1, options.vectorToEye)) {
253417
+ searchRange.setNull();
253418
+ searchRange.extend(workPoint0, workPoint1);
253419
+ options.searcher.searchRange2d(searchRange, clipEdgeToConvexPolygon);
253110
253420
  }
253111
253421
  }
253112
- if (chainContext !== undefined) {
253113
- chainContext.clusterAndMergeVerticesXYZ();
253114
- result = chainContext.collectMaximalChains();
253422
+ }
253423
+ else {
253424
+ const context = _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_14__.ClipSweptLineStringContext.create(points, options.vectorToEye);
253425
+ if (context) {
253426
+ for (visitor.reset(); visitor.moveToNextFacet();) {
253427
+ if (options.collectAll || options.collectFromThisFacetNormal(_geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_8__.PolygonOps.areaNormalGo(visitor.point, workNormal)))
253428
+ context.processPolygon(visitor.point.getArray(), addSegment);
253429
+ }
253115
253430
  }
253116
253431
  }
253432
+ if (chainContext) {
253433
+ chainContext.clusterAndMergeVerticesXYZ();
253434
+ result = chainContext.collectMaximalChains();
253435
+ }
253117
253436
  return result;
253118
253437
  }
253119
253438
  /**
253120
253439
  * Sweep the line string in the z-direction to intersections with a mesh, using a search object for speedup.
253121
- * @param lineStringPoints input line string to drape on the mesh.
253122
- * @param polyfaceOrVisitor mesh, or mesh visitor to traverse only part of a mesh.
253123
- * @param searchByReadIndex object for searching facet 2D ranges tagged by mesh read index.
253124
- * @example Using a 5x5 indexed search grid:
253125
- * ```
253126
- * const xyRange = Range2d.createFrom(myPolyface.range());
253127
- * const searcher = GriddedRaggedRange2dSetWithOverflow.create<number>(xyRange, 5, 5)!;
253128
- * for (const visitor = myPolyface.createVisitor(0); visitor.moveToNextFacet();) {
253129
- * searcher.addRange(visitor.point.getRange(), visitor.currentReadIndex());
253130
- * }
253131
- * const drapedLineStrings = PolyfaceQuery.sweepLineStringToFacetsXY(lineString, myPolyface, searcher);
253132
- * ```
253440
+ * @param points the linestring to drape onto the mesh.
253441
+ * @param source target facet set. For best results, facets should be convex and planar.
253442
+ * @param searcher object for searching facet 2D ranges tagged by mesh read index.
253133
253443
  * @returns the collected line strings.
253134
- */
253135
- static sweepLineStringToFacetsXY(lineStringPoints, polyfaceOrVisitor, searchByReadIndex) {
253136
- const chainContext = _topology_ChainMerge__WEBPACK_IMPORTED_MODULE_27__.ChainMergeContext.create();
253137
- const sweepVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(0, 0, 1);
253138
- const searchRange = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_28__.Range3d.create();
253139
- let visitor;
253140
- if (polyfaceOrVisitor instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface)
253141
- visitor = polyfaceOrVisitor.createVisitor(0);
253142
- else
253143
- visitor = polyfaceOrVisitor;
253144
- let lineStringSource;
253145
- if (Array.isArray(lineStringPoints))
253146
- lineStringSource = new _geometry3d_Point3dArrayCarrier__WEBPACK_IMPORTED_MODULE_29__.Point3dArrayCarrier(lineStringPoints);
253147
- else
253148
- lineStringSource = lineStringPoints;
253444
+ * @see [[sweepLineStringToFacets]] for further options.
253445
+ */
253446
+ static sweepLineStringToFacetsXY(points, source, searcher) {
253447
+ const chainContext = _topology_ChainMerge__WEBPACK_IMPORTED_MODULE_26__.ChainMergeContext.create();
253448
+ const vectorToEye = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.unitZ();
253449
+ const searchRange = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_27__.Range3d.create();
253450
+ const workPoint0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.createZero();
253451
+ const workPoint1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.createZero();
253452
+ const visitor = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface ? source.createVisitor(0) : source;
253453
+ visitor.setNumWrap(0);
253454
+ let edgeClipper;
253455
+ const clipEdgeToConvexPolygon = (_facetRange, readIndex) => {
253456
+ if (visitor.moveToReadIndex(readIndex))
253457
+ edgeClipper?.processPolygon(visitor.point, (ptA, ptB) => chainContext.addSegment(ptA, ptB));
253458
+ return true;
253459
+ };
253460
+ const lineStringSource = Array.isArray(points) ? new _geometry3d_Point3dArrayCarrier__WEBPACK_IMPORTED_MODULE_28__.Point3dArrayCarrier(points) : points;
253149
253461
  for (let i = 1; i < lineStringSource.length; i++) {
253150
- const point0 = lineStringSource.getPoint3dAtUncheckedPointIndex(i - 1);
253151
- const point1 = lineStringSource.getPoint3dAtUncheckedPointIndex(i);
253152
- const edgeClipper = _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_14__.EdgeClipData.createPointPointSweep(point0, point1, sweepVector);
253153
- if (edgeClipper !== undefined) {
253154
- _geometry3d_Range__WEBPACK_IMPORTED_MODULE_28__.Range3d.createNull(searchRange);
253155
- searchRange.extendPoint(point0);
253156
- searchRange.extendPoint(point1);
253157
- searchByReadIndex.searchRange2d(searchRange, (_facetRange, readIndex) => {
253158
- if (visitor.moveToReadIndex(readIndex))
253159
- edgeClipper.processPolygon(visitor.point, (pointA, pointB) => chainContext.addSegment(pointA, pointB));
253160
- return true;
253161
- });
253462
+ lineStringSource.getPoint3dAtUncheckedPointIndex(i - 1, workPoint0);
253463
+ lineStringSource.getPoint3dAtUncheckedPointIndex(i, workPoint1);
253464
+ if (edgeClipper = _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_14__.EdgeClipData.createPointPointSweep(workPoint0, workPoint1, vectorToEye)) {
253465
+ searchRange.setNull();
253466
+ searchRange.extend(workPoint0, workPoint1);
253467
+ searcher.searchRange2d(searchRange, clipEdgeToConvexPolygon);
253162
253468
  }
253163
253469
  }
253164
253470
  chainContext.clusterAndMergeVerticesXYZ();
@@ -253173,20 +253479,16 @@ class PolyfaceQuery {
253173
253479
  */
253174
253480
  static sweepLinestringToFacetsXYReturnLines(linestringPoints, polyface) {
253175
253481
  const options = SweepLineStringToFacetsOptions.create(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.unitZ(), _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createSmallAngle(), false, true, true, true);
253176
- const result = PolyfaceQuery.sweepLineStringToFacets(linestringPoints, polyface, options);
253177
- return result;
253482
+ return PolyfaceQuery.sweepLineStringToFacets(linestringPoints, polyface, options);
253178
253483
  }
253179
253484
  /**
253180
253485
  * Find segments (within the linestring) which project to facets.
253181
253486
  * * Return chains.
253182
- * * This calls [[sweepLineStringToFacets]] with options created by
253183
- * `const options = SweepLineStringToFacetsOptions.create(Vector3d.unitZ(), Angle.createSmallAngle(),true, true, true, true);`
253487
+ * * This calls [[sweepLineStringToFacets]] with default options.
253184
253488
  * @deprecated in 4.x. Use [[PolyfaceQuery.sweepLineStringToFacets]] to get further options.
253185
253489
  */
253186
253490
  static sweepLinestringToFacetsXYReturnChains(linestringPoints, polyface) {
253187
- const options = SweepLineStringToFacetsOptions.create(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.unitZ(), _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createSmallAngle(), true, true, true, true);
253188
- const result = PolyfaceQuery.sweepLineStringToFacets(linestringPoints, polyface, options);
253189
- return result;
253491
+ return PolyfaceQuery.sweepLineStringToFacets(linestringPoints, polyface);
253190
253492
  }
253191
253493
  /**
253192
253494
  * Find segments (within the linestring) which project to facets.
@@ -253198,7 +253500,7 @@ class PolyfaceQuery {
253198
253500
  * * Facets are ASSUMED to be convex and planar, and not overlap in the z direction.
253199
253501
  */
253200
253502
  static async asyncSweepLinestringToFacetsXYReturnChains(linestringPoints, polyface) {
253201
- const chainContext = _topology_ChainMerge__WEBPACK_IMPORTED_MODULE_27__.ChainMergeContext.create();
253503
+ const chainContext = _topology_ChainMerge__WEBPACK_IMPORTED_MODULE_26__.ChainMergeContext.create();
253202
253504
  await Promise.resolve(this.asyncAnnounceSweepLinestringToConvexPolyfaceXY(linestringPoints, polyface, (_linestring, _segmentIndex, _polyface, _facetIndex, points, indexA, indexB) => {
253203
253505
  chainContext.addSegment(points[indexA], points[indexB]);
253204
253506
  }));
@@ -253214,7 +253516,7 @@ class PolyfaceQuery {
253214
253516
  if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_7__.Polyface) {
253215
253517
  return this.collectRangeLengthData(polyface.createVisitor(0));
253216
253518
  }
253217
- const rangeData = new _RangeLengthData__WEBPACK_IMPORTED_MODULE_30__.RangeLengthData();
253519
+ const rangeData = new _RangeLengthData__WEBPACK_IMPORTED_MODULE_29__.RangeLengthData();
253218
253520
  // polyface is a visitor
253219
253521
  for (polyface.reset(); polyface.moveToNextFacet();)
253220
253522
  rangeData.accumulateGrowableXYZArrayRange(polyface.point);
@@ -253227,9 +253529,9 @@ class PolyfaceQuery {
253227
253529
  static cloneWithTVertexFixup(polyface) {
253228
253530
  const oldFacetVisitor = polyface.createVisitor(1); // this is to visit the existing facets
253229
253531
  const newFacetVisitor = polyface.createVisitor(0); // this is to build the new facets
253230
- const rangeSearcher = _multiclip_XYPointBuckets__WEBPACK_IMPORTED_MODULE_31__.XYPointBuckets.create(polyface.data.point, 30);
253231
- const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_17__.PolyfaceBuilder.create();
253232
- const edgeRange = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_28__.Range3d.createNull();
253532
+ const rangeSearcher = _multiclip_XYPointBuckets__WEBPACK_IMPORTED_MODULE_30__.XYPointBuckets.create(polyface.data.point, 30);
253533
+ const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create();
253534
+ const edgeRange = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_27__.Range3d.createNull();
253233
253535
  const point0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create();
253234
253536
  const point1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create();
253235
253537
  const spacePoint = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create();
@@ -253361,7 +253663,7 @@ class PolyfaceQuery {
253361
253663
  * @param clusterSelector indicates whether to copy 0, 1, or all facets in each cluster of duplicate facets.
253362
253664
  */
253363
253665
  static cloneByFacetDuplication(source, includeSingletons, clusterSelector) {
253364
- const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_17__.PolyfaceBuilder.create();
253666
+ const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create();
253365
253667
  const visitor = source.createVisitor(0);
253366
253668
  this.announceDuplicateFacetIndices(source, (clusterFacetIndices) => {
253367
253669
  let numToSelect = 0;
@@ -253388,7 +253690,7 @@ class PolyfaceQuery {
253388
253690
  static cloneWithColinearEdgeFixup(polyface) {
253389
253691
  const oldFacetVisitor = polyface.createVisitor(2); // this is to visit the existing facets
253390
253692
  const newFacetVisitor = polyface.createVisitor(0); // this is to build the new facets
253391
- const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_17__.PolyfaceBuilder.create();
253693
+ const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create();
253392
253694
  const vector01 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create();
253393
253695
  const vector12 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create();
253394
253696
  const numPoint = polyface.data.point.length;
@@ -253438,11 +253740,11 @@ class PolyfaceQuery {
253438
253740
  static setEdgeVisibility(polyface, clusters, value) {
253439
253741
  for (const cluster of clusters) {
253440
253742
  if (cluster instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_11__.SortableEdge) {
253441
- this.setSingleEdgeVisibility(polyface, cluster.facetIndex, cluster.vertexIndexA, value);
253743
+ this.setSingleEdgeVisibility(polyface, cluster.facetIndex, cluster.startVertex, value);
253442
253744
  }
253443
253745
  else if (Array.isArray(cluster)) {
253444
253746
  for (const e1 of cluster)
253445
- this.setSingleEdgeVisibility(polyface, e1.facetIndex, e1.vertexIndexA, value);
253747
+ this.setSingleEdgeVisibility(polyface, e1.facetIndex, e1.startVertex, value);
253446
253748
  }
253447
253749
  }
253448
253750
  }
@@ -253544,8 +253846,8 @@ class PolyfaceQuery {
253544
253846
  && undefined !== PolyfaceQuery.computeFacetUnitNormal(visitor, e1.facetIndex, normal1)) {
253545
253847
  const edgeAngle = normal0.smallerUnorientedAngleTo(normal1);
253546
253848
  if (edgeAngle.radians > sharpEdgeAngle.radians) {
253547
- this.setSingleEdgeVisibility(mesh, e0.facetIndex, e0.vertexIndexA, true);
253548
- this.setSingleEdgeVisibility(mesh, e1.facetIndex, e1.vertexIndexA, true);
253849
+ this.setSingleEdgeVisibility(mesh, e0.facetIndex, e0.startVertex, true);
253850
+ this.setSingleEdgeVisibility(mesh, e1.facetIndex, e1.startVertex, true);
253549
253851
  }
253550
253852
  }
253551
253853
  }
@@ -253581,7 +253883,7 @@ class PolyfaceQuery {
253581
253883
  * @internal
253582
253884
  */
253583
253885
  static convertToHalfEdgeGraph(mesh) {
253584
- const builder = new _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_32__.HalfEdgeGraphFromIndexedLoopsContext();
253886
+ const builder = new _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_31__.HalfEdgeGraphFromIndexedLoopsContext();
253585
253887
  const visitor = mesh.createVisitor(0);
253586
253888
  for (visitor.reset(); visitor.moveToNextFacet();) {
253587
253889
  builder.insertLoop(visitor.pointIndex);
@@ -253598,11 +253900,11 @@ class PolyfaceQuery {
253598
253900
  }
253599
253901
  /** Examine adjacent facet orientations throughout the mesh. If possible, reverse a subset to achieve proper pairing. */
253600
253902
  static reorientVertexOrderAroundFacetsForConsistentOrientation(mesh) {
253601
- return _FacetOrientation__WEBPACK_IMPORTED_MODULE_33__.FacetOrientationFixup.doFixup(mesh);
253903
+ return _FacetOrientation__WEBPACK_IMPORTED_MODULE_32__.FacetOrientationFixup.doFixup(mesh);
253602
253904
  }
253603
253905
  /** Set up indexed normals with one normal in the plane of each facet of the mesh. */
253604
253906
  static buildPerFaceNormals(polyface) {
253605
- _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_34__.BuildAverageNormalsContext.buildPerFaceNormals(polyface);
253907
+ _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_33__.BuildAverageNormalsContext.buildPerFaceNormals(polyface);
253606
253908
  }
253607
253909
  /**
253608
253910
  * * At each vertex of the mesh:
@@ -253616,7 +253918,7 @@ class PolyfaceQuery {
253616
253918
  * @param toleranceAngle averaging is done between normals up to this angle.
253617
253919
  */
253618
253920
  static buildAverageNormals(polyface, toleranceAngle = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createDegrees(31.0)) {
253619
- _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_34__.BuildAverageNormalsContext.buildFastAverageNormals(polyface, toleranceAngle);
253921
+ _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_33__.BuildAverageNormalsContext.buildFastAverageNormals(polyface, toleranceAngle);
253620
253922
  }
253621
253923
  /**
253622
253924
  * Offset the faces of the mesh.
@@ -253626,9 +253928,9 @@ class PolyfaceQuery {
253626
253928
  * @returns shifted mesh.
253627
253929
  */
253628
253930
  static cloneOffset(source, signedOffsetDistance, offsetOptions = OffsetMeshOptions.create()) {
253629
- const strokeOptions = _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_26__.StrokeOptions.createForFacets();
253630
- const offsetBuilder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_17__.PolyfaceBuilder.create(strokeOptions);
253631
- _multiclip_OffsetMeshContext__WEBPACK_IMPORTED_MODULE_35__.OffsetMeshContext.buildOffsetMeshWithEdgeChamfers(source, offsetBuilder, signedOffsetDistance, offsetOptions);
253931
+ const strokeOptions = _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_25__.StrokeOptions.createForFacets();
253932
+ const offsetBuilder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create(strokeOptions);
253933
+ _multiclip_OffsetMeshContext__WEBPACK_IMPORTED_MODULE_34__.OffsetMeshContext.buildOffsetMeshWithEdgeChamfers(source, offsetBuilder, signedOffsetDistance, offsetOptions);
253632
253934
  return offsetBuilder.claimPolyface();
253633
253935
  }
253634
253936
  static _workTriangle;
@@ -253665,17 +253967,17 @@ class PolyfaceQuery {
253665
253967
  const numEdges = visitor.pointCount; // #vertices = #edges since numWrap is zero
253666
253968
  const vertices = visitor.point;
253667
253969
  if (3 === numEdges) {
253668
- const tri = this._workTriangle = _geometry3d_BarycentricTriangle__WEBPACK_IMPORTED_MODULE_36__.BarycentricTriangle.create(vertices.getPoint3dAtUncheckedPointIndex(0), vertices.getPoint3dAtUncheckedPointIndex(1), vertices.getPoint3dAtUncheckedPointIndex(2), this._workTriangle);
253970
+ const tri = this._workTriangle = _geometry3d_BarycentricTriangle__WEBPACK_IMPORTED_MODULE_35__.BarycentricTriangle.create(vertices.getPoint3dAtUncheckedPointIndex(0), vertices.getPoint3dAtUncheckedPointIndex(1), vertices.getPoint3dAtUncheckedPointIndex(2), this._workTriangle);
253669
253971
  const detail3 = this._workTriDetail = tri.intersectRay3d(ray, this._workTriDetail);
253670
253972
  tri.snapLocationToEdge(detail3, options?.distanceTolerance, options?.parameterTolerance);
253671
- detail = this._workFacetDetail3 = _FacetLocationDetail__WEBPACK_IMPORTED_MODULE_37__.TriangularFacetLocationDetail.create(visitor.currentReadIndex(), detail3, this._workFacetDetail3);
253973
+ detail = this._workFacetDetail3 = _FacetLocationDetail__WEBPACK_IMPORTED_MODULE_36__.TriangularFacetLocationDetail.create(visitor.currentReadIndex(), detail3, this._workFacetDetail3);
253672
253974
  }
253673
253975
  else {
253674
253976
  const detailN = this._workPolyDetail = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_8__.PolygonOps.intersectRay3d(vertices, ray, tol, this._workPolyDetail);
253675
253977
  if (_geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_8__.PolygonOps.isConvex(vertices))
253676
- detail = this._workFacetDetailC = _FacetLocationDetail__WEBPACK_IMPORTED_MODULE_37__.ConvexFacetLocationDetail.create(visitor.currentReadIndex(), numEdges, detailN, this._workFacetDetailC);
253978
+ detail = this._workFacetDetailC = _FacetLocationDetail__WEBPACK_IMPORTED_MODULE_36__.ConvexFacetLocationDetail.create(visitor.currentReadIndex(), numEdges, detailN, this._workFacetDetailC);
253677
253979
  else
253678
- detail = this._workFacetDetailNC = _FacetLocationDetail__WEBPACK_IMPORTED_MODULE_37__.NonConvexFacetLocationDetail.create(visitor.currentReadIndex(), numEdges, detailN, this._workFacetDetailNC);
253980
+ detail = this._workFacetDetailNC = _FacetLocationDetail__WEBPACK_IMPORTED_MODULE_36__.NonConvexFacetLocationDetail.create(visitor.currentReadIndex(), numEdges, detailN, this._workFacetDetailNC);
253679
253981
  }
253680
253982
  if (detail.isInsideOrOn) { // set optional caches, process the intersection
253681
253983
  if (options?.needNormal && visitor.normal)
@@ -254315,14 +254617,14 @@ let numNodeCreated = 0;
254315
254617
  * * _range = the union of ranges below in the heap
254316
254618
  * * _appData = application data associated with the node.
254317
254619
  * * Construction methods may place multiple _appData items in each node.
254318
- * * In common use, only the leaves will have _appData. However, the class definitions allow _appData at all nodes, and search algorithms must include them.
254620
+ * * In common use, only the leaves will have _appData. However, the class definitions allow _appData at all nodes, and search algorithms must include them.
254319
254621
  * * CONSTRUCTION
254320
254622
  * * The RangeTreeNode.createByIndexSplits method constructs the tree with simple right-left splits within an array of input items.
254321
254623
  * * The appData is placed entirely in the leaves.
254322
- * * caller can specify:
254624
+ * * The caller can specify:
254323
254625
  * * the number of _appData items per leaf
254324
254626
  * * the number of children per node within the tree.
254325
- * * "deep" trees (2 children per node and one appData per leaf) may have (compared to shallow trees with many children per node and many appData per leaf)
254627
+ * * Compared to "shallow" trees with many children per node and many appData per leaf, "deep" trees with 2 children per node and 1 appData per leaf may have:
254326
254628
  * * faster search because lower nodes have smaller ranges that will be skipped by search algorithms.
254327
254629
  * * larger memory use because of more nodes
254328
254630
  * * For future construction methods:
@@ -257235,15 +257537,15 @@ __webpack_require__.r(__webpack_exports__);
257235
257537
  /* harmony export */ EdgeClipData: () => (/* binding */ EdgeClipData),
257236
257538
  /* harmony export */ SweepLineStringToFacetContext: () => (/* binding */ SweepLineStringToFacetContext)
257237
257539
  /* harmony export */ });
257238
- /* harmony import */ var _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../geometry3d/Transform */ "../../core/geometry/lib/esm/geometry3d/Transform.js");
257239
- /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
257240
- /* harmony import */ var _geometry3d_Segment1d__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../geometry3d/Segment1d */ "../../core/geometry/lib/esm/geometry3d/Segment1d.js");
257241
- /* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
257242
- /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
257243
257540
  /* harmony import */ var _clipping_ClipPlane__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../clipping/ClipPlane */ "../../core/geometry/lib/esm/clipping/ClipPlane.js");
257244
257541
  /* harmony import */ var _clipping_ConvexClipPlaneSet__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../clipping/ConvexClipPlaneSet */ "../../core/geometry/lib/esm/clipping/ConvexClipPlaneSet.js");
257245
- /* harmony import */ var _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../geometry3d/PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
257542
+ /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
257246
257543
  /* harmony import */ var _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../geometry3d/Matrix3d */ "../../core/geometry/lib/esm/geometry3d/Matrix3d.js");
257544
+ /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
257545
+ /* harmony import */ var _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../geometry3d/PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
257546
+ /* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
257547
+ /* harmony import */ var _geometry3d_Segment1d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../geometry3d/Segment1d */ "../../core/geometry/lib/esm/geometry3d/Segment1d.js");
257548
+ /* harmony import */ var _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../geometry3d/Transform */ "../../core/geometry/lib/esm/geometry3d/Transform.js");
257247
257549
  /*---------------------------------------------------------------------------------------------
257248
257550
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
257249
257551
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -257266,24 +257568,23 @@ class SweepLineStringToFacetContext {
257266
257568
  _numSpacePoints;
257267
257569
  constructor(spacePoints) {
257268
257570
  this._spacePoints = spacePoints;
257269
- this._spacePointsRange = new _geometry3d_Range__WEBPACK_IMPORTED_MODULE_0__.Range3d();
257270
- spacePoints.setRange(this._spacePointsRange);
257571
+ this._spacePointsRange = spacePoints.getRange();
257271
257572
  this._numSpacePoints = this._spacePoints.length;
257272
257573
  }
257273
257574
  static create(xyz) {
257274
257575
  if (xyz.length > 1) {
257275
- return new SweepLineStringToFacetContext(xyz.clone());
257576
+ return new SweepLineStringToFacetContext(xyz);
257276
257577
  }
257277
257578
  return undefined;
257278
257579
  }
257279
257580
  // temporaries reused over multiple calls to process a single facet . ..
257280
- _segmentPoint0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create();
257281
- _segmentPoint1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create();
257282
- _localSegmentPoint0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create();
257283
- _localSegmentPoint1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create();
257284
- _clipFractions = _geometry3d_Segment1d__WEBPACK_IMPORTED_MODULE_2__.Segment1d.create(0, 1);
257285
- _localFrame = _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_3__.Transform.createIdentity();
257286
- _polygonRange = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_0__.Range3d.create();
257581
+ _segmentPoint0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
257582
+ _segmentPoint1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
257583
+ _localSegmentPoint0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
257584
+ _localSegmentPoint1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
257585
+ _clipFractions = _geometry3d_Segment1d__WEBPACK_IMPORTED_MODULE_1__.Segment1d.create(0, 1);
257586
+ _localFrame = _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_2__.Transform.createIdentity();
257587
+ _polygonRange = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_3__.Range3d.create();
257287
257588
  /** process a single polygon.
257288
257589
  * @returns number crudely indicating how much work was done.
257289
257590
  */
@@ -257359,7 +257660,7 @@ class EdgeClipData {
257359
257660
  }
257360
257661
  /** create object from segment and sweep. Inputs are not captured. */
257361
257662
  static createPointPointSweep(pointA, pointB, sweep) {
257362
- const edgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.createStartEnd(pointA, pointB);
257663
+ const edgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.createStartEnd(pointA, pointB);
257363
257664
  const fraction = edgeVector.fractionOfProjectionToVector(sweep);
257364
257665
  // The unbounded plane of the swept edge will intersect facets in lines that may extend beyond the swept bounded line.
257365
257666
  // That linework will be clipped between two facing planes with normal along the perpendicular dropped from the edge vector to the sweep vector.
@@ -257408,16 +257709,16 @@ class ClipSweptLineStringContext {
257408
257709
  }
257409
257710
  static create(xyz, sweepVector) {
257410
257711
  if (sweepVector === undefined)
257411
- sweepVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(0, 0, 1);
257712
+ sweepVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create(0, 0, 1);
257412
257713
  if (xyz.length > 1) {
257413
- const point = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.createZero();
257414
- const newPoint = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.createZero();
257714
+ const point = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.createZero();
257715
+ const newPoint = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.createZero();
257415
257716
  const edgeData = [];
257416
257717
  xyz.getPoint3dAtUncheckedPointIndex(0, point);
257417
257718
  let localToWorldMatrix = _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_8__.Matrix3d.createRigidHeadsUp(sweepVector);
257418
257719
  if (localToWorldMatrix === undefined)
257419
257720
  localToWorldMatrix = _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_8__.Matrix3d.createIdentity();
257420
- const localToWorld = _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_3__.Transform.createOriginAndMatrix(point, localToWorldMatrix);
257721
+ const localToWorld = _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_2__.Transform.createOriginAndMatrix(point, localToWorldMatrix);
257421
257722
  const worldToLocal = localToWorld.inverse();
257422
257723
  const localRange = xyz.getRange(worldToLocal);
257423
257724
  for (let i = 1; i < xyz.length; i++) {
@@ -257438,7 +257739,7 @@ class ClipSweptLineStringContext {
257438
257739
  */
257439
257740
  processPolygon(polygon, announceEdge) {
257440
257741
  if (this._worldToLocal !== undefined && this._localRange !== undefined) {
257441
- const polygonRange = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_0__.Range3d.createTransformedArray(this._worldToLocal, polygon);
257742
+ const polygonRange = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_3__.Range3d.createTransformedArray(this._worldToLocal, polygon);
257442
257743
  if (!polygonRange.intersectsRangeXY(this._localRange))
257443
257744
  return;
257444
257745
  }
@@ -272086,7 +272387,7 @@ class ChainMergeContext {
272086
272387
  }
272087
272388
  return n;
272088
272389
  }
272089
- /** Collect chains which have maximum edge count, broken at an vertex with other than 2 edges.
272390
+ /** Collect chains which have maximum edge count, broken at vertices with more than 2 edges.
272090
272391
  * * This is assumed to be preceded by a call to a vertex-cluster step such as `clusterAndMergeVerticesYXZ`
272091
272392
  */
272092
272393
  collectMaximalChains() {
@@ -312718,7 +313019,7 @@ var loadLanguages = instance.loadLanguages;
312718
313019
  /***/ ((module) => {
312719
313020
 
312720
313021
  "use strict";
312721
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.0.0-dev.113","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","@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","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"}}');
313022
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.0.0-dev.114","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","@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","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"}}');
312722
313023
 
312723
313024
  /***/ })
312724
313025