@itwin/rpcinterface-full-stack-tests 5.2.0 → 5.2.1
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.
- package/lib/dist/bundled-tests.js +348 -281
- package/lib/dist/bundled-tests.js.map +1 -1
- package/lib/dist/core_frontend_lib_esm_ApproximateTerrainHeightsProps_js.bundled-tests.js.map +1 -1
- package/lib/dist/vendors-common_temp_node_modules_pnpm_cross-fetch_4_0_0_node_modules_cross-fetch_dist_browser-24291b.bundled-tests.js.map +1 -1
- package/lib/dist/vendors-common_temp_node_modules_pnpm_loaders_gl_draco_4_3_4__loaders_gl_core_4_3_4_node_modu-4c1fc9.bundled-tests.js.map +1 -1
- package/package.json +15 -15
|
@@ -181633,6 +181633,7 @@ class ArcGISImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODULE_0__.
|
|
|
181633
181633
|
if (this._accessTokenRequired && this._accessClient) {
|
|
181634
181634
|
this._lastAccessToken = await _tile_internal__WEBPACK_IMPORTED_MODULE_0__.ArcGisUtilities.appendSecurityToken(urlObj, this._accessClient, {
|
|
181635
181635
|
mapLayerUrl: new URL(this._settings.url),
|
|
181636
|
+
portal: typeof this._settings.properties?.portal === "string" ? this._settings.properties.portal : undefined,
|
|
181636
181637
|
userName: this._settings.userName,
|
|
181637
181638
|
password: this._settings.password
|
|
181638
181639
|
});
|
|
@@ -230680,16 +230681,14 @@ class Arc3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_1__.CurvePrimitive
|
|
|
230680
230681
|
}
|
|
230681
230682
|
/** Return the (signed) area between (a fractional portion of) the arc and the chord between those points. */
|
|
230682
230683
|
areaToChordXY(fraction0, fraction1) {
|
|
230683
|
-
|
|
230684
|
-
// areas in arc of unit circle with radians limits
|
|
230684
|
+
const detJ = _Geometry__WEBPACK_IMPORTED_MODULE_5__.Geometry.crossProductXYXY(this._matrix.coffs[0], this._matrix.coffs[3], this._matrix.coffs[1], this._matrix.coffs[4]); // area scale factor from local to world
|
|
230685
230685
|
const radians0 = this._sweep.fractionToRadians(fraction0);
|
|
230686
230686
|
const radians1 = this._sweep.fractionToRadians(fraction1);
|
|
230687
|
-
|
|
230688
|
-
|
|
230689
|
-
|
|
230690
|
-
detJ = -detJ;
|
|
230687
|
+
const alpha = 0.5 * (radians1 - radians0); // signed area of local sector
|
|
230688
|
+
// Compute signed area of local triangle ("wedge") formed by origin and arc endpoints p0, p1:
|
|
230689
|
+
// (p0 x p1)/2 = (cos(r0)sin(r1)-cos(r1)sin(r0))/2 = sin(r1-r0)/2 = cos(a)sin(a)
|
|
230691
230690
|
const wedgeArea = Math.cos(alpha) * Math.sin(alpha);
|
|
230692
|
-
return (alpha - wedgeArea) * detJ;
|
|
230691
|
+
return (alpha - wedgeArea) * detJ; // to world
|
|
230693
230692
|
}
|
|
230694
230693
|
/**
|
|
230695
230694
|
* Construct an offset of the instance curve as viewed in the xy-plane (ignoring z).
|
|
@@ -234116,8 +234115,7 @@ class CurveOps {
|
|
|
234116
234115
|
/**
|
|
234117
234116
|
* Check whether or not the curves are planar, and if so, return a localToWorld frame.
|
|
234118
234117
|
* @param curves input geometry: curves or points.
|
|
234119
|
-
* @param
|
|
234120
|
-
* @param result optional pre-allocated object to populate and return.
|
|
234118
|
+
* @param options bundle of options.
|
|
234121
234119
|
* @returns localToWorld frame `T` for coplanar curves, or undefined if they are not coplanar.
|
|
234122
234120
|
* `T` satisfies:
|
|
234123
234121
|
* * `T.origin` is in the plane.
|
|
@@ -234137,9 +234135,7 @@ class CurveOps {
|
|
|
234137
234135
|
* Check whether or not the curves lie in a straight line, and if so, return a colinear ray.
|
|
234138
234136
|
* * This test does not take curve traversal or point order into account.
|
|
234139
234137
|
* @param curves input geometry: curves or points.
|
|
234140
|
-
* @param
|
|
234141
|
-
* @param tolerance optional maximum allowable linear deviation, default [[Geometry.smallMetricDistance]].
|
|
234142
|
-
* @param result optional pre-allocated object to populate and return.
|
|
234138
|
+
* @param options bundle of options.
|
|
234143
234139
|
* @returns ray colinear with input, or undefined if input is not colinear.
|
|
234144
234140
|
*/
|
|
234145
234141
|
static isColinear(curves, options) {
|
|
@@ -238828,17 +238824,18 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
238828
238824
|
/* harmony export */ });
|
|
238829
238825
|
/* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
|
|
238830
238826
|
/* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
|
|
238827
|
+
/* harmony import */ var _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../geometry3d/Transform */ "../../core/geometry/lib/esm/geometry3d/Transform.js");
|
|
238831
238828
|
/* harmony import */ var _topology_Graph__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../topology/Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
|
|
238832
|
-
/* harmony import */ var
|
|
238829
|
+
/* harmony import */ var _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../topology/HalfEdgeGraphSearch */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphSearch.js");
|
|
238833
238830
|
/* harmony import */ var _topology_Merging__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../topology/Merging */ "../../core/geometry/lib/esm/topology/Merging.js");
|
|
238834
238831
|
/* harmony import */ var _Arc3d__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Arc3d */ "../../core/geometry/lib/esm/curve/Arc3d.js");
|
|
238835
238832
|
/* harmony import */ var _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../CurveLocationDetail */ "../../core/geometry/lib/esm/curve/CurveLocationDetail.js");
|
|
238836
238833
|
/* harmony import */ var _LineSegment3d__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
|
|
238837
238834
|
/* harmony import */ var _LineString3d__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
|
|
238838
|
-
/* harmony import */ var
|
|
238839
|
-
/* harmony import */ var
|
|
238840
|
-
/* harmony import */ var
|
|
238841
|
-
/* harmony import */ var
|
|
238835
|
+
/* harmony import */ var _Loop__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
|
|
238836
|
+
/* harmony import */ var _ParityRegion__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../ParityRegion */ "../../core/geometry/lib/esm/curve/ParityRegion.js");
|
|
238837
|
+
/* harmony import */ var _RegionOps__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../RegionOps */ "../../core/geometry/lib/esm/curve/RegionOps.js");
|
|
238838
|
+
/* harmony import */ var _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../RegionOpsClassificationSweeps */ "../../core/geometry/lib/esm/curve/RegionOpsClassificationSweeps.js");
|
|
238842
238839
|
/*---------------------------------------------------------------------------------------------
|
|
238843
238840
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
238844
238841
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
@@ -238856,9 +238853,29 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
238856
238853
|
|
|
238857
238854
|
|
|
238858
238855
|
|
|
238856
|
+
|
|
238859
238857
|
/** @packageDocumentation
|
|
238860
238858
|
* @module Curve
|
|
238861
238859
|
*/
|
|
238860
|
+
function computeSortAngle(curve, fraction, reverse) {
|
|
238861
|
+
const ray = curve.fractionToPointAndDerivative(fraction);
|
|
238862
|
+
const s = reverse ? -1.0 : 1.0;
|
|
238863
|
+
return Math.atan2(s * ray.direction.y, s * ray.direction.x);
|
|
238864
|
+
}
|
|
238865
|
+
function getFractionOnCurve(pair, curve) {
|
|
238866
|
+
if (pair.detailA.curve === curve)
|
|
238867
|
+
return pair.detailA.fraction;
|
|
238868
|
+
if (pair.detailB.curve === curve)
|
|
238869
|
+
return pair.detailB.fraction;
|
|
238870
|
+
return undefined;
|
|
238871
|
+
}
|
|
238872
|
+
function getDetailOnCurve(pair, curve) {
|
|
238873
|
+
if (pair.detailA.curve === curve)
|
|
238874
|
+
return pair.detailA;
|
|
238875
|
+
if (pair.detailB.curve === curve)
|
|
238876
|
+
return pair.detailB;
|
|
238877
|
+
return undefined;
|
|
238878
|
+
}
|
|
238862
238879
|
class MapCurvePrimitiveToCurveLocationDetailPairArray {
|
|
238863
238880
|
primitiveToPair = new Map();
|
|
238864
238881
|
// index assigned to this primitive (for debugging)
|
|
@@ -238921,8 +238938,11 @@ class MapCurvePrimitiveToCurveLocationDetailPairArray {
|
|
|
238921
238938
|
*/
|
|
238922
238939
|
class PlanarSubdivision {
|
|
238923
238940
|
/**
|
|
238924
|
-
* Create a graph from
|
|
238925
|
-
* Z-coordinates are ignored.
|
|
238941
|
+
* Create a graph from curves and precomputed intersections.
|
|
238942
|
+
* * Z-coordinates are ignored.
|
|
238943
|
+
* @param primitives input curves
|
|
238944
|
+
* @param allPairs array of curve-curve xy-intersections
|
|
238945
|
+
* @param mergeTolerance optional distance tolerance for clustering vertices. Default value is [[Geometry.smallMetricDistance]].
|
|
238926
238946
|
*/
|
|
238927
238947
|
static assembleHalfEdgeGraph(primitives, allPairs, mergeTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance) {
|
|
238928
238948
|
// map from key CurvePrimitive to CurveLocationDetailPair
|
|
@@ -238968,31 +238988,45 @@ class PlanarSubdivision {
|
|
|
238968
238988
|
return graph;
|
|
238969
238989
|
}
|
|
238970
238990
|
/**
|
|
238971
|
-
*
|
|
238972
|
-
* *
|
|
238991
|
+
* Filter for trivial curve fragment: fast computation if line segment; otherwise clip, flatten, and measure.
|
|
238992
|
+
* * Different metrics are employed for expedience.
|
|
238993
|
+
*/
|
|
238994
|
+
static isCurveTrivialXY(p, point0, fraction0, point1, fraction1, mergeTolerance) {
|
|
238995
|
+
if (_Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSmallRelative(fraction0 - fraction1))
|
|
238996
|
+
return true;
|
|
238997
|
+
if (!(p instanceof _LineSegment3d__WEBPACK_IMPORTED_MODULE_3__.LineSegment3d)) {
|
|
238998
|
+
const p0 = p.clonePartialCurve(fraction0, fraction1);
|
|
238999
|
+
if (p0?.tryTransformInPlace(_geometry3d_Transform__WEBPACK_IMPORTED_MODULE_8__.Transform.createRowValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0))) // flatten
|
|
239000
|
+
return p0.curveLength() <= mergeTolerance; // Euclidean
|
|
239001
|
+
}
|
|
239002
|
+
return point0.isAlmostEqualXY(point1, mergeTolerance); // Manhattan
|
|
239003
|
+
}
|
|
239004
|
+
/**
|
|
239005
|
+
* Create a pair of mated half edges referencing a non-trivial interval of a primitive.
|
|
238973
239006
|
* @param graph containing graph
|
|
238974
239007
|
* @param p the curve
|
|
238975
239008
|
* @param point0 start point
|
|
238976
239009
|
* @param fraction0 starting fraction
|
|
238977
239010
|
* @param point1 end point
|
|
238978
239011
|
* @param fraction1 end fraction
|
|
238979
|
-
* @
|
|
239012
|
+
* @param mergeTolerance optional maximum xy-length of a trivial edge
|
|
239013
|
+
* @returns end point and fraction
|
|
238980
239014
|
*/
|
|
238981
239015
|
static addHalfEdge(graph, p, point0, fraction0, point1, fraction1, mergeTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance) {
|
|
238982
|
-
if (
|
|
238983
|
-
|
|
238984
|
-
|
|
238985
|
-
|
|
238986
|
-
|
|
238987
|
-
|
|
238988
|
-
|
|
238989
|
-
|
|
238990
|
-
|
|
238991
|
-
|
|
238992
|
-
|
|
238993
|
-
|
|
238994
|
-
|
|
238995
|
-
return { point: point1, fraction: fraction1 };
|
|
239016
|
+
if (!this.isCurveTrivialXY(p, point0, fraction0, point1, fraction1, mergeTolerance)) {
|
|
239017
|
+
const halfEdge = graph.createEdgeXYAndZ(point0, 0, point1, 0);
|
|
239018
|
+
if (p.parent && p.parent instanceof _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_9__.RegionGroupMember && p.parent.parentGroup.groupOpType === _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_9__.RegionGroupOpType.NonBounding)
|
|
239019
|
+
halfEdge.setMaskAroundEdge(_topology_Graph__WEBPACK_IMPORTED_MODULE_6__.HalfEdgeMask.BRIDGE_EDGE);
|
|
239020
|
+
const detail01 = _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_5__.CurveLocationDetail.createCurveEvaluatedFractionFraction(p, fraction0, fraction1);
|
|
239021
|
+
const mate = halfEdge.edgeMate;
|
|
239022
|
+
halfEdge.edgeTag = detail01;
|
|
239023
|
+
halfEdge.sortData = 1.0;
|
|
239024
|
+
mate.edgeTag = detail01;
|
|
239025
|
+
mate.sortData = -1.0;
|
|
239026
|
+
halfEdge.sortAngle = computeSortAngle(p, fraction0, false);
|
|
239027
|
+
mate.sortAngle = computeSortAngle(p, fraction1, true);
|
|
239028
|
+
}
|
|
239029
|
+
return { point: point1, fraction: fraction1 }; // where the next curve fragment starts
|
|
238996
239030
|
}
|
|
238997
239031
|
/**
|
|
238998
239032
|
* Based on computed (and toleranced) area, push the loop (pointer) onto the appropriate array of positive, negative,
|
|
@@ -239002,7 +239036,7 @@ class PlanarSubdivision {
|
|
|
239002
239036
|
* @returns the area (forced to zero if within tolerance)
|
|
239003
239037
|
*/
|
|
239004
239038
|
static collectSignedLoop(loop, outLoops, zeroAreaTolerance = 1.0e-10, isSliverFace) {
|
|
239005
|
-
let area = isSliverFace ? 0.0 :
|
|
239039
|
+
let area = isSliverFace ? 0.0 : _RegionOps__WEBPACK_IMPORTED_MODULE_10__.RegionOps.computeXYArea(loop);
|
|
239006
239040
|
if (area === undefined)
|
|
239007
239041
|
area = 0;
|
|
239008
239042
|
if (Math.abs(area) < zeroAreaTolerance)
|
|
@@ -239028,32 +239062,31 @@ class PlanarSubdivision {
|
|
|
239028
239062
|
return undefined;
|
|
239029
239063
|
}
|
|
239030
239064
|
/** Create the geometry for a topological edge. */
|
|
239031
|
-
static createCurveInEdge(edge) {
|
|
239065
|
+
static createCurveInEdge(edge, z) {
|
|
239066
|
+
let result;
|
|
239032
239067
|
const info = this.extractGeometryFromEdge(edge);
|
|
239033
|
-
if (info) {
|
|
239034
|
-
|
|
239035
|
-
|
|
239036
|
-
|
|
239068
|
+
if (info && info.detail.curve && info.detail.fraction1) {
|
|
239069
|
+
const f0 = info.reversed ? info.detail.fraction1 : info.detail.fraction;
|
|
239070
|
+
const f1 = info.reversed ? info.detail.fraction : info.detail.fraction1;
|
|
239071
|
+
result = info.detail.curve.clonePartialCurve(f0, f1);
|
|
239072
|
+
if (result && z !== undefined)
|
|
239073
|
+
result.tryTransformInPlace(_geometry3d_Transform__WEBPACK_IMPORTED_MODULE_8__.Transform.createRowValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, z));
|
|
239037
239074
|
}
|
|
239038
|
-
return
|
|
239075
|
+
return result;
|
|
239039
239076
|
}
|
|
239040
239077
|
/**
|
|
239041
239078
|
* Create a [[Loop]] for the given face or super face.
|
|
239042
239079
|
* @param face a node in the face loop, or an array of HalfEdges that comprise a loop (e.g., a super face).
|
|
239043
|
-
* @param
|
|
239044
|
-
* @param compress whether to consolidate adjacent curves in the output Loop (default `false`).
|
|
239045
|
-
* If `announce` is provided, no compression is performed, as edges and curves would no longer be in 1-1 correspondence.
|
|
239046
|
-
* @param closureTol absolute xy-distance for confirming the returned Loop is closed (default [[Geometry.smallMetricDistance]]).
|
|
239080
|
+
* @param options bundle of options.
|
|
239047
239081
|
* @returns the Loop, or `undefined` if it is not closed within xy-tolerance.
|
|
239048
239082
|
*/
|
|
239049
|
-
static createLoopInFace(face,
|
|
239050
|
-
if
|
|
239051
|
-
|
|
239052
|
-
const
|
|
239053
|
-
|
|
239054
|
-
const curve = this.createCurveInEdge(he);
|
|
239083
|
+
static createLoopInFace(face, options) {
|
|
239084
|
+
const consolidate = options?.announceEdge ? false : options?.compress ?? false; // can't compress if announcing
|
|
239085
|
+
const loop = _Loop__WEBPACK_IMPORTED_MODULE_11__.Loop.create();
|
|
239086
|
+
const addEdgeCurve = (edge) => {
|
|
239087
|
+
const curve = this.createCurveInEdge(edge, options?.z);
|
|
239055
239088
|
if (curve) {
|
|
239056
|
-
|
|
239089
|
+
options?.announceEdge?.(edge, curve, loop);
|
|
239057
239090
|
loop.tryAddChild(curve);
|
|
239058
239091
|
}
|
|
239059
239092
|
};
|
|
@@ -239061,12 +239094,12 @@ class PlanarSubdivision {
|
|
|
239061
239094
|
face.forEach(addEdgeCurve);
|
|
239062
239095
|
else
|
|
239063
239096
|
face.announceEdgesInFace(addEdgeCurve);
|
|
239064
|
-
if (
|
|
239065
|
-
const
|
|
239066
|
-
|
|
239067
|
-
|
|
239097
|
+
if (consolidate) {
|
|
239098
|
+
const consolidateOptions = new _RegionOps__WEBPACK_IMPORTED_MODULE_10__.ConsolidateAdjacentCurvePrimitivesOptions();
|
|
239099
|
+
consolidateOptions.consolidateLoopSeam = true;
|
|
239100
|
+
_RegionOps__WEBPACK_IMPORTED_MODULE_10__.RegionOps.consolidateAdjacentPrimitives(loop, consolidateOptions);
|
|
239068
239101
|
}
|
|
239069
|
-
if (loop.isPhysicallyClosedCurve(closureTol, true))
|
|
239102
|
+
if (loop.isPhysicallyClosedCurve(options?.closureTol, true))
|
|
239070
239103
|
return loop;
|
|
239071
239104
|
(0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.assert)(() => false, "face is not physically closed");
|
|
239072
239105
|
return undefined;
|
|
@@ -239075,17 +239108,19 @@ class PlanarSubdivision {
|
|
|
239075
239108
|
* Create a [[Loop]] or [[ParityRegion]] for the given face.
|
|
239076
239109
|
* * A ParityRegion is created for a split-washer type face by removing bridge edges.
|
|
239077
239110
|
* @param face a node in the face loop.
|
|
239078
|
-
* @param
|
|
239079
|
-
* @
|
|
239080
|
-
* @param closureTol absolute xy-distance for confirming the returned Loop is closed (default [[Geometry.smallMetricDistance]]).
|
|
239081
|
-
* @returns the Loop or ParityRegion, or `undefined` if one could not be computed
|
|
239111
|
+
* @param options bundle of options.
|
|
239112
|
+
* @returns the Loop or ParityRegion, or `undefined` if one could not be computed.
|
|
239082
239113
|
*/
|
|
239083
|
-
static createLoopOrParityRegionInFace(face,
|
|
239114
|
+
static createLoopOrParityRegionInFace(face, options) {
|
|
239084
239115
|
let region;
|
|
239085
|
-
|
|
239116
|
+
const visitMask = options?.visitMask ?? _topology_Graph__WEBPACK_IMPORTED_MODULE_6__.HalfEdgeMask.VISITED;
|
|
239117
|
+
const bridgeMask = options?.bridgeMask ?? _topology_Graph__WEBPACK_IMPORTED_MODULE_6__.HalfEdgeMask.BRIDGE_EDGE;
|
|
239118
|
+
let startBridgeEdge;
|
|
239119
|
+
// is it a split-washer face?
|
|
239120
|
+
if (face.isSplitWasherFace(bridgeMask) && (startBridgeEdge = face.findMaskAroundFace(bridgeMask, true))) {
|
|
239086
239121
|
const loops = [];
|
|
239087
239122
|
const loopEdges = [];
|
|
239088
|
-
const bridgeStack = [
|
|
239123
|
+
const bridgeStack = [startBridgeEdge];
|
|
239089
239124
|
const announceEdge = (he) => { he.setMask(visitMask); loopEdges.push(he); };
|
|
239090
239125
|
const announceBridge = (he) => { if (!he.isMaskSet(visitMask))
|
|
239091
239126
|
bridgeStack.push(he); };
|
|
@@ -239099,7 +239134,7 @@ class PlanarSubdivision {
|
|
|
239099
239134
|
continue;
|
|
239100
239135
|
loopEdges.length = 0;
|
|
239101
239136
|
if (loopSeed.announceEdgesInSuperFace(bridgeMask, announceEdge, announceBridge)) {
|
|
239102
|
-
const loop = this.createLoopInFace(loopEdges,
|
|
239137
|
+
const loop = this.createLoopInFace(loopEdges, options);
|
|
239103
239138
|
if (loop) {
|
|
239104
239139
|
loops.push(loop);
|
|
239105
239140
|
continue;
|
|
@@ -239107,13 +239142,13 @@ class PlanarSubdivision {
|
|
|
239107
239142
|
}
|
|
239108
239143
|
}
|
|
239109
239144
|
}
|
|
239110
|
-
region =
|
|
239111
|
-
region =
|
|
239145
|
+
region = _RegionOps__WEBPACK_IMPORTED_MODULE_10__.RegionOps.sortOuterAndHoleLoopsXY(loops);
|
|
239146
|
+
region = _RegionOps__WEBPACK_IMPORTED_MODULE_10__.RegionOps.simplifyRegion(region);
|
|
239112
239147
|
}
|
|
239113
239148
|
else {
|
|
239114
|
-
region = this.createLoopInFace(face,
|
|
239149
|
+
region = this.createLoopInFace(face, options);
|
|
239115
239150
|
}
|
|
239116
|
-
return (region && (region instanceof
|
|
239151
|
+
return (region && (region instanceof _Loop__WEBPACK_IMPORTED_MODULE_11__.Loop || region instanceof _ParityRegion__WEBPACK_IMPORTED_MODULE_12__.ParityRegion)) ? region : undefined;
|
|
239117
239152
|
}
|
|
239118
239153
|
/** Return true if there are only two edges in the face loop, and their start curvatures are the same. */
|
|
239119
239154
|
static isNullFace(he) {
|
|
@@ -239140,7 +239175,7 @@ class PlanarSubdivision {
|
|
|
239140
239175
|
return e1;
|
|
239141
239176
|
}
|
|
239142
239177
|
static collectSignedLoopSetsInHalfEdgeGraph(graph, zeroAreaTolerance = 1.0e-10) {
|
|
239143
|
-
const q =
|
|
239178
|
+
const q = _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_13__.HalfEdgeGraphSearch.collectConnectedComponentsWithExteriorParityMasks(graph, undefined);
|
|
239144
239179
|
const result = [];
|
|
239145
239180
|
const edgeMap = new Map();
|
|
239146
239181
|
for (const faceSeeds of q) {
|
|
@@ -239148,24 +239183,23 @@ class PlanarSubdivision {
|
|
|
239148
239183
|
const edges = [];
|
|
239149
239184
|
for (const faceSeed of faceSeeds) {
|
|
239150
239185
|
const isNullFace = this.isNullFace(faceSeed);
|
|
239151
|
-
const
|
|
239152
|
-
|
|
239153
|
-
|
|
239154
|
-
|
|
239155
|
-
|
|
239156
|
-
|
|
239157
|
-
|
|
239158
|
-
|
|
239159
|
-
|
|
239160
|
-
|
|
239161
|
-
|
|
239162
|
-
|
|
239163
|
-
|
|
239164
|
-
edgeMap.delete(mate);
|
|
239165
|
-
}
|
|
239186
|
+
const announceEdge = isNullFace ? undefined : (he, curveC, loopC) => {
|
|
239187
|
+
const mate = this.getNonNullEdgeMate(graph, he);
|
|
239188
|
+
if (mate !== undefined) {
|
|
239189
|
+
const e = edgeMap.get(mate);
|
|
239190
|
+
if (e === undefined) {
|
|
239191
|
+
// Record this as loopA,edgeA of a shared edge to be completed later from the other side of the edge
|
|
239192
|
+
const e1 = new _Loop__WEBPACK_IMPORTED_MODULE_11__.LoopCurveLoopCurve(loopC, curveC, undefined, undefined);
|
|
239193
|
+
edgeMap.set(he, e1);
|
|
239194
|
+
}
|
|
239195
|
+
else if (e instanceof _Loop__WEBPACK_IMPORTED_MODULE_11__.LoopCurveLoopCurve) {
|
|
239196
|
+
e.setB(loopC, curveC);
|
|
239197
|
+
edges.push(e);
|
|
239198
|
+
edgeMap.delete(mate);
|
|
239166
239199
|
}
|
|
239167
239200
|
}
|
|
239168
|
-
}
|
|
239201
|
+
};
|
|
239202
|
+
const loop = this.createLoopInFace(faceSeed, { announceEdge });
|
|
239169
239203
|
if (loop)
|
|
239170
239204
|
this.collectSignedLoop(loop, componentAreas, zeroAreaTolerance, isNullFace);
|
|
239171
239205
|
}
|
|
@@ -239176,25 +239210,6 @@ class PlanarSubdivision {
|
|
|
239176
239210
|
return result;
|
|
239177
239211
|
}
|
|
239178
239212
|
}
|
|
239179
|
-
function sortAngle(curve, fraction, reverse) {
|
|
239180
|
-
const ray = curve.fractionToPointAndDerivative(fraction);
|
|
239181
|
-
const s = reverse ? -1.0 : 1.0;
|
|
239182
|
-
return Math.atan2(s * ray.direction.y, s * ray.direction.x);
|
|
239183
|
-
}
|
|
239184
|
-
function getFractionOnCurve(pair, curve) {
|
|
239185
|
-
if (pair.detailA.curve === curve)
|
|
239186
|
-
return pair.detailA.fraction;
|
|
239187
|
-
if (pair.detailB.curve === curve)
|
|
239188
|
-
return pair.detailB.fraction;
|
|
239189
|
-
return undefined;
|
|
239190
|
-
}
|
|
239191
|
-
function getDetailOnCurve(pair, curve) {
|
|
239192
|
-
if (pair.detailA.curve === curve)
|
|
239193
|
-
return pair.detailA;
|
|
239194
|
-
if (pair.detailB.curve === curve)
|
|
239195
|
-
return pair.detailB;
|
|
239196
|
-
return undefined;
|
|
239197
|
-
}
|
|
239198
239213
|
|
|
239199
239214
|
|
|
239200
239215
|
/***/ }),
|
|
@@ -240020,7 +240035,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
240020
240035
|
/* harmony export */ RegionOps: () => (/* binding */ RegionOps)
|
|
240021
240036
|
/* harmony export */ });
|
|
240022
240037
|
/* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
|
|
240023
|
-
/* harmony import */ var
|
|
240038
|
+
/* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
|
|
240024
240039
|
/* harmony import */ var _geometry3d_FrameBuilder__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../geometry3d/FrameBuilder */ "../../core/geometry/lib/esm/geometry3d/FrameBuilder.js");
|
|
240025
240040
|
/* harmony import */ var _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../geometry3d/GrowableXYZArray */ "../../core/geometry/lib/esm/geometry3d/GrowableXYZArray.js");
|
|
240026
240041
|
/* harmony import */ var _geometry3d_IndexedXYZCollection__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../geometry3d/IndexedXYZCollection */ "../../core/geometry/lib/esm/geometry3d/IndexedXYZCollection.js");
|
|
@@ -240032,7 +240047,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
240032
240047
|
/* harmony import */ var _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../geometry3d/Ray3d */ "../../core/geometry/lib/esm/geometry3d/Ray3d.js");
|
|
240033
240048
|
/* harmony import */ var _geometry3d_SortablePolygon__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ../geometry3d/SortablePolygon */ "../../core/geometry/lib/esm/geometry3d/SortablePolygon.js");
|
|
240034
240049
|
/* harmony import */ var _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ../geometry3d/Transform */ "../../core/geometry/lib/esm/geometry3d/Transform.js");
|
|
240035
|
-
/* harmony import */ var
|
|
240050
|
+
/* harmony import */ var _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../geometry4d/MomentData */ "../../core/geometry/lib/esm/geometry4d/MomentData.js");
|
|
240036
240051
|
/* harmony import */ var _polyface_PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../polyface/PolyfaceBuilder */ "../../core/geometry/lib/esm/polyface/PolyfaceBuilder.js");
|
|
240037
240052
|
/* harmony import */ var _topology_Graph__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../topology/Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
|
|
240038
240053
|
/* harmony import */ var _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../topology/HalfEdgeGraphSearch */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphSearch.js");
|
|
@@ -240057,7 +240072,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
240057
240072
|
/* harmony import */ var _Query_CurveSplitContext__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./Query/CurveSplitContext */ "../../core/geometry/lib/esm/curve/Query/CurveSplitContext.js");
|
|
240058
240073
|
/* harmony import */ var _Query_InOutTests__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./Query/InOutTests */ "../../core/geometry/lib/esm/curve/Query/InOutTests.js");
|
|
240059
240074
|
/* harmony import */ var _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./Query/PlanarSubdivision */ "../../core/geometry/lib/esm/curve/Query/PlanarSubdivision.js");
|
|
240060
|
-
/* harmony import */ var
|
|
240075
|
+
/* harmony import */ var _RegionMomentsXY__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./RegionMomentsXY */ "../../core/geometry/lib/esm/curve/RegionMomentsXY.js");
|
|
240061
240076
|
/* harmony import */ var _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./RegionOpsClassificationSweeps */ "../../core/geometry/lib/esm/curve/RegionOpsClassificationSweeps.js");
|
|
240062
240077
|
/* harmony import */ var _UnionRegion__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./UnionRegion */ "../../core/geometry/lib/esm/curve/UnionRegion.js");
|
|
240063
240078
|
/*---------------------------------------------------------------------------------------------
|
|
@@ -240109,7 +240124,29 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
240109
240124
|
|
|
240110
240125
|
|
|
240111
240126
|
/**
|
|
240112
|
-
*
|
|
240127
|
+
* * Options to control method [[RegionOps.consolidateAdjacentPrimitives]].
|
|
240128
|
+
* @public
|
|
240129
|
+
*/
|
|
240130
|
+
class ConsolidateAdjacentCurvePrimitivesOptions {
|
|
240131
|
+
/** True to consolidate adjacent linear geometry into a single LineString3d. */
|
|
240132
|
+
consolidateLinearGeometry = true;
|
|
240133
|
+
/** True to consolidate contiguous compatible arcs into a single Arc3d. */
|
|
240134
|
+
consolidateCompatibleArcs = true;
|
|
240135
|
+
/**
|
|
240136
|
+
* True to attempt consolidation of the first and last primitives of a [[Loop]] or physically closed linestring data,
|
|
240137
|
+
* allowing location of the seam to change.
|
|
240138
|
+
*/
|
|
240139
|
+
consolidateLoopSeam = false;
|
|
240140
|
+
/** Disable LineSegment3d and LineString3d point compression. */
|
|
240141
|
+
disableLinearCompression = false;
|
|
240142
|
+
/** Tolerance for detecting identical points. */
|
|
240143
|
+
duplicatePointTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance;
|
|
240144
|
+
/** Tolerance for removing interior colinear points (if `!disableLinearCompression`). */
|
|
240145
|
+
colinearPointTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance;
|
|
240146
|
+
}
|
|
240147
|
+
/**
|
|
240148
|
+
* Enumeration of the binary operation types for Boolean operations.
|
|
240149
|
+
* @see [[RegionOps.regionBooleanXY]], [[RegionOps.polygonBooleanXYToLoops]], [[RegionOps.polygonBooleanXYToPolyface]].
|
|
240113
240150
|
* @public
|
|
240114
240151
|
*/
|
|
240115
240152
|
var RegionBinaryOpType;
|
|
@@ -240143,9 +240180,9 @@ class RegionOps {
|
|
|
240143
240180
|
* @param region any [[Loop]], [[ParityRegion]], or [[UnionRegion]].
|
|
240144
240181
|
*/
|
|
240145
240182
|
static computeXYAreaMoments(region) {
|
|
240146
|
-
const handler = new
|
|
240183
|
+
const handler = new _RegionMomentsXY__WEBPACK_IMPORTED_MODULE_2__.RegionMomentsXY();
|
|
240147
240184
|
const result = region.dispatchToGeometryHandler(handler);
|
|
240148
|
-
if (result instanceof
|
|
240185
|
+
if (result instanceof _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_3__.MomentData) {
|
|
240149
240186
|
result.shiftOriginAndSumsToCentroidOfSums();
|
|
240150
240187
|
return result;
|
|
240151
240188
|
}
|
|
@@ -240156,9 +240193,13 @@ class RegionOps {
|
|
|
240156
240193
|
* @param range range of planar region to tolerance.
|
|
240157
240194
|
* @param distanceTolerance optional absolute distance tolerance.
|
|
240158
240195
|
*/
|
|
240159
|
-
static computeXYAreaTolerance(range, distanceTolerance =
|
|
240160
|
-
//
|
|
240161
|
-
|
|
240196
|
+
static computeXYAreaTolerance(range, distanceTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance) {
|
|
240197
|
+
// ensure the result is nonzero: we never want to report a zero-area loop as a signed-area loop
|
|
240198
|
+
if (distanceTolerance === 0)
|
|
240199
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallFloatingPoint * 10; // observed area 2e-15 computed for a zero-area loop
|
|
240200
|
+
// If A = bh and e is distance tolerance, let A' be the region with b and h extended by half the tolerance.
|
|
240201
|
+
// Then A' := (b+e/2)(h+e/2) = A + e/2(b+h+e/2), which motivates our area tol = A'-A = e/2(b+h+e/2).
|
|
240202
|
+
const halfDistTol = 0.5 * Math.abs(distanceTolerance);
|
|
240162
240203
|
return halfDistTol * (range.xLength() + range.yLength() + halfDistTol);
|
|
240163
240204
|
}
|
|
240164
240205
|
/**
|
|
@@ -240169,9 +240210,9 @@ class RegionOps {
|
|
|
240169
240210
|
* @param region any [[Loop]], [[ParityRegion]], or [[UnionRegion]].
|
|
240170
240211
|
*/
|
|
240171
240212
|
static computeXYArea(region) {
|
|
240172
|
-
const handler = new
|
|
240213
|
+
const handler = new _RegionMomentsXY__WEBPACK_IMPORTED_MODULE_2__.RegionMomentsXY();
|
|
240173
240214
|
const result = region.dispatchToGeometryHandler(handler);
|
|
240174
|
-
if (result instanceof
|
|
240215
|
+
if (result instanceof _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_3__.MomentData) {
|
|
240175
240216
|
return result.quantitySum;
|
|
240176
240217
|
}
|
|
240177
240218
|
return undefined;
|
|
@@ -240373,7 +240414,7 @@ class RegionOps {
|
|
|
240373
240414
|
* * Regions without children are removed.
|
|
240374
240415
|
* * No Boolean operations are performed.
|
|
240375
240416
|
* @param region region to simplify in place
|
|
240376
|
-
* @returns reference to the updated input region
|
|
240417
|
+
* @returns reference to the updated input region, or `undefined` if no children.
|
|
240377
240418
|
* @see [[simplifyRegionType]]
|
|
240378
240419
|
*/
|
|
240379
240420
|
static simplifyRegion(region) {
|
|
@@ -240398,6 +240439,14 @@ class RegionOps {
|
|
|
240398
240439
|
return region.children.splice(0, 1)[0];
|
|
240399
240440
|
return region;
|
|
240400
240441
|
}
|
|
240442
|
+
/**
|
|
240443
|
+
* Helper method to sample a z-coordinate from the input region(s).
|
|
240444
|
+
* * The assumption is that the input is horizontal.
|
|
240445
|
+
*/
|
|
240446
|
+
static getZCoordinate(xyRegion) {
|
|
240447
|
+
const localToWorld = _geometry3d_FrameBuilder__WEBPACK_IMPORTED_MODULE_5__.FrameBuilder.createRightHandedFrame(undefined, xyRegion);
|
|
240448
|
+
return localToWorld ? localToWorld.origin.z : 0;
|
|
240449
|
+
}
|
|
240401
240450
|
/**
|
|
240402
240451
|
* Return areas defined by a boolean operation.
|
|
240403
240452
|
* @note For best results, input regions should have correctly oriented loops. See [[sortOuterAndHoleLoopsXY]].
|
|
@@ -240408,18 +240457,30 @@ class RegionOps {
|
|
|
240408
240457
|
* @param loopsA first set of loops (treated as a union)
|
|
240409
240458
|
* @param loopsB second set of loops (treated as a union)
|
|
240410
240459
|
* @param operation indicates Union, Intersection, Parity, AMinusB, or BMinusA
|
|
240411
|
-
* @param
|
|
240460
|
+
* @param mergeToleranceOrOptions absolute distance tolerance for merging loops, or multiple options settings. Default value is [[Geometry.smallMetricDistance]].
|
|
240412
240461
|
* @returns a region resulting from merging input loops and the boolean operation.
|
|
240413
240462
|
*/
|
|
240414
|
-
static regionBooleanXY(loopsA, loopsB, operation,
|
|
240415
|
-
|
|
240463
|
+
static regionBooleanXY(loopsA, loopsB, operation, mergeToleranceOrOptions = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance) {
|
|
240464
|
+
let mergeTolerance;
|
|
240465
|
+
let simplifyUnion;
|
|
240466
|
+
if (typeof mergeToleranceOrOptions === "number") {
|
|
240467
|
+
mergeTolerance = mergeToleranceOrOptions;
|
|
240468
|
+
simplifyUnion = false;
|
|
240469
|
+
}
|
|
240470
|
+
else {
|
|
240471
|
+
mergeTolerance = mergeToleranceOrOptions.mergeTolerance ?? _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance;
|
|
240472
|
+
simplifyUnion = mergeToleranceOrOptions.simplifyUnion ?? false;
|
|
240473
|
+
}
|
|
240474
|
+
let result = _UnionRegion__WEBPACK_IMPORTED_MODULE_14__.UnionRegion.create();
|
|
240416
240475
|
const context = _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__.RegionBooleanContext.create(_RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__.RegionGroupOpType.Union, _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__.RegionGroupOpType.Union);
|
|
240417
240476
|
context.addMembers(loopsA, loopsB);
|
|
240418
240477
|
context.annotateAndMergeCurvesInGraph(mergeTolerance);
|
|
240478
|
+
const bridgeMask = _topology_Graph__WEBPACK_IMPORTED_MODULE_15__.HalfEdgeMask.BRIDGE_EDGE;
|
|
240419
240479
|
const visitMask = context.graph.grabMask(false);
|
|
240420
240480
|
const range = context.groupA.range().union(context.groupB.range());
|
|
240421
240481
|
const areaTol = this.computeXYAreaTolerance(range, mergeTolerance);
|
|
240422
|
-
const
|
|
240482
|
+
const z = RegionOps.getZCoordinate(operation === RegionBinaryOpType.BMinusA ? loopsB : loopsA);
|
|
240483
|
+
const options = { compress: true, closureTol: mergeTolerance, bridgeMask, visitMask, z };
|
|
240423
240484
|
context.runClassificationSweep(operation, (_graph, face, faceType, area) => {
|
|
240424
240485
|
// ignore danglers and null faces, but not 2-edge "banana" faces with nonzero area
|
|
240425
240486
|
if (face.countEdgesAroundFace() < 2)
|
|
@@ -240427,12 +240488,20 @@ class RegionOps {
|
|
|
240427
240488
|
if (Math.abs(area) < areaTol)
|
|
240428
240489
|
return;
|
|
240429
240490
|
if (faceType === 1) {
|
|
240430
|
-
const loopOrParityRegion = _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_16__.PlanarSubdivision.createLoopOrParityRegionInFace(face,
|
|
240491
|
+
const loopOrParityRegion = _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_16__.PlanarSubdivision.createLoopOrParityRegionInFace(face, options);
|
|
240431
240492
|
if (loopOrParityRegion)
|
|
240432
240493
|
result.tryAddChild(loopOrParityRegion);
|
|
240433
240494
|
}
|
|
240434
240495
|
});
|
|
240435
240496
|
context.graph.dropMask(visitMask);
|
|
240497
|
+
if (simplifyUnion && operation === RegionBinaryOpType.Union) {
|
|
240498
|
+
const signedLoops = RegionOps.constructAllXYRegionLoops(result);
|
|
240499
|
+
if (signedLoops) {
|
|
240500
|
+
const outerLoops = signedLoops.map((component) => component.negativeAreaLoops).flat();
|
|
240501
|
+
if (outerLoops.length > 0)
|
|
240502
|
+
result = _UnionRegion__WEBPACK_IMPORTED_MODULE_14__.UnionRegion.create(...outerLoops);
|
|
240503
|
+
}
|
|
240504
|
+
}
|
|
240436
240505
|
return this.simplifyRegion(result);
|
|
240437
240506
|
}
|
|
240438
240507
|
/**
|
|
@@ -240534,11 +240603,11 @@ class RegionOps {
|
|
|
240534
240603
|
let maxGap = 0.0;
|
|
240535
240604
|
let isPath = false;
|
|
240536
240605
|
if (wrap)
|
|
240537
|
-
maxGap =
|
|
240606
|
+
maxGap = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.maxXY(maxGap, curves[0].startPoint().distance(curves[n - 1].endPoint()));
|
|
240538
240607
|
for (let i = 0; i + 1 < n; i++)
|
|
240539
|
-
maxGap =
|
|
240608
|
+
maxGap = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.maxXY(maxGap, curves[i].endPoint().distance(curves[i + 1].startPoint()));
|
|
240540
240609
|
let collection;
|
|
240541
|
-
if (
|
|
240610
|
+
if (_Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSmallMetricDistance(maxGap)) {
|
|
240542
240611
|
collection = wrap ? _Loop__WEBPACK_IMPORTED_MODULE_8__.Loop.create() : _Path__WEBPACK_IMPORTED_MODULE_24__.Path.create();
|
|
240543
240612
|
isPath = true;
|
|
240544
240613
|
}
|
|
@@ -240608,7 +240677,7 @@ class RegionOps {
|
|
|
240608
240677
|
* @param gapTolerance distance to be treated as "effectively zero" when assembling fragments head-to-tail
|
|
240609
240678
|
* @returns chains, possibly wrapped in a [[BagOfCurves]].
|
|
240610
240679
|
*/
|
|
240611
|
-
static collectChains(fragments, gapTolerance =
|
|
240680
|
+
static collectChains(fragments, gapTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance) {
|
|
240612
240681
|
return _CurveOps__WEBPACK_IMPORTED_MODULE_22__.CurveOps.collectChains(fragments, gapTolerance);
|
|
240613
240682
|
}
|
|
240614
240683
|
/**
|
|
@@ -240661,7 +240730,7 @@ class RegionOps {
|
|
|
240661
240730
|
else if (data instanceof _geometry3d_IndexedXYZCollection__WEBPACK_IMPORTED_MODULE_10__.IndexedXYZCollection) {
|
|
240662
240731
|
let dataToUse;
|
|
240663
240732
|
if (requireClosurePoint && data.length === 5) {
|
|
240664
|
-
if (!
|
|
240733
|
+
if (!_Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.isSmallMetricDistance(data.distanceIndexIndex(0, 4)))
|
|
240665
240734
|
return undefined;
|
|
240666
240735
|
dataToUse = data;
|
|
240667
240736
|
}
|
|
@@ -240673,7 +240742,7 @@ class RegionOps {
|
|
|
240673
240742
|
}
|
|
240674
240743
|
else {
|
|
240675
240744
|
dataToUse = _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_18__.GrowableXYZArray.create(data);
|
|
240676
|
-
_geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_29__.PolylineCompressionContext.compressInPlaceByShortEdgeLength(dataToUse,
|
|
240745
|
+
_geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_29__.PolylineCompressionContext.compressInPlaceByShortEdgeLength(dataToUse, _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance);
|
|
240677
240746
|
if (dataToUse.length < (requireClosurePoint ? 5 : 4))
|
|
240678
240747
|
return undefined;
|
|
240679
240748
|
}
|
|
@@ -240753,7 +240822,7 @@ class RegionOps {
|
|
|
240753
240822
|
* * Physically closed input curves are each returned wrapped in a Loop to facilitate xy-algorithms,
|
|
240754
240823
|
* but outside this limited context, these Loops only makes sense if they are planar.
|
|
240755
240824
|
*/
|
|
240756
|
-
static collectRegionsAndClosedPrimitives(curves, tolerance =
|
|
240825
|
+
static collectRegionsAndClosedPrimitives(curves, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance) {
|
|
240757
240826
|
const regions = [];
|
|
240758
240827
|
if (!Array.isArray(curves))
|
|
240759
240828
|
curves = [curves];
|
|
@@ -240794,7 +240863,7 @@ class RegionOps {
|
|
|
240794
240863
|
* * `edges` contains a [[LoopCurveLoopCurve]] object for each component edge, collecting both loops adjacent
|
|
240795
240864
|
* to the edge and a constituent curve in each.
|
|
240796
240865
|
*/
|
|
240797
|
-
static constructAllXYRegionLoops(curvesAndRegions, tolerance =
|
|
240866
|
+
static constructAllXYRegionLoops(curvesAndRegions, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance, addBridges = true) {
|
|
240798
240867
|
let primitives = RegionOps.collectCurvePrimitives(curvesAndRegions, undefined, true, true);
|
|
240799
240868
|
primitives = _internalContexts_TransferWithSplitArcs__WEBPACK_IMPORTED_MODULE_34__.TransferWithSplitArcs.clone(_CurveCollection__WEBPACK_IMPORTED_MODULE_25__.BagOfCurves.create(...primitives)).children;
|
|
240800
240869
|
const range = this.curveArrayRange(primitives);
|
|
@@ -240802,13 +240871,15 @@ class RegionOps {
|
|
|
240802
240871
|
if (addBridges) { // generate a temp graph to extract its bridge edges
|
|
240803
240872
|
const context = _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__.RegionBooleanContext.create(_RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__.RegionGroupOpType.Union, _RegionOpsClassificationSweeps__WEBPACK_IMPORTED_MODULE_13__.RegionGroupOpType.Union);
|
|
240804
240873
|
const regions = this.collectRegionsAndClosedPrimitives(curvesAndRegions, tolerance);
|
|
240805
|
-
|
|
240806
|
-
|
|
240807
|
-
|
|
240808
|
-
|
|
240809
|
-
|
|
240810
|
-
|
|
240811
|
-
|
|
240874
|
+
if (regions.length > 0) {
|
|
240875
|
+
context.addMembers(regions, undefined);
|
|
240876
|
+
context.annotateAndMergeCurvesInGraph(tolerance);
|
|
240877
|
+
context.graph.announceEdges((_graph, edge) => {
|
|
240878
|
+
if (edge.isMaskSet(_topology_Graph__WEBPACK_IMPORTED_MODULE_15__.HalfEdgeMask.BRIDGE_EDGE))
|
|
240879
|
+
primitives.push(_LineSegment3d__WEBPACK_IMPORTED_MODULE_35__.LineSegment3d.create(edge.getPoint3d(), edge.faceSuccessor.getPoint3d()));
|
|
240880
|
+
return true;
|
|
240881
|
+
});
|
|
240882
|
+
}
|
|
240812
240883
|
}
|
|
240813
240884
|
const intersections = _CurveCurve__WEBPACK_IMPORTED_MODULE_36__.CurveCurve.allIntersectionsAmongPrimitivesXY(primitives, tolerance);
|
|
240814
240885
|
const graph = _Query_PlanarSubdivision__WEBPACK_IMPORTED_MODULE_16__.PlanarSubdivision.assembleHalfEdgeGraph(primitives, intersections, tolerance);
|
|
@@ -241025,27 +241096,6 @@ function pushToInOnOutArrays(curve, select, arrayNegative, array0, arrayPositive
|
|
|
241025
241096
|
else
|
|
241026
241097
|
array0.push(curve);
|
|
241027
241098
|
}
|
|
241028
|
-
/**
|
|
241029
|
-
* * Options to control method `RegionOps.consolidateAdjacentPrimitives`.
|
|
241030
|
-
* @public
|
|
241031
|
-
*/
|
|
241032
|
-
class ConsolidateAdjacentCurvePrimitivesOptions {
|
|
241033
|
-
/** True to consolidate adjacent linear geometry into a single LineString3d. */
|
|
241034
|
-
consolidateLinearGeometry = true;
|
|
241035
|
-
/** True to consolidate contiguous compatible arcs into a single Arc3d. */
|
|
241036
|
-
consolidateCompatibleArcs = true;
|
|
241037
|
-
/**
|
|
241038
|
-
* True to attempt consolidation of the first and last primitives of a [[Loop]] or physically closed linestring data,
|
|
241039
|
-
* allowing location of the seam to change.
|
|
241040
|
-
*/
|
|
241041
|
-
consolidateLoopSeam = false;
|
|
241042
|
-
/** Disable LineSegment3d and LineString3d point compression. */
|
|
241043
|
-
disableLinearCompression = false;
|
|
241044
|
-
/** Tolerance for detecting identical points. */
|
|
241045
|
-
duplicatePointTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistance;
|
|
241046
|
-
/** Tolerance for removing interior colinear points (if `!disableLinearCompression`). */
|
|
241047
|
-
colinearPointTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistance;
|
|
241048
|
-
}
|
|
241049
241099
|
|
|
241050
241100
|
|
|
241051
241101
|
/***/ }),
|
|
@@ -241722,13 +241772,11 @@ class RegionBooleanContext {
|
|
|
241722
241772
|
const nodeHasBeenVisitedMask = this.graph.grabMask();
|
|
241723
241773
|
const componentArray = GraphComponentArray.create(this.graph);
|
|
241724
241774
|
for (const component of componentArray.components) {
|
|
241725
|
-
const exteriorHalfEdge =
|
|
241726
|
-
|
|
241727
|
-
|
|
241728
|
-
|
|
241729
|
-
|
|
241730
|
-
RegionOpsFaceToFaceSearch.faceToFaceSearchFromOuterLoop(this.graph, exteriorHalfEdge, faceHasBeenVisitedMask, nodeHasBeenVisitedMask, this);
|
|
241731
|
-
}
|
|
241775
|
+
const exteriorHalfEdge = component.faces[component.faceAreas.indexOf(Math.min(...component.faceAreas))];
|
|
241776
|
+
const exteriorMask = _topology_Graph__WEBPACK_IMPORTED_MODULE_0__.HalfEdgeMask.EXTERIOR;
|
|
241777
|
+
const allMasksToClear = exteriorMask | faceHasBeenVisitedMask | nodeHasBeenVisitedMask;
|
|
241778
|
+
this.graph.clearMask(allMasksToClear);
|
|
241779
|
+
RegionOpsFaceToFaceSearch.faceToFaceSearchFromOuterLoop(this.graph, exteriorHalfEdge, faceHasBeenVisitedMask, nodeHasBeenVisitedMask, this);
|
|
241732
241780
|
}
|
|
241733
241781
|
this.graph.dropMask(faceHasBeenVisitedMask);
|
|
241734
241782
|
this.graph.dropMask(nodeHasBeenVisitedMask);
|
|
@@ -241901,8 +241949,10 @@ class GraphComponent {
|
|
|
241901
241949
|
f.sumAroundFace(vertexFunction);
|
|
241902
241950
|
}
|
|
241903
241951
|
this.faceAreas.length = 0;
|
|
241952
|
+
if (faceAreaFunction === faceAreaFromCurvedEdgeData && !this.faces.every((he) => he.edgeTag instanceof _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_16__.CurveLocationDetail))
|
|
241953
|
+
faceAreaFunction = undefined; // prerequisite CurveLocationDetails are absent, fall through to default
|
|
241904
241954
|
if (!faceAreaFunction)
|
|
241905
|
-
faceAreaFunction = (node) => _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_4__.HalfEdgeGraphSearch.signedFaceArea(node);
|
|
241955
|
+
faceAreaFunction = (node) => _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_4__.HalfEdgeGraphSearch.signedFaceArea(node); // polygon area
|
|
241906
241956
|
for (const f of this.faces) {
|
|
241907
241957
|
this.faceAreas.push(faceAreaFunction(f));
|
|
241908
241958
|
}
|
|
@@ -244401,7 +244451,9 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
244401
244451
|
// The fraction and extend parameters allow all combinations to be passed in.
|
|
244402
244452
|
dispatchSegmentArc(cpA, extendA0, pointA0, fractionA0, pointA1, fractionA1, extendA1, arc, extendB0, extendB1, reversed) {
|
|
244403
244453
|
const tol2 = this._coincidentGeometryContext.tolerance * this._coincidentGeometryContext.tolerance;
|
|
244404
|
-
|
|
244454
|
+
const cosines = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_9__.GrowableFloat64Array(2);
|
|
244455
|
+
const sines = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_9__.GrowableFloat64Array(2);
|
|
244456
|
+
const radians = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_9__.GrowableFloat64Array(2);
|
|
244405
244457
|
// Arc: X = C + cU + sV
|
|
244406
244458
|
// Line: contains points A0,A1
|
|
244407
244459
|
// Arc point colinear with line if det (A0, A1, X) = 0
|
|
@@ -244421,27 +244473,30 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
244421
244473
|
const alpha = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.center);
|
|
244422
244474
|
const beta = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.vector0);
|
|
244423
244475
|
const gamma = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.vector90);
|
|
244424
|
-
|
|
244425
|
-
const
|
|
244426
|
-
|
|
244427
|
-
|
|
244428
|
-
|
|
244429
|
-
|
|
244476
|
+
let numRoots = _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_10__.AnalyticRoots.appendImplicitLineUnitCircleIntersections(alpha, beta, gamma, cosines, sines, radians);
|
|
244477
|
+
const closeApproach = (0 === numRoots);
|
|
244478
|
+
if (closeApproach)
|
|
244479
|
+
numRoots = 1; // we returned the arc's closest approach as the first "root"; if within tolerance and at endpoints, we record it
|
|
244480
|
+
const acceptSolution = (iRoot, checkOnlyEndPointDistance = false) => {
|
|
244481
|
+
const arcPoint = data.center.plus2Scaled(data.vector0, cosines.atUncheckedIndex(iRoot), data.vector90, sines.atUncheckedIndex(iRoot));
|
|
244482
|
+
let fArc = data.sweep.radiansToSignedFraction(radians.atUncheckedIndex(iRoot), extendB0);
|
|
244483
|
+
let fLine = _numerics_SmallSystem__WEBPACK_IMPORTED_MODULE_8__.SmallSystem.lineSegment3dHXYClosestPointUnbounded(pointA0H, pointA1H, arcPoint);
|
|
244484
|
+
if (fLine === undefined)
|
|
244485
|
+
return undefined;
|
|
244486
|
+
if (!checkOnlyEndPointDistance && this.acceptFraction(extendA0, fLine, extendA1) && this.acceptFraction(extendB0, fArc, extendB1))
|
|
244487
|
+
return { fLine, fArc };
|
|
244488
|
+
// check for an endpoint intersection that is beyond parametric tolerance but within point tolerance
|
|
244489
|
+
fLine = fLine < 0.5 ? 0 : 1;
|
|
244490
|
+
fArc = data.sweep.fractionToSignedPeriodicFraction(fArc) < 0.5 ? 0 : 1;
|
|
244491
|
+
const pointAH = fLine ? pointA1H : pointA0H;
|
|
244492
|
+
const pointBH = fArc ? pointB1H : pointB0H;
|
|
244493
|
+
const dist2 = pointAH.realDistanceSquaredXY(pointBH);
|
|
244494
|
+
return (dist2 !== undefined && _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.isDistanceWithinTol(dist2, tol2)) ? { fLine, fArc } : undefined;
|
|
244495
|
+
};
|
|
244430
244496
|
for (let i = 0; i < numRoots; i++) {
|
|
244431
|
-
const
|
|
244432
|
-
|
|
244433
|
-
|
|
244434
|
-
if (lineFraction !== undefined) {
|
|
244435
|
-
if (this.acceptFraction(extendA0, lineFraction, extendA1) && this.acceptFraction(extendB0, arcFraction, extendB1)) {
|
|
244436
|
-
this.recordPointWithLocalFractions(lineFraction, cpA, fractionA0, fractionA1, arcFraction, arc, 0, 1, reversed);
|
|
244437
|
-
}
|
|
244438
|
-
else { // check for endpoint intersections beyond parametric tolerance but within point tolerance
|
|
244439
|
-
const pointAH = lineFraction < 0.5 ? pointA0H : pointA1H;
|
|
244440
|
-
const pointBH = (arcFraction = data.sweep.fractionToSignedPeriodicFraction(arcFraction)) < 0.5 ? pointB0H : pointB1H;
|
|
244441
|
-
if ((dist2 = pointAH.realDistanceSquaredXY(pointBH)) !== undefined && _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.isDistanceWithinTol(dist2, tol2))
|
|
244442
|
-
this.recordPointWithLocalFractions(lineFraction < 0.5 ? 0 : 1, cpA, fractionA0, fractionA1, arcFraction < 0.5 ? 0 : 1, arc, 0, 1, reversed);
|
|
244443
|
-
}
|
|
244444
|
-
}
|
|
244497
|
+
const result = acceptSolution(i, closeApproach);
|
|
244498
|
+
if (result)
|
|
244499
|
+
this.recordPointWithLocalFractions(result.fLine, cpA, fractionA0, fractionA1, result.fArc, arc, 0, 1, reversed);
|
|
244445
244500
|
}
|
|
244446
244501
|
}
|
|
244447
244502
|
else {
|
|
@@ -244459,27 +244514,30 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
244459
244514
|
const alpha = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.center, 1);
|
|
244460
244515
|
const beta = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector0, 0);
|
|
244461
244516
|
const gamma = _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector90, 0);
|
|
244462
|
-
|
|
244463
|
-
const
|
|
244464
|
-
|
|
244465
|
-
|
|
244466
|
-
|
|
244467
|
-
|
|
244517
|
+
let numRoots = _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_10__.AnalyticRoots.appendImplicitLineUnitCircleIntersections(alpha, beta, gamma, cosines, sines, radians);
|
|
244518
|
+
const closeApproach = (0 === numRoots);
|
|
244519
|
+
if (closeApproach)
|
|
244520
|
+
numRoots = 1; // we returned the arc's closest approach as the first "root"; if within tolerance and at endpoints, we record it
|
|
244521
|
+
const acceptSolution = (iRoot, checkOnlyEndPointDistance = false) => {
|
|
244522
|
+
const arcPoint = data.center.plus2Scaled(data.vector0, cosines.atUncheckedIndex(iRoot), data.vector90, sines.atUncheckedIndex(iRoot));
|
|
244523
|
+
let fArc = data.sweep.radiansToSignedFraction(radians.atUncheckedIndex(iRoot), extendB0);
|
|
244524
|
+
let fLine = _numerics_SmallSystem__WEBPACK_IMPORTED_MODULE_8__.SmallSystem.lineSegment3dXYClosestPointUnbounded(pointA0Local, pointA1Local, arcPoint);
|
|
244525
|
+
if (fLine === undefined)
|
|
244526
|
+
return undefined;
|
|
244527
|
+
if (!checkOnlyEndPointDistance && this.acceptFraction(extendA0, fLine, extendA1) && this.acceptFraction(extendB0, fArc, extendB1))
|
|
244528
|
+
return { fLine, fArc };
|
|
244529
|
+
// check for an endpoint intersection that is beyond parametric tolerance but within point tolerance
|
|
244530
|
+
fLine = fLine < 0.5 ? 0 : 1;
|
|
244531
|
+
fArc = data.sweep.fractionToSignedPeriodicFraction(fArc) < 0.5 ? 0 : 1;
|
|
244532
|
+
const pointALocal = fLine ? pointA1Local : pointA0Local;
|
|
244533
|
+
const pointBLocal = fArc ? pointB1Local : pointB0Local;
|
|
244534
|
+
const dist2 = pointALocal.distanceSquaredXY(pointBLocal);
|
|
244535
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.isDistanceWithinTol(dist2, tol2) ? { fLine, fArc } : undefined;
|
|
244536
|
+
};
|
|
244468
244537
|
for (let i = 0; i < numRoots; i++) {
|
|
244469
|
-
const
|
|
244470
|
-
|
|
244471
|
-
|
|
244472
|
-
if (lineFraction !== undefined) {
|
|
244473
|
-
if (this.acceptFraction(extendA0, lineFraction, extendA1) && this.acceptFraction(extendB0, arcFraction, extendB1)) {
|
|
244474
|
-
this.recordPointWithLocalFractions(lineFraction, cpA, fractionA0, fractionA1, arcFraction, arc, 0, 1, reversed);
|
|
244475
|
-
}
|
|
244476
|
-
else { // check for endpoint intersections beyond parametric tolerance but within point tolerance
|
|
244477
|
-
const pointALocal = lineFraction < 0.5 ? pointA0Local : pointA1Local;
|
|
244478
|
-
const pointBLocal = (arcFraction = data.sweep.fractionToSignedPeriodicFraction(arcFraction)) < 0.5 ? pointB0Local : pointB1Local;
|
|
244479
|
-
if ((dist2 = pointALocal.distanceSquaredXY(pointBLocal)) !== undefined && _Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.isDistanceWithinTol(dist2, tol2))
|
|
244480
|
-
this.recordPointWithLocalFractions(lineFraction < 0.5 ? 0 : 1, cpA, fractionA0, fractionA1, arcFraction < 0.5 ? 0 : 1, arc, 0, 1, reversed);
|
|
244481
|
-
}
|
|
244482
|
-
}
|
|
244538
|
+
const result = acceptSolution(i, closeApproach);
|
|
244539
|
+
if (result)
|
|
244540
|
+
this.recordPointWithLocalFractions(result.fLine, cpA, fractionA0, fractionA1, result.fArc, arc, 0, 1, reversed);
|
|
244483
244541
|
}
|
|
244484
244542
|
}
|
|
244485
244543
|
}
|
|
@@ -244502,12 +244560,23 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
244502
244560
|
localB.coffs[0], localB.coffs[3], localB.coffs[6], // vector0 xyw
|
|
244503
244561
|
localB.coffs[1], localB.coffs[4], localB.coffs[7], // vector90 xyw
|
|
244504
244562
|
ellipseRadians, circleRadians);
|
|
244563
|
+
const tol2 = this._coincidentGeometryContext.tolerance * this._coincidentGeometryContext.tolerance;
|
|
244505
244564
|
// the intersections are transform-invariant, so the solution angles apply directly to the input arcs
|
|
244506
244565
|
for (let i = 0; i < ellipseRadians.length; i++) {
|
|
244507
|
-
|
|
244508
|
-
|
|
244509
|
-
if (this.acceptFraction(extendA0, fractionA, extendA1) && this.acceptFraction(extendB0, fractionB, extendB1))
|
|
244566
|
+
let fractionA = cpA.sweep.radiansToSignedFraction(circleRadians[i], extendA0);
|
|
244567
|
+
let fractionB = cpB.sweep.radiansToSignedFraction(ellipseRadians[i], extendB0);
|
|
244568
|
+
if (this.acceptFraction(extendA0, fractionA, extendA1) && this.acceptFraction(extendB0, fractionB, extendB1)) {
|
|
244510
244569
|
this.recordPointWithLocalFractions(fractionA, cpA, 0, 1, fractionB, cpB, 0, 1, reversed);
|
|
244570
|
+
}
|
|
244571
|
+
else { // check for endpoint intersection beyond angular tolerance but within point tolerance
|
|
244572
|
+
fractionA = cpA.sweep.fractionToSignedPeriodicFraction(fractionA) < 0.5 ? 0 : 1;
|
|
244573
|
+
fractionB = cpB.sweep.fractionToSignedPeriodicFraction(fractionB) < 0.5 ? 0 : 1;
|
|
244574
|
+
const endPointA = cpA.fractionToPoint(fractionA, CurveCurveIntersectXY._workPointAA0);
|
|
244575
|
+
const endPointB = cpB.fractionToPoint(fractionB, CurveCurveIntersectXY._workPointBB0);
|
|
244576
|
+
const dist2 = endPointA.distanceSquaredXY(endPointB);
|
|
244577
|
+
if (_Geometry__WEBPACK_IMPORTED_MODULE_4__.Geometry.isDistanceWithinTol(dist2, tol2))
|
|
244578
|
+
this.recordPointWithLocalFractions(fractionA, cpA, 0, 1, fractionB, cpB, 0, 1, reversed);
|
|
244579
|
+
}
|
|
244511
244580
|
}
|
|
244512
244581
|
}
|
|
244513
244582
|
}
|
|
@@ -244520,6 +244589,15 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
244520
244589
|
* 5- Convert intersection angles to fractions and record intersections.
|
|
244521
244590
|
*/
|
|
244522
244591
|
dispatchArcArc(cpA, extendA0, extendA1, cpB, extendB0, extendB1, reversed) {
|
|
244592
|
+
// overlap handling. perspective is not handled.
|
|
244593
|
+
if (this._coincidentGeometryContext && !this._worldToLocalPerspective && !this._worldToLocalAffine) {
|
|
244594
|
+
const pairs = this._coincidentGeometryContext.coincidentArcIntersectionXY(cpA, cpB, true);
|
|
244595
|
+
if (pairs) {
|
|
244596
|
+
this.recordPairs(cpA, cpB, pairs, reversed);
|
|
244597
|
+
return;
|
|
244598
|
+
}
|
|
244599
|
+
}
|
|
244600
|
+
// look for isolated intersections
|
|
244523
244601
|
let matrixA;
|
|
244524
244602
|
let matrixB;
|
|
244525
244603
|
if (this._worldToLocalPerspective) {
|
|
@@ -244536,27 +244614,13 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
244536
244614
|
}
|
|
244537
244615
|
const conditionA = matrixA.conditionNumber();
|
|
244538
244616
|
const conditionB = matrixB.conditionNumber();
|
|
244539
|
-
//
|
|
244617
|
+
// order the arcs so that the first one we pass in is closer to circular
|
|
244540
244618
|
if (conditionA > conditionB)
|
|
244541
244619
|
this.dispatchArcArcThisOrder(cpA, matrixA, extendA0, extendA1, cpB, matrixB, extendB0, extendB1, reversed);
|
|
244542
244620
|
else
|
|
244543
244621
|
this.dispatchArcArcThisOrder(cpB, matrixB, extendB0, extendB1, cpA, matrixA, extendA0, extendA1, !reversed);
|
|
244544
|
-
// overlap handling. perspective is not handled.
|
|
244545
|
-
if (!this._coincidentGeometryContext) {
|
|
244546
|
-
// do nothing
|
|
244547
|
-
}
|
|
244548
|
-
else if (this._worldToLocalPerspective) {
|
|
244549
|
-
// do nothing
|
|
244550
|
-
}
|
|
244551
|
-
else if (this._worldToLocalAffine) {
|
|
244552
|
-
// do nothing
|
|
244553
|
-
}
|
|
244554
|
-
else {
|
|
244555
|
-
const pairs = this._coincidentGeometryContext.coincidentArcIntersectionXY(cpA, cpB, true);
|
|
244556
|
-
if (pairs !== undefined)
|
|
244557
|
-
this.recordPairs(cpA, cpB, pairs, reversed);
|
|
244558
|
-
}
|
|
244559
244622
|
}
|
|
244623
|
+
/** Compute the intersection of an arc and a B-spline curve. */
|
|
244560
244624
|
dispatchArcBsplineCurve3d(cpA, extendA0, extendA1, cpB, extendB0, extendB1, reversed) {
|
|
244561
244625
|
// Arc: X = C + cU + sV
|
|
244562
244626
|
// implicitize the arc as viewed. This "3d" matrix is homogeneous "XYW" not "xyz"
|
|
@@ -244571,8 +244635,6 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
244571
244635
|
}
|
|
244572
244636
|
// The worldToLocal has moved the arc vectors into local space.
|
|
244573
244637
|
// matrixA captures the xyw parts (ignoring z)
|
|
244574
|
-
// for any point in world space,
|
|
244575
|
-
// THIS CODE ONLY WORKS FOR
|
|
244576
244638
|
const matrixAInverse = matrixA.inverse();
|
|
244577
244639
|
if (matrixAInverse) {
|
|
244578
244640
|
const orderF = cpB.order; // order of the beziers for simple coordinates
|
|
@@ -244591,36 +244653,34 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
244591
244653
|
const awy = matrixAInverse.at(2, 1);
|
|
244592
244654
|
const awz = 0.0;
|
|
244593
244655
|
const aww = matrixAInverse.at(2, 2);
|
|
244594
|
-
|
|
244595
|
-
|
|
244596
|
-
|
|
244597
|
-
|
|
244598
|
-
|
|
244599
|
-
|
|
244600
|
-
|
|
244601
|
-
|
|
244602
|
-
|
|
244603
|
-
|
|
244604
|
-
|
|
244605
|
-
|
|
244606
|
-
|
|
244607
|
-
|
|
244608
|
-
|
|
244609
|
-
|
|
244610
|
-
|
|
244611
|
-
|
|
244612
|
-
|
|
244613
|
-
|
|
244614
|
-
|
|
244615
|
-
|
|
244616
|
-
|
|
244617
|
-
|
|
244618
|
-
|
|
244619
|
-
|
|
244620
|
-
|
|
244621
|
-
|
|
244622
|
-
this.recordPointWithLocalFractions(arcFraction, cpA, 0, 1, fractionB, cpB, 0, 1, reversed);
|
|
244623
|
-
}
|
|
244656
|
+
let bezier;
|
|
244657
|
+
for (let spanIndex = 0;; spanIndex++) {
|
|
244658
|
+
bezier = cpB.getSaturatedBezierSpan3dH(spanIndex, bezier);
|
|
244659
|
+
if (!bezier)
|
|
244660
|
+
break;
|
|
244661
|
+
if (this._worldToLocalPerspective)
|
|
244662
|
+
bezier.tryMultiplyMatrix4dInPlace(this._worldToLocalPerspective);
|
|
244663
|
+
else if (this._worldToLocalAffine)
|
|
244664
|
+
bezier.tryTransformInPlace(this._worldToLocalAffine);
|
|
244665
|
+
univariateBezierG.zero();
|
|
244666
|
+
bezier.poleProductsXYZW(coffF, axx, axy, axz, axw);
|
|
244667
|
+
univariateBezierG.addSquaredSquaredBezier(coffF, 1.0);
|
|
244668
|
+
bezier.poleProductsXYZW(coffF, ayx, ayy, ayz, ayw);
|
|
244669
|
+
univariateBezierG.addSquaredSquaredBezier(coffF, 1.0);
|
|
244670
|
+
bezier.poleProductsXYZW(coffF, awx, awy, awz, aww);
|
|
244671
|
+
univariateBezierG.addSquaredSquaredBezier(coffF, -1.0);
|
|
244672
|
+
const roots = univariateBezierG.roots(0.0, true);
|
|
244673
|
+
if (roots) {
|
|
244674
|
+
for (const root of roots) {
|
|
244675
|
+
const fractionB = bezier.fractionToParentFraction(root);
|
|
244676
|
+
// The univariate bezier (which has been transformed by the view transform) evaluates into xyw space
|
|
244677
|
+
const bcurvePoint4d = bezier.fractionToPoint4d(root);
|
|
244678
|
+
const c = bcurvePoint4d.dotProductXYZW(axx, axy, axz, axw);
|
|
244679
|
+
const s = bcurvePoint4d.dotProductXYZW(ayx, ayy, ayz, ayw);
|
|
244680
|
+
const arcFraction = cpA.sweep.radiansToSignedFraction(Math.atan2(s, c), extendA0);
|
|
244681
|
+
if (this.acceptFraction(extendA0, arcFraction, extendA1) &&
|
|
244682
|
+
this.acceptFraction(extendB0, fractionB, extendB1)) {
|
|
244683
|
+
this.recordPointWithLocalFractions(arcFraction, cpA, 0, 1, fractionB, cpB, 0, 1, reversed);
|
|
244624
244684
|
}
|
|
244625
244685
|
}
|
|
244626
244686
|
}
|
|
@@ -256224,7 +256284,8 @@ class GrowableXYArray extends _IndexedXYCollection__WEBPACK_IMPORTED_MODULE_0__.
|
|
|
256224
256284
|
newPoints._xyInUse = this.length;
|
|
256225
256285
|
return newPoints;
|
|
256226
256286
|
}
|
|
256227
|
-
/**
|
|
256287
|
+
/**
|
|
256288
|
+
* Create an array by copying data from various point formats.
|
|
256228
256289
|
* Valid inputs are:
|
|
256229
256290
|
* * Point2d
|
|
256230
256291
|
* * Point3d
|
|
@@ -257002,7 +257063,8 @@ class GrowableXYZArray extends _IndexedXYZCollection__WEBPACK_IMPORTED_MODULE_0_
|
|
|
257002
257063
|
compressInPlace(tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance) {
|
|
257003
257064
|
return GrowableXYZArray.createCompressed(this, tolerance, this);
|
|
257004
257065
|
}
|
|
257005
|
-
/**
|
|
257066
|
+
/**
|
|
257067
|
+
* Create an array by copying data from various point formats.
|
|
257006
257068
|
* Valid inputs are:
|
|
257007
257069
|
* * Point2d
|
|
257008
257070
|
* * Point3d
|
|
@@ -258100,8 +258162,8 @@ class PointsIterator {
|
|
|
258100
258162
|
[Symbol.iterator]() { return this; }
|
|
258101
258163
|
}
|
|
258102
258164
|
/**
|
|
258103
|
-
*
|
|
258104
|
-
* * This allows algorithms to work with Point3d[] or
|
|
258165
|
+
* Abstract base class for read-only access to XYZ data with indexed reference.
|
|
258166
|
+
* * This allows algorithms to work with Point3d[] or [[GrowableXYZArray]].
|
|
258105
258167
|
* * GrowableXYZArray implements these for its data.
|
|
258106
258168
|
* * Point3dArrayCarrier carries a (reference to) a Point3d[] and implements the methods with calls on that array reference.
|
|
258107
258169
|
* * In addition to "point by point" accessors, other abstract members compute commonly useful vector data "between points".
|
|
@@ -258319,7 +258381,7 @@ class IndexedXYZCollection {
|
|
|
258319
258381
|
}
|
|
258320
258382
|
}
|
|
258321
258383
|
/**
|
|
258322
|
-
*
|
|
258384
|
+
* Abstract base class extends [[IndexedXYZCollection]] with methods that modify the collection.
|
|
258323
258385
|
* @public
|
|
258324
258386
|
*/
|
|
258325
258387
|
class IndexedReadWriteXYZCollection extends IndexedXYZCollection {
|
|
@@ -269013,8 +269075,8 @@ class PolylineOps {
|
|
|
269013
269075
|
* Checks if all points are colinear.
|
|
269014
269076
|
* * This test does not take point order into account.
|
|
269015
269077
|
* @param points array of points to check.
|
|
269016
|
-
* @param distanceTol
|
|
269017
|
-
* @param xyOnly
|
|
269078
|
+
* @param distanceTol maximum allowable distance that geometry can deviate from colinearity.Default is [[Geometry.smallMetricDistance]].
|
|
269079
|
+
* @param xyOnly whether to ignore z-coordinates in the colinearity test.
|
|
269018
269080
|
*/
|
|
269019
269081
|
static isColinear(points, distanceTol = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance, xyOnly = false) {
|
|
269020
269082
|
if (points.length < 3)
|
|
@@ -277100,9 +277162,9 @@ class ClusterableArray extends _geometry3d_GrowableBlockedArray__WEBPACK_IMPORTE
|
|
|
277100
277162
|
candidateBlockIndex = firstSort[j];
|
|
277101
277163
|
if (candidateBlockIndex === ClusterableArray.clusterTerminator)
|
|
277102
277164
|
continue; // nearby in sort direction but already in a cluster.
|
|
277103
|
-
if (this.component(candidateBlockIndex, 0)
|
|
277165
|
+
if (this.component(candidateBlockIndex, 0) > barrierU)
|
|
277104
277166
|
break;
|
|
277105
|
-
if (this.distanceBetweenSubBlocks(clusterStartBlockIndex, candidateBlockIndex, k0, k1)
|
|
277167
|
+
if (this.distanceBetweenSubBlocks(clusterStartBlockIndex, candidateBlockIndex, k0, k1) <= clusterTolerance) {
|
|
277106
277168
|
clusterIndices[m++] = candidateBlockIndex; // The candidate is in the block
|
|
277107
277169
|
firstSort[j] = ClusterableArray.clusterTerminator; // and it will not be reused as future block base
|
|
277108
277170
|
}
|
|
@@ -312887,13 +312949,21 @@ class HalfEdgeGraphMerge {
|
|
|
312887
312949
|
static isNullFace(node) {
|
|
312888
312950
|
return node.isMaskSet(_Graph__WEBPACK_IMPORTED_MODULE_3__.HalfEdgeMask.NULL_FACE) && node.faceSuccessor.isMaskSet(_Graph__WEBPACK_IMPORTED_MODULE_3__.HalfEdgeMask.NULL_FACE) && node === node.faceSuccessor.faceSuccessor;
|
|
312889
312951
|
}
|
|
312890
|
-
/**
|
|
312891
|
-
*
|
|
312892
|
-
* *
|
|
312893
|
-
* *
|
|
312894
|
-
* * This
|
|
312895
|
-
*
|
|
312896
|
-
*
|
|
312952
|
+
/**
|
|
312953
|
+
* Cluster the HalfEdges so that xy-coordinates within `mergeTolerance` are equated.
|
|
312954
|
+
* * Note that any additional data (e.g., edgeTag, faceTag) on the HalfEdges are ignored. In particular,
|
|
312955
|
+
* [[CurveLocationDetail]]s attached to clustered HalfEdges do *not* get their points adjusted.
|
|
312956
|
+
* * This is a simple merge algorithm:
|
|
312957
|
+
* * untwist all edges from the vertex loops
|
|
312958
|
+
* * collect array of (x,y,theta) at all nodes
|
|
312959
|
+
* * lexical sort of the array
|
|
312960
|
+
* * twist all edges together in sort order around each vertex
|
|
312961
|
+
* * This effectively creates valid face loops for a planar subdivision if there are no edge crossings.
|
|
312962
|
+
* * If there are edge crossings, the graph can be a (highly complicated) Klein bottle topology.
|
|
312963
|
+
* * [[HalfEdgeMask.NULL_FACE]] is cleared throughout and applied within null faces.
|
|
312964
|
+
* @param graph input graph
|
|
312965
|
+
* @param outboundRadiansFunction optional function to compute the sort angle of an edge at its start vertex
|
|
312966
|
+
* @param clusterTol optional distance tolerance for clustering vertices. Default value is [[Geometry.smallMetricDistance]].
|
|
312897
312967
|
*/
|
|
312898
312968
|
static clusterAndMergeXYTheta(graph, outboundRadiansFunction, clusterTol = _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallMetricDistance) {
|
|
312899
312969
|
const allNodes = graph.allHalfEdges;
|
|
@@ -312951,14 +313021,11 @@ class HalfEdgeGraphMerge {
|
|
|
312951
313021
|
const unmatchedNullFaceNodes = [];
|
|
312952
313022
|
k0 = 0;
|
|
312953
313023
|
let thetaA, thetaB;
|
|
312954
|
-
// GeometryCoreTestIO.consoleLog("START VERTEX LINKS");
|
|
312955
313024
|
// now pinch each neighboring pair together
|
|
312956
313025
|
for (let k1 = 0; k1 < numK; k1++) {
|
|
312957
313026
|
if (order[k1] === _numerics_ClusterableArray__WEBPACK_IMPORTED_MODULE_5__.ClusterableArray.clusterTerminator) {
|
|
312958
313027
|
// nodes identified in order[k0]..order[k1-1] are properly sorted around a vertex.
|
|
312959
313028
|
if (k1 > k0) {
|
|
312960
|
-
// const xy = clusters.getPoint2d(order[k0]);
|
|
312961
|
-
// GeometryCoreTestIO.consoleLog({ k0, k1, x: xy.x, y: xy.y });
|
|
312962
313029
|
if (k1 > k0 + 1)
|
|
312963
313030
|
this.secondarySortAroundVertex(clusters, order, allNodes, k0, k1);
|
|
312964
313031
|
this.doAnnounceVertexNeighborhood(clusters, order, allNodes, k0, k1);
|
|
@@ -337706,7 +337773,7 @@ class TestContext {
|
|
|
337706
337773
|
this.initializeRpcInterfaces({ title: this.settings.Backend.name, version: this.settings.Backend.version });
|
|
337707
337774
|
const iModelClient = new imodels_client_management_1.IModelsClient({ api: { baseUrl: `https://${process.env.IMJS_URL_PREFIX ?? ""}api.bentley.com/imodels` } });
|
|
337708
337775
|
await core_frontend_1.NoRenderApp.startup({
|
|
337709
|
-
applicationVersion: "5.2.
|
|
337776
|
+
applicationVersion: "5.2.1",
|
|
337710
337777
|
applicationId: this.settings.gprid,
|
|
337711
337778
|
authorizationClient: new frontend_1.TestFrontendAuthorizationClient(this.serviceAuthToken),
|
|
337712
337779
|
hubAccess: new imodels_access_frontend_1.FrontendIModelsAccess(iModelClient),
|
|
@@ -362973,7 +363040,7 @@ var loadLanguages = instance.loadLanguages;
|
|
|
362973
363040
|
/***/ ((module) => {
|
|
362974
363041
|
|
|
362975
363042
|
"use strict";
|
|
362976
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.2.
|
|
363043
|
+
module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.2.1","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs && npm run -s build:esm && npm run -s webpackWorkers && npm run -s copy:workers && npm run -s copy:draco","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2022 --outDir lib/esm","clean":"rimraf -g lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","copy:workers":"cpx \\"./lib/workers/webpack/parse-imdl-worker.js\\" ./lib/public/scripts","copy:draco":"cpx \\"./node_modules/@loaders.gl/draco/dist/libs/*\\" ./lib/public/scripts","docs":"betools docs --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-inline-config -c extraction.eslint.config.js \\"./src/**/*.ts\\" 1>&2","lint":"eslint \\"./src/**/*.ts\\" 1>&2","lint-fix":"eslint --fix -f visualstudio \\"./src/**/*.ts\\" 1>&2","lint-deprecation":"eslint --fix -f visualstudio --no-inline-config -c ../../common/config/eslint/eslint.config.deprecation-policy.js \\"./src/**/*.ts\\"","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run webpackTestWorker && vitest --run","cover":"npm run webpackTestWorker && vitest --run","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2 && npm run -s webpackTestWorker","webpackTestWorker":"webpack --config ./src/test/worker/webpack.config.js 1>&2 && cpx \\"./lib/test/test-worker.js\\" ./lib/test","webpackWorkers":"webpack --config ./src/workers/ImdlParser/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core.git","directory":"core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*","@itwin/eslint-plugin":"5.2.2-dev.2","@types/chai-as-promised":"^7","@types/draco3d":"^1.4.10","@types/sinon":"^17.0.2","@vitest/browser":"^3.0.6","@vitest/coverage-v8":"^3.0.6","cpx2":"^8.0.0","eslint":"^9.31.0","glob":"^10.3.12","playwright":"~1.47.1","rimraf":"^6.0.1","sinon":"^17.0.2","source-map-loader":"^5.0.0","typescript":"~5.6.2","typemoq":"^2.1.0","vitest":"^3.0.6","vite-multiple-assets":"^1.3.1","vite-plugin-static-copy":"2.2.0","webpack":"^5.97.1"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/cloud-agnostic-core":"^2.2.4","@itwin/object-storage-core":"^2.3.0","@itwin/core-i18n":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^4.3.4","@loaders.gl/draco":"^4.3.4","fuse.js":"^3.3.0","wms-capabilities":"0.4.0"}}');
|
|
362977
363044
|
|
|
362978
363045
|
/***/ }),
|
|
362979
363046
|
|