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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -194261,6 +194261,7 @@ __webpack_require__.r(__webpack_exports__);
194261
194261
  /* harmony export */ "NewtonEvaluatorRtoRD": () => (/* reexport safe */ _numerics_Newton__WEBPACK_IMPORTED_MODULE_51__.NewtonEvaluatorRtoRD),
194262
194262
  /* harmony export */ "NullGeometryHandler": () => (/* reexport safe */ _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODULE_8__.NullGeometryHandler),
194263
194263
  /* harmony export */ "NumberArray": () => (/* reexport safe */ _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_23__.NumberArray),
194264
+ /* harmony export */ "OffsetMeshOptions": () => (/* reexport safe */ _polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_116__.OffsetMeshOptions),
194264
194265
  /* harmony export */ "OffsetOptions": () => (/* reexport safe */ _curve_internalContexts_PolygonOffsetContext__WEBPACK_IMPORTED_MODULE_79__.OffsetOptions),
194265
194266
  /* harmony export */ "Order2Bezier": () => (/* reexport safe */ _numerics_BezierPolynomials__WEBPACK_IMPORTED_MODULE_49__.Order2Bezier),
194266
194267
  /* harmony export */ "Order3Bezier": () => (/* reexport safe */ _numerics_BezierPolynomials__WEBPACK_IMPORTED_MODULE_49__.Order3Bezier),
@@ -212656,6 +212657,44 @@ class Angle {
212656
212657
  const uDotV = ux * vx + uy * vy + uz * vz;
212657
212658
  return Math.atan2(_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.crossProductMagnitude(ux, uy, uz, vx, vy, vz), uDotV);
212658
212659
  }
212660
+ /**
212661
+ * * Returns the angle between two vectors, with the vectors given as xyz components, and an up vector to resolve angle to a full 2PI range.
212662
+ * * The returned angle is (-PI < radians <= PI) or (0 <= radians < 2 * PI)
212663
+ * * The angle is in the plane of the U and V vectors.
212664
+ * * The upVector determines a positive side of the plane but need not be strictly perpendicular to the plane.
212665
+ *
212666
+ * @param ux x component of vector u
212667
+ * @param uy y component of vector u
212668
+ * @param uz z component of vector u
212669
+ * @param vx x component of vector v
212670
+ * @param vy y component of vector v
212671
+ * @param vz z component of vector v
212672
+ * @param upVectorX x component of vector to positive side of plane.
212673
+ * @param upVectorY y component of vector to positive side of plane.
212674
+ * @param upVectorZ z component of vector to positive side of plane.
212675
+ * @param adjustToAllPositive if true, return strictly non-negative sweep (0 <= radians < 2*PI). If false, return signed (-PI < radians <= PI)
212676
+ */
212677
+ static orientedRadiansBetweenVectorsXYZ(ux, uy, uz, vx, vy, vz, upVectorX, upVectorY, upVectorZ, adjustToPositive = false) {
212678
+ const uDotV = ux * vx + uy * vy + uz * vz;
212679
+ const wx = uy * vz - uz * vy;
212680
+ const wy = uz * vx - ux * vz;
212681
+ const wz = ux * vy - uy * vx;
212682
+ const upDotW = upVectorX * wx + upVectorY * wy + upVectorZ * wz;
212683
+ const crossMagnitude = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(wx, wy, wz);
212684
+ if (upDotW < 0.0) {
212685
+ if (adjustToPositive) {
212686
+ // The turn is greater than 180 degrees. Take a peculiarly oriented atan2 to get the excess-180 part as addition to PI.
212687
+ // This gives the smoothest numerical transition passing PI.
212688
+ return Math.PI + Math.atan2(crossMagnitude, -uDotV);
212689
+ }
212690
+ else {
212691
+ return -Math.atan2(crossMagnitude, uDotV);
212692
+ }
212693
+ }
212694
+ else {
212695
+ return Math.atan2(crossMagnitude, uDotV);
212696
+ }
212697
+ }
212659
212698
  /**
212660
212699
  * Add a multiple of a full circle angle (360 degrees, 2PI) in place.
212661
212700
  * @param multiple multiplier factor
@@ -222356,9 +222395,12 @@ __webpack_require__.r(__webpack_exports__);
222356
222395
  * @module CartesianGeometry
222357
222396
  */
222358
222397
  // cspell:word CWXY
222398
+ // cspell:word arctan
222399
+ // cspell:word Rodrigues
222359
222400
 
222360
222401
 
222361
222402
 
222403
+ // cspell:word CCWXY
222362
222404
  /**
222363
222405
  * * `XYZ` is a minimal object containing x,y,z and operations that are meaningful without change in both point and vector.
222364
222406
  * * `XYZ` is not instantiable.
@@ -223701,18 +223743,17 @@ class Vector3d extends XYZ {
223701
223743
  else
223702
223744
  return theta;
223703
223745
  }
223704
- /**
223705
- * Return the (strongly typed Angle) angle from this vector to vectorB, measured in the plane containing both,
223706
- * with vectorW indicating which side to view to control sign of the angle.
223707
- * * The returned angle can range from negative 180 degrees (negative PI radians) to positive 180 degrees
223708
- * * (positive PI radians), not closed on the negative side.
223709
- * * The returned angle is "in the plane containing the two vectors"
223710
- * * `vectorW` distinguishes between the sides of the plane, but does not have to be perpendicular.
223711
- * * The returned angle has the same sign as vectorW dot product (thisVector cross vectorB)
223712
- * * Use planarRadiansTo to measure the angle between vectors that are projected to another plane.
223713
- * @param vectorB target vector.
223714
- * @param vectorW distinguishes between the sides of the plane.
223715
- */
223746
+ /** Return the (strongly typed Angle) angle from this vector to vectorB, measured in the plane containing both,
223747
+ * with vectorW indicating which side to view to control sign of the angle.
223748
+ * * The returned angle can range from negative 180 degrees (negative PI radians) to positive 180 degrees
223749
+ * * (positive PI radians), not closed on the negative side.
223750
+ * * The returned angle is "in the plane containing the two vectors"
223751
+ * * `vectorW` distinguishes between the sides of the plane, but does not have to be perpendicular.
223752
+ * * The returned angle has the same sign as vectorW dot product (thisVector cross vectorB)
223753
+ * * Use planarRadiansTo to measure the angle between vectors that are projected to another plane.
223754
+ * @param vectorB target vector.
223755
+ * @param vectorW distinguishes between the sides of the plane.
223756
+ */
223716
223757
  signedAngleTo(vectorB, vectorW) {
223717
223758
  return _Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createRadians(this.signedRadiansTo(vectorB, vectorW));
223718
223759
  }
@@ -236449,6 +236490,20 @@ class SmallSystem {
236449
236490
  }
236450
236491
  return undefined;
236451
236492
  }
236493
+ /**
236494
+ * Compute the intersection of three planes.
236495
+ * @param xyzA point on the first plane
236496
+ * @param normalA normal of the first plane
236497
+ * @param xyzB point on the second plane
236498
+ * @param normalB normal of the second plane
236499
+ * @param xyzC point on the third plane
236500
+ * @param normalC normal of the third plane
236501
+ * @param result optional result
236502
+ * @returns intersection point of the three planes (as a Vector3d), or undefined if at least two planes are parallel.
236503
+ */
236504
+ static intersect3Planes(xyzA, normalA, xyzB, normalB, xyzC, normalC, result) {
236505
+ return this.linearSystem3d(normalA.x, normalA.y, normalA.z, normalB.x, normalB.y, normalB.z, normalC.x, normalC.y, normalC.z, _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.dotProductXYZXYZ(xyzA.x, xyzA.y, xyzA.z, normalA.x, normalA.y, normalA.z), _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.dotProductXYZXYZ(xyzB.x, xyzB.y, xyzB.z, normalB.x, normalB.y, normalB.z), _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.dotProductXYZXYZ(xyzC.x, xyzC.y, xyzC.z, normalC.x, normalC.y, normalC.z), result);
236506
+ }
236452
236507
  /**
236453
236508
  * * in rowB, replace `rowB[j] += a * rowB[pivot] * rowA[j] / rowA[pivot]` for `j>pivot`
236454
236509
  * @param rowA row that does not change
@@ -240560,10 +240615,29 @@ class PolyfaceBuilder extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
240560
240615
  if (sector.uv)
240561
240616
  sector.uvIndex = this._polyface.addParam(sector.uv);
240562
240617
  }
240618
+ addSectorTriangle(sectorA0, sectorA1, sectorA2) {
240619
+ if (sectorA0.xyz.isAlmostEqual(sectorA1.xyz)
240620
+ || sectorA1.xyz.isAlmostEqual(sectorA2.xyz)
240621
+ || sectorA2.xyz.isAlmostEqual(sectorA0.xyz)) {
240622
+ // trivially degenerate triangle !!! skip !!!
240623
+ }
240624
+ else {
240625
+ if (this._options.needNormals)
240626
+ this.addIndexedTriangleNormalIndexes(sectorA0.normalIndex, sectorA1.normalIndex, sectorA2.normalIndex);
240627
+ if (this._options.needParams)
240628
+ this.addIndexedTriangleParamIndexes(sectorA0.uvIndex, sectorA1.uvIndex, sectorA2.uvIndex);
240629
+ this.addIndexedTrianglePointIndexes(sectorA0.xyzIndex, sectorA1.xyzIndex, sectorA2.xyzIndex);
240630
+ this._polyface.terminateFacet();
240631
+ }
240632
+ }
240563
240633
  addSectorQuadA01B01(sectorA0, sectorA1, sectorB0, sectorB1) {
240564
240634
  if (sectorA0.xyz.isAlmostEqual(sectorA1.xyz) && sectorB0.xyz.isAlmostEqual(sectorB1.xyz)) {
240565
240635
  // ignore null quad !!
240566
240636
  }
240637
+ else if (this._options.shouldTriangulate) {
240638
+ this.addSectorTriangle(sectorA0, sectorA1, sectorB1);
240639
+ this.addSectorTriangle(sectorB1, sectorB0, sectorA0);
240640
+ }
240567
240641
  else {
240568
240642
  if (this._options.needNormals)
240569
240643
  this.addIndexedQuadNormalIndexes(sectorA0.normalIndex, sectorA1.normalIndex, sectorB0.normalIndex, sectorB1.normalIndex);
@@ -240640,12 +240714,30 @@ class PolyfaceBuilder extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
240640
240714
  }
240641
240715
  const numPoints = pointA.length;
240642
240716
  for (let i = 1; i < numPoints; i++) {
240643
- if (pointA.atUncheckedIndex(i - 1) !== pointA.atUncheckedIndex(i) || pointB.atUncheckedIndex(i - 1) !== pointB.atUncheckedIndex(i)) {
240644
- this.addIndexedQuadPointIndexes(pointA.atUncheckedIndex(i - 1), pointA.atUncheckedIndex(i), pointB.atUncheckedIndex(i - 1), pointB.atUncheckedIndex(i));
240645
- if (normalA && normalB)
240646
- this.addIndexedQuadNormalIndexes(normalA.atUncheckedIndex(i - 1), normalA.atUncheckedIndex(i), normalB.atUncheckedIndex(i - 1), normalB.atUncheckedIndex(i));
240647
- if (paramA && paramB)
240648
- this.addIndexedQuadParamIndexes(paramA.atUncheckedIndex(i - 1), paramA.atUncheckedIndex(i), paramB.atUncheckedIndex(i - 1), paramB.atUncheckedIndex(i));
240717
+ if (this.options.shouldTriangulate) {
240718
+ if (distinctIndices(pointA.atUncheckedIndex(i - 1), pointA.atUncheckedIndex(i), pointB.atUncheckedIndex(i))) {
240719
+ this.addIndexedTrianglePointIndexes(pointA.atUncheckedIndex(i - 1), pointA.atUncheckedIndex(i), pointB.atUncheckedIndex(i));
240720
+ if (normalA && normalB)
240721
+ this.addIndexedTriangleNormalIndexes(normalA.atUncheckedIndex(i - 1), normalA.atUncheckedIndex(i), normalB.atUncheckedIndex(i - 1));
240722
+ if (paramA && paramB)
240723
+ this.addIndexedTriangleParamIndexes(paramA.atUncheckedIndex(i - 1), paramA.atUncheckedIndex(i), paramB.atUncheckedIndex(i - 1));
240724
+ }
240725
+ if (distinctIndices(pointB.atUncheckedIndex(i), pointB.atUncheckedIndex(i - 1), pointA.atUncheckedIndex(i - 1))) {
240726
+ this.addIndexedTrianglePointIndexes(pointA.atUncheckedIndex(i - 1), pointB.atUncheckedIndex(i), pointB.atUncheckedIndex(i - 1));
240727
+ if (normalA && normalB)
240728
+ this.addIndexedTriangleNormalIndexes(normalA.atUncheckedIndex(i - 1), normalB.atUncheckedIndex(i), normalB.atUncheckedIndex(i - 1));
240729
+ if (paramA && paramB)
240730
+ this.addIndexedTriangleParamIndexes(paramA.atUncheckedIndex(i - 1), paramB.atUncheckedIndex(i), paramB.atUncheckedIndex(i - 1));
240731
+ }
240732
+ }
240733
+ else {
240734
+ if (pointA.atUncheckedIndex(i - 1) !== pointA.atUncheckedIndex(i) || pointB.atUncheckedIndex(i - 1) !== pointB.atUncheckedIndex(i)) {
240735
+ this.addIndexedQuadPointIndexes(pointA.atUncheckedIndex(i - 1), pointA.atUncheckedIndex(i), pointB.atUncheckedIndex(i - 1), pointB.atUncheckedIndex(i));
240736
+ if (normalA && normalB)
240737
+ this.addIndexedQuadNormalIndexes(normalA.atUncheckedIndex(i - 1), normalA.atUncheckedIndex(i), normalB.atUncheckedIndex(i - 1), normalB.atUncheckedIndex(i));
240738
+ if (paramA && paramB)
240739
+ this.addIndexedQuadParamIndexes(paramA.atUncheckedIndex(i - 1), paramA.atUncheckedIndex(i), paramB.atUncheckedIndex(i - 1), paramB.atUncheckedIndex(i));
240740
+ }
240649
240741
  this._polyface.terminateFacet();
240650
240742
  }
240651
240743
  }
@@ -241642,6 +241734,9 @@ function resolveToIndexedXYZCollectionOrCarrier(points) {
241642
241734
  return points.packedPoints;
241643
241735
  return points;
241644
241736
  }
241737
+ function distinctIndices(i0, i1, i2) {
241738
+ return i0 !== i1 && i1 !== i2 && i2 !== i0;
241739
+ }
241645
241740
 
241646
241741
 
241647
241742
  /***/ }),
@@ -242810,38 +242905,41 @@ function compressUnusedGrowableXYZArray(data: GrowableXYZArray, indices: number[
242810
242905
  __webpack_require__.r(__webpack_exports__);
242811
242906
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
242812
242907
  /* harmony export */ "DuplicateFacetClusterSelector": () => (/* binding */ DuplicateFacetClusterSelector),
242908
+ /* harmony export */ "OffsetMeshOptions": () => (/* binding */ OffsetMeshOptions),
242813
242909
  /* harmony export */ "PolyfaceQuery": () => (/* binding */ PolyfaceQuery)
242814
242910
  /* harmony export */ });
242815
242911
  /* harmony import */ var _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../geometry3d/PointHelpers */ "../../core/geometry/lib/esm/geometry3d/PointHelpers.js");
242816
- /* harmony import */ var _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../curve/CurveCollection */ "../../core/geometry/lib/esm/curve/CurveCollection.js");
242912
+ /* harmony import */ var _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../curve/CurveCollection */ "../../core/geometry/lib/esm/curve/CurveCollection.js");
242817
242913
  /* harmony import */ var _curve_internalContexts_MultiChainCollector__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../curve/internalContexts/MultiChainCollector */ "../../core/geometry/lib/esm/curve/internalContexts/MultiChainCollector.js");
242818
- /* harmony import */ var _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../curve/LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
242819
- /* harmony import */ var _curve_LineString3d__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../curve/LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
242820
- /* harmony import */ var _curve_Loop__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../curve/Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
242914
+ /* harmony import */ var _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../curve/LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
242915
+ /* harmony import */ var _curve_LineString3d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../curve/LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
242916
+ /* harmony import */ var _curve_Loop__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../curve/Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
242821
242917
  /* harmony import */ var _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../curve/StrokeOptions */ "../../core/geometry/lib/esm/curve/StrokeOptions.js");
242822
- /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
242823
- /* harmony import */ var _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../geometry3d/Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
242918
+ /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
242919
+ /* harmony import */ var _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../geometry3d/Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
242824
242920
  /* harmony import */ var _geometry3d_FrameBuilder__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../geometry3d/FrameBuilder */ "../../core/geometry/lib/esm/geometry3d/FrameBuilder.js");
242825
- /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
242826
- /* harmony import */ var _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../geometry3d/PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
242921
+ /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
242922
+ /* harmony import */ var _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../geometry3d/PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
242827
242923
  /* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
242828
- /* harmony import */ var _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../geometry4d/Matrix4d */ "../../core/geometry/lib/esm/geometry4d/Matrix4d.js");
242829
- /* harmony import */ var _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../geometry4d/MomentData */ "../../core/geometry/lib/esm/geometry4d/MomentData.js");
242830
- /* harmony import */ var _numerics_UnionFind__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../numerics/UnionFind */ "../../core/geometry/lib/esm/numerics/UnionFind.js");
242924
+ /* harmony import */ var _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../geometry4d/Matrix4d */ "../../core/geometry/lib/esm/geometry4d/Matrix4d.js");
242925
+ /* harmony import */ var _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../geometry4d/MomentData */ "../../core/geometry/lib/esm/geometry4d/MomentData.js");
242926
+ /* harmony import */ var _numerics_UnionFind__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../numerics/UnionFind */ "../../core/geometry/lib/esm/numerics/UnionFind.js");
242831
242927
  /* harmony import */ var _topology_ChainMerge__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../topology/ChainMerge */ "../../core/geometry/lib/esm/topology/ChainMerge.js");
242832
242928
  /* harmony import */ var _topology_Graph__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../topology/Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
242833
242929
  /* harmony import */ var _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../topology/HalfEdgeGraphSearch */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphSearch.js");
242834
242930
  /* harmony import */ var _topology_Merging__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../topology/Merging */ "../../core/geometry/lib/esm/topology/Merging.js");
242835
- /* harmony import */ var _FacetOrientation__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./FacetOrientation */ "../../core/geometry/lib/esm/polyface/FacetOrientation.js");
242836
- /* harmony import */ var _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./IndexedEdgeMatcher */ "../../core/geometry/lib/esm/polyface/IndexedEdgeMatcher.js");
242931
+ /* harmony import */ var _FacetOrientation__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./FacetOrientation */ "../../core/geometry/lib/esm/polyface/FacetOrientation.js");
242932
+ /* harmony import */ var _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./IndexedEdgeMatcher */ "../../core/geometry/lib/esm/polyface/IndexedEdgeMatcher.js");
242837
242933
  /* harmony import */ var _IndexedPolyfaceVisitor__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./IndexedPolyfaceVisitor */ "../../core/geometry/lib/esm/polyface/IndexedPolyfaceVisitor.js");
242838
- /* harmony import */ var _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./multiclip/BuildAverageNormalsContext */ "../../core/geometry/lib/esm/polyface/multiclip/BuildAverageNormalsContext.js");
242839
- /* harmony import */ var _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./multiclip/SweepLineStringToFacetContext */ "../../core/geometry/lib/esm/polyface/multiclip/SweepLineStringToFacetContext.js");
242934
+ /* harmony import */ var _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./multiclip/BuildAverageNormalsContext */ "../../core/geometry/lib/esm/polyface/multiclip/BuildAverageNormalsContext.js");
242935
+ /* harmony import */ var _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./multiclip/SweepLineStringToFacetContext */ "../../core/geometry/lib/esm/polyface/multiclip/SweepLineStringToFacetContext.js");
242840
242936
  /* harmony import */ var _multiclip_XYPointBuckets__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./multiclip/XYPointBuckets */ "../../core/geometry/lib/esm/polyface/multiclip/XYPointBuckets.js");
242841
- /* harmony import */ var _Polyface__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Polyface */ "../../core/geometry/lib/esm/polyface/Polyface.js");
242937
+ /* harmony import */ var _Polyface__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Polyface */ "../../core/geometry/lib/esm/polyface/Polyface.js");
242842
242938
  /* harmony import */ var _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./PolyfaceBuilder */ "../../core/geometry/lib/esm/polyface/PolyfaceBuilder.js");
242843
242939
  /* harmony import */ var _RangeLengthData__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./RangeLengthData */ "../../core/geometry/lib/esm/polyface/RangeLengthData.js");
242844
242940
  /* harmony import */ var _topology_SpaceTriangulation__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../topology/SpaceTriangulation */ "../../core/geometry/lib/esm/topology/SpaceTriangulation.js");
242941
+ /* harmony import */ var _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../topology/HalfEdgeGraphFromIndexedLoopsContext */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js");
242942
+ /* harmony import */ var _multiclip_OffsetMeshContext__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./multiclip/OffsetMeshContext */ "../../core/geometry/lib/esm/polyface/multiclip/OffsetMeshContext.js");
242845
242943
  /*---------------------------------------------------------------------------------------------
242846
242944
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
242847
242945
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -242881,6 +242979,41 @@ __webpack_require__.r(__webpack_exports__);
242881
242979
 
242882
242980
 
242883
242981
 
242982
+
242983
+
242984
+ /**
242985
+ * Options carrier for [[PolyfaceQuery.cloneOffset]].
242986
+ * * Default options are strongly recommended.
242987
+ * * The option most likely to be changed is chamferTurnAngle
242988
+ * @public
242989
+ */
242990
+ class OffsetMeshOptions {
242991
+ /** Constructor -- CAPTURE parameters ... */
242992
+ constructor(smoothSingleAngleBetweenNormals = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(25), smoothAccumulatedAngleBetweenNormals = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(60), chamferTurnAngle = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(90)) {
242993
+ this.smoothSingleAngleBetweenNormals = smoothSingleAngleBetweenNormals.clone();
242994
+ this.smoothAccumulatedAngleBetweenNormals = smoothAccumulatedAngleBetweenNormals.clone();
242995
+ this.chamferAngleBetweenNormals = chamferTurnAngle.clone();
242996
+ }
242997
+ /** construct and return an OffsetMeshOptions with given parameters.
242998
+ * * Angles are forced to minimum values.
242999
+ * * Clones of the angles are given to the constructor.
243000
+ * @param smoothSingleRadiansBetweenNormals an angle larger than this (between facets) is considered a sharp edge
243001
+ * @param smoothAccumulatedAngleBetweenNormals angles that sum to this much may be consolidated for average normal
243002
+ * @param chamferTurnAngleBetweenNormals when facets meet with larger angle, a chamfer edge may be added if the angle between facet normals is larger than this.
243003
+ */
243004
+ static create(smoothSingleAngleBetweenNormals = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(25), smoothAccumulatedAngleBetweenNormals = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(60), chamferTurnAngleBetweenNormals = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(120)) {
243005
+ const mySmoothSingleRadiansBetweenNormals = smoothSingleAngleBetweenNormals.clone();
243006
+ const mySmoothAccumulatedRadiansBetweenNormals = smoothAccumulatedAngleBetweenNormals.clone();
243007
+ const myChamferTurnAngleBetweenNormals = chamferTurnAngleBetweenNormals.clone();
243008
+ if (mySmoothSingleRadiansBetweenNormals.degrees < 1)
243009
+ mySmoothAccumulatedRadiansBetweenNormals.setDegrees(1.0);
243010
+ if (mySmoothAccumulatedRadiansBetweenNormals.degrees < 1.0)
243011
+ mySmoothAccumulatedRadiansBetweenNormals.setDegrees(1.0);
243012
+ if (mySmoothAccumulatedRadiansBetweenNormals.degrees < 15.0)
243013
+ mySmoothAccumulatedRadiansBetweenNormals.setDegrees(15.0);
243014
+ return new OffsetMeshOptions(mySmoothSingleRadiansBetweenNormals, mySmoothAccumulatedRadiansBetweenNormals, myChamferTurnAngleBetweenNormals);
243015
+ }
243016
+ }
242884
243017
  /**
242885
243018
  * Enumeration of cases for retaining facets among duplicates
242886
243019
  * @public
@@ -242902,12 +243035,12 @@ var DuplicateFacetClusterSelector;
242902
243035
  class PolyfaceQuery {
242903
243036
  /** copy the points from a visitor into a Linestring3d in a Loop object */
242904
243037
  static visitorToLoop(visitor) {
242905
- const ls = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_0__.LineString3d.createPoints(visitor.point.getPoint3dArray());
242906
- return _curve_Loop__WEBPACK_IMPORTED_MODULE_1__.Loop.create(ls);
243038
+ const ls = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_1__.LineString3d.createPoints(visitor.point.getPoint3dArray());
243039
+ return _curve_Loop__WEBPACK_IMPORTED_MODULE_2__.Loop.create(ls);
242907
243040
  }
242908
243041
  /** Create a linestring loop for each facet of the polyface. */
242909
243042
  static indexedPolyfaceToLoops(polyface) {
242910
- const result = _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_2__.BagOfCurves.create();
243043
+ const result = _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_3__.BagOfCurves.create();
242911
243044
  const visitor = polyface.createVisitor(1);
242912
243045
  while (visitor.moveToNextFacet()) {
242913
243046
  const loop = PolyfaceQuery.visitorToLoop(visitor);
@@ -242921,17 +243054,17 @@ class PolyfaceQuery {
242921
243054
  static sumFacetAreas(source, vectorToEye) {
242922
243055
  let s = 0;
242923
243056
  if (source !== undefined) {
242924
- if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface)
243057
+ if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
242925
243058
  return PolyfaceQuery.sumFacetAreas(source.createVisitor(1), vectorToEye);
242926
243059
  let unitVectorToEye;
242927
243060
  if (vectorToEye !== undefined)
242928
243061
  unitVectorToEye = vectorToEye.normalize();
242929
243062
  source.reset();
242930
243063
  while (source.moveToNextFacet()) {
242931
- const scaledNormal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_4__.PolygonOps.areaNormal(source.point.getPoint3dArray());
243064
+ const scaledNormal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.areaNormal(source.point.getPoint3dArray());
242932
243065
  let area = scaledNormal.magnitude();
242933
243066
  if (unitVectorToEye !== undefined) {
242934
- const scale = _Geometry__WEBPACK_IMPORTED_MODULE_5__.Geometry.conditionalDivideCoordinate(1.0, area);
243067
+ const scale = _Geometry__WEBPACK_IMPORTED_MODULE_6__.Geometry.conditionalDivideCoordinate(1.0, area);
242935
243068
  if (scale !== undefined)
242936
243069
  area *= scaledNormal.dotProduct(unitVectorToEye) * scale;
242937
243070
  }
@@ -242948,12 +243081,12 @@ class PolyfaceQuery {
242948
243081
  */
242949
243082
  static sumTetrahedralVolumes(source, origin) {
242950
243083
  let s = 0;
242951
- if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface)
243084
+ if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
242952
243085
  return PolyfaceQuery.sumTetrahedralVolumes(source.createVisitor(0), origin);
242953
243086
  let myOrigin = origin;
242954
- const facetOrigin = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
242955
- const targetA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
242956
- const targetB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
243087
+ const facetOrigin = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
243088
+ const targetA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
243089
+ const targetB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
242957
243090
  source.reset();
242958
243091
  while (source.moveToNextFacet()) {
242959
243092
  if (myOrigin === undefined)
@@ -242974,20 +243107,20 @@ class PolyfaceQuery {
242974
243107
  *
242975
243108
  */
242976
243109
  static sumVolumeBetweenFacetsAndPlane(source, plane) {
242977
- if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface)
243110
+ if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
242978
243111
  return PolyfaceQuery.sumVolumeBetweenFacetsAndPlane(source.createVisitor(0), plane);
242979
- const facetOrigin = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
242980
- const targetA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
242981
- const targetB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
242982
- const triangleNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Vector3d.create();
243112
+ const facetOrigin = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
243113
+ const targetA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
243114
+ const targetB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
243115
+ const triangleNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
242983
243116
  const planeNormal = plane.getNormalRef();
242984
243117
  let h0, hA, hB;
242985
243118
  let signedVolumeSum = 0.0;
242986
243119
  let signedTriangleArea;
242987
243120
  let singleFacetArea;
242988
- const positiveAreaMomentSums = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_7__.MomentData.create(undefined, true);
242989
- const negativeAreaMomentSums = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_7__.MomentData.create(undefined, true);
242990
- const singleFacetProducts = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_8__.Matrix4d.createZero();
243121
+ const positiveAreaMomentSums = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.create(undefined, true);
243122
+ const negativeAreaMomentSums = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.create(undefined, true);
243123
+ const singleFacetProducts = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__.Matrix4d.createZero();
242991
243124
  const projectToPlane = plane.getProjectionToPlane();
242992
243125
  source.reset();
242993
243126
  // For each facet ..
@@ -243014,7 +243147,7 @@ class PolyfaceQuery {
243014
243147
  }
243015
243148
  singleFacetProducts.setZero();
243016
243149
  source.point.multiplyTransformInPlace(projectToPlane);
243017
- _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_4__.PolygonOps.addSecondMomentAreaProducts(source.point, facetOrigin, singleFacetProducts);
243150
+ _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.addSecondMomentAreaProducts(source.point, facetOrigin, singleFacetProducts);
243018
243151
  if (singleFacetArea > 0) {
243019
243152
  positiveAreaMomentSums.accumulateProductsFromOrigin(facetOrigin, singleFacetProducts, 1.0);
243020
243153
  }
@@ -243024,8 +243157,8 @@ class PolyfaceQuery {
243024
243157
  }
243025
243158
  positiveAreaMomentSums.shiftOriginAndSumsToCentroidOfSums();
243026
243159
  negativeAreaMomentSums.shiftOriginAndSumsToCentroidOfSums();
243027
- const positiveAreaMoments = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_7__.MomentData.inertiaProductsToPrincipalAxes(positiveAreaMomentSums.origin, positiveAreaMomentSums.sums);
243028
- const negativeAreaMoments = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_7__.MomentData.inertiaProductsToPrincipalAxes(negativeAreaMomentSums.origin, negativeAreaMomentSums.sums);
243160
+ const positiveAreaMoments = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.inertiaProductsToPrincipalAxes(positiveAreaMomentSums.origin, positiveAreaMomentSums.sums);
243161
+ const negativeAreaMoments = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.inertiaProductsToPrincipalAxes(negativeAreaMomentSums.origin, negativeAreaMomentSums.sums);
243029
243162
  return {
243030
243163
  volume: signedVolumeSum / 6.0,
243031
243164
  positiveProjectedFacetAreaMoments: positiveAreaMoments,
@@ -243034,23 +243167,23 @@ class PolyfaceQuery {
243034
243167
  }
243035
243168
  /** Return the inertia products [xx,xy,xz,xw, yw, etc] integrated over all all facets, as viewed from origin. */
243036
243169
  static sumFacetSecondAreaMomentProducts(source, origin) {
243037
- if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface)
243170
+ if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
243038
243171
  return PolyfaceQuery.sumFacetSecondAreaMomentProducts(source.createVisitor(0), origin);
243039
- const products = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_8__.Matrix4d.createZero();
243172
+ const products = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__.Matrix4d.createZero();
243040
243173
  source.reset();
243041
243174
  while (source.moveToNextFacet()) {
243042
- _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_4__.PolygonOps.addSecondMomentAreaProducts(source.point, origin, products);
243175
+ _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.addSecondMomentAreaProducts(source.point, origin, products);
243043
243176
  }
243044
243177
  return products;
243045
243178
  }
243046
243179
  /** Return the inertia products [xx,xy,xz,xw, yw, etc] integrated over all tetrahedral volumes from origin */
243047
243180
  static sumFacetSecondVolumeMomentProducts(source, origin) {
243048
- if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface)
243181
+ if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
243049
243182
  return PolyfaceQuery.sumFacetSecondVolumeMomentProducts(source.createVisitor(0), origin);
243050
- const products = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_8__.Matrix4d.createZero();
243183
+ const products = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__.Matrix4d.createZero();
243051
243184
  source.reset();
243052
243185
  while (source.moveToNextFacet()) {
243053
- _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_4__.PolygonOps.addSecondMomentVolumeProducts(source.point, origin, products);
243186
+ _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.addSecondMomentVolumeProducts(source.point, origin, products);
243054
243187
  }
243055
243188
  return products;
243056
243189
  }
@@ -243064,7 +243197,7 @@ class PolyfaceQuery {
243064
243197
  if (!origin)
243065
243198
  return undefined;
243066
243199
  const inertiaProducts = PolyfaceQuery.sumFacetSecondAreaMomentProducts(source, origin);
243067
- return _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_7__.MomentData.inertiaProductsToPrincipalAxes(origin, inertiaProducts);
243200
+ return _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.inertiaProductsToPrincipalAxes(origin, inertiaProducts);
243068
243201
  }
243069
243202
  /** Compute area moments for the mesh. In the returned MomentData:
243070
243203
  * * origin is the centroid.
@@ -243078,7 +243211,7 @@ class PolyfaceQuery {
243078
243211
  if (!origin)
243079
243212
  return undefined;
243080
243213
  const inertiaProducts = PolyfaceQuery.sumFacetSecondVolumeMomentProducts(source, origin);
243081
- return _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_7__.MomentData.inertiaProductsToPrincipalAxes(origin, inertiaProducts);
243214
+ return _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.inertiaProductsToPrincipalAxes(origin, inertiaProducts);
243082
243215
  }
243083
243216
  /**
243084
243217
  * Test for convex volume by dihedral angle tests on all edges.
@@ -243110,14 +243243,14 @@ class PolyfaceQuery {
243110
243243
  * * (but null edges are permitted -- These occur naturally at edges of quads at north or south pole)
243111
243244
  */
243112
243245
  static dihedralAngleSummary(source, ignoreBoundaries = false) {
243113
- const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.IndexedEdgeMatcher();
243246
+ const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
243114
243247
  const visitor = source.createVisitor(1);
243115
243248
  visitor.reset();
243116
243249
  const centroidNormal = [];
243117
243250
  let normalCounter = 0;
243118
243251
  while (visitor.moveToNextFacet()) {
243119
243252
  const numEdges = visitor.pointCount - 1;
243120
- const normal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_4__.PolygonOps.centroidAreaNormal(visitor.point);
243253
+ const normal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.centroidAreaNormal(visitor.point);
243121
243254
  if (normal === undefined)
243122
243255
  return 0;
243123
243256
  centroidNormal.push(normal);
@@ -243134,12 +243267,12 @@ class PolyfaceQuery {
243134
243267
  let numPositive = 0;
243135
243268
  let numPlanar = 0;
243136
243269
  let numNegative = 0;
243137
- const edgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Vector3d.create();
243270
+ const edgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
243138
243271
  for (const cluster of manifoldClusters) {
243139
243272
  const sideA = cluster[0];
243140
243273
  const sideB = cluster[1];
243141
- if (sideA instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.SortableEdge
243142
- && sideB instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.SortableEdge
243274
+ if (sideA instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge
243275
+ && sideB instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge
243143
243276
  && source.data.point.vectorIndexIndex(sideA.vertexIndexA, sideA.vertexIndexB, edgeVector)) {
243144
243277
  const dihedralAngle = centroidNormal[sideA.facetIndex].direction.signedAngleTo(centroidNormal[sideB.facetIndex].direction, edgeVector);
243145
243278
  if (dihedralAngle.isAlmostZero)
@@ -243172,7 +243305,7 @@ class PolyfaceQuery {
243172
243305
  * * Any edge with 2 incident facets in the same direction triggers a `false` return.
243173
243306
  */
243174
243307
  static isPolyfaceManifold(source, allowSimpleBoundaries = false) {
243175
- const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.IndexedEdgeMatcher();
243308
+ const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
243176
243309
  const visitor = source.createVisitor(1);
243177
243310
  visitor.reset();
243178
243311
  while (visitor.moveToNextFacet()) {
@@ -243195,9 +243328,9 @@ class PolyfaceQuery {
243195
243328
  * @returns
243196
243329
  */
243197
243330
  static boundaryEdges(source, includeDanglers = true, includeMismatch = true, includeNull = true) {
243198
- const result = new _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_2__.BagOfCurves();
243331
+ const result = new _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_3__.BagOfCurves();
243199
243332
  const announceEdge = (pointA, pointB, _indexA, _indexB, _readIndex) => {
243200
- result.tryAddChild(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_10__.LineSegment3d.create(pointA, pointB));
243333
+ result.tryAddChild(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(pointA, pointB));
243201
243334
  };
243202
243335
  PolyfaceQuery.announceBoundaryEdges(source, announceEdge, includeDanglers, includeMismatch, includeNull);
243203
243336
  if (result.children.length === 0)
@@ -243216,8 +243349,8 @@ class PolyfaceQuery {
243216
243349
  static announceBoundaryEdges(source, announceEdge, includeDanglers = true, includeMismatch = true, includeNull = true) {
243217
243350
  if (source === undefined)
243218
243351
  return undefined;
243219
- const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.IndexedEdgeMatcher();
243220
- const visitor = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface ? source.createVisitor(1) : source;
243352
+ const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
243353
+ const visitor = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface ? source.createVisitor(1) : source;
243221
243354
  visitor.setNumWrap(1);
243222
243355
  visitor.reset();
243223
243356
  while (visitor.moveToNextFacet()) {
@@ -243242,7 +243375,7 @@ class PolyfaceQuery {
243242
243375
  const sourcePolyface = visitor.clientPolyface();
243243
243376
  for (const list of badList) {
243244
243377
  for (const e of list) {
243245
- const e1 = e instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.SortableEdge ? e : e[0];
243378
+ const e1 = e instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge ? e : e[0];
243246
243379
  const indexA = e1.vertexIndexA;
243247
243380
  const indexB = e1.vertexIndexB;
243248
243381
  const pointA = sourcePolyface.data.getPoint(indexA);
@@ -243257,7 +243390,7 @@ class PolyfaceQuery {
243257
243390
  * * Facets are ASSUMED to be convex and planar.
243258
243391
  */
243259
243392
  static announceSweepLinestringToConvexPolyfaceXY(linestringPoints, polyface, announce) {
243260
- const context = _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_11__.SweepLineStringToFacetContext.create(linestringPoints);
243393
+ const context = _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_12__.SweepLineStringToFacetContext.create(linestringPoints);
243261
243394
  if (context) {
243262
243395
  const visitor = polyface.createVisitor(0);
243263
243396
  for (visitor.reset(); visitor.moveToNextFacet();) {
@@ -243290,7 +243423,7 @@ class PolyfaceQuery {
243290
243423
  * @internal
243291
243424
  */
243292
243425
  static async asyncAnnounceSweepLinestringToConvexPolyfaceXY(linestringPoints, polyface, announce) {
243293
- const context = _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_11__.SweepLineStringToFacetContext.create(linestringPoints);
243426
+ const context = _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_12__.SweepLineStringToFacetContext.create(linestringPoints);
243294
243427
  this.awaitBlockCount = 0;
243295
243428
  let workTotal = 0;
243296
243429
  if (context) {
@@ -243310,11 +243443,11 @@ class PolyfaceQuery {
243310
243443
  * * Return array of arrays of facet indices.
243311
243444
  */
243312
243445
  static partitionFacetIndicesByVertexConnectedComponent(polyface) {
243313
- if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface) {
243446
+ if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
243314
243447
  return this.partitionFacetIndicesByVertexConnectedComponent(polyface.createVisitor(0));
243315
243448
  }
243316
243449
  // The polyface is really a visitor !!!
243317
- const context = new _numerics_UnionFind__WEBPACK_IMPORTED_MODULE_12__.UnionFindContext(this.visitorClientPointCount(polyface));
243450
+ const context = new _numerics_UnionFind__WEBPACK_IMPORTED_MODULE_13__.UnionFindContext(this.visitorClientPointCount(polyface));
243318
243451
  for (polyface.reset(); polyface.moveToNextFacet();) {
243319
243452
  const firstVertexIndexOnThisFacet = polyface.pointIndex[0];
243320
243453
  for (const vertexIndex of polyface.pointIndex)
@@ -243347,7 +243480,7 @@ class PolyfaceQuery {
243347
243480
  * * Return array of arrays of facet indices.
243348
243481
  */
243349
243482
  static partitionFacetIndicesByVisibilityVector(polyface, vectorToEye, sideAngleTolerance) {
243350
- if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface) {
243483
+ if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
243351
243484
  return this.partitionFacetIndicesByVisibilityVector(polyface.createVisitor(0), vectorToEye, sideAngleTolerance);
243352
243485
  }
243353
243486
  const facetsInComponent = [];
@@ -243359,7 +243492,7 @@ class PolyfaceQuery {
243359
243492
  const sideComponent = facetsInComponent[2];
243360
243493
  const radiansTol = Math.max(sideAngleTolerance.radians, 1.0e-8);
243361
243494
  for (polyface.reset(); polyface.moveToNextFacet();) {
243362
- const areaNormal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_4__.PolygonOps.areaNormalGo(polyface.point);
243495
+ const areaNormal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.areaNormalGo(polyface.point);
243363
243496
  const index = polyface.currentReadIndex();
243364
243497
  if (areaNormal) {
243365
243498
  const angle = areaNormal.angleFromPerpendicular(vectorToEye);
@@ -243386,7 +243519,7 @@ class PolyfaceQuery {
243386
243519
  * @param vectorToEye
243387
243520
  * @param sideAngleTolerance
243388
243521
  */
243389
- static boundaryOfVisibleSubset(polyface, visibilitySelect, vectorToEye, sideAngleTolerance = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_13__.Angle.createDegrees(1.0e-3)) {
243522
+ static boundaryOfVisibleSubset(polyface, visibilitySelect, vectorToEye, sideAngleTolerance = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(1.0e-3)) {
243390
243523
  const partitionedIndices = this.partitionFacetIndicesByVisibilityVector(polyface, vectorToEye, sideAngleTolerance);
243391
243524
  if (partitionedIndices[visibilitySelect].length === 0)
243392
243525
  return undefined;
@@ -243400,8 +243533,8 @@ class PolyfaceQuery {
243400
243533
  * @param mesh
243401
243534
  */
243402
243535
  static announceBoundaryChainsAsLineString3d(mesh, announceLoop) {
243403
- const collector = new _curve_internalContexts_MultiChainCollector__WEBPACK_IMPORTED_MODULE_15__.MultiChainCollector(_Geometry__WEBPACK_IMPORTED_MODULE_5__.Geometry.smallMetricDistance, 1000);
243404
- PolyfaceQuery.announceBoundaryEdges(mesh, (pointA, pointB, _indexA, _indexB) => collector.captureCurve(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_10__.LineSegment3d.create(pointA, pointB)), true, false, false);
243536
+ const collector = new _curve_internalContexts_MultiChainCollector__WEBPACK_IMPORTED_MODULE_15__.MultiChainCollector(_Geometry__WEBPACK_IMPORTED_MODULE_6__.Geometry.smallMetricDistance, 1000);
243537
+ PolyfaceQuery.announceBoundaryEdges(mesh, (pointA, pointB, _indexA, _indexB) => collector.captureCurve(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(pointA, pointB)), true, false, false);
243405
243538
  collector.announceChainsAsLineString3d(announceLoop);
243406
243539
  }
243407
243540
  /**
@@ -243412,7 +243545,7 @@ class PolyfaceQuery {
243412
243545
  * @returns
243413
243546
  */
243414
243547
  static cloneWithMaximalPlanarFacets(mesh) {
243415
- if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface)
243548
+ if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
243416
243549
  return this.cloneWithMaximalPlanarFacets(mesh.createVisitor(0));
243417
243550
  const numFacets = PolyfaceQuery.visitorClientFacetCount(mesh);
243418
243551
  const smoothEdges = PolyfaceQuery.collectEdgesByDihedralAngle(mesh);
@@ -243437,7 +243570,7 @@ class PolyfaceQuery {
243437
243570
  const edges = [];
243438
243571
  const edgeStrings = [];
243439
243572
  PolyfaceQuery.announceBoundaryEdges(fragment, (pointA, pointB, _indexA, _indexB) => {
243440
- edges.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_10__.LineSegment3d.create(pointA, pointB));
243573
+ edges.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(pointA, pointB));
243441
243574
  edgeStrings.push([pointA.clone(), pointB.clone()]);
243442
243575
  });
243443
243576
  const chains = _curve_internalContexts_MultiChainCollector__WEBPACK_IMPORTED_MODULE_15__.OffsetHelpers.collectChains(edges, gapTolerance, planarityTolerance);
@@ -243478,7 +243611,7 @@ class PolyfaceQuery {
243478
243611
  * @returns
243479
243612
  */
243480
243613
  static fillSimpleHoles(mesh, options, unfilledChains) {
243481
- if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface)
243614
+ if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
243482
243615
  return this.fillSimpleHoles(mesh.createVisitor(0), options, unfilledChains);
243483
243616
  const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create();
243484
243617
  const chains = [];
@@ -243492,7 +243625,7 @@ class PolyfaceQuery {
243492
243625
  rejected = true;
243493
243626
  else if (options.maxPerimeter !== undefined && _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_21__.Point3dArray.sumEdgeLengths(points, false) > options.maxPerimeter)
243494
243627
  rejected = true;
243495
- else if (options.upVector !== undefined && _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_4__.PolygonOps.sumTriangleAreasPerpendicularToUpVector(points, options.upVector) <= 0.0)
243628
+ else if (options.upVector !== undefined && _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.sumTriangleAreasPerpendicularToUpVector(points, options.upVector) <= 0.0)
243496
243629
  rejected = true;
243497
243630
  if (!rejected && _topology_SpaceTriangulation__WEBPACK_IMPORTED_MODULE_22__.SpacePolygonTriangulation.triangulateSimplestSpaceLoop(points, (_loop, triangles) => {
243498
243631
  for (const t of triangles)
@@ -243515,7 +243648,7 @@ class PolyfaceQuery {
243515
243648
  *
243516
243649
  */
243517
243650
  static clonePartitions(polyface, partitions) {
243518
- if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface) {
243651
+ if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
243519
243652
  return this.clonePartitions(polyface.createVisitor(0), partitions);
243520
243653
  }
243521
243654
  polyface.setNumWrap(0);
@@ -243539,7 +243672,7 @@ class PolyfaceQuery {
243539
243672
  /** Clone facets that pass an filter function
243540
243673
  */
243541
243674
  static cloneFiltered(source, filter) {
243542
- if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface) {
243675
+ if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
243543
243676
  return this.cloneFiltered(source.createVisitor(0), filter);
243544
243677
  }
243545
243678
  source.setNumWrap(0);
@@ -243591,9 +243724,9 @@ class PolyfaceQuery {
243591
243724
  * @return collection of facet index arrays, one array per connected component
243592
243725
  */
243593
243726
  static partitionFacetIndicesBySortableEdgeClusters(edgeClusters, numFacets) {
243594
- const context = new _numerics_UnionFind__WEBPACK_IMPORTED_MODULE_12__.UnionFindContext(numFacets);
243727
+ const context = new _numerics_UnionFind__WEBPACK_IMPORTED_MODULE_13__.UnionFindContext(numFacets);
243595
243728
  for (const cluster of edgeClusters) {
243596
- if (cluster instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.SortableEdge) {
243729
+ if (cluster instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge) {
243597
243730
  // this edge does not connect anywhere. Ignore it!!
243598
243731
  }
243599
243732
  else {
@@ -243625,11 +243758,11 @@ class PolyfaceQuery {
243625
243758
  * @return collection of facet index arrays, one per connected component
243626
243759
  */
243627
243760
  static partitionFacetIndicesByEdgeConnectedComponent(polyface, stopAtVisibleEdges = false) {
243628
- if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface) {
243761
+ if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
243629
243762
  return this.partitionFacetIndicesByEdgeConnectedComponent(polyface.createVisitor(0), stopAtVisibleEdges);
243630
243763
  }
243631
243764
  polyface.setNumWrap(1);
243632
- const matcher = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.IndexedEdgeMatcher();
243765
+ const matcher = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
243633
243766
  polyface.reset();
243634
243767
  let numFacets = 0;
243635
243768
  while (polyface.moveToNextFacet()) {
@@ -243667,7 +243800,7 @@ class PolyfaceQuery {
243667
243800
  static sweepLinestringToFacetsXYReturnLines(linestringPoints, polyface) {
243668
243801
  const drapeGeometry = [];
243669
243802
  this.announceSweepLinestringToConvexPolyfaceXY(linestringPoints, polyface, (_linestring, _segmentIndex, _polyface, _facetIndex, points, indexA, indexB) => {
243670
- drapeGeometry.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_10__.LineSegment3d.create(points[indexA], points[indexB]));
243803
+ drapeGeometry.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(points[indexA], points[indexB]));
243671
243804
  });
243672
243805
  return drapeGeometry;
243673
243806
  }
@@ -243702,7 +243835,7 @@ class PolyfaceQuery {
243702
243835
  * * Return statistical summary of x,y,z ranges.
243703
243836
  */
243704
243837
  static collectRangeLengthData(polyface) {
243705
- if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface) {
243838
+ if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
243706
243839
  return this.collectRangeLengthData(polyface.createVisitor(0));
243707
243840
  }
243708
243841
  const rangeData = new _RangeLengthData__WEBPACK_IMPORTED_MODULE_25__.RangeLengthData();
@@ -243720,10 +243853,10 @@ class PolyfaceQuery {
243720
243853
  const rangeSearcher = _multiclip_XYPointBuckets__WEBPACK_IMPORTED_MODULE_26__.XYPointBuckets.create(polyface.data.point, 30);
243721
243854
  const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create();
243722
243855
  const edgeRange = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_27__.Range3d.createNull();
243723
- const point0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
243724
- const point1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
243725
- const spacePoint = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Point3d.create();
243726
- const segment = _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_10__.LineSegment3d.create(point0, point1);
243856
+ const point0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
243857
+ const point1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
243858
+ const spacePoint = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
243859
+ const segment = _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(point0, point1);
243727
243860
  for (oldFacetVisitor.reset(); oldFacetVisitor.moveToNextFacet();) {
243728
243861
  newFacetVisitor.clearArrays();
243729
243862
  for (let i = 0; i + 1 < oldFacetVisitor.point.length; i++) {
@@ -243732,7 +243865,7 @@ class PolyfaceQuery {
243732
243865
  oldFacetVisitor.point.getPoint3dAtUncheckedPointIndex(i + 1, point1);
243733
243866
  newFacetVisitor.pushDataFrom(oldFacetVisitor, i);
243734
243867
  edgeRange.setNull();
243735
- _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_10__.LineSegment3d.create(point0, point1, segment);
243868
+ _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(point0, point1, segment);
243736
243869
  let detailArray;
243737
243870
  edgeRange.extend(point0);
243738
243871
  edgeRange.extend(point1);
@@ -243877,8 +244010,8 @@ class PolyfaceQuery {
243877
244010
  const oldFacetVisitor = polyface.createVisitor(2); // This is to visit the existing facets.
243878
244011
  const newFacetVisitor = polyface.createVisitor(0); // This is to build the new facets.
243879
244012
  const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create();
243880
- const vector01 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Vector3d.create();
243881
- const vector12 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Vector3d.create();
244013
+ const vector01 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
244014
+ const vector12 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
243882
244015
  const numPoint = polyface.data.point.length;
243883
244016
  const pointState = new Int32Array(numPoint);
243884
244017
  // FIRST PASS -- in each sector of each facet, determine if the sector has colinear incoming and outgoing vectors.
@@ -243925,7 +244058,7 @@ class PolyfaceQuery {
243925
244058
  */
243926
244059
  static setEdgeVisibility(polyface, clusters, value) {
243927
244060
  for (const cluster of clusters) {
243928
- if (cluster instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.SortableEdge) {
244061
+ if (cluster instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge) {
243929
244062
  this.setSingleEdgeVisibility(polyface, cluster.facetIndex, cluster.vertexIndexA, value);
243930
244063
  }
243931
244064
  else if (Array.isArray(cluster)) {
@@ -243968,9 +244101,9 @@ class PolyfaceQuery {
243968
244101
  * @param polyface a mesh, or a visitor assumed to have numWrap === 1
243969
244102
  */
243970
244103
  static createIndexedEdges(polyface) {
243971
- if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface)
244104
+ if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
243972
244105
  return this.createIndexedEdges(polyface.createVisitor(1));
243973
- const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.IndexedEdgeMatcher();
244106
+ const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
243974
244107
  polyface.reset();
243975
244108
  while (polyface.moveToNextFacet()) {
243976
244109
  const numEdges = polyface.pointCount - 1;
@@ -243989,17 +244122,17 @@ class PolyfaceQuery {
243989
244122
  * @param sharpEdges true to reverse the angle threshold test and return sharp edges; otherwise return smooth edges (default)
243990
244123
  */
243991
244124
  static collectEdgesByDihedralAngle(mesh, maxSmoothEdgeAngle, sharpEdges = false) {
243992
- if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_3__.Polyface)
244125
+ if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
243993
244126
  return this.collectEdgesByDihedralAngle(mesh.createVisitor(1), maxSmoothEdgeAngle, sharpEdges);
243994
244127
  mesh.setNumWrap(1);
243995
244128
  const allEdges = this.createIndexedEdges(mesh);
243996
244129
  const manifoldEdges = [];
243997
244130
  allEdges.sortAndCollectClusters(manifoldEdges);
243998
244131
  if (undefined === maxSmoothEdgeAngle || maxSmoothEdgeAngle.radians < 0)
243999
- maxSmoothEdgeAngle = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_13__.Angle.createRadians(_Geometry__WEBPACK_IMPORTED_MODULE_5__.Geometry.smallAngleRadians);
244132
+ maxSmoothEdgeAngle = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createRadians(_Geometry__WEBPACK_IMPORTED_MODULE_6__.Geometry.smallAngleRadians);
244000
244133
  const outEdges = [];
244001
- const normal0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Vector3d.create();
244002
- const normal1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Vector3d.create();
244134
+ const normal0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
244135
+ const normal1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
244003
244136
  for (const pair of manifoldEdges) {
244004
244137
  if (Array.isArray(pair) && pair.length === 2) {
244005
244138
  const e0 = pair[0];
@@ -244038,8 +244171,8 @@ class PolyfaceQuery {
244038
244171
  this.markAllEdgeVisibility(mesh, false);
244039
244172
  this.setEdgeVisibility(mesh, boundaryEdges, true);
244040
244173
  if (sharpEdgeAngle !== undefined) {
244041
- const normal0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Vector3d.create();
244042
- const normal1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Vector3d.create();
244174
+ const normal0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
244175
+ const normal1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
244043
244176
  for (const pair of pairedEdges) {
244044
244177
  if (Array.isArray(pair) && pair.length === 2) {
244045
244178
  const e0 = pair[0];
@@ -244061,9 +244194,9 @@ class PolyfaceQuery {
244061
244194
  */
244062
244195
  static computeFacetUnitNormal(visitor, facetIndex, result) {
244063
244196
  if (!result)
244064
- result = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Vector3d.create();
244197
+ result = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
244065
244198
  if (visitor.moveToReadIndex(facetIndex)) {
244066
- if (_geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_4__.PolygonOps.unitNormal(visitor.point, result))
244199
+ if (_geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.unitNormal(visitor.point, result))
244067
244200
  return result;
244068
244201
  }
244069
244202
  return undefined;
@@ -244078,20 +244211,41 @@ class PolyfaceQuery {
244078
244211
  for (let i = 0; i < data.edgeVisible.length; i++)
244079
244212
  data.edgeVisible[i] = value;
244080
244213
  }
244214
+ /**
244215
+ * Create a HalfEdgeGraph with a face for each facet of the IndexedPolyface
244216
+ * @param mesh mesh to convert
244217
+ * @internal
244218
+ */
244219
+ static convertToHalfEdgeGraph(mesh) {
244220
+ const builder = new _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_28__.HalfEdgeGraphFromIndexedLoopsContext();
244221
+ const visitor = mesh.createVisitor(0);
244222
+ for (visitor.reset(); visitor.moveToNextFacet();) {
244223
+ builder.insertLoop(visitor.pointIndex);
244224
+ }
244225
+ const graph = builder.graph;
244226
+ const xyz = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
244227
+ graph.announceNodes((_graph, halfEdge) => {
244228
+ const vertexIndex = halfEdge.i;
244229
+ mesh.data.getPoint(vertexIndex, xyz);
244230
+ halfEdge.setXYZ(xyz);
244231
+ return true;
244232
+ });
244233
+ return graph;
244234
+ }
244081
244235
  /**
244082
244236
  * * Examine adjacent facet orientations throughout the mesh
244083
244237
  * * If possible, reverse a subset to achieve proper pairing.
244084
244238
  * @param mesh
244085
244239
  */
244086
244240
  static reorientVertexOrderAroundFacetsForConsistentOrientation(mesh) {
244087
- return _FacetOrientation__WEBPACK_IMPORTED_MODULE_28__.FacetOrientationFixup.doFixup(mesh);
244241
+ return _FacetOrientation__WEBPACK_IMPORTED_MODULE_29__.FacetOrientationFixup.doFixup(mesh);
244088
244242
  }
244089
244243
  /**
244090
244244
  * Set up indexed normals with one normal in the plane of each facet of the mesh.
244091
244245
  * @param polyface
244092
244246
  */
244093
244247
  static buildPerFaceNormals(polyface) {
244094
- _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_29__.BuildAverageNormalsContext.buildPerFaceNormals(polyface);
244248
+ _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_30__.BuildAverageNormalsContext.buildPerFaceNormals(polyface);
244095
244249
  }
244096
244250
  /**
244097
244251
  * * At each vertex of the mesh
@@ -244103,8 +244257,21 @@ class PolyfaceQuery {
244103
244257
  * @param polyface polyface to update.
244104
244258
  * @param toleranceAngle averaging is done between normals up to this angle.
244105
244259
  */
244106
- static buildAverageNormals(polyface, toleranceAngle = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_13__.Angle.createDegrees(31.0)) {
244107
- _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_29__.BuildAverageNormalsContext.buildFastAverageNormals(polyface, toleranceAngle);
244260
+ static buildAverageNormals(polyface, toleranceAngle = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(31.0)) {
244261
+ _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_30__.BuildAverageNormalsContext.buildFastAverageNormals(polyface, toleranceAngle);
244262
+ }
244263
+ /**
244264
+ * Offset the faces of the mesh.
244265
+ * @param source original mesh
244266
+ * @param signedOffsetDistance distance to offset
244267
+ * @param offsetOptions angle options. The default options are recommended.
244268
+ * @returns shifted mesh.
244269
+ */
244270
+ static cloneOffset(source, signedOffsetDistance, offsetOptions = OffsetMeshOptions.create()) {
244271
+ const strokeOptions = _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_23__.StrokeOptions.createForFacets();
244272
+ const offsetBuilder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create(strokeOptions);
244273
+ _multiclip_OffsetMeshContext__WEBPACK_IMPORTED_MODULE_31__.OffsetMeshContext.buildOffsetMeshWithEdgeChamfers(source, offsetBuilder, signedOffsetDistance, offsetOptions);
244274
+ return offsetBuilder.claimPolyface();
244108
244275
  }
244109
244276
  }
244110
244277
  // amount of computation to do per step of async methods.
@@ -245016,6 +245183,1064 @@ class LinearSearchRange2dArray {
245016
245183
  }
245017
245184
 
245018
245185
 
245186
+ /***/ }),
245187
+
245188
+ /***/ "../../core/geometry/lib/esm/polyface/multiclip/OffsetMeshContext.js":
245189
+ /*!***************************************************************************!*\
245190
+ !*** ../../core/geometry/lib/esm/polyface/multiclip/OffsetMeshContext.js ***!
245191
+ \***************************************************************************/
245192
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
245193
+
245194
+ "use strict";
245195
+ __webpack_require__.r(__webpack_exports__);
245196
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
245197
+ /* harmony export */ "FacetOffsetProperties": () => (/* binding */ FacetOffsetProperties),
245198
+ /* harmony export */ "OffsetMeshContext": () => (/* binding */ OffsetMeshContext),
245199
+ /* harmony export */ "SectorOffsetProperties": () => (/* binding */ SectorOffsetProperties)
245200
+ /* harmony export */ });
245201
+ /* harmony import */ var _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../numerics/Polynomials */ "../../core/geometry/lib/esm/numerics/Polynomials.js");
245202
+ /* harmony import */ var _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../geometry3d/GrowableXYZArray */ "../../core/geometry/lib/esm/geometry3d/GrowableXYZArray.js");
245203
+ /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
245204
+ /* harmony import */ var _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../geometry3d/PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
245205
+ /* harmony import */ var _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../geometry3d/Ray3d */ "../../core/geometry/lib/esm/geometry3d/Ray3d.js");
245206
+ /* harmony import */ var _topology_Graph__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../topology/Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
245207
+ /* harmony import */ var _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../topology/HalfEdgeGraphFromIndexedLoopsContext */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js");
245208
+ /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
245209
+ /* harmony import */ var _geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../geometry3d/PolylineCompressionByEdgeOffset */ "../../core/geometry/lib/esm/geometry3d/PolylineCompressionByEdgeOffset.js");
245210
+ /* harmony import */ var _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../geometry3d/Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
245211
+ /*---------------------------------------------------------------------------------------------
245212
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
245213
+ * See LICENSE.md in the project root for license terms and full copyright notice.
245214
+ *--------------------------------------------------------------------------------------------*/
245215
+ /** @packageDocumentation
245216
+ * @module Polyface
245217
+ */
245218
+
245219
+
245220
+
245221
+
245222
+
245223
+
245224
+
245225
+
245226
+
245227
+
245228
+ function isDefinedAndTrue(value) {
245229
+ if (value === undefined)
245230
+ return false;
245231
+ return value;
245232
+ }
245233
+ class AverageNormalData {
245234
+ constructor() {
245235
+ this.numActiveSectors = 0;
245236
+ this.numInactiveSectors = 0; // exterior and sling.
245237
+ this.averageNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create();
245238
+ this.radiansSum = 0.0;
245239
+ this.maxDeviationRadiansFromAverage = 0.0;
245240
+ }
245241
+ clear() {
245242
+ this.numActiveSectors = 0;
245243
+ this.numInactiveSectors = 0; // exterior and sling.
245244
+ this.averageNormal.setZero();
245245
+ this.radiansSum = 0.0;
245246
+ this.maxDeviationRadiansFromAverage = 0.0;
245247
+ }
245248
+ /** Add a normal to the evolving sum, scaled by radians in the corner */
245249
+ accumulateNormal(node, normal, inactiveMask) {
245250
+ if (node.isMaskSet(inactiveMask)) {
245251
+ this.numInactiveSectors++;
245252
+ }
245253
+ else {
245254
+ const sectorSweepRadians = _topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.sectorSweepRadiansXYZ(node, normal);
245255
+ this.averageNormal.addScaledInPlace(normal, sectorSweepRadians);
245256
+ this.radiansSum += sectorSweepRadians;
245257
+ this.numActiveSectors++;
245258
+ }
245259
+ }
245260
+ /** normalize the accumulated normals. */
245261
+ finishNormalAveraging() {
245262
+ if (this.numActiveSectors > 0 && this.averageNormal.normalizeInPlace()) {
245263
+ return true;
245264
+ }
245265
+ return false;
245266
+ }
245267
+ /** Compute the deviation from average. update max deviation member */
245268
+ recordDeviation(normal, isActive) {
245269
+ if (isActive) {
245270
+ const radians = this.averageNormal.radiansTo(normal);
245271
+ this.maxDeviationRadiansFromAverage = Math.max(Math.abs(this.maxDeviationRadiansFromAverage), radians);
245272
+ }
245273
+ else {
245274
+ }
245275
+ }
245276
+ /** Return the max deviation as computed on prior calls to recordDeviation */
245277
+ get maxDeviationRadians() { return this.maxDeviationRadiansFromAverage; }
245278
+ }
245279
+ function emitSector(sector) {
245280
+ if (OffsetMeshContext.stringDebugFunction !== undefined) {
245281
+ OffsetMeshContext.stringDebugFunction(` Sector xyz ${sector.xyz.x},${sector.xyz.y},${sector.xyz.z} `);
245282
+ OffsetMeshContext.stringDebugFunction(` normal ${sector.normal.x},${sector.normal.y},${sector.normal.z} `);
245283
+ }
245284
+ }
245285
+ // facet properties used during offset.
245286
+ //
245287
+ class FacetOffsetProperties {
245288
+ constructor(facetIndex, normal) {
245289
+ this.facetIndex = facetIndex;
245290
+ this.facetNormal = normal;
245291
+ }
245292
+ }
245293
+ /**
245294
+ * Sector properties during offset.
245295
+ * * this.normal may be initially assigned as the facet normal but can mutate by
245296
+ * averaging with neighbors.
245297
+ * * this.xyz is initially the base mesh xyz but is expected to move along the normal.
245298
+ * * this.count is used locally in computations.
245299
+ */
245300
+ class SectorOffsetProperties {
245301
+ constructor(normal, xyz) {
245302
+ this.xyz = xyz;
245303
+ this.normal = normal;
245304
+ this.count = 0;
245305
+ }
245306
+ /**
245307
+ * Compute the angle between plane normals on opposite sides of the edge.
245308
+ * * parallel normals have zero angle.
245309
+ * * if the edge cuts inward to the volume behind the faces, the angle is negative.
245310
+ * * if the edge is outward (a convex edge) the the volume, the angle is positive.
245311
+ * @param edgeNodeA node on one side of the edge
245312
+ * @param edgeVector pre-allocated vector to receive vector along edge.
245313
+ * @param averageNormal pre-allocated vector to receive the average normal for a chamfer of the offset edge.
245314
+ * @param offsetDistance distance of offset being constructed. The sign of this resolves angle ambiguity.
245315
+ * @param radiansTolerance tolerance for large angle between normals.
245316
+ * @returns true if this edge has SectorOffsetProperties on both sides and the angle between normals angle exceeds radiansTolerance.
245317
+ */
245318
+ static edgeHasLargeExteriorAngleBetweenNormals(edgeNodeA, edgeVector, averageNormal, offsetDistance, radiansTolerance = Math.PI * 0.5) {
245319
+ const propsA = edgeNodeA.edgeTag;
245320
+ const edgeNodeB = edgeNodeA.edgeMate;
245321
+ const propsB = edgeNodeB.edgeTag;
245322
+ if (propsA !== undefined && propsB !== undefined) {
245323
+ edgeNodeA.vectorToFaceSuccessor(edgeVector);
245324
+ const radians = propsA.normal.signedRadiansTo(propsB.normal, edgeVector);
245325
+ if (_Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.split3WaySign(offsetDistance, -1, 1, 1) * radians >= radiansTolerance) {
245326
+ _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.createAdd2Scaled(propsA.normal, 1.0, propsB.normal, 1.0, averageNormal);
245327
+ if (averageNormal.normalizeInPlace())
245328
+ return true;
245329
+ }
245330
+ }
245331
+ return false;
245332
+ }
245333
+ static almostEqualNormals(sectorA, sectorB, radiansTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallAngleRadians) {
245334
+ return sectorA.normal.radiansTo(sectorB.normal) <= radiansTolerance;
245335
+ }
245336
+ static radiansBetweenNormals(sectorA, sectorB) {
245337
+ return sectorA.normal.radiansTo(sectorB.normal);
245338
+ }
245339
+ // Set the offset point this.xyz as sum of the nodeXyz + distance * this.normal
245340
+ setOffsetPointAtDistanceAtHalfEdge(halfEdge, distance) {
245341
+ halfEdge.getPoint3d(this.xyz);
245342
+ this.xyz.addScaledInPlace(this.normal, distance);
245343
+ }
245344
+ // Copy xyz from parameter into (preexisting object) xyz
245345
+ static setXYZAtHalfEdge(halfEdge, xyz) {
245346
+ const props = halfEdge.edgeTag;
245347
+ if (props !== undefined && xyz !== undefined)
245348
+ props.xyz.set(xyz.x, xyz.y, xyz.z);
245349
+ }
245350
+ // Set the offset point this.xyz directly
245351
+ setXYAndZ(xyz) {
245352
+ this.xyz.set(xyz.x, xyz.y, xyz.z);
245353
+ }
245354
+ // Look through the half edge to its properties. Set the normal there. Optionally set xyz from node xyz and offset distance
245355
+ static setNormalAtHalfEdge(halfEdge, uvw, distance) {
245356
+ const props = halfEdge.edgeTag;
245357
+ if (props !== undefined) {
245358
+ props.normal.set(uvw.x, uvw.y, uvw.z);
245359
+ if (distance !== undefined)
245360
+ props.setOffsetPointAtDistanceAtHalfEdge(halfEdge, distance);
245361
+ }
245362
+ }
245363
+ // Look through the half edge and its vertex successor to properties. Get the two normals. Return the angle sweeping from one to the next
245364
+ static sweepRadiansAroundNormal(nodeA, upVector) {
245365
+ const propsA = nodeA.edgeTag;
245366
+ const propsB = nodeA.vertexSuccessor.edgeTag;
245367
+ if (propsA !== undefined && propsB !== undefined) {
245368
+ return propsA.normal.planarRadiansTo(propsB.normal, upVector);
245369
+ }
245370
+ return undefined;
245371
+ }
245372
+ // Look through the half edge to its properties. return (if possible) the coordinates
245373
+ static getSectorPointAtHalfEdge(halfEdge, xyz, xyzArray) {
245374
+ const props = halfEdge.edgeTag;
245375
+ if (props !== undefined) {
245376
+ if (xyz !== undefined)
245377
+ xyz.setFromPoint3d(props.xyz);
245378
+ if (xyzArray !== undefined)
245379
+ xyzArray.push(props.xyz);
245380
+ return true;
245381
+ }
245382
+ return false;
245383
+ }
245384
+ // access the XYZ and push to the array (which makes copies, not reference)
245385
+ // return pointer to the SectorOffsetProperties
245386
+ static pushXYZ(xyzArray, halfEdge) {
245387
+ const sector = halfEdge.edgeTag;
245388
+ if (sector !== undefined)
245389
+ xyzArray.push(sector.xyz);
245390
+ return sector;
245391
+ }
245392
+ // Dereference to execute: accumulatingVector += halfEdge.edgeTag.normal * scale
245393
+ static accumulateScaledNormalAtHalfEdge(halfEdge, scale, accumulatingVector) {
245394
+ const sector = halfEdge.edgeTag;
245395
+ if (sector !== undefined)
245396
+ accumulatingVector.addScaledInPlace(sector.normal, scale);
245397
+ }
245398
+ }
245399
+ /*
245400
+ About Chamfer Edges ..... as constructed in addChamferTopologyToAllEdges
245401
+
245402
+ When edge vertex X to vertex Y has a sharp angle between normals, a "chamfer face" must be created to "fatten" it.
245403
+
245404
+ The original half edges (nodes) for the edge are AX and AY. These are "mates" in the halfEdge mental model. As always,
245405
+ AX is (as needed)
245406
+ (i) the preferred half edge for the left side of the edge moving from X to Y. (i.e. above the edge)
245407
+ (ii) a part of the face loop for the face to the left when proceeding CCW around the face to the above the drawn edge
245408
+ (iii) a part of the vertex loop around X
245409
+ Likewise, AY is (as needed)
245410
+ (i) the preferred half edge for the left side of the edge moving from Y to X (i.e. below the edge)
245411
+ (ii) a part of the face loop for the face to the left of the edge when proceeding CCW around the face below the edge.
245412
+ (iii) a part of the vertex loop around Y
245413
+
245414
+ AX------>
245415
+ X______________________________________________________________________Y
245416
+ <---AY
245417
+
245418
+ When the chamfer face is created, it needs to have a sliver face "inside the edge" -- something in the space here
245419
+
245420
+ AX------>
245421
+ _____________________________________________________________________
245422
+ / \
245423
+ X Y
245424
+ \_____________________________________________________________________/
245425
+ <---AY
245426
+
245427
+ The chamfer face will have a plane normal is the average of the two faces' plane normals.
245428
+
245429
+ The creation sequence for the chamfer face puts a slit "inside the edge" as above HalfEdges AX and AY remain as parts
245430
+ of their respective face loops. In addition, at each end a singleton edge "sling" face is inserted at each
245431
+ end of the sliver face.
245432
+
245433
+ The sequence is:
245434
+
245435
+ STEP 1: splitEdgeCreateSliver creates the sliver face with 2 half edges DX and DY
245436
+ STEP 2: splitEdge (with undefined as the "prior" edge) creates a sling with HalfEdge CX "inside" and BX "outside".
245437
+ (The sling face is not yet attached to X -- briefly floating in space)
245438
+ STEP 3: pinch of HalfEdges BX and DX inserts the sling face "inside" the slit face at the X end.
245439
+
245440
+ Steps 2 and 3 are executed from each end. Due to the symmetric structure, a 2-pass loop can apply the logic at each end without distinct names in code.
245441
+
245442
+ AX------>
245443
+ _______________________________________________________________
245444
+ / <---DY \
245445
+ / \
245446
+ / BX---> \
245447
+ / _______________ _______________ \
245448
+ | / \ / <----CY \ |
245449
+ |/ \ / \|
245450
+ X | | Y
245451
+ |\ CX---> / \ /|
245452
+ | \_______________/ \_______________/ |
245453
+ \ <---BY /
245454
+ \ /
245455
+ \ DX---> /
245456
+ \ ______________________________________________________________/
245457
+ <---AY
245458
+
245459
+ During the construction, the letters ABCD are used as above, but with prefixes emphasizing their role
245460
+ outsideAX, outsideAY
245461
+ slingB, slingC, sliverD
245462
+
245463
+ The "inside" sling faces (CX and CY) each have their own FacetOffsetProperties and SectorOffsetProperties.
245464
+ The sliver face has its own FacetOffsetProperties which are referenced by DX, BY, DY, BX.
245465
+ Each of those 4 has its own SectorOffSetProperties.
245466
+
245467
+ Important properties during offset construction:
245468
+ 1) the original graph always has original topology and coordinates
245469
+ 2) Each face of the original graph has a FacetOffsetProperties with a representative point and a normal. These are unchanged during the computation.
245470
+ 3) Each node has its own SectorOffsetProperties with a coordinate and normal independent of the parent node.
245471
+ 3.1 The first offset coordinates in each node are directly offset by face normal.
245472
+ 3.2 This creates mismatch across edges and around vertices.
245473
+ 3.3 Various sweeps "around each vertex" try to do intersections among appropriate offset planes to find
245474
+ common coordinates in place of the initial mismatches.
245475
+ 4) The independence of all the sectors allows the offset construction to fix things up in any order it chooses.
245476
+ 5) During the construction, the xyz in SectorOffsetProperties around a single vertex do NOT have to match.
245477
+ 6) At output time, there are three sweeps:
245478
+ 6.1: By face: Go around the face and output a facet with the coordinates in the various sectors.
245479
+ 6.2: By edge: For each edge, if the sector xyz match across both ends output nothing. If not, output a triangle or quad
245480
+ 6.3: By vertex: At each vertex, if all vertex coordinates match output nothing. Otherwise output a facet with all the coordinates.
245481
+ */
245482
+ class OffsetMeshContext {
245483
+ constructor(basePolyface, baseGraph, options) {
245484
+ this._basePolyface = basePolyface;
245485
+ this._baseGraph = baseGraph;
245486
+ this._breakMaskA = baseGraph.grabMask();
245487
+ this._breakMaskB = baseGraph.grabMask();
245488
+ this._insideOfChamferFace = baseGraph.grabMask();
245489
+ this._outsideOfChamferFace = baseGraph.grabMask();
245490
+ this._insideChamferSling = baseGraph.grabMask();
245491
+ this._outsideEndOfChamferFace = baseGraph.grabMask();
245492
+ this._exteriorMask = _topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdgeMask.EXTERIOR;
245493
+ this._offsetCoordinatesReassigned = baseGraph.grabMask();
245494
+ this._smoothRadiansBetweenNormals = options.smoothSingleAngleBetweenNormals.radians;
245495
+ this._chamferTurnRadians = options.chamferAngleBetweenNormals.radians;
245496
+ this._smoothAccumulatedRadiansBetweenNormals = options.smoothAccumulatedAngleBetweenNormals.radians;
245497
+ }
245498
+ /** "Exterior" side of a bare edge of the mesh */
245499
+ get exteriorMask() { return this._exteriorMask; }
245500
+ /** "First" sector of a smooth sequence. */
245501
+ get breakMaskA() { return this._breakMaskA; }
245502
+ /** "Last" sector of a smooth sequence. */
245503
+ get breakMaskB() { return this._breakMaskB; }
245504
+ /** This edge is on a chamfered face, and along the original edge */
245505
+ get insideOfChamferFace() { return this._insideOfChamferFace; }
245506
+ /** This is the original edge of a chamfer face */
245507
+ get outsideOfChamferFace() { return this._outsideOfChamferFace; }
245508
+ /** This edge is on a chamfered face, and at the end -- other side may be a sling */
245509
+ get insideChamferSling() { return this._insideChamferSling; }
245510
+ /** This is the outside of the end of a chamfer face -- i.e. the inside of a new face-at-vertex */
245511
+ get outsideEndOfChamferFace() { return this._outsideEndOfChamferFace; }
245512
+ // At each node . .
245513
+ // * Find the sector data
245514
+ // * recompute the sector point using node XYZ and sectorData normal.
245515
+ applyFaceNormalOffsetsToSectorData(distance) {
245516
+ this._baseGraph.announceNodes((_graph, node) => {
245517
+ const sectorData = node.edgeTag;
245518
+ if (sectorData !== undefined) {
245519
+ sectorData.setOffsetPointAtDistanceAtHalfEdge(node, distance);
245520
+ }
245521
+ return true;
245522
+ });
245523
+ }
245524
+ /**
245525
+ * * build a mesh offset by given distance.
245526
+ * * output the mesh to the given builder.
245527
+ * @param basePolyface original mesh
245528
+ * @param builder polyface builder to receive the new mesh.
245529
+ * @param distance signed offset distance.
245530
+ */
245531
+ static buildOffsetMeshWithEdgeChamfers(basePolyface, builder, distance, options) {
245532
+ const baseGraph = this.buildBaseGraph(basePolyface);
245533
+ if (baseGraph !== undefined) {
245534
+ const offsetBuilder = new OffsetMeshContext(basePolyface, baseGraph, options);
245535
+ offsetBuilder.applyFaceNormalOffsetsToSectorData(distance);
245536
+ if (OffsetMeshContext.graphDebugFunction !== undefined)
245537
+ OffsetMeshContext.graphDebugFunction("BaseGraph", baseGraph, offsetBuilder._breakMaskA, offsetBuilder._breakMaskB);
245538
+ const outputSelector = options.outputSelector ? options.outputSelector : {
245539
+ outputOffsetsFromFaces: true,
245540
+ outputOffsetsFromEdges: true,
245541
+ outputOffsetsFromVertices: true,
245542
+ };
245543
+ if (isDefinedAndTrue(outputSelector.outputOffsetsFromFacesBeforeChamfers))
245544
+ offsetBuilder.announceFacetsWithSectorCoordinatesAroundFaces(builder);
245545
+ offsetBuilder.addChamferTopologyToAllEdges(options, distance);
245546
+ offsetBuilder.computeOffsetFacetIntersections(distance);
245547
+ if (OffsetMeshContext.graphDebugFunction !== undefined)
245548
+ OffsetMeshContext.graphDebugFunction("after computeEdgeChamfers", baseGraph, offsetBuilder._breakMaskA, offsetBuilder._breakMaskB);
245549
+ if (isDefinedAndTrue(outputSelector.outputOffsetsFromFaces))
245550
+ offsetBuilder.announceFacetsWithSectorCoordinatesAroundFaces(builder);
245551
+ if (isDefinedAndTrue(outputSelector.outputOffsetsFromEdges))
245552
+ offsetBuilder.announceFacetsWithSectorCoordinatesAroundEdges(builder);
245553
+ if (isDefinedAndTrue(outputSelector.outputOffsetsFromVertices))
245554
+ offsetBuilder.announceFacetsWithSectorCoordinatesAroundVertices(builder);
245555
+ }
245556
+ }
245557
+ /**
245558
+ * For each face of the graph, shift vertices by offsetDistance and emit to the builder as a facet
245559
+ * @param polyfaceBuilder
245560
+ */
245561
+ announceSimpleOffsetFromFaces(polyfaceBuilder, offsetDistance) {
245562
+ const xyzLoop = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__.GrowableXYZArray();
245563
+ const xyz = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create(); // reused at each point around each facet.
245564
+ const uvw = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create(); // reused once per facet
245565
+ const announceNodeAroundFace = (node) => {
245566
+ node.getPoint3d(xyz);
245567
+ xyz.addInPlace(uvw);
245568
+ xyzLoop.push(xyz);
245569
+ return 0;
245570
+ };
245571
+ this._baseGraph.announceFaceLoops((_graph, seed) => {
245572
+ if (!seed.isMaskSet(_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdgeMask.EXTERIOR)) {
245573
+ const facetProperties = seed.faceTag;
245574
+ uvw.setFromVector3d(facetProperties.facetNormal.direction);
245575
+ uvw.scaleInPlace(offsetDistance);
245576
+ xyzLoop.length = 0;
245577
+ seed.sumAroundFace(announceNodeAroundFace);
245578
+ polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);
245579
+ }
245580
+ return true;
245581
+ });
245582
+ }
245583
+ /**
245584
+ * For each face of the graph, output the xyz of the sector data
245585
+ * @param polyfaceBuilder
245586
+ */
245587
+ announceFacetsWithSectorCoordinatesAroundFaces(polyfaceBuilder) {
245588
+ const xyzLoop = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__.GrowableXYZArray();
245589
+ // For face loop visits .. get the point from the sector data.
245590
+ const announceNodeAroundFace = (node) => {
245591
+ const sectorData = node.edgeTag;
245592
+ if (sectorData !== undefined) {
245593
+ xyzLoop.push(sectorData.xyz);
245594
+ }
245595
+ return 0;
245596
+ };
245597
+ this._baseGraph.announceFaceLoops((_graph, seed) => {
245598
+ if (!seed.isMaskSet(_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdgeMask.EXTERIOR)) {
245599
+ xyzLoop.length = 0;
245600
+ seed.sumAroundFace(announceNodeAroundFace);
245601
+ if (xyzLoop.length > 2)
245602
+ polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);
245603
+ }
245604
+ return true;
245605
+ });
245606
+ }
245607
+ countBits(mask) {
245608
+ let n = 0;
245609
+ let mask1 = mask;
245610
+ while (mask1 !== 0) {
245611
+ if (mask1 & 0x01)
245612
+ n++;
245613
+ mask1 = mask1 >> 1;
245614
+ }
245615
+ return n;
245616
+ }
245617
+ /**
245618
+ * For each edge of the graph . .
245619
+ * * Collect coordinates in 4 sectors going around the edge
245620
+ * * Compress with tight tolerance so adjacent sectors with clean point match reduce to a single point.
245621
+ * * Emit as a facet.
245622
+ * @param polyfaceBuilder
245623
+ */
245624
+ announceFacetsWithSectorCoordinatesAroundEdges(polyfaceBuilder) {
245625
+ const xyzLoop = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__.GrowableXYZArray();
245626
+ const primaryCompressionTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallMetricDistance;
245627
+ const allMasksForEdgesToIgnore = this._exteriorMask
245628
+ | this._outsideEndOfChamferFace
245629
+ | this._outsideOfChamferFace
245630
+ | this._insideOfChamferFace
245631
+ | this._insideChamferSling;
245632
+ this._baseGraph.announceEdges((_graph, nodeA) => {
245633
+ // This starts by looking for EXTERIOR on both sides ...
245634
+ if (nodeA.findMaskAroundEdge(this._exteriorMask) !== undefined) {
245635
+ return true;
245636
+ }
245637
+ else if (!nodeA.isMaskSet(allMasksForEdgesToIgnore)) { // By design, we believe that these two test for allMasksForEdgesToIgnore condition would catch the EXTERIOR case above
245638
+ const nodeB = nodeA.faceSuccessor;
245639
+ const nodeC = nodeA.edgeMate;
245640
+ if (!nodeC.isMaskSet(allMasksForEdgesToIgnore)) {
245641
+ const nodeD = nodeC.faceSuccessor;
245642
+ xyzLoop.clear();
245643
+ SectorOffsetProperties.getSectorPointAtHalfEdge(nodeA, undefined, xyzLoop);
245644
+ SectorOffsetProperties.getSectorPointAtHalfEdge(nodeB, undefined, xyzLoop);
245645
+ SectorOffsetProperties.getSectorPointAtHalfEdge(nodeC, undefined, xyzLoop);
245646
+ SectorOffsetProperties.getSectorPointAtHalfEdge(nodeD, undefined, xyzLoop);
245647
+ _geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_4__.PolylineCompressionContext.compressInPlaceByShortEdgeLength(xyzLoop, primaryCompressionTolerance);
245648
+ if (xyzLoop.length > 2) {
245649
+ polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);
245650
+ }
245651
+ }
245652
+ }
245653
+ else {
245654
+ return true;
245655
+ }
245656
+ return true;
245657
+ });
245658
+ }
245659
+ getCoordinateString(node, showXYZ = true, showFaceSuccessorXYZ = false) {
245660
+ if (showXYZ) {
245661
+ if (showFaceSuccessorXYZ) {
245662
+ return `${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(node)} ==> ${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(node.faceSuccessor)}`;
245663
+ }
245664
+ else {
245665
+ return `${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(node)}`;
245666
+ }
245667
+ }
245668
+ else {
245669
+ if (showFaceSuccessorXYZ) {
245670
+ return `==> ${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(node.faceSuccessor)}`;
245671
+ }
245672
+ else {
245673
+ return "";
245674
+ }
245675
+ }
245676
+ }
245677
+ inspectMasks(node, showXYZ = true, showFaceSuccessorXYZ = false) {
245678
+ const s = "[";
245679
+ const v = s.concat(node.id.toString(), node.isMaskSet(this._exteriorMask) ? "X" : "", node.isMaskSet(this.breakMaskA) ? "A" : "", node.isMaskSet(this.breakMaskB) ? "B" : "", node.isMaskSet(this.insideChamferSling) ? "(sling)" : "", node.isMaskSet(this.insideOfChamferFace) ? "(in chamfer)" : "", node.isMaskSet(this.outsideEndOfChamferFace) ? "(@sling)" : "", node.isMaskSet(this.outsideOfChamferFace) ? "(@chamfer)" : "", this.getCoordinateString(node, showXYZ, showFaceSuccessorXYZ), "]");
245680
+ return v;
245681
+ }
245682
+ /**
245683
+ * For each face of the graph, output the xyz of the sector data
245684
+ * @param polyfaceBuilder
245685
+ */
245686
+ announceFacetsWithSectorCoordinatesAroundVertices(polyfaceBuilder) {
245687
+ const xyzLoop = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__.GrowableXYZArray();
245688
+ const primaryCompressionTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallMetricDistance;
245689
+ this._baseGraph.announceVertexLoops((_graph, seed) => {
245690
+ if (!seed.findMaskAroundVertex(this._exteriorMask)) {
245691
+ xyzLoop.length = 0;
245692
+ seed.sumAroundVertex((node) => {
245693
+ if (!node.isMaskSet(this._insideChamferSling))
245694
+ SectorOffsetProperties.getSectorPointAtHalfEdge(node, undefined, xyzLoop);
245695
+ return 0.0;
245696
+ });
245697
+ _geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_4__.PolylineCompressionContext.compressInPlaceByShortEdgeLength(xyzLoop, primaryCompressionTolerance);
245698
+ if (xyzLoop.length > 2) {
245699
+ polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);
245700
+ }
245701
+ }
245702
+ return true;
245703
+ });
245704
+ }
245705
+ /**
245706
+ * * Exterior half edges have HalfEdgeMask.EXTERIOR
245707
+ * * All interior half edge around a facet have facetTag pointing to a facetProperties object for that facet.
245708
+ * * the facetOffsetProperties object has the simple facet normal.
245709
+ * * Each half edge has edgeTag pointing to to a sectorOffsetProperties object
245710
+ * * the sectorOffsetProperties has a copy of the facet normal.
245711
+ * @param polyface
245712
+ * @returns graph
245713
+ */
245714
+ static buildBaseGraph(polyface) {
245715
+ const graphBuilder = new _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_5__.HalfEdgeGraphFromIndexedLoopsContext();
245716
+ const visitor = polyface.createVisitor();
245717
+ const xyzA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
245718
+ const xyzB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
245719
+ for (visitor.reset(); visitor.moveToNextFacet();) {
245720
+ const normal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_6__.PolygonOps.centroidAreaNormal(visitor.point);
245721
+ if (normal !== undefined) {
245722
+ const edgeA = graphBuilder.insertLoop(visitor.pointIndex, (insideHalfEdge) => {
245723
+ const mate = insideHalfEdge.edgeMate;
245724
+ polyface.data.getPoint(insideHalfEdge.i, xyzA);
245725
+ insideHalfEdge.setXYZ(xyzA);
245726
+ polyface.data.getPoint(mate.i, xyzB);
245727
+ mate.setXYZ(xyzB);
245728
+ });
245729
+ const facetProperties = new FacetOffsetProperties(visitor.currentReadIndex(), normal);
245730
+ if (edgeA !== undefined) {
245731
+ edgeA.sumAroundFace((edgeB) => {
245732
+ edgeB.faceTag = facetProperties;
245733
+ edgeB.edgeTag = new SectorOffsetProperties(normal.direction.clone(), edgeB.getPoint3d());
245734
+ return 0;
245735
+ });
245736
+ }
245737
+ }
245738
+ }
245739
+ return graphBuilder.graph;
245740
+ }
245741
+ setOffsetAtDistanceAroundVertex(vertexSeed, distance, ignoreChamfers = false) {
245742
+ vertexSeed.sumAroundVertex((nodeAroundVertex) => {
245743
+ const props = nodeAroundVertex.edgeTag;
245744
+ if (props !== undefined) {
245745
+ if (ignoreChamfers && this.isInsideChamferOrSling(vertexSeed)) {
245746
+ // SKIP !!
245747
+ }
245748
+ else {
245749
+ props.setOffsetPointAtDistanceAtHalfEdge(nodeAroundVertex, distance);
245750
+ }
245751
+ }
245752
+ return 0.0;
245753
+ });
245754
+ }
245755
+ setOffsetXYAndZAroundVertex(vertexSeed, xyz) {
245756
+ vertexSeed.sumAroundVertex((nodeAroundVertex) => {
245757
+ const props = nodeAroundVertex.edgeTag;
245758
+ if (props !== undefined) {
245759
+ props.setXYAndZ(xyz);
245760
+ nodeAroundVertex.setMask(this._offsetCoordinatesReassigned);
245761
+ }
245762
+ return 0.0;
245763
+ });
245764
+ }
245765
+ /**
245766
+ * * start at vertexSeed.
245767
+ * * set the offset point at up to (and including) one with (a) this._breakMaskB or (b) this._exteriorMask
245768
+ * *
245769
+ * @param vertexSeed first node to mark.
245770
+ * @param f function to call to announce each node and its sector properties.
245771
+ * @returns number of nodes marked.
245772
+ */
245773
+ announceNodeAndSectorPropertiesInSmoothSector(vertexSeed, f) {
245774
+ let n = 0;
245775
+ for (let currentNode = vertexSeed;; currentNode = currentNode.vertexSuccessor) {
245776
+ const props = currentNode.edgeTag;
245777
+ if (props !== undefined) {
245778
+ f(currentNode, props);
245779
+ n++;
245780
+ }
245781
+ if (currentNode.isMaskSet(this._breakMaskB))
245782
+ return n;
245783
+ // REMARK: these additional exit conditions should not happen if (a) the graph is properly marked and (b) the start node is not exterior.
245784
+ if (currentNode.isMaskSet(this._exteriorMask))
245785
+ return n;
245786
+ if (currentNode === vertexSeed && n === 0)
245787
+ return n;
245788
+ }
245789
+ }
245790
+ computeAverageNormalAndMaxDeviationAroundVertex(vertexSeed, data) {
245791
+ data.clear();
245792
+ const inactiveNodeMask = this._exteriorMask | this._insideChamferSling;
245793
+ vertexSeed.sumAroundVertex((node) => {
245794
+ const sectorData = node.edgeTag;
245795
+ if (sectorData)
245796
+ data.accumulateNormal(node, sectorData.normal, inactiveNodeMask);
245797
+ return 0.0;
245798
+ });
245799
+ if (!data.finishNormalAveraging()) {
245800
+ return undefined;
245801
+ }
245802
+ vertexSeed.sumAroundVertex((node) => {
245803
+ const sectorData = node.edgeTag;
245804
+ if (sectorData)
245805
+ data.recordDeviation(sectorData.normal, !node.isMaskSet(inactiveNodeMask));
245806
+ return 0.0;
245807
+ });
245808
+ return data.maxDeviationRadians;
245809
+ }
245810
+ assignOffsetByAverageNormalAroundVertex(vertexSeed, maxAllowedDeviationRadians, data, distance) {
245811
+ const maxDeviationRadians = this.computeAverageNormalAndMaxDeviationAroundVertex(vertexSeed, data);
245812
+ if (OffsetMeshContext.stringDebugFunction) {
245813
+ OffsetMeshContext.stringDebugFunction(`XYZ ${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(vertexSeed)} Average Normal ${data.averageNormal.toJSON()}`);
245814
+ OffsetMeshContext.stringDebugFunction(` angle ratio ${data.radiansSum / (2 * Math.PI)} maxDeviation ${data.maxDeviationRadiansFromAverage}`);
245815
+ }
245816
+ if (maxDeviationRadians !== undefined && maxDeviationRadians <= maxAllowedDeviationRadians) {
245817
+ vertexSeed.sumAroundVertex((node) => {
245818
+ SectorOffsetProperties.setNormalAtHalfEdge(node, data.averageNormal, distance);
245819
+ return 0;
245820
+ });
245821
+ return true;
245822
+ }
245823
+ return false;
245824
+ }
245825
+ /** Search around a vertex for a sector which has a different normal from its vertexPredecessor.
245826
+ * * The seed will be the first candidate considered
245827
+ */
245828
+ markBreakEdgesAndSaveAverageNormalsAroundVertex(vertexSeed) {
245829
+ vertexSeed.clearMaskAroundVertex(this._breakMaskA);
245830
+ vertexSeed.clearMaskAroundVertex(this._breakMaskB);
245831
+ const smoothSingleSmoothRadiansBetweenNormals = this._smoothRadiansBetweenNormals;
245832
+ const accumulatedRadiansBetweenNormals = this._smoothAccumulatedRadiansBetweenNormals;
245833
+ // Step 1: Examine the edge between nodeA and the sector on its vertex predecessor side. This (alone) determines single angle breaks.
245834
+ let numBreaks = 0;
245835
+ let nodeP = vertexSeed;
245836
+ let _numSmooth = 0;
245837
+ do {
245838
+ const nodeQ = nodeP.edgeMate;
245839
+ const nodeR = nodeQ.faceSuccessor; // same as nodeA.vertexPredecessor
245840
+ if (nodeP.isMaskSet(this._exteriorMask)) {
245841
+ if (!nodeQ.isMaskSet(this._exteriorMask)) {
245842
+ nodeR.setMask(this._breakMaskB);
245843
+ numBreaks++;
245844
+ }
245845
+ }
245846
+ else {
245847
+ if (nodeP.isMaskSet(this._outsideOfChamferFace)) {
245848
+ nodeP.setMask(this._breakMaskA);
245849
+ }
245850
+ else if (nodeP.isMaskSet(this._outsideEndOfChamferFace)) {
245851
+ nodeP.setMask(this._breakMaskA);
245852
+ nodeP.setMask(this._breakMaskB);
245853
+ }
245854
+ else if (nodeP.isMaskSet(this._insideChamferSling)) {
245855
+ // This is the sling. It's normal is along edge -- not really a break.
245856
+ }
245857
+ else if (nodeP.isMaskSet(this._insideOfChamferFace)) {
245858
+ nodeP.setMask(this._breakMaskA);
245859
+ nodeP.setMask(this._breakMaskB);
245860
+ nodeR.setMask(this._breakMaskB);
245861
+ }
245862
+ else if (nodeQ.isMaskSet(this._exteriorMask)) {
245863
+ numBreaks++;
245864
+ nodeP.setMask(this._breakMaskA);
245865
+ }
245866
+ else if (!SectorOffsetProperties.almostEqualNormals(nodeP.edgeTag, nodeR.edgeTag, smoothSingleSmoothRadiansBetweenNormals)) {
245867
+ nodeP.setMask(this._breakMaskA);
245868
+ numBreaks++;
245869
+ nodeR.setMask(this._breakMaskB);
245870
+ }
245871
+ else {
245872
+ _numSmooth++;
245873
+ }
245874
+ }
245875
+ nodeP = nodeP.vertexSuccessor;
245876
+ } while (nodeP !== vertexSeed);
245877
+ if (OffsetMeshContext.stringDebugFunction !== undefined)
245878
+ OffsetMeshContext.stringDebugFunction(` numSkip ${_numSmooth} `);
245879
+ if (numBreaks === 0) {
245880
+ // make the first vertex a break so subsequent searches have a place to start
245881
+ vertexSeed.setMask(this._breakMaskA);
245882
+ vertexSeed.vertexPredecessor.setMask(this._breakMaskB);
245883
+ numBreaks = 1;
245884
+ }
245885
+ // Step 2: At each single break, sweep forward to its closing breakB. Insert breaks at accumulated angles.
245886
+ // (minor TODO: for the insertion case, try to split more equally.)
245887
+ const nodeAStart = nodeP.findMaskAroundVertex(this._breakMaskA);
245888
+ if (nodeAStart !== undefined) {
245889
+ nodeP = nodeAStart;
245890
+ do {
245891
+ if (nodeP.isMaskSet(this._breakMaskA) && !nodeP.isMaskSet(this._breakMaskB)) {
245892
+ let accumulatedRadians = 0.0;
245893
+ do {
245894
+ const nodeB = nodeP.vertexSuccessor;
245895
+ accumulatedRadians += SectorOffsetProperties.radiansBetweenNormals(nodeP.edgeTag, nodeB.edgeTag);
245896
+ if (accumulatedRadians > accumulatedRadiansBetweenNormals) {
245897
+ nodeP.setMask(this._breakMaskB);
245898
+ nodeB.setMask(this._breakMaskA);
245899
+ numBreaks++;
245900
+ accumulatedRadians = 0.0;
245901
+ }
245902
+ nodeP = nodeB;
245903
+ } while (!nodeP.isMaskSet(this._breakMaskB));
245904
+ }
245905
+ else {
245906
+ nodeP = nodeP.vertexSuccessor;
245907
+ }
245908
+ } while (nodeP !== nodeAStart);
245909
+ }
245910
+ if (numBreaks > 0 && nodeAStart !== undefined) {
245911
+ // In each compound sector, accumulate and install average normal.
245912
+ nodeP = nodeAStart;
245913
+ const averageNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create();
245914
+ const edgeVectorU = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create();
245915
+ const edgeVectorV = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create();
245916
+ averageNormal.setZero();
245917
+ do {
245918
+ if (nodeP.isMaskSet(this._breakMaskA) && !nodeP.isMaskSet(this._breakMaskB)) {
245919
+ let nodeQ = nodeP;
245920
+ averageNormal.setZero();
245921
+ for (;;) {
245922
+ nodeQ.vectorToFaceSuccessor(edgeVectorU);
245923
+ nodeQ.vectorToFacePredecessor(edgeVectorV);
245924
+ let singleSectorRadians = edgeVectorU.signedRadiansTo(edgeVectorV, nodeQ.faceTag.facetNormal.direction);
245925
+ if (singleSectorRadians < 0.0)
245926
+ singleSectorRadians += Math.PI * 2;
245927
+ SectorOffsetProperties.accumulateScaledNormalAtHalfEdge(nodeQ, singleSectorRadians, averageNormal);
245928
+ if (nodeQ.isMaskSet(this._breakMaskB))
245929
+ break;
245930
+ nodeQ = nodeQ.vertexSuccessor;
245931
+ }
245932
+ if (averageNormal.normalizeInPlace()) {
245933
+ nodeQ = nodeP;
245934
+ for (;;) {
245935
+ SectorOffsetProperties.setNormalAtHalfEdge(nodeQ, averageNormal);
245936
+ if (nodeQ.isMaskSet(this._breakMaskB))
245937
+ break;
245938
+ nodeQ = nodeQ.vertexSuccessor;
245939
+ }
245940
+ }
245941
+ }
245942
+ nodeP = nodeP.vertexSuccessor;
245943
+ } while (nodeP !== nodeAStart);
245944
+ }
245945
+ }
245946
+ /** Compute the point of intersection of the planes in the sectors of 3 half edges */
245947
+ compute3SectorIntersection(nodeA, nodeB, nodeC, result) {
245948
+ const sectorA = nodeA.edgeTag;
245949
+ const sectorB = nodeB.edgeTag;
245950
+ const sectorC = nodeC.edgeTag;
245951
+ const vector = _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_7__.SmallSystem.intersect3Planes(sectorA.xyz, sectorA.normal, sectorB.xyz, sectorB.normal, sectorC.xyz, sectorC.normal, result);
245952
+ return vector;
245953
+ }
245954
+ /** Compute the point of intersection of the planes in the sectors of 3 half edges */
245955
+ compute3SectorIntersectionDebug(nodeA, nodeB, nodeC, result) {
245956
+ const sectorA = nodeA.edgeTag;
245957
+ const sectorB = nodeB.edgeTag;
245958
+ const sectorC = nodeC.edgeTag;
245959
+ if (OffsetMeshContext.stringDebugFunction !== undefined) {
245960
+ OffsetMeshContext.stringDebugFunction(`compute3${this.inspectMasks(nodeA)}${this.inspectMasks(nodeB)}${this.inspectMasks(nodeC)} `);
245961
+ for (const sector of [sectorA, sectorB, sectorC])
245962
+ emitSector(sector);
245963
+ }
245964
+ const vector = _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_7__.SmallSystem.intersect3Planes(sectorA.xyz, sectorA.normal, sectorB.xyz, sectorB.normal, sectorC.xyz, sectorC.normal, result);
245965
+ if (OffsetMeshContext.stringDebugFunction !== undefined) {
245966
+ if (vector === undefined)
245967
+ OffsetMeshContext.stringDebugFunction(" NO INTERSECTION");
245968
+ else
245969
+ OffsetMeshContext.stringDebugFunction(` ComputedVector ${vector.x},${vector.y},${vector.z} `);
245970
+ }
245971
+ return vector;
245972
+ }
245973
+ /** Compute the point of intersection of the planes in the sectors of 2 half edges, using cross product of their normals to resolve */
245974
+ compute2SectorIntersection(nodeA, nodeB, result) {
245975
+ const sectorA = nodeA.edgeTag;
245976
+ const sectorB = nodeB.edgeTag;
245977
+ const normalC = sectorA.normal.crossProduct(sectorB.normal);
245978
+ return _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_7__.SmallSystem.intersect3Planes(sectorA.xyz, sectorA.normal, sectorB.xyz, sectorB.normal, sectorB.xyz, normalC, result);
245979
+ }
245980
+ /**
245981
+ * * at input, graph has all original faces and edges
245982
+ * * each sector points to a faceProperties with original facet normal
245983
+ * * at exit:
245984
+ * * new "chamfer faces" are added outside of edges with angle between normal sin excess of options.chamferTurnAngleBetweenNormals
245985
+ * * the original edge is split along its length to create space
245986
+ * * one edge "along" each direction inside the slit.
245987
+ * * a sling edge at each end of the slit.
245988
+ * * outside of the sling is part of the slit face loop.
245989
+ * * inside is a single-node face
245990
+ * * thus the slit itself has 4 nodes.
245991
+ * * the two nodes at each end can thus contain the two distinct points at that end of the chamfer.
245992
+ * * all 4 nodes of the slit face point to a new FacetOffsetProperties with the average normal.
245993
+ * * the inside of each sling face has
245994
+ * * original vertex coordinates in the node
245995
+ * * face properties with a normal pointing outward from that end of the original edge -- hence define a plane that can clip the chamfer
245996
+ * * the two points at each end of the chamfer are computed as the intersection of
245997
+ * * chamfer plane
245998
+ * * sling plane
245999
+ * * adjacent plane of the face on the other side of the edge being chamfered.
246000
+ * @param distance distance to offset. The sign of this is important in the chamfer construction.
246001
+ */
246002
+ addChamferTopologyToAllEdges(options, distance) {
246003
+ const edgesToChamfer = [];
246004
+ const chamferRadians = options.chamferAngleBetweenNormals.radians;
246005
+ const vertexXYZ = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create(); // reuse
246006
+ const edgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create(); // reuse
246007
+ const outwardEdgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create(); // reuse
246008
+ const averageNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create(); // reuse
246009
+ // collect all the edges with sharp turn angle.
246010
+ this._baseGraph.announceEdges((_graph, edgeNode) => {
246011
+ if (SectorOffsetProperties.edgeHasLargeExteriorAngleBetweenNormals(edgeNode, edgeVector, averageNormal, distance, chamferRadians)) {
246012
+ edgesToChamfer.push(edgeNode);
246013
+ return true;
246014
+ }
246015
+ return true;
246016
+ });
246017
+ // Create sliver faces.
246018
+ // Sliver face gets an average normal from its neighbors.
246019
+ // outsideA is the HalfEdge labeled A in the diagram.
246020
+ // sliverDX and sliverDY are the edges "inside the sliver" at the respective X and Y ends.
246021
+ for (const outsideA of edgesToChamfer) {
246022
+ // remark: this recomputes as in collection round.
246023
+ if (SectorOffsetProperties.edgeHasLargeExteriorAngleBetweenNormals(outsideA, edgeVector, averageNormal, chamferRadians)) {
246024
+ // This copies coordinates and vertex id .... sectorOffsetProperties are delayed until late in the 2-pass loop below.
246025
+ // The returned HalfEdge is labeled D in the diagram
246026
+ const sliverDX = this._baseGraph.splitEdgeCreateSliverFace(outsideA);
246027
+ const sliverDY = sliverDX.facePredecessor;
246028
+ const offsetPoint = sliverDX.getPoint3d();
246029
+ offsetPoint.addScaledInPlace(averageNormal, distance);
246030
+ const ray = _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_8__.Ray3d.createCapture(offsetPoint, averageNormal.clone());
246031
+ const facetProperties = new FacetOffsetProperties(-1, ray);
246032
+ // for each side (hence end) of the sliver face, set mask and install a sling loop for the anticipated end of the chamfer face
246033
+ // new node names in the loop omit X or Y suffix because that is implied by which pass is running.
246034
+ let s = -1.0;
246035
+ for (const sliverD of [sliverDX, sliverDY]) {
246036
+ edgeVector.scale(s, outwardEdgeVector);
246037
+ sliverD.getPoint3d(vertexXYZ);
246038
+ sliverD.setMask(this._insideOfChamferFace);
246039
+ sliverD.edgeMate.setMask(this._outsideOfChamferFace);
246040
+ // mark and reference the chamfer face.
246041
+ sliverD.faceTag = facetProperties;
246042
+ // sling at this end
246043
+ const slingB = this._baseGraph.splitEdge(undefined, vertexXYZ.x, vertexXYZ.y, vertexXYZ.z, sliverD.i);
246044
+ const slingC = slingB.edgeMate;
246045
+ slingB.setMask(this._outsideEndOfChamferFace);
246046
+ slingB.faceTag = facetProperties;
246047
+ slingC.setMask(this._insideChamferSling);
246048
+ _topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.pinch(sliverD, slingB);
246049
+ const endNormal = _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_8__.Ray3d.create(vertexXYZ, outwardEdgeVector); // clones the inputs
246050
+ const slingFaceProperties = new FacetOffsetProperties(-1, endNormal);
246051
+ slingC.faceTag = slingFaceProperties;
246052
+ // initialize sectors with existing vertex point.
246053
+ sliverD.edgeTag = new SectorOffsetProperties(averageNormal.clone(), offsetPoint.clone());
246054
+ slingB.edgeTag = new SectorOffsetProperties(averageNormal.clone(), offsetPoint.clone());
246055
+ slingC.edgeTag = new SectorOffsetProperties(outwardEdgeVector.clone(), vertexXYZ.clone());
246056
+ // OffsetMeshContext.stringDebugFunction("Chamfer Setup");
246057
+ const chamferPointE = this.compute3SectorIntersection(sliverD, sliverD.edgeMate, slingC);
246058
+ const chamferPointF = this.compute3SectorIntersection(slingB, slingB.vertexSuccessor, slingC);
246059
+ // sliverD.edgeTag = new SectorOffsetProperties(averageNormal.clone(), vertexXYZ.clone());
246060
+ SectorOffsetProperties.setXYZAtHalfEdge(sliverD, chamferPointE);
246061
+ SectorOffsetProperties.setXYZAtHalfEdge(slingB, chamferPointF);
246062
+ s *= -1.0;
246063
+ }
246064
+ }
246065
+ }
246066
+ }
246067
+ /**
246068
+ * * at input:
246069
+ * * Each node points to sectorOffsetProperties with previously computed XYZ (presumably mismatched)
246070
+ * * at exit:
246071
+ * * Each sectorOffsetProperties has an offset point computed with consideration of offset planes in the neighborhood.
246072
+ * @param distance distance to offset.
246073
+ */
246074
+ computeOffsetFacetIntersections(distance) {
246075
+ if (OffsetMeshContext.stringDebugFunction !== undefined)
246076
+ OffsetMeshContext.stringDebugFunction("***** recompute intersections");
246077
+ const breakEdges = [];
246078
+ const vertexXYZ = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
246079
+ const chamferXYZ = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
246080
+ const maxVertexMove = 2.0 * distance;
246081
+ const averageNormalData = new AverageNormalData();
246082
+ const maxAllowedNormalDeviationRadians = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_9__.Angle.degreesToRadians(25.0);
246083
+ //
246084
+ // FOR EACH VERTEX
246085
+ //
246086
+ this._baseGraph.announceVertexLoops((_graph, vertexSeedA) => {
246087
+ // reposition to an important vertex.
246088
+ // first choice: a chamfer face.
246089
+ let vertexSeed = vertexSeedA.findMaskAroundVertex(this._outsideEndOfChamferFace);
246090
+ if (vertexSeed === undefined)
246091
+ vertexSeed = vertexSeedA.findMaskAroundVertex(this._breakMaskA);
246092
+ if (vertexSeed === undefined)
246093
+ vertexSeed = vertexSeedA;
246094
+ if (OffsetMeshContext.stringDebugFunction !== undefined) {
246095
+ OffsetMeshContext.stringDebugFunction("");
246096
+ OffsetMeshContext.stringDebugFunction(` VERTEX LOOP ${vertexSeed.getPoint3d().toJSON()} `);
246097
+ vertexSeed.sumAroundVertex((node) => { OffsetMeshContext.stringDebugFunction(this.inspectMasks(node, false, true)); return 0; });
246098
+ }
246099
+ // Take care of the easiest vertices directly . . . note that this returns from the lambda, not computeOffsetFacetIntersections
246100
+ if (this.assignOffsetByAverageNormalAroundVertex(vertexSeed, maxAllowedNormalDeviationRadians, averageNormalData, distance))
246101
+ return true;
246102
+ this.markBreakEdgesAndSaveAverageNormalsAroundVertex(vertexSeed);
246103
+ this.setOffsetAtDistanceAroundVertex(vertexSeed, distance, true);
246104
+ vertexSeed.collectMaskedEdgesAroundVertex(this._breakMaskA, true, breakEdges);
246105
+ if (OffsetMeshContext.stringDebugFunction !== undefined) {
246106
+ OffsetMeshContext.stringDebugFunction(` BREAK EDGES from ${this.inspectMasks(vertexSeed, true, false)}`);
246107
+ for (const node of breakEdges) {
246108
+ OffsetMeshContext.stringDebugFunction(this.inspectMasks(node, false, true));
246109
+ }
246110
+ }
246111
+ if (breakEdges.length <= 1) {
246112
+ // just one smooth sequence.
246113
+ // everything is set already.
246114
+ }
246115
+ else if (breakEdges.length === 2) {
246116
+ // exterior vertex with two incident smooth
246117
+ const vectorFromOrigin = this.compute2SectorIntersection(breakEdges[0], breakEdges[1]);
246118
+ if (vectorFromOrigin !== undefined) {
246119
+ this.setOffsetXYAndZAroundVertex(vertexSeed, vectorFromOrigin);
246120
+ }
246121
+ }
246122
+ else if (breakEdges.length === 3) {
246123
+ if (OffsetMeshContext.stringDebugFunction !== undefined)
246124
+ OffsetMeshContext.stringDebugFunction(` Vertex Update just ${breakEdges.length} `);
246125
+ const vectorFromOrigin = this.compute3SectorIntersection(breakEdges[0], breakEdges[1], breakEdges[2]);
246126
+ if (vectorFromOrigin !== undefined) {
246127
+ this.setOffsetXYAndZAroundVertex(vertexSeed, vectorFromOrigin);
246128
+ }
246129
+ // simple 3-face corner . . .
246130
+ }
246131
+ else {
246132
+ // Lots and Lots of edges
246133
+ // each set of 3 sectors independently generates an offset for its central sector.
246134
+ if (OffsetMeshContext.stringDebugFunction !== undefined)
246135
+ OffsetMeshContext.stringDebugFunction(` Vertex Update breakEdges ${breakEdges.length} `);
246136
+ vertexSeed.getPoint3d(vertexXYZ);
246137
+ // Pass 1 -- look for intersection among multiple chamfers
246138
+ for (let i = 0; i < breakEdges.length; i++) {
246139
+ const i0 = i;
246140
+ const i1 = (i0 + 1) % breakEdges.length;
246141
+ const i2 = (i1 + 1) % breakEdges.length;
246142
+ if (breakEdges[i0].isMaskSet(this._outsideEndOfChamferFace)
246143
+ && breakEdges[i1].isMaskSet(this._outsideOfChamferFace)
246144
+ && breakEdges[i2].isMaskSet(this._insideOfChamferFace)) {
246145
+ if (OffsetMeshContext.stringDebugFunction !== undefined)
246146
+ OffsetMeshContext.stringDebugFunction(` ChamferChamfer Fixup ${this.inspectMasks(breakEdges[i0])} ${this.inspectMasks(breakEdges[i1])} ${this.inspectMasks(breakEdges[i2])} `);
246147
+ const vectorFromOrigin = this.compute3SectorIntersection(breakEdges[i0], breakEdges[i1], breakEdges[i2]);
246148
+ if (vectorFromOrigin !== undefined) {
246149
+ // Treat all 3 spots as possibly compound sequences
246150
+ for (const iOutput of [i0, i1, i2]) {
246151
+ this.announceNodeAndSectorPropertiesInSmoothSector(breakEdges[iOutput], (node, properties) => {
246152
+ properties.setXYAndZ(vectorFromOrigin);
246153
+ node.setMask(this._offsetCoordinatesReassigned);
246154
+ });
246155
+ }
246156
+ // Since all three were reset, skip past. This is done on the acyclic integer that controls the loop.
246157
+ i += 2;
246158
+ }
246159
+ }
246160
+ }
246161
+ // Pass 2 -- look for unassigned nodes just before or after a chamfer.
246162
+ // The chamfer wins
246163
+ for (let i = 0; i < breakEdges.length; i++) {
246164
+ const i0 = i;
246165
+ const i1 = (i0 + 1) % breakEdges.length;
246166
+ if (this.isInsideSling(breakEdges[i0], breakEdges[i1]))
246167
+ continue;
246168
+ if (!this.isOffsetAssigned(breakEdges[i0])
246169
+ && breakEdges[i1].isMaskSet(this.insideOfChamferFace)) {
246170
+ this.transferXYZFromNodeToSmoothSector(breakEdges[i1], breakEdges[i0], "push left from chamfer", chamferXYZ);
246171
+ }
246172
+ else if (!this.isOffsetAssigned(breakEdges[i1])
246173
+ && breakEdges[i0].isMaskSet(this.outsideEndOfChamferFace)) {
246174
+ this.transferXYZFromNodeToSmoothSector(breakEdges[i0], breakEdges[i1], "push right from chamfer", chamferXYZ);
246175
+ }
246176
+ }
246177
+ // Pass 3 -- look for unassigned nodes as middle of 3-face intersections
246178
+ for (let i = 0; i < breakEdges.length; i++) {
246179
+ const i0 = i;
246180
+ const i1 = (i0 + 1) % breakEdges.length;
246181
+ const i2 = (i1 + 1) % breakEdges.length;
246182
+ if (this.isInsideSling(breakEdges[i0], breakEdges[i1], breakEdges[i2]))
246183
+ continue;
246184
+ if (this.isOffsetAssigned(breakEdges[i1]))
246185
+ continue;
246186
+ if (OffsetMeshContext.stringDebugFunction !== undefined)
246187
+ OffsetMeshContext.stringDebugFunction(` Intersection Fixup ${this.inspectMasks(breakEdges[i0])} ${this.inspectMasks(breakEdges[i1])} ${this.inspectMasks(breakEdges[i2])} `);
246188
+ const vectorFromOrigin = this.compute3SectorIntersection(breakEdges[i0], breakEdges[i1], breakEdges[i2]);
246189
+ if (vectorFromOrigin !== undefined) {
246190
+ if (vertexXYZ.distance(vectorFromOrigin) < maxVertexMove) {
246191
+ this.announceNodeAndSectorPropertiesInSmoothSector(breakEdges[i1], (node, properties) => {
246192
+ properties.setXYAndZ(vectorFromOrigin);
246193
+ node.setMask(this._offsetCoordinatesReassigned);
246194
+ });
246195
+ }
246196
+ }
246197
+ }
246198
+ }
246199
+ if (OffsetMeshContext.stringDebugFunction !== undefined) {
246200
+ const n0 = vertexSeed.countMaskAroundVertex(this._offsetCoordinatesReassigned, false);
246201
+ const n1 = vertexSeed.countMaskAroundVertex(this._offsetCoordinatesReassigned, true);
246202
+ const message = ` **** Vertex offset mask counts(TRUE ${n1})(FALSE ${n0})`;
246203
+ OffsetMeshContext.stringDebugFunction(message);
246204
+ }
246205
+ return true;
246206
+ });
246207
+ }
246208
+ // return true if any of these nodes is "inside" the sling at the end of a chamfer.
246209
+ isInsideSling(node0, node1, node2) {
246210
+ return node0.isMaskSet(this._insideChamferSling)
246211
+ || (node1 !== undefined && node1.isMaskSet(this._insideChamferSling))
246212
+ || (node2 !== undefined && node2.isMaskSet(this._insideChamferSling));
246213
+ }
246214
+ // return true if any of these nodes is "inside" the sling at the end of a chamfer.
246215
+ isInsideChamferOrSling(node0) {
246216
+ return node0.isMaskSet(this._insideChamferSling)
246217
+ || node0.isMaskSet(this._insideOfChamferFace)
246218
+ || node0.isMaskSet(this._outsideEndOfChamferFace);
246219
+ }
246220
+ isOffsetAssigned(node0, node1, node2) {
246221
+ return node0.isMaskSet(this._offsetCoordinatesReassigned)
246222
+ || (node1 !== undefined && node1.isMaskSet(this._offsetCoordinatesReassigned))
246223
+ || (node2 !== undefined && node2.isMaskSet(this._offsetCoordinatesReassigned));
246224
+ }
246225
+ /**
246226
+ *
246227
+ * @param sourceNode node with good xyz
246228
+ * @param destinationStartNode first of a sequence of nodes to set (delimited by masks)
246229
+ * @param description string for debug
246230
+ * @param workPoint point to use for coordinate transfer.
246231
+ */
246232
+ transferXYZFromNodeToSmoothSector(sourceNode, destinationStartNode, description, workPoint) {
246233
+ if (OffsetMeshContext.stringDebugFunction !== undefined)
246234
+ OffsetMeshContext.stringDebugFunction(` ${description} ${this.inspectMasks(sourceNode)} to ${this.inspectMasks(destinationStartNode)}} `);
246235
+ SectorOffsetProperties.getSectorPointAtHalfEdge(sourceNode, workPoint, undefined);
246236
+ this.announceNodeAndSectorPropertiesInSmoothSector(destinationStartNode, (node, properties) => {
246237
+ properties.setXYAndZ(workPoint);
246238
+ node.setMask(this._offsetCoordinatesReassigned);
246239
+ });
246240
+ }
246241
+ }
246242
+
246243
+
245019
246244
  /***/ }),
245020
246245
 
245021
246246
  /***/ "../../core/geometry/lib/esm/polyface/multiclip/RangeSearch.js":
@@ -254224,16 +255449,16 @@ class Sample {
254224
255449
  _curve_Arc3d__WEBPACK_IMPORTED_MODULE_20__.Arc3d.createXY(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(5, 0), 5, _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_0__.AngleSweep.createStartEndDegrees(180, 0)), _curve_Arc3d__WEBPACK_IMPORTED_MODULE_20__.Arc3d.createXY(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(15, 0), 5, _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_0__.AngleSweep.createStartEndDegrees(180, 360)), _curve_Arc3d__WEBPACK_IMPORTED_MODULE_20__.Arc3d.createXY(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(25, 0), 5, _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_0__.AngleSweep.createStartEndDegrees(180, 0)))));
254225
255450
  result.push(_curve_CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_44__.CurveChainWithDistanceIndex.createCapture(_curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(// 2-pt Interpolation Curve
254226
255451
  _bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3d.createCapture(_bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3dOptions.create({
254227
- fitPoints: [pointsA[0], pointsA[1]]
255452
+ fitPoints: [pointsA[0], pointsA[1]],
254228
255453
  })))));
254229
255454
  result.push(_curve_CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_44__.CurveChainWithDistanceIndex.createCapture(_curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(// 3-pt Interpolation Curve
254230
255455
  _bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3d.createCapture(_bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3dOptions.create({
254231
- fitPoints: [pointsA[0], pointsA[1], pointsA[2]]
255456
+ fitPoints: [pointsA[0], pointsA[1], pointsA[2]],
254232
255457
  })))));
254233
255458
  result.push(_curve_CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_44__.CurveChainWithDistanceIndex.createCapture(_curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(_bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3d.createCapture(_bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3dOptions.create({
254234
255459
  fitPoints: pointsA,
254235
255460
  startTangent: _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(1, -1),
254236
- endTangent: _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(-1, -1)
255461
+ endTangent: _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(-1, -1),
254237
255462
  })))));
254238
255463
  result.push(_curve_CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_44__.CurveChainWithDistanceIndex.createCapture(_curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(_curve_spiral_IntegratedSpiral3d__WEBPACK_IMPORTED_MODULE_39__.IntegratedSpiral3d.createRadiusRadiusBearingBearing(_geometry3d_Segment1d__WEBPACK_IMPORTED_MODULE_40__.Segment1d.create(0, 100), _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_0__.AngleSweep.createStartEndDegrees(10, 75), _geometry3d_Segment1d__WEBPACK_IMPORTED_MODULE_40__.Segment1d.create(0, 1), _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_16__.Transform.createOriginAndMatrix(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.createZero(), _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_12__.Matrix3d.createRotationAroundAxisIndex(2, _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__.Angle.createDegrees(30))), "bloss"))));
254239
255464
  result.push(_curve_CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_44__.CurveChainWithDistanceIndex.createCapture(_curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(_curve_spiral_DirectSpiral3d__WEBPACK_IMPORTED_MODULE_41__.DirectSpiral3d.createDirectHalfCosine(_geometry3d_Transform__WEBPACK_IMPORTED_MODULE_16__.Transform.createOriginAndMatrix(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.createZero(), _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_12__.Matrix3d.createRotationAroundAxisIndex(2, _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__.Angle.createDegrees(110))), 50, 350, _geometry3d_Segment1d__WEBPACK_IMPORTED_MODULE_40__.Segment1d.create(0, 1)))));
@@ -254347,8 +255572,11 @@ class Sample {
254347
255572
  /** Create swept "solids" that can be capped.
254348
255573
  * * At least one of each solid type.
254349
255574
  * * each is within 10 of the origin all directions.
255575
+ * @param capped true to include caps
255576
+ * @param rotationAngle angle of rotation for the angular sweep. The default is 90 degrees.
255577
+ * Beware that the rotation sweep created with the default or any positive angle produces a mesh with inward normals.
254350
255578
  */
254351
- static createClosedSolidSampler(capped) {
255579
+ static createClosedSolidSampler(capped, rotationAngle = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__.Angle.createDegrees(90)) {
254352
255580
  const result = [];
254353
255581
  result.push(_solid_Box__WEBPACK_IMPORTED_MODULE_35__.Box.createRange(_geometry3d_Range__WEBPACK_IMPORTED_MODULE_4__.Range3d.createXYZXYZ(0, 0, 0, 3, 2, 5), capped));
254354
255582
  result.push(_solid_Cone__WEBPACK_IMPORTED_MODULE_33__.Cone.createAxisPoints(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(0, 0, 0), _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(0, 0, 5), 1.0, 1.0, capped));
@@ -254360,18 +255588,23 @@ class Sample {
254360
255588
  const pointQ2 = arcA.fractionAndDistanceToPointOnTangent(1.0, 0.5);
254361
255589
  const pointR1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(point0.x, pointQ1.y);
254362
255590
  const pointR2 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(point0.x, pointQ1.y);
255591
+ const pointR3 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(pointQ1.x - 1, pointQ1.y);
255592
+ const pointR4 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(pointQ1.x - 3, pointQ1.y);
254363
255593
  const linestringQ1 = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_15__.LineString3d.create(arcA.fractionToPoint(1.0), pointQ1, pointR1, point0);
254364
255594
  const linestringQ2 = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_15__.LineString3d.create(arcA.fractionToPoint(1.0), pointQ2, pointR2, point0);
255595
+ const linestringQ3 = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_15__.LineString3d.create(arcA.fractionToPoint(1.0), pointQ2, pointR3, pointR4, point0);
254365
255596
  const contourZ = _curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(linestringQ1.clone());
254366
255597
  const contourA = _curve_Loop__WEBPACK_IMPORTED_MODULE_23__.Loop.create(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_19__.LineSegment3d.create(point0, arcA.fractionToPoint(0)), arcA.clone(), linestringQ1.clone());
254367
255598
  const contourB = _curve_Loop__WEBPACK_IMPORTED_MODULE_23__.Loop.create(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_19__.LineSegment3d.create(point0, arcA.fractionToPoint(0)), arcA.clone(), linestringQ2.clone());
255599
+ const contourC1 = _curve_Loop__WEBPACK_IMPORTED_MODULE_23__.Loop.create(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_19__.LineSegment3d.create(point0, arcA.fractionToPoint(0)), arcA.clone(), linestringQ3.clone());
254368
255600
  contourB.tryTransformInPlace(_geometry3d_Transform__WEBPACK_IMPORTED_MODULE_16__.Transform.createTranslationXYZ(1, 1, 3));
254369
255601
  // const contourC = contourB.cloneTransformed(Transform.createTranslationXYZ(2, 1, 4))!;
254370
255602
  result.push(_solid_LinearSweep__WEBPACK_IMPORTED_MODULE_30__.LinearSweep.create(contourA, _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(0, 0, 5), capped));
255603
+ result.push(_solid_LinearSweep__WEBPACK_IMPORTED_MODULE_30__.LinearSweep.create(contourC1, _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(0, 0, 5), capped));
254371
255604
  const axis = _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_14__.Ray3d.createXYZUVW(0, 8, 0, 1, 0, 0);
254372
- result.push(_solid_RotationalSweep__WEBPACK_IMPORTED_MODULE_31__.RotationalSweep.create(contourA.clone(), axis.clone(), _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__.Angle.createDegrees(90), capped));
255605
+ result.push(_solid_RotationalSweep__WEBPACK_IMPORTED_MODULE_31__.RotationalSweep.create(contourA.clone(), axis.clone(), rotationAngle, capped));
254373
255606
  if (!capped)
254374
- result.push(_solid_RotationalSweep__WEBPACK_IMPORTED_MODULE_31__.RotationalSweep.create(contourZ.clone(), axis.clone(), _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__.Angle.createDegrees(90), false));
255607
+ result.push(_solid_RotationalSweep__WEBPACK_IMPORTED_MODULE_31__.RotationalSweep.create(contourZ.clone(), axis.clone(), rotationAngle, false));
254375
255608
  result.push(_solid_RuledSweep__WEBPACK_IMPORTED_MODULE_36__.RuledSweep.create([contourA.clone(), contourB.clone()], capped));
254376
255609
  const transformC = _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_16__.Transform.createScaleAboutPoint(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(0, 0, 8), 0.5);
254377
255610
  const contourC = contourB.cloneTransformed(transformC);
@@ -258796,12 +260029,13 @@ __webpack_require__.r(__webpack_exports__);
258796
260029
  /* harmony export */ "HalfEdgeGraph": () => (/* binding */ HalfEdgeGraph),
258797
260030
  /* harmony export */ "HalfEdgeMask": () => (/* binding */ HalfEdgeMask)
258798
260031
  /* harmony export */ });
258799
- /* harmony import */ var _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../curve/LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
260032
+ /* harmony import */ var _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../curve/LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
258800
260033
  /* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
260034
+ /* harmony import */ var _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../geometry3d/Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
258801
260035
  /* harmony import */ var _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../geometry3d/Point2dVector2d */ "../../core/geometry/lib/esm/geometry3d/Point2dVector2d.js");
258802
260036
  /* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
258803
- /* harmony import */ var _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../numerics/Polynomials */ "../../core/geometry/lib/esm/numerics/Polynomials.js");
258804
- /* harmony import */ var _MaskManager__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./MaskManager */ "../../core/geometry/lib/esm/topology/MaskManager.js");
260037
+ /* harmony import */ var _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../numerics/Polynomials */ "../../core/geometry/lib/esm/numerics/Polynomials.js");
260038
+ /* harmony import */ var _MaskManager__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./MaskManager */ "../../core/geometry/lib/esm/topology/MaskManager.js");
258805
260039
  /*---------------------------------------------------------------------------------------------
258806
260040
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
258807
260041
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -258815,6 +260049,7 @@ __webpack_require__.r(__webpack_exports__);
258815
260049
 
258816
260050
 
258817
260051
 
260052
+
258818
260053
  // import { GraphChecker } from "../test/topology/Graph.test";
258819
260054
  /* eslint-disable @typescript-eslint/no-this-alias */
258820
260055
  // cspell:word CONSTU
@@ -258902,6 +260137,7 @@ class HalfEdge {
258902
260137
  this.sortAngle = undefined;
258903
260138
  this.sortData = undefined;
258904
260139
  this.edgeTag = undefined;
260140
+ this.faceTag = undefined;
258905
260141
  // Always created in pairs, init here to make TS compiler and JS runtime happy
258906
260142
  this._facePredecessor = this;
258907
260143
  this._faceSuccessor = this;
@@ -259022,6 +260258,36 @@ class HalfEdge {
259022
260258
  }
259023
260259
  return newA;
259024
260260
  }
260261
+ /**
260262
+ * * Create a new sliver face "inside" an existing edge.
260263
+ * * Insert it "within" the base edge.
260264
+ * * This requires two new half edges.
260265
+ * * if the base is undefined, create a single-edge loop.
260266
+ * * This (unlike pinch) breaks the edgeMate pairing of the base edge.
260267
+ * * This preserves xyz and i properties at all existing vertices.
260268
+ * * The two new half edges are a sliver face (via their predecessor and successor)
260269
+ * * Each new edge mates to one existing edge.
260270
+ * @returns Returns the reference to the half edge created.
260271
+ */
260272
+ static splitEdgeCreateSliverFace(baseA, heArray) {
260273
+ // raw edges ...
260274
+ const newA = new HalfEdge();
260275
+ const newB = new HalfEdge();
260276
+ const baseB = baseA.edgeMate;
260277
+ if (heArray) {
260278
+ heArray.push(newA);
260279
+ heArray.push(newB);
260280
+ }
260281
+ newA._faceSuccessor = newA._facePredecessor = newB;
260282
+ newB._faceSuccessor = newB._facePredecessor = newA;
260283
+ // newA is in vertex loop with baseA etc.
260284
+ // newA mates to baseB
260285
+ HalfEdge.setEdgeMates(newA, baseB);
260286
+ HalfEdge.setEdgeMates(newB, baseA);
260287
+ newA.copyDataFrom(baseA, true, true, false, false);
260288
+ newB.copyDataFrom(baseB, true, true, false, false);
260289
+ return newA;
260290
+ }
259025
260291
  /**
259026
260292
  * Copy "edge based" content of fromNode to toNode
259027
260293
  * * edgeTag
@@ -259232,6 +260498,35 @@ class HalfEdge {
259232
260498
  }
259233
260499
  return count;
259234
260500
  }
260501
+ /** Returns the first node with given mask value around this vertex loop. */
260502
+ findMaskAroundVertex(mask, value = true) {
260503
+ let node = this;
260504
+ do {
260505
+ if (node.isMaskSet(mask) === value)
260506
+ return node;
260507
+ node = node.vertexSuccessor;
260508
+ } while (node !== this);
260509
+ return undefined;
260510
+ }
260511
+ /** Returns the first node with given mask value around this face loop. */
260512
+ findMaskAroundFace(mask, value = true) {
260513
+ let node = this;
260514
+ do {
260515
+ if (node.isMaskSet(mask) === value)
260516
+ return node;
260517
+ node = node.faceSuccessor;
260518
+ } while (node !== this);
260519
+ return undefined;
260520
+ }
260521
+ /** Returns the first node with given mask value on this edge (i.e. examining this and this.mate) */
260522
+ findMaskAroundEdge(mask, value = true) {
260523
+ if (this.isMaskSet(mask) === value)
260524
+ return this;
260525
+ const mate = this.edgeMate;
260526
+ if (mate.isMaskSet(mask) === value)
260527
+ return mate;
260528
+ return undefined;
260529
+ }
259235
260530
  /** Set a mask, and return prior value.
259236
260531
  * @param mask mask to apply
259237
260532
  */
@@ -259249,6 +260544,15 @@ class HalfEdge {
259249
260544
  this.y = node.y;
259250
260545
  this.z = node.z;
259251
260546
  }
260547
+ /**
260548
+ * Set (copy) the this.x, this.y, this.z from xyz.x, xyz.y, xyz.z
260549
+ * @param node source with x,y,z properties
260550
+ */
260551
+ setXYZ(xyz) {
260552
+ this.x = xyz.x;
260553
+ this.y = xyz.y;
260554
+ this.z = xyz.z;
260555
+ }
259252
260556
  /**
259253
260557
  * Test if mask bits are set in the node's bitMask.
259254
260558
  * @return Return true (as a simple boolean, not a mask) if any bits of the mask parameter match bits of the node's bitMask
@@ -259338,6 +260642,10 @@ class HalfEdge {
259338
260642
  const s = `${node.id.toString()}+${HalfEdge.nodeToMaskString(node)}[${node.x},${node.y}]`;
259339
260643
  return s;
259340
260644
  }
260645
+ /** Return the [id, [x,y],z] of a node. Useful for collector methods. */
260646
+ static nodeToIdXYZString(node) {
260647
+ return `[${node.id.toString()}: ${node.x},${node.y},${node.z}]`;
260648
+ }
259341
260649
  /** Create a string representation of the mask
259342
260650
  * * Null mask is empty string.
259343
260651
  * * Appended characters B,P,X for Boundary, Primary, Exterior mask bits.
@@ -259362,7 +260670,13 @@ class HalfEdge {
259362
260670
  }
259363
260671
  /** Return Vector3d to face successor */
259364
260672
  vectorToFaceSuccessor(result) {
259365
- return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(this.faceSuccessor.x - this.x, this.faceSuccessor.y - this.y, this.faceSuccessor.z - this.z, result);
260673
+ const other = this.faceSuccessor;
260674
+ return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(other.x - this.x, other.y - this.y, other.z - this.z, result);
260675
+ }
260676
+ /** Return Vector3d to face successor */
260677
+ vectorToFacePredecessor(result) {
260678
+ const other = this.facePredecessor;
260679
+ return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(other.x - this.x, other.y - this.y, other.z - this.z, result);
259366
260680
  }
259367
260681
  /** test if spaceNode is in the sector at sectorNode */
259368
260682
  static isNodeVisibleInSector(spaceNode, sectorNode) {
@@ -259486,6 +260800,14 @@ class HalfEdge {
259486
260800
  static testNodeMaskNotExterior(node) { return !node.isMaskSet(HalfEdgeMask.EXTERIOR); }
259487
260801
  /** Returns Returns true if the node does NOT have Mask.EXTERIOR_MASK set. */
259488
260802
  static testMateMaskExterior(node) { return node.edgeMate.isMaskSet(HalfEdgeMask.EXTERIOR); }
260803
+ /** Returns radians between this edge and its face predecessor edge, using all three coordinates x,y,z and given normal to resolve sweep direction.
260804
+ * * The returned angle is positive, i.e. may be larger than PI radians.
260805
+ */
260806
+ static sectorSweepRadiansXYZ(node, normal) {
260807
+ const nodeB = node.faceSuccessor;
260808
+ const nodeC = node.facePredecessor;
260809
+ return _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__.Angle.orientedRadiansBetweenVectorsXYZ(nodeB.x - node.x, nodeB.y - node.y, nodeB.z - node.z, nodeC.x - node.x, nodeC.y - node.y, nodeC.z - node.z, normal.x, normal.y, normal.z, true);
260810
+ }
259489
260811
  /** Returns Returns true if the face has positive area in xy parts. */
259490
260812
  static testFacePositiveAreaXY(node) {
259491
260813
  return node.countEdgesAroundFace() > 2 && node.signedFaceArea() > 0.0;
@@ -259517,6 +260839,26 @@ class HalfEdge {
259517
260839
  } while (node !== this);
259518
260840
  return nodes;
259519
260841
  }
260842
+ /**
260843
+ * search around a vertex for nodes that have a specified mask setting.
260844
+ * @param vertexSeed first node to search
260845
+ * @param mask target mask
260846
+ * @param value target value for mask on half edges.
260847
+ * @param collectedNodes optional array to be cleared and receive masked nodes
260848
+ */
260849
+ collectMaskedEdgesAroundVertex(mask, value = true, result) {
260850
+ if (result === undefined)
260851
+ result = [];
260852
+ else
260853
+ result.length = 0;
260854
+ let node = this;
260855
+ do {
260856
+ if (node.isMaskSet(mask) === value)
260857
+ result.push(node);
260858
+ node = node.vertexSuccessor;
260859
+ } while (node !== this);
260860
+ return result;
260861
+ }
259520
260862
  /**
259521
260863
  *
259522
260864
  * * Evaluate f(node) at each outbound node around this node's vertex loop.
@@ -259700,7 +261042,7 @@ class HalfEdge {
259700
261042
  const nodeB1 = nodeB0.faceSuccessor;
259701
261043
  if (!result)
259702
261044
  result = _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_0__.Vector2d.create();
259703
- if (_numerics_Polynomials__WEBPACK_IMPORTED_MODULE_3__.SmallSystem.linearSystem2d(nodeA1.x - nodeA0.x, nodeB0.x - nodeB1.x, nodeA1.y - nodeA0.y, nodeB0.y - nodeB1.y, nodeB0.x - nodeA0.x, nodeB0.y - nodeA0.y, result))
261045
+ if (_numerics_Polynomials__WEBPACK_IMPORTED_MODULE_4__.SmallSystem.linearSystem2d(nodeA1.x - nodeA0.x, nodeB0.x - nodeB1.x, nodeA1.y - nodeA0.y, nodeB0.y - nodeB1.y, nodeB0.x - nodeA0.x, nodeB0.y - nodeA0.y, result))
259704
261046
  return result;
259705
261047
  return undefined;
259706
261048
  }
@@ -259709,8 +261051,7 @@ class HalfEdge {
259709
261051
  * * If the edge is horizontal with (approximate) identical y, return the node.
259710
261052
  * * If the edge is horizontal with different y, return undefined.
259711
261053
  * * If the edge is not horizontal, return the fractional position (possibly outside 0..1) of the intersection.
259712
- * @param nodeA Base node of edge
259713
- * @param result optional preallocated result
261054
+ * @param node0 Base node of edge
259714
261055
  */
259715
261056
  static horizontalScanFraction(node0, y) {
259716
261057
  const node1 = node0.faceSuccessor;
@@ -259725,8 +261066,7 @@ class HalfEdge {
259725
261066
  * * Compute fractional coordinates of the intersection of a horizontal line with an edge.
259726
261067
  * * If the edge is horizontal return undefined (no test for horizontal at y!!!)
259727
261068
  * * If the edge is not horizontal and y is between its end y's, return the fraction
259728
- * @param nodeA Base node of edge
259729
- * @param result optional preallocated result
261069
+ * @param node0 Base node of edge
259730
261070
  */
259731
261071
  static horizontalScanFraction01(node0, y) {
259732
261072
  const node1 = node0.faceSuccessor;
@@ -259740,6 +261080,31 @@ class HalfEdge {
259740
261080
  return fraction;
259741
261081
  return undefined;
259742
261082
  }
261083
+ /**
261084
+ * Copy various data from source to this.
261085
+ * @param source other half edge.
261086
+ * @param XYZ copy simple coordinates
261087
+ * @param copyVertexData true to copy data belonging to the vertex. (i.e. the "i" member)
261088
+ * @param copyVertexData true to copy data belonging to the edge. (i.e. call transferEdgeData)
261089
+ * @param copyFaceData true to copy faceTag
261090
+ */
261091
+ copyDataFrom(source, copyXYZ, copyVertexData, copyEdgeData, copyFaceData) {
261092
+ if (copyXYZ) {
261093
+ this.x = source.x;
261094
+ this.y = source.y;
261095
+ this.z = source.z;
261096
+ }
261097
+ if (copyVertexData) {
261098
+ this.i = source.i;
261099
+ }
261100
+ if (copyEdgeData) {
261101
+ HalfEdge.transferEdgeProperties(source, this);
261102
+ this.edgeTag = source.edgeTag;
261103
+ }
261104
+ if (copyFaceData) {
261105
+ this.faceTag = source.faceTag;
261106
+ }
261107
+ }
259743
261108
  }
259744
261109
  HalfEdge._edgePropertyMasks = [HalfEdgeMask.BOUNDARY_EDGE, HalfEdgeMask.EXTERIOR, HalfEdgeMask.PRIMARY_EDGE, HalfEdgeMask.NULL_FACE];
259745
261110
  HalfEdge._totalNodesCreated = 0;
@@ -259753,7 +261118,7 @@ class HalfEdgeGraph {
259753
261118
  constructor() {
259754
261119
  this._numNodesCreated = 0;
259755
261120
  this.allHalfEdges = [];
259756
- this._maskManager = _MaskManager__WEBPACK_IMPORTED_MODULE_4__.MaskManager.create(HalfEdgeMask.ALL_GRAB_DROP_MASKS);
261121
+ this._maskManager = _MaskManager__WEBPACK_IMPORTED_MODULE_5__.MaskManager.create(HalfEdgeMask.ALL_GRAB_DROP_MASKS);
259757
261122
  }
259758
261123
  /** Ask for a mask (from the graph's free pool.) for caller's use.
259759
261124
  * * Optionally clear the mask throughout the graph.
@@ -259780,6 +261145,19 @@ class HalfEdgeGraph {
259780
261145
  const a = HalfEdge.createHalfEdgePairWithCoordinates(xA, yA, zA, iA, xB, yB, zB, iB, this.allHalfEdges);
259781
261146
  return a;
259782
261147
  }
261148
+ /**
261149
+ * * Create 2 half edges forming 2 vertices, 1 edge, and 1 face
261150
+ * * The two edges are joined as edgeMate pair.
261151
+ * * The two edges are a 2-half-edge face loop in both the faceSuccessor and facePredecessor directions.
261152
+ * * The two edges are added to the graph's HalfEdge set
261153
+ * * Coordinates are set to zero.
261154
+ * * ids are installed in the two half edges.
261155
+ * @returns Return pointer to the first half edge created. (This has idA as its id.)
261156
+ */
261157
+ createEdgeIdId(iA = 0, iB = 0) {
261158
+ const a = HalfEdge.createHalfEdgePairWithCoordinates(0.0, 0.0, 0.0, iA, 0.0, 0.0, 0.0, iB, this.allHalfEdges);
261159
+ return a;
261160
+ }
259783
261161
  /**
259784
261162
  * * create an edge from coordinates x,y,z to (the tail of) an existing half edge.
259785
261163
  * @returns Return pointer to the half edge with tail at x,y,z
@@ -259824,6 +261202,20 @@ class HalfEdgeGraph {
259824
261202
  const he = HalfEdge.splitEdge(base, xA, yA, zA, iA, this.allHalfEdges);
259825
261203
  return he;
259826
261204
  }
261205
+ /**
261206
+ * * Create a sliver face "within" an edge.
261207
+ * * this creates two half edges.
261208
+ * * The existing edges both stay in their same face loops and retain coordinates and i value.
261209
+ * * Each existing edge's mate is a new edge (rather than original mate)
261210
+ * * Coordinates are copied to the new edges at respective vertices.
261211
+ * * New faceTag and edgeTag undefined.
261212
+ * * i members are copied around their respective vertices.
261213
+ * @returns Returns the reference to the half edge created.
261214
+ */
261215
+ splitEdgeCreateSliverFace(base) {
261216
+ const he = HalfEdge.splitEdgeCreateSliverFace(base, this.allHalfEdges);
261217
+ return he;
261218
+ }
259827
261219
  /**
259828
261220
  * * Insert a vertex in the edge beginning at base, with coordinates specified as a fraction along the existing edge.
259829
261221
  * * this creates two half edges.
@@ -259892,7 +261284,7 @@ class HalfEdgeGraph {
259892
261284
  const segments = [];
259893
261285
  for (const node of this.allHalfEdges) {
259894
261286
  if (node.id < node.edgeMate.id)
259895
- segments.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_5__.LineSegment3d.create(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(node.x, node.y), _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(node.faceSuccessor.x, node.faceSuccessor.y)));
261287
+ segments.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_6__.LineSegment3d.create(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(node.x, node.y), _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(node.faceSuccessor.x, node.faceSuccessor.y)));
259896
261288
  }
259897
261289
  return segments;
259898
261290
  }
@@ -259961,6 +261353,26 @@ class HalfEdgeGraph {
259961
261353
  break;
259962
261354
  }
259963
261355
  }
261356
+ /**
261357
+ * * Visit each edge of the graph once.
261358
+ * * Call the announceEdge function.
261359
+ * * the edge mate will NOT appear in an announceEdge call.
261360
+ * * continue search if announceEdge(graph, node) returns true
261361
+ * * terminate search if announceEdge (graph, node) returns false
261362
+ * @param announceEdge function to apply at one node of each edge.
261363
+ */
261364
+ announceEdges(announceEdge) {
261365
+ this.clearMask(HalfEdgeMask.VISITED);
261366
+ for (const node of this.allHalfEdges) {
261367
+ if (node.getMask(HalfEdgeMask.VISITED))
261368
+ continue;
261369
+ const mate = node.edgeMate;
261370
+ node.setMask(HalfEdgeMask.VISITED);
261371
+ mate.setMask(HalfEdgeMask.VISITED);
261372
+ if (!announceEdge(this, node))
261373
+ break;
261374
+ }
261375
+ }
259964
261376
  /**
259965
261377
  * * Visit each vertex loop of the graph once.
259966
261378
  * * Call the announceVertex function
@@ -259979,8 +261391,8 @@ class HalfEdgeGraph {
259979
261391
  }
259980
261392
  }
259981
261393
  /**
259982
- * * Visit each vertex loop of the graph once.
259983
- * * Call the announceVertex function
261394
+ * * Visit each half edge (node) of the graph once.
261395
+ * * Call the announceNode function
259984
261396
  * * continue search if announceNode(graph, node) returns true
259985
261397
  * * terminate search if announce face (graph, node) returns false
259986
261398
  * @param announceNode function to apply at one node of each face.
@@ -260039,6 +261451,99 @@ class HalfEdgeGraph {
260039
261451
  }
260040
261452
 
260041
261453
 
261454
+ /***/ }),
261455
+
261456
+ /***/ "../../core/geometry/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js":
261457
+ /*!************************************************************************************!*\
261458
+ !*** ../../core/geometry/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js ***!
261459
+ \************************************************************************************/
261460
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
261461
+
261462
+ "use strict";
261463
+ __webpack_require__.r(__webpack_exports__);
261464
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
261465
+ /* harmony export */ "HalfEdgeGraphFromIndexedLoopsContext": () => (/* binding */ HalfEdgeGraphFromIndexedLoopsContext)
261466
+ /* harmony export */ });
261467
+ /* harmony import */ var _Graph__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
261468
+ /*---------------------------------------------------------------------------------------------
261469
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
261470
+ * See LICENSE.md in the project root for license terms and full copyright notice.
261471
+ *--------------------------------------------------------------------------------------------*/
261472
+
261473
+ /** @packageDocumentation
261474
+ * @module Topology
261475
+ */
261476
+ /**
261477
+ * Context for building a half edge graph from loops defined only by indices.
261478
+ * * Direct use case:
261479
+ * * Create the context.
261480
+ * * Repeatedly call insertLoop(indicesAroundLoop) to announce various loops.
261481
+ * * Finish by accessing the graph property.
261482
+ * @internal
261483
+ */
261484
+ class HalfEdgeGraphFromIndexedLoopsContext {
261485
+ constructor() {
261486
+ this._unmatchedEdges = new Map();
261487
+ this._graph = new _Graph__WEBPACK_IMPORTED_MODULE_0__.HalfEdgeGraph();
261488
+ this._halfEdgesAroundCurrentLoop = [];
261489
+ }
261490
+ get graph() { return this._graph; }
261491
+ indexPairToString(index0, index1) {
261492
+ return `${index0.toString()},${index1.toString()}`;
261493
+ }
261494
+ /** Create a loop with specified indices at its vertices.
261495
+ * * For an edge with index pair [indexA, indexB]:
261496
+ * * if [indexB, indexA] has never appeared, a HalfEdge mated pair is created.
261497
+ * * One of that mated pair becomes a HalfEdge in this loop.
261498
+ * * The other is "unmatched"
261499
+ * * When announceMatedHalfEdges(halfEdge) is called:
261500
+ * * halfEdge and its mate are "new"
261501
+ * * all coordinates are zeros.
261502
+ * * each contains (as its halfEdge.id property) one index of the [indexA,indexB] pair.
261503
+ * * those coordinates and indices will never be referenced again by this construction sequence -- the caller is free to mutate them as needed.
261504
+ * * if [indexB, indexA] appeared previously (and its outer HalfEdge was left "unmatched"),
261505
+ * the "unmatched" HalfEdge is used in the loop being constructed.
261506
+ * @param indices Array of indices around the edge. This is accessed cyclically.
261507
+ * @param announceMatedHalfEdges optional function to be called as mated pairs are created. At the call,
261508
+ * the given HalfEdge and its mate will have a pair of successive indices from the array.
261509
+ */
261510
+ insertLoop(indices, announceMatedHalfEdges) {
261511
+ const n = indices.length;
261512
+ if (n > 1) {
261513
+ let index0 = indices[indices.length - 1];
261514
+ this._halfEdgesAroundCurrentLoop.length = 0;
261515
+ for (const index1 of indices) {
261516
+ const insideString = this.indexPairToString(index0, index1);
261517
+ const halfEdgePreviouslyConstructedFromOppositeSide = this._unmatchedEdges.get(insideString);
261518
+ if (halfEdgePreviouslyConstructedFromOppositeSide === undefined) {
261519
+ // This is the first appearance of this edge in either direction.
261520
+ const outsideString = this.indexPairToString(index1, index0); // string referencing the "other" side of the new edge.
261521
+ const newHalfEdgeAroundLoop = this._graph.createEdgeIdId(index0, index1);
261522
+ if (announceMatedHalfEdges !== undefined)
261523
+ announceMatedHalfEdges(newHalfEdgeAroundLoop);
261524
+ this._unmatchedEdges.set(outsideString, newHalfEdgeAroundLoop.edgeMate);
261525
+ this._halfEdgesAroundCurrentLoop.push(newHalfEdgeAroundLoop);
261526
+ newHalfEdgeAroundLoop.edgeMate.setMask(_Graph__WEBPACK_IMPORTED_MODULE_0__.HalfEdgeMask.EXTERIOR);
261527
+ }
261528
+ else {
261529
+ this._halfEdgesAroundCurrentLoop.push(halfEdgePreviouslyConstructedFromOppositeSide);
261530
+ halfEdgePreviouslyConstructedFromOppositeSide.clearMask(_Graph__WEBPACK_IMPORTED_MODULE_0__.HalfEdgeMask.EXTERIOR);
261531
+ }
261532
+ index0 = index1;
261533
+ }
261534
+ let halfEdgeA = this._halfEdgesAroundCurrentLoop[this._halfEdgesAroundCurrentLoop.length - 1];
261535
+ for (const halfEdgeB of this._halfEdgesAroundCurrentLoop) {
261536
+ const halfEdgeC = halfEdgeA.faceSuccessor;
261537
+ _Graph__WEBPACK_IMPORTED_MODULE_0__.HalfEdge.pinch(halfEdgeB, halfEdgeC);
261538
+ halfEdgeA = halfEdgeB;
261539
+ }
261540
+ return this._halfEdgesAroundCurrentLoop[0];
261541
+ }
261542
+ return undefined;
261543
+ }
261544
+ }
261545
+
261546
+
260042
261547
  /***/ }),
260043
261548
 
260044
261549
  /***/ "../../core/geometry/lib/esm/topology/HalfEdgeGraphSearch.js":
@@ -285523,7 +287028,7 @@ class TestContext {
285523
287028
  this.initializeRpcInterfaces({ title: this.settings.Backend.name, version: this.settings.Backend.version });
285524
287029
  const iModelClient = new imodels_client_management_1.IModelsClient({ api: { baseUrl: `https://${(_a = process.env.IMJS_URL_PREFIX) !== null && _a !== void 0 ? _a : ""}api.bentley.com/imodels` } });
285525
287030
  await core_frontend_1.NoRenderApp.startup({
285526
- applicationVersion: "4.0.0-dev.6",
287031
+ applicationVersion: "4.0.0-dev.7",
285527
287032
  applicationId: this.settings.gprid,
285528
287033
  authorizationClient: new frontend_1.TestFrontendAuthorizationClient(this.adminUserAccessToken),
285529
287034
  hubAccess: new imodels_access_frontend_1.FrontendIModelsAccess(iModelClient),
@@ -304952,7 +306457,7 @@ module.exports = JSON.parse('{"name":"axios","version":"0.21.4","description":"P
304952
306457
  /***/ ((module) => {
304953
306458
 
304954
306459
  "use strict";
304955
- module.exports = JSON.parse('{"name":"@itwin/core-frontend","version":"4.0.0-dev.6","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs","build:ci":"npm run -s build && npm run -s build:esm","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2020 --outDir lib/esm","clean":"rimraf lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","docs":"betools docs --includes=../../generated-docs/extract --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/primitives,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-eslintrc -c \\"../../tools/eslint-plugin/dist/configs/extension-exports-config.js\\" \\"./src/**/*.ts\\" 1>&2","lint":"eslint -f visualstudio \\"./src/**/*.ts\\" 1>&2","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run -s webpackTests && certa -r chrome","cover":"npm -s test","test:debug":"certa -r chrome --debug","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core/tree/master/core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:^4.0.0-dev.6","@itwin/core-bentley":"workspace:^4.0.0-dev.6","@itwin/core-common":"workspace:^4.0.0-dev.6","@itwin/core-geometry":"workspace:^4.0.0-dev.6","@itwin/core-orbitgt":"workspace:^4.0.0-dev.6","@itwin/core-quantity":"workspace:^4.0.0-dev.6"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/certa":"workspace:*","@itwin/eslint-plugin":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@types/chai":"4.3.1","@types/chai-as-promised":"^7","@types/deep-assign":"^0.1.0","@types/lodash":"^4.14.0","@types/mocha":"^8.2.2","@types/node":"18.11.5","@types/qs":"^6.5.0","@types/semver":"7.3.10","@types/superagent":"^4.1.14","@types/sinon":"^9.0.0","babel-loader":"~8.2.5","babel-plugin-istanbul":"~6.1.1","chai":"^4.1.2","chai-as-promised":"^7","cpx2":"^3.0.0","eslint":"^7.11.0","glob":"^7.1.2","mocha":"^10.0.0","nyc":"^15.1.0","rimraf":"^3.0.2","sinon":"^9.0.2","source-map-loader":"^4.0.0","typescript":"~4.4.0","webpack":"^5.64.4"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/object-storage-azure":"~1.4.0","@itwin/cloud-agnostic-core":"~1.4.0","@itwin/object-storage-core":"~1.4.0","@itwin/core-i18n":"workspace:*","@itwin/core-telemetry":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^3.1.6","@loaders.gl/draco":"^3.1.6","deep-assign":"^2.0.0","fuse.js":"^3.3.0","lodash":"^4.17.10","qs":"^6.5.3","semver":"^7.3.5","superagent":"^7.1.5","wms-capabilities":"0.4.0","reflect-metadata":"0.1.13"},"nyc":{"extends":"./node_modules/@itwin/build-tools/.nycrc"},"eslintConfig":{"plugins":["@itwin"],"extends":"plugin:@itwin/itwinjs-recommended","rules":{"@itwin/no-internal-barrel-imports":["error",{"required-barrel-modules":["./src/tile/internal.ts"]}],"@itwin/public-extension-exports":["error",{"releaseTags":["public","preview"],"outputApiFile":false}]},"overrides":[{"files":["*.test.ts","*.test.tsx","**/test/**/*.ts"],"rules":{"@itwin/no-internal-barrel-imports":"off"}}]}}');
306460
+ module.exports = JSON.parse('{"name":"@itwin/core-frontend","version":"4.0.0-dev.7","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs","build:ci":"npm run -s build && npm run -s build:esm","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2020 --outDir lib/esm","clean":"rimraf lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","docs":"betools docs --includes=../../generated-docs/extract --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/primitives,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-eslintrc -c \\"../../tools/eslint-plugin/dist/configs/extension-exports-config.js\\" \\"./src/**/*.ts\\" 1>&2","lint":"eslint -f visualstudio \\"./src/**/*.ts\\" 1>&2","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run -s webpackTests && certa -r chrome","cover":"npm -s test","test:debug":"certa -r chrome --debug","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core/tree/master/core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:^4.0.0-dev.7","@itwin/core-bentley":"workspace:^4.0.0-dev.7","@itwin/core-common":"workspace:^4.0.0-dev.7","@itwin/core-geometry":"workspace:^4.0.0-dev.7","@itwin/core-orbitgt":"workspace:^4.0.0-dev.7","@itwin/core-quantity":"workspace:^4.0.0-dev.7"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/certa":"workspace:*","@itwin/eslint-plugin":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@types/chai":"4.3.1","@types/chai-as-promised":"^7","@types/deep-assign":"^0.1.0","@types/lodash":"^4.14.0","@types/mocha":"^8.2.2","@types/node":"18.11.5","@types/qs":"^6.5.0","@types/semver":"7.3.10","@types/superagent":"^4.1.14","@types/sinon":"^9.0.0","babel-loader":"~8.2.5","babel-plugin-istanbul":"~6.1.1","chai":"^4.1.2","chai-as-promised":"^7","cpx2":"^3.0.0","eslint":"^7.11.0","glob":"^7.1.2","mocha":"^10.0.0","nyc":"^15.1.0","rimraf":"^3.0.2","sinon":"^9.0.2","source-map-loader":"^4.0.0","typescript":"~4.4.0","webpack":"^5.64.4"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/object-storage-azure":"~1.4.0","@itwin/cloud-agnostic-core":"~1.4.0","@itwin/object-storage-core":"~1.4.0","@itwin/core-i18n":"workspace:*","@itwin/core-telemetry":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^3.1.6","@loaders.gl/draco":"^3.1.6","deep-assign":"^2.0.0","fuse.js":"^3.3.0","lodash":"^4.17.10","qs":"^6.5.3","semver":"^7.3.5","superagent":"^7.1.5","wms-capabilities":"0.4.0","reflect-metadata":"0.1.13"},"nyc":{"extends":"./node_modules/@itwin/build-tools/.nycrc"},"eslintConfig":{"plugins":["@itwin"],"extends":"plugin:@itwin/itwinjs-recommended","rules":{"@itwin/no-internal-barrel-imports":["error",{"required-barrel-modules":["./src/tile/internal.ts"]}],"@itwin/public-extension-exports":["error",{"releaseTags":["public","preview"],"outputApiFile":false}]},"overrides":[{"files":["*.test.ts","*.test.tsx","**/test/**/*.ts"],"rules":{"@itwin/no-internal-barrel-imports":"off"}}]}}');
304956
306461
 
304957
306462
  /***/ }),
304958
306463