@itwin/ecschema-rpcinterface-tests 4.0.0-dev.6 → 4.0.0-dev.8
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/_07c5.bundled-tests.js.map +1 -1
- package/lib/dist/bundled-tests.js +2174 -613
- 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/object-storage.bundled-tests.js.map +1 -1
- package/lib/dist/vendors-common_temp_node_modules_pnpm_itwin_object-storage-azure_1_4_0_node_modules_itwin_obj-3576c6.bundled-tests.js.map +1 -1
- package/lib/dist/vendors-common_temp_node_modules_pnpm_loaders_gl_draco_3_2_13_node_modules_loaders_gl_draco_d-e0d984.bundled-tests.js.map +1 -1
- package/lib/dist/vendors-common_temp_node_modules_pnpm_reflect-metadata_0_1_13_node_modules_reflect-metadata_R-610cb3.bundled-tests.js.map +1 -1
- package/package.json +16 -16
|
@@ -190305,9 +190305,9 @@ class Geometry {
|
|
|
190305
190305
|
return 2 - ((-axis - 1) % 3);
|
|
190306
190306
|
}
|
|
190307
190307
|
/** Return the AxisOrder for which axisIndex is the first named axis.
|
|
190308
|
-
* * `axisIndex===0`returns AxisOrder.XYZ
|
|
190309
|
-
* * `axisIndex===1`returns AxisOrder.YZX
|
|
190310
|
-
* * `axisIndex===2`returns AxisOrder.ZXY
|
|
190308
|
+
* * `axisIndex === 0` returns `AxisOrder.XYZ`
|
|
190309
|
+
* * `axisIndex === 1` returns `AxisOrder.YZX`
|
|
190310
|
+
* * `axisIndex === 2` returns `AxisOrder.ZXY`
|
|
190311
190311
|
*/
|
|
190312
190312
|
static axisIndexToRightHandedAxisOrder(axisIndex) {
|
|
190313
190313
|
if (axisIndex === 0)
|
|
@@ -190319,7 +190319,9 @@ class Geometry {
|
|
|
190319
190319
|
return Geometry.axisIndexToRightHandedAxisOrder(Geometry.cyclic3dAxis(axisIndex));
|
|
190320
190320
|
}
|
|
190321
190321
|
/** Return the largest absolute distance from a to either of b0 or b1 */
|
|
190322
|
-
static maxAbsDiff(a, b0, b1) {
|
|
190322
|
+
static maxAbsDiff(a, b0, b1) {
|
|
190323
|
+
return Math.max(Math.abs(a - b0), Math.abs(a - b1));
|
|
190324
|
+
}
|
|
190323
190325
|
/** Return the largest absolute absolute value among x,y,z */
|
|
190324
190326
|
static maxAbsXYZ(x, y, z) {
|
|
190325
190327
|
return Geometry.maxXYZ(Math.abs(x), Math.abs(y), Math.abs(z));
|
|
@@ -190364,19 +190366,33 @@ class Geometry {
|
|
|
190364
190366
|
return q;
|
|
190365
190367
|
}
|
|
190366
190368
|
/** Return the hypotenuse `sqrt(x*x + y*y)`. This is much faster than `Math.hypot(x,y)`. */
|
|
190367
|
-
static hypotenuseXY(x, y) {
|
|
190369
|
+
static hypotenuseXY(x, y) {
|
|
190370
|
+
return Math.sqrt(x * x + y * y);
|
|
190371
|
+
}
|
|
190368
190372
|
/** Return the squared `hypotenuse (x*x + y*y)`. */
|
|
190369
|
-
static hypotenuseSquaredXY(x, y) {
|
|
190373
|
+
static hypotenuseSquaredXY(x, y) {
|
|
190374
|
+
return x * x + y * y;
|
|
190375
|
+
}
|
|
190370
190376
|
/** Return the square of x */
|
|
190371
|
-
static square(x) {
|
|
190377
|
+
static square(x) {
|
|
190378
|
+
return x * x;
|
|
190379
|
+
}
|
|
190372
190380
|
/** Return the hypotenuse `sqrt(x*x + y*y + z*z)`. This is much faster than `Math.hypot(x,y,z)`. */
|
|
190373
|
-
static hypotenuseXYZ(x, y, z) {
|
|
190381
|
+
static hypotenuseXYZ(x, y, z) {
|
|
190382
|
+
return Math.sqrt(x * x + y * y + z * z);
|
|
190383
|
+
}
|
|
190374
190384
|
/** Return the squared hypotenuse `(x*x + y*y + z*z)`. This is much faster than `Math.hypot(x,y,z)`. */
|
|
190375
|
-
static hypotenuseSquaredXYZ(x, y, z) {
|
|
190385
|
+
static hypotenuseSquaredXYZ(x, y, z) {
|
|
190386
|
+
return x * x + y * y + z * z;
|
|
190387
|
+
}
|
|
190376
190388
|
/** Return the (full 4d) hypotenuse `sqrt(x*x + y*y + z*z + w*w)`. This is much faster than `Math.hypot(x,y,z,w)`. */
|
|
190377
|
-
static hypotenuseXYZW(x, y, z, w) {
|
|
190389
|
+
static hypotenuseXYZW(x, y, z, w) {
|
|
190390
|
+
return Math.sqrt(x * x + y * y + z * z + w * w);
|
|
190391
|
+
}
|
|
190378
190392
|
/** Return the squared hypotenuse `(x*x + y*y + z*z+w*w)`. This is much faster than `Math.hypot(x,y,z)`. */
|
|
190379
|
-
static hypotenuseSquaredXYZW(x, y, z, w) {
|
|
190393
|
+
static hypotenuseSquaredXYZW(x, y, z, w) {
|
|
190394
|
+
return x * x + y * y + z * z + w * w;
|
|
190395
|
+
}
|
|
190380
190396
|
/**
|
|
190381
190397
|
* Return the distance between xy points given as numbers.
|
|
190382
190398
|
* @param x0 x coordinate of point 0
|
|
@@ -201233,6 +201249,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
201233
201249
|
/* harmony export */ "NewtonEvaluatorRtoRD": () => (/* reexport safe */ _numerics_Newton__WEBPACK_IMPORTED_MODULE_51__.NewtonEvaluatorRtoRD),
|
|
201234
201250
|
/* harmony export */ "NullGeometryHandler": () => (/* reexport safe */ _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODULE_8__.NullGeometryHandler),
|
|
201235
201251
|
/* harmony export */ "NumberArray": () => (/* reexport safe */ _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_23__.NumberArray),
|
|
201252
|
+
/* harmony export */ "OffsetMeshOptions": () => (/* reexport safe */ _polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_116__.OffsetMeshOptions),
|
|
201236
201253
|
/* harmony export */ "OffsetOptions": () => (/* reexport safe */ _curve_internalContexts_PolygonOffsetContext__WEBPACK_IMPORTED_MODULE_79__.OffsetOptions),
|
|
201237
201254
|
/* harmony export */ "Order2Bezier": () => (/* reexport safe */ _numerics_BezierPolynomials__WEBPACK_IMPORTED_MODULE_49__.Order2Bezier),
|
|
201238
201255
|
/* harmony export */ "Order3Bezier": () => (/* reexport safe */ _numerics_BezierPolynomials__WEBPACK_IMPORTED_MODULE_49__.Order3Bezier),
|
|
@@ -204244,11 +204261,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
204244
204261
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
204245
204262
|
/* harmony export */ "CurveCurve": () => (/* binding */ CurveCurve)
|
|
204246
204263
|
/* harmony export */ });
|
|
204247
|
-
/* harmony import */ var
|
|
204248
|
-
/* harmony import */ var
|
|
204249
|
-
/* harmony import */ var
|
|
204250
|
-
/* harmony import */ var
|
|
204251
|
-
/* harmony import */ var
|
|
204264
|
+
/* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
|
|
204265
|
+
/* harmony import */ var _CurveCollection__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./CurveCollection */ "../../core/geometry/lib/esm/curve/CurveCollection.js");
|
|
204266
|
+
/* harmony import */ var _CurveCurveCloseApproachXY__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./CurveCurveCloseApproachXY */ "../../core/geometry/lib/esm/curve/CurveCurveCloseApproachXY.js");
|
|
204267
|
+
/* harmony import */ var _CurveCurveIntersectXY__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./CurveCurveIntersectXY */ "../../core/geometry/lib/esm/curve/CurveCurveIntersectXY.js");
|
|
204268
|
+
/* harmony import */ var _CurveCurveIntersectXYZ__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./CurveCurveIntersectXYZ */ "../../core/geometry/lib/esm/curve/CurveCurveIntersectXYZ.js");
|
|
204269
|
+
/* harmony import */ var _CurvePrimitive__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./CurvePrimitive */ "../../core/geometry/lib/esm/curve/CurvePrimitive.js");
|
|
204252
204270
|
/*---------------------------------------------------------------------------------------------
|
|
204253
204271
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
204254
204272
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
@@ -204261,6 +204279,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
204261
204279
|
|
|
204262
204280
|
|
|
204263
204281
|
|
|
204282
|
+
|
|
204264
204283
|
/**
|
|
204265
204284
|
* `CurveCurve` has static method for various computations that work on a pair of curves or curve collections.
|
|
204266
204285
|
* @public
|
|
@@ -204268,17 +204287,18 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
204268
204287
|
class CurveCurve {
|
|
204269
204288
|
/**
|
|
204270
204289
|
* Return xy intersections of 2 curves.
|
|
204271
|
-
* @param geometryA
|
|
204290
|
+
* @param geometryA first geometry
|
|
204272
204291
|
* @param extendA true to allow geometryA to extend
|
|
204273
204292
|
* @param geometryB second geometry
|
|
204274
204293
|
* @param extendB true to allow geometryB to extend
|
|
204294
|
+
* @param tolerance optional distance tolerance for coincidence
|
|
204275
204295
|
*/
|
|
204276
|
-
static intersectionXYPairs(geometryA, extendA, geometryB, extendB) {
|
|
204277
|
-
const handler = new
|
|
204278
|
-
if (geometryB instanceof
|
|
204296
|
+
static intersectionXYPairs(geometryA, extendA, geometryB, extendB, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
|
|
204297
|
+
const handler = new _CurveCurveIntersectXY__WEBPACK_IMPORTED_MODULE_1__.CurveCurveIntersectXY(undefined, geometryA, extendA, geometryB, extendB, tolerance);
|
|
204298
|
+
if (geometryB instanceof _CurvePrimitive__WEBPACK_IMPORTED_MODULE_2__.CurvePrimitive) {
|
|
204279
204299
|
geometryA.dispatchToGeometryHandler(handler);
|
|
204280
204300
|
}
|
|
204281
|
-
else if (geometryB instanceof
|
|
204301
|
+
else if (geometryB instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_3__.CurveCollection) {
|
|
204282
204302
|
const allCurves = geometryB.collectCurvePrimitives();
|
|
204283
204303
|
for (const child of allCurves) {
|
|
204284
204304
|
handler.resetGeometry(geometryA, false, child, false);
|
|
@@ -204289,13 +204309,14 @@ class CurveCurve {
|
|
|
204289
204309
|
}
|
|
204290
204310
|
/**
|
|
204291
204311
|
* Return xy intersections of 2 projected curves
|
|
204292
|
-
* @param geometryA
|
|
204312
|
+
* @param geometryA first geometry
|
|
204293
204313
|
* @param extendA true to allow geometryA to extend
|
|
204294
204314
|
* @param geometryB second geometry
|
|
204295
204315
|
* @param extendB true to allow geometryB to extend
|
|
204316
|
+
* @param tolerance optional distance tolerance for coincidence
|
|
204296
204317
|
*/
|
|
204297
|
-
static intersectionProjectedXYPairs(worldToLocal, geometryA, extendA, geometryB, extendB) {
|
|
204298
|
-
const handler = new
|
|
204318
|
+
static intersectionProjectedXYPairs(worldToLocal, geometryA, extendA, geometryB, extendB, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
|
|
204319
|
+
const handler = new _CurveCurveIntersectXY__WEBPACK_IMPORTED_MODULE_1__.CurveCurveIntersectXY(worldToLocal, geometryA, extendA, geometryB, extendB, tolerance);
|
|
204299
204320
|
geometryA.dispatchToGeometryHandler(handler);
|
|
204300
204321
|
return handler.grabPairedResults();
|
|
204301
204322
|
}
|
|
@@ -204304,25 +204325,26 @@ class CurveCurve {
|
|
|
204304
204325
|
* * Implemented for combinations of LineSegment3d, LineString3d, Arc3d.
|
|
204305
204326
|
* * Not Implemented for bspline and bezier curves.
|
|
204306
204327
|
* @beta
|
|
204307
|
-
* @param geometryA
|
|
204328
|
+
* @param geometryA first geometry
|
|
204308
204329
|
* @param extendA true to allow geometryA to extend
|
|
204309
204330
|
* @param geometryB second geometry
|
|
204310
204331
|
* @param extendB true to allow geometryB to extend
|
|
204311
204332
|
*/
|
|
204312
204333
|
static intersectionXYZ(geometryA, extendA, geometryB, extendB) {
|
|
204313
|
-
const handler = new
|
|
204334
|
+
const handler = new _CurveCurveIntersectXYZ__WEBPACK_IMPORTED_MODULE_4__.CurveCurveIntersectXYZ(geometryA, extendA, geometryB, extendB);
|
|
204314
204335
|
geometryA.dispatchToGeometryHandler(handler);
|
|
204315
204336
|
return handler.grabResults();
|
|
204316
204337
|
}
|
|
204317
204338
|
/**
|
|
204318
204339
|
* Return xy intersections of 2 curves.
|
|
204319
|
-
* @param geometryA
|
|
204340
|
+
* @param geometryA first geometry
|
|
204320
204341
|
* @param extendA true to allow geometryA to extend
|
|
204321
204342
|
* @param geometryB second geometry
|
|
204322
204343
|
* @param extendB true to allow geometryB to extend
|
|
204344
|
+
* @param tolerance optional distance tolerance for coincidence
|
|
204323
204345
|
*/
|
|
204324
|
-
static allIntersectionsAmongPrimitivesXY(primitives) {
|
|
204325
|
-
const handler = new
|
|
204346
|
+
static allIntersectionsAmongPrimitivesXY(primitives, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
|
|
204347
|
+
const handler = new _CurveCurveIntersectXY__WEBPACK_IMPORTED_MODULE_1__.CurveCurveIntersectXY(undefined, undefined, false, undefined, false, tolerance);
|
|
204326
204348
|
for (let i = 0; i < primitives.length; i++) {
|
|
204327
204349
|
const geometryA = primitives[i];
|
|
204328
204350
|
for (let j = i + 1; j < primitives.length; j++) {
|
|
@@ -204334,11 +204356,11 @@ class CurveCurve {
|
|
|
204334
204356
|
}
|
|
204335
204357
|
/**
|
|
204336
204358
|
* Return xy close approaches of 2 projected curves
|
|
204337
|
-
* @param geometryA
|
|
204359
|
+
* @param geometryA first geometry
|
|
204338
204360
|
* @param geometryB second geometry
|
|
204339
204361
|
*/
|
|
204340
204362
|
static closeApproachProjectedXYPairs(geometryA, geometryB, maxDistance) {
|
|
204341
|
-
const handler = new
|
|
204363
|
+
const handler = new _CurveCurveCloseApproachXY__WEBPACK_IMPORTED_MODULE_5__.CurveCurveCloseApproachXY(geometryA, geometryB);
|
|
204342
204364
|
handler.maxDistanceToAccept = maxDistance;
|
|
204343
204365
|
geometryA.dispatchToGeometryHandler(handler);
|
|
204344
204366
|
return handler.grabPairedResults();
|
|
@@ -205107,8 +205129,8 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
205107
205129
|
/* harmony export */ "CurveLocationDetailArrayPair": () => (/* binding */ CurveLocationDetailArrayPair)
|
|
205108
205130
|
/* harmony export */ });
|
|
205109
205131
|
/* harmony import */ var _bspline_BSplineCurve__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../bspline/BSplineCurve */ "../../core/geometry/lib/esm/bspline/BSplineCurve.js");
|
|
205110
|
-
/* harmony import */ var
|
|
205111
|
-
/* harmony import */ var
|
|
205132
|
+
/* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
|
|
205133
|
+
/* harmony import */ var _geometry3d_CoincidentGeometryOps__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../geometry3d/CoincidentGeometryOps */ "../../core/geometry/lib/esm/geometry3d/CoincidentGeometryOps.js");
|
|
205112
205134
|
/* harmony import */ var _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../geometry3d/GeometryHandler */ "../../core/geometry/lib/esm/geometry3d/GeometryHandler.js");
|
|
205113
205135
|
/* harmony import */ var _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../geometry3d/GrowableFloat64Array */ "../../core/geometry/lib/esm/geometry3d/GrowableFloat64Array.js");
|
|
205114
205136
|
/* harmony import */ var _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../geometry3d/Matrix3d */ "../../core/geometry/lib/esm/geometry3d/Matrix3d.js");
|
|
@@ -205133,14 +205155,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
205133
205155
|
|
|
205134
205156
|
|
|
205135
205157
|
|
|
205136
|
-
// import { Arc3d } from "./Arc3d";
|
|
205137
205158
|
|
|
205138
205159
|
|
|
205139
205160
|
|
|
205140
205161
|
|
|
205141
205162
|
|
|
205142
205163
|
|
|
205143
|
-
// import { LineString3d } from "./LineString3d";
|
|
205144
205164
|
|
|
205145
205165
|
|
|
205146
205166
|
|
|
@@ -205193,8 +205213,9 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
205193
205213
|
* @param extendA flag to enable using extension of geometryA.
|
|
205194
205214
|
* @param geometryB second curve for intersection. Saved for reference by specific handler methods.
|
|
205195
205215
|
* @param extendB flag for extension of geometryB.
|
|
205216
|
+
* @param tolerance optional distance tolerance for coincidence
|
|
205196
205217
|
*/
|
|
205197
|
-
constructor(worldToLocal, _geometryA, extendA, geometryB, extendB) {
|
|
205218
|
+
constructor(worldToLocal, _geometryA, extendA, geometryB, extendB, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistance) {
|
|
205198
205219
|
super();
|
|
205199
205220
|
// this.geometryA = _geometryA;
|
|
205200
205221
|
this._extendA = extendA;
|
|
@@ -205207,7 +205228,7 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
205207
205228
|
if (!this._worldToLocalAffine)
|
|
205208
205229
|
this._worldToLocalPerspective = worldToLocal.clone();
|
|
205209
205230
|
}
|
|
205210
|
-
this._coincidentGeometryContext =
|
|
205231
|
+
this._coincidentGeometryContext = _geometry3d_CoincidentGeometryOps__WEBPACK_IMPORTED_MODULE_4__.CoincidentGeometryQuery.create(tolerance);
|
|
205211
205232
|
this.reinitialize();
|
|
205212
205233
|
}
|
|
205213
205234
|
reinitialize() {
|
|
@@ -205226,13 +205247,15 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
205226
205247
|
return false;
|
|
205227
205248
|
return true;
|
|
205228
205249
|
}
|
|
205229
|
-
|
|
205230
|
-
|
|
205250
|
+
/** Test the fraction by strict parameter, but allow toleranced distance test at ends.
|
|
205251
|
+
* @param tolerance optional distance tolerance to check proximity to start/end point
|
|
205252
|
+
*/
|
|
205253
|
+
acceptFractionOnLine(extend0, fraction, extend1, pointA, pointB, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistance) {
|
|
205231
205254
|
if (!extend0 && fraction < 0) {
|
|
205232
|
-
return
|
|
205255
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.isDistanceWithinTol(fraction * pointA.distanceXY(pointB), tolerance);
|
|
205233
205256
|
}
|
|
205234
205257
|
else if (!extend1 && fraction > 1.0)
|
|
205235
|
-
return
|
|
205258
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.isDistanceWithinTol((fraction - 1.0) * pointA.distanceXY(pointB), tolerance);
|
|
205236
205259
|
return true;
|
|
205237
205260
|
}
|
|
205238
205261
|
/**
|
|
@@ -205247,7 +205270,7 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
205247
205270
|
return result;
|
|
205248
205271
|
}
|
|
205249
205272
|
sameCurveAndFraction(cp, fraction, detail) {
|
|
205250
|
-
return cp === detail.curve &&
|
|
205273
|
+
return cp === detail.curve && _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.isAlmostEqualNumber(fraction, detail.fraction);
|
|
205251
205274
|
}
|
|
205252
205275
|
/** compute intersection of two line segments.
|
|
205253
205276
|
* filter by extension rules.
|
|
@@ -205259,14 +205282,14 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
205259
205282
|
let globalFractionA1, globalFractionB1;
|
|
205260
205283
|
const isInterval = intervalDetails !== undefined && intervalDetails.detailA.hasFraction1 && intervalDetails.detailB.hasFraction1;
|
|
205261
205284
|
if (isInterval) {
|
|
205262
|
-
globalFractionA =
|
|
205263
|
-
globalFractionB =
|
|
205264
|
-
globalFractionA1 =
|
|
205265
|
-
globalFractionB1 =
|
|
205285
|
+
globalFractionA = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionA0, intervalDetails.detailA.fraction, fractionA1);
|
|
205286
|
+
globalFractionB = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionB0, intervalDetails.detailB.fraction, fractionB1);
|
|
205287
|
+
globalFractionA1 = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionA0, intervalDetails.detailA.fraction1, fractionA1);
|
|
205288
|
+
globalFractionB1 = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionB0, intervalDetails.detailB.fraction1, fractionB1);
|
|
205266
205289
|
}
|
|
205267
205290
|
else {
|
|
205268
|
-
globalFractionA = globalFractionA1 =
|
|
205269
|
-
globalFractionB = globalFractionB1 =
|
|
205291
|
+
globalFractionA = globalFractionA1 = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionA0, localFractionA, fractionA1);
|
|
205292
|
+
globalFractionB = globalFractionB1 = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionB0, localFractionB, fractionB1);
|
|
205270
205293
|
}
|
|
205271
205294
|
// ignore duplicate of most recent point . ..
|
|
205272
205295
|
const numPrevious = this._results.length;
|
|
@@ -205328,8 +205351,8 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
205328
205351
|
this.recordPointWithLocalFractions(overlap.detailA.fraction, cpA, fractionA0, fractionA1, overlap.detailB.fraction, cpB, fractionB0, fractionB1, reversed, overlap);
|
|
205329
205352
|
}
|
|
205330
205353
|
else if (_numerics_Polynomials__WEBPACK_IMPORTED_MODULE_6__.SmallSystem.lineSegment3dXYTransverseIntersectionUnbounded(pointA0, pointA1, pointB0, pointB1, uv)) {
|
|
205331
|
-
if (this.acceptFractionOnLine(extendA0, uv.x, extendA1, pointA0, pointA1)
|
|
205332
|
-
&& this.acceptFractionOnLine(extendB0, uv.y, extendB1, pointB0, pointB1)) {
|
|
205354
|
+
if (this.acceptFractionOnLine(extendA0, uv.x, extendA1, pointA0, pointA1, this._coincidentGeometryContext.tolerance)
|
|
205355
|
+
&& this.acceptFractionOnLine(extendB0, uv.y, extendB1, pointB0, pointB1, this._coincidentGeometryContext.tolerance)) {
|
|
205333
205356
|
this.recordPointWithLocalFractions(uv.x, cpA, fractionA0, fractionA1, uv.y, cpB, fractionB0, fractionB1, reversed);
|
|
205334
205357
|
}
|
|
205335
205358
|
}
|
|
@@ -205387,9 +205410,9 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
205387
205410
|
const data = arc.toTransformedPoint4d(this._worldToLocalPerspective);
|
|
205388
205411
|
const pointA0H = this._worldToLocalPerspective.multiplyPoint3d(pointA0, 1);
|
|
205389
205412
|
const pointA1H = this._worldToLocalPerspective.multiplyPoint3d(pointA1, 1);
|
|
205390
|
-
const alpha =
|
|
205391
|
-
const beta =
|
|
205392
|
-
const gamma =
|
|
205413
|
+
const alpha = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.center);
|
|
205414
|
+
const beta = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.vector0);
|
|
205415
|
+
const gamma = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.vector90);
|
|
205393
205416
|
const cosines = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array(2);
|
|
205394
205417
|
const sines = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array(2);
|
|
205395
205418
|
const radians = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array(2);
|
|
@@ -205411,9 +205434,9 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
205411
205434
|
pointA0Local = this._worldToLocalAffine.multiplyPoint3d(pointA0);
|
|
205412
205435
|
pointA1Local = this._worldToLocalAffine.multiplyPoint3d(pointA1);
|
|
205413
205436
|
}
|
|
205414
|
-
const alpha =
|
|
205415
|
-
const beta =
|
|
205416
|
-
const gamma =
|
|
205437
|
+
const alpha = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.center, 1);
|
|
205438
|
+
const beta = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector0, 0);
|
|
205439
|
+
const gamma = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector90, 0);
|
|
205417
205440
|
const cosines = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array(2);
|
|
205418
205441
|
const sines = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array(2);
|
|
205419
205442
|
const radians = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array(2);
|
|
@@ -205638,8 +205661,8 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
205638
205661
|
let bezierBFraction = r;
|
|
205639
205662
|
bezierB.fractionToPoint4d(bezierBFraction, this._xyzwB);
|
|
205640
205663
|
const segmentAFraction = _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_6__.SmallSystem.lineSegment3dHXYClosestPointUnbounded(this._xyzwA0, this._xyzwA1, this._xyzwB);
|
|
205641
|
-
if (segmentAFraction &&
|
|
205642
|
-
let bezierAFraction =
|
|
205664
|
+
if (segmentAFraction && _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.isIn01WithTolerance(segmentAFraction, intervalTolerance)) {
|
|
205665
|
+
let bezierAFraction = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(f0, segmentAFraction, f1);
|
|
205643
205666
|
const xyMatchingFunction = new BezierBezierIntersectionXYRRToRRD(bezierA, bezierB);
|
|
205644
205667
|
const newtonSearcher = new _numerics_Newton__WEBPACK_IMPORTED_MODULE_0__.Newton2dUnboundedWithDerivative(xyMatchingFunction);
|
|
205645
205668
|
newtonSearcher.setUV(bezierAFraction, bezierBFraction);
|
|
@@ -219628,6 +219651,44 @@ class Angle {
|
|
|
219628
219651
|
const uDotV = ux * vx + uy * vy + uz * vz;
|
|
219629
219652
|
return Math.atan2(_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.crossProductMagnitude(ux, uy, uz, vx, vy, vz), uDotV);
|
|
219630
219653
|
}
|
|
219654
|
+
/**
|
|
219655
|
+
* * 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.
|
|
219656
|
+
* * The returned angle is (-PI < radians <= PI) or (0 <= radians < 2 * PI)
|
|
219657
|
+
* * The angle is in the plane of the U and V vectors.
|
|
219658
|
+
* * The upVector determines a positive side of the plane but need not be strictly perpendicular to the plane.
|
|
219659
|
+
*
|
|
219660
|
+
* @param ux x component of vector u
|
|
219661
|
+
* @param uy y component of vector u
|
|
219662
|
+
* @param uz z component of vector u
|
|
219663
|
+
* @param vx x component of vector v
|
|
219664
|
+
* @param vy y component of vector v
|
|
219665
|
+
* @param vz z component of vector v
|
|
219666
|
+
* @param upVectorX x component of vector to positive side of plane.
|
|
219667
|
+
* @param upVectorY y component of vector to positive side of plane.
|
|
219668
|
+
* @param upVectorZ z component of vector to positive side of plane.
|
|
219669
|
+
* @param adjustToAllPositive if true, return strictly non-negative sweep (0 <= radians < 2*PI). If false, return signed (-PI < radians <= PI)
|
|
219670
|
+
*/
|
|
219671
|
+
static orientedRadiansBetweenVectorsXYZ(ux, uy, uz, vx, vy, vz, upVectorX, upVectorY, upVectorZ, adjustToPositive = false) {
|
|
219672
|
+
const uDotV = ux * vx + uy * vy + uz * vz;
|
|
219673
|
+
const wx = uy * vz - uz * vy;
|
|
219674
|
+
const wy = uz * vx - ux * vz;
|
|
219675
|
+
const wz = ux * vy - uy * vx;
|
|
219676
|
+
const upDotW = upVectorX * wx + upVectorY * wy + upVectorZ * wz;
|
|
219677
|
+
const crossMagnitude = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(wx, wy, wz);
|
|
219678
|
+
if (upDotW < 0.0) {
|
|
219679
|
+
if (adjustToPositive) {
|
|
219680
|
+
// The turn is greater than 180 degrees. Take a peculiarly oriented atan2 to get the excess-180 part as addition to PI.
|
|
219681
|
+
// This gives the smoothest numerical transition passing PI.
|
|
219682
|
+
return Math.PI + Math.atan2(crossMagnitude, -uDotV);
|
|
219683
|
+
}
|
|
219684
|
+
else {
|
|
219685
|
+
return -Math.atan2(crossMagnitude, uDotV);
|
|
219686
|
+
}
|
|
219687
|
+
}
|
|
219688
|
+
else {
|
|
219689
|
+
return Math.atan2(crossMagnitude, uDotV);
|
|
219690
|
+
}
|
|
219691
|
+
}
|
|
219631
219692
|
/**
|
|
219632
219693
|
* Add a multiple of a full circle angle (360 degrees, 2PI) in place.
|
|
219633
219694
|
* @param multiple multiplier factor
|
|
@@ -220455,6 +220516,9 @@ class CoincidentGeometryQuery {
|
|
|
220455
220516
|
constructor(tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
|
|
220456
220517
|
this._tolerance = tolerance;
|
|
220457
220518
|
}
|
|
220519
|
+
get tolerance() {
|
|
220520
|
+
return this._tolerance;
|
|
220521
|
+
}
|
|
220458
220522
|
static create(tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
|
|
220459
220523
|
return new CoincidentGeometryQuery(tolerance);
|
|
220460
220524
|
}
|
|
@@ -225004,6 +225068,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
225004
225068
|
|
|
225005
225069
|
|
|
225006
225070
|
/* eslint-disable @itwin/prefer-get */
|
|
225071
|
+
// cSpell:words XXYZ YXYZ ZXYZ
|
|
225007
225072
|
/**
|
|
225008
225073
|
* PackedMatrix3dOps contains static methods for matrix operations where the matrix is a Float64Array.
|
|
225009
225074
|
* * The Float64Array contains the matrix entries in row-major order
|
|
@@ -225631,7 +225696,8 @@ class Matrix3d {
|
|
|
225631
225696
|
return undefined;
|
|
225632
225697
|
}
|
|
225633
225698
|
/**
|
|
225634
|
-
* Construct a rigid matrix using vectorA and its 2 perpendicular.
|
|
225699
|
+
* Construct a rigid matrix (orthogonal matrix with +1 determinant) using vectorA and its 2 perpendicular.
|
|
225700
|
+
* * If axisOrder is not passed then `AxisOrder = AxisOrder.ZXY` is used as default.
|
|
225635
225701
|
* * This function internally uses createPerpendicularVectorFavorXYPlane and createRigidFromColumns.
|
|
225636
225702
|
*/
|
|
225637
225703
|
static createRigidHeadsUp(vectorA, axisOrder = _Geometry__WEBPACK_IMPORTED_MODULE_0__.AxisOrder.ZXY, result) {
|
|
@@ -225643,7 +225709,7 @@ class Matrix3d {
|
|
|
225643
225709
|
}
|
|
225644
225710
|
return Matrix3d.createIdentity(result);
|
|
225645
225711
|
}
|
|
225646
|
-
/** Return the matrix for rotation of `angle` around `axis` */
|
|
225712
|
+
/** Return the matrix for rotation of `angle` around desired `axis` */
|
|
225647
225713
|
static createRotationAroundVector(axis, angle, result) {
|
|
225648
225714
|
// Rodriguez formula (matrix form), https://mathworld.wolfram.com/RodriguesRotationFormula.html
|
|
225649
225715
|
const c = angle.cos();
|
|
@@ -225657,7 +225723,7 @@ class Matrix3d {
|
|
|
225657
225723
|
}
|
|
225658
225724
|
return undefined;
|
|
225659
225725
|
}
|
|
225660
|
-
/** Returns a rotation of specified angle around
|
|
225726
|
+
/** Returns a rotation of specified angle around one of the main axis (X,Y,Z).
|
|
225661
225727
|
* @param axisIndex index of axis (AxisIndex.X, AxisIndex.Y, AxisIndex.Z) kept fixed by the rotation.
|
|
225662
225728
|
* @param angle angle of rotation
|
|
225663
225729
|
* @param result optional result matrix.
|
|
@@ -225680,14 +225746,33 @@ class Matrix3d {
|
|
|
225680
225746
|
return myResult;
|
|
225681
225747
|
}
|
|
225682
225748
|
/**
|
|
225683
|
-
|
|
225684
|
-
|
|
225685
|
-
|
|
225686
|
-
|
|
225687
|
-
|
|
225688
|
-
|
|
225689
|
-
|
|
225690
|
-
|
|
225749
|
+
* Replace current rows Ui and Uj with (c*Ui + s*Uj) and (c*Uj - s*Ui).
|
|
225750
|
+
* * There is no checking for i,j being 0,1,2.
|
|
225751
|
+
* @param i first row index. **must be 0,1,2** (unchecked)
|
|
225752
|
+
* @param j second row index. **must be 0,1,2** (unchecked)
|
|
225753
|
+
* @param c fist coefficient
|
|
225754
|
+
* @param s second coefficient
|
|
225755
|
+
*/
|
|
225756
|
+
applyGivensRowOp(i, j, c, s) {
|
|
225757
|
+
let ii = 3 * i;
|
|
225758
|
+
let jj = 3 * j;
|
|
225759
|
+
const limit = ii + 3;
|
|
225760
|
+
for (; ii < limit; ii++, jj++) {
|
|
225761
|
+
const a = this.coffs[ii];
|
|
225762
|
+
const b = this.coffs[jj];
|
|
225763
|
+
this.coffs[ii] = a * c + b * s;
|
|
225764
|
+
this.coffs[jj] = -a * s + b * c;
|
|
225765
|
+
}
|
|
225766
|
+
}
|
|
225767
|
+
/**
|
|
225768
|
+
* Replace current columns Ui and Uj with (c*Ui + s*Uj) and (c*Uj - s*Ui).
|
|
225769
|
+
* * There is no checking for i,j being 0,1,2.
|
|
225770
|
+
* * This is used in compute intensive inner loops
|
|
225771
|
+
* @param i first row index. **must be 0,1,2** (unchecked)
|
|
225772
|
+
* @param j second row index. **must be 0,1,2** (unchecked)
|
|
225773
|
+
* @param c fist coefficient
|
|
225774
|
+
* @param s second coefficient
|
|
225775
|
+
*/
|
|
225691
225776
|
applyGivensColumnOp(i, j, c, s) {
|
|
225692
225777
|
const limit = i + 9;
|
|
225693
225778
|
for (; i < limit; i += 3, j += 3) {
|
|
@@ -225698,12 +225783,12 @@ class Matrix3d {
|
|
|
225698
225783
|
}
|
|
225699
225784
|
}
|
|
225700
225785
|
/**
|
|
225701
|
-
|
|
225702
|
-
|
|
225703
|
-
|
|
225704
|
-
|
|
225705
|
-
|
|
225706
|
-
|
|
225786
|
+
* Create a matrix from column vectors.
|
|
225787
|
+
* ```
|
|
225788
|
+
* equation
|
|
225789
|
+
* \begin{bmatrix}U_x & V_x & W_x \\ U_y & V_y & W_y \\ U_z & V_z & W_z \end{bmatrix}
|
|
225790
|
+
* ```
|
|
225791
|
+
*/
|
|
225707
225792
|
static createColumns(vectorU, vectorV, vectorW, result) {
|
|
225708
225793
|
return Matrix3d.createRowValues(vectorU.x, vectorV.x, vectorW.x, vectorU.y, vectorV.y, vectorW.y, vectorU.z, vectorV.z, vectorW.z, result);
|
|
225709
225794
|
}
|
|
@@ -225720,8 +225805,9 @@ class Matrix3d {
|
|
|
225720
225805
|
* * ColumnX points in the rightVector direction
|
|
225721
225806
|
* * ColumnY points in the upVector direction
|
|
225722
225807
|
* * ColumnZ is a unit cross product of ColumnX and ColumnY.
|
|
225723
|
-
* * Optionally rotate
|
|
225724
|
-
* * Optionally rotate
|
|
225808
|
+
* * Optionally rotate by 45 degrees around `upVector` to bring its left or right vertical edge to center.
|
|
225809
|
+
* * Optionally rotate by arctan(1/sqrt(2)) ~ 35.264 degrees around `rightVector` to bring the top or bottom
|
|
225810
|
+
* horizontal edge of the view to the center (for isometric views).
|
|
225725
225811
|
* * This is expected to be used with various principal unit vectors that are perpendicular to each other.
|
|
225726
225812
|
* * STANDARD TOP VIEW: createViewedAxes(Vector3d.unitX(), Vector3d.unitY(), 0, 0)
|
|
225727
225813
|
* * STANDARD FRONT VIEW: createViewedAxes(Vector3d.unitX(), Vector3d.unitZ(), 0, 0)
|
|
@@ -225729,16 +225815,20 @@ class Matrix3d {
|
|
|
225729
225815
|
* * STANDARD RIGHT VIEW: createViewedAxes(Vector3d.unitY(), Vector3d.unitZ(), 0, 0)
|
|
225730
225816
|
* * STANDARD LEFT VIEW: createViewedAxes(Vector3d.unitY(-1), Vector3d.unitZ(), 0, 0)
|
|
225731
225817
|
* * STANDARD BOTTOM VIEW: createViewedAxes(Vector3d.unitX(), Vector3d.unitY(-1), 0, 0)
|
|
225818
|
+
* * STANDARD ISO VIEW: createViewedAxes(Vector3d.unitX(), Vector3d.unitZ(), -1, 1)
|
|
225819
|
+
* * STANDARD RIGHT ISO VIEW: createViewedAxes(Vector3d.unitX(), Vector3d.unitZ(), 1, 1)
|
|
225820
|
+
* * Front, right, back, left, top, and bottom standard views are views from faces of the cube
|
|
225821
|
+
* and iso and right iso standard views are views from corners of the cube.
|
|
225732
225822
|
* * Note: createViewedAxes is column-based so always returns local to world
|
|
225733
225823
|
*
|
|
225734
225824
|
* @param rightVector ColumnX of the returned matrix. Expected to be perpendicular to upVector.
|
|
225735
225825
|
* @param upVector ColumnY of the returned matrix. Expected to be perpendicular to rightVector.
|
|
225736
|
-
* @param leftNoneRight Specifies the ccw rotation around
|
|
225737
|
-
* "-1" indicates rotation by 45 degrees to bring the left vertical edge to center, "0" means no rotation,
|
|
225826
|
+
* @param leftNoneRight Specifies the ccw rotation around `upVector` axis. Normally one of "-1", "0", and "1",
|
|
225827
|
+
* where "-1" indicates rotation by 45 degrees to bring the left vertical edge to center, "0" means no rotation,
|
|
225738
225828
|
* and "1" indicates rotation by 45 degrees to bring the right vertical edge to center. Other numbers are
|
|
225739
225829
|
* used as multiplier for this 45 degree rotation.
|
|
225740
|
-
* @param topNoneBottom Specifies the ccw rotation around
|
|
225741
|
-
* "-1" indicates isometric rotation (35.264 degrees) to bring the bottom upward, "0" means no rotation,
|
|
225830
|
+
* @param topNoneBottom Specifies the ccw rotation around `rightVector` axis. Normally one of "-1", "0", and "1",
|
|
225831
|
+
* where "-1" indicates isometric rotation (35.264 degrees) to bring the bottom upward, "0" means no rotation,
|
|
225742
225832
|
* and "1" indicates isometric rotation (35.264 degrees) to bring the top downward. Other numbers are
|
|
225743
225833
|
* used as multiplier for the 35.264 degree rotation.
|
|
225744
225834
|
* @returns matrix = [rightVector, upVector, rightVector cross upVector] with the applied rotations specified
|
|
@@ -225776,9 +225866,11 @@ class Matrix3d {
|
|
|
225776
225866
|
* * Default is TOP view (`local X = world X`, `local Y = world Y`, `local Z = world Z`).
|
|
225777
225867
|
* * To change view from the TOP to one of the other 7 standard views, we need to multiply "world data" to
|
|
225778
225868
|
* the corresponding matrix1 provided by `createStandardWorldToView(index, false)` and then
|
|
225779
|
-
* `matrix1.multiply(world data)` will
|
|
225869
|
+
* `matrix1.multiply(world data)` will return "local data".
|
|
225780
225870
|
* * To change view back to the TOP, we need to multiply "local data" to the corresponding matrix2 provided
|
|
225781
225871
|
* by `createStandardWorldToView(index, true)` and then `matrix2.multiply(local data)` will returns "world data".
|
|
225872
|
+
* * Note: No matter how you rotate the world axis, local X is always pointing right, local Y is always pointing up,
|
|
225873
|
+
* and local Z is always pointing toward you.
|
|
225782
225874
|
*
|
|
225783
225875
|
* @param index standard view index `StandardViewIndex.Top, Bottom, Left, Right, Front, Back, Iso, RightIso`
|
|
225784
225876
|
* @param invert if false (default), the return matrix is world to local (view) and if true, the the return
|
|
@@ -225787,343 +225879,182 @@ class Matrix3d {
|
|
|
225787
225879
|
*/
|
|
225788
225880
|
static createStandardWorldToView(index, invert = false, result) {
|
|
225789
225881
|
switch (index) {
|
|
225790
|
-
//
|
|
225882
|
+
// Start with TOP view, ccw rotation by 180 degrees around X
|
|
225791
225883
|
case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Bottom:
|
|
225792
225884
|
result = Matrix3d.createRowValues(1, 0, 0, 0, -1, 0, 0, 0, -1);
|
|
225793
225885
|
break;
|
|
225794
|
-
//
|
|
225886
|
+
// Start with TOP view, ccw rotation by -90 degrees around X and by 90 degrees around Z
|
|
225795
225887
|
case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Left:
|
|
225796
225888
|
result = Matrix3d.createRowValues(0, -1, 0, 0, 0, 1, -1, 0, 0);
|
|
225797
225889
|
break;
|
|
225798
|
-
//
|
|
225890
|
+
// Start with TOP view, ccw rotation by -90 degrees around X and by -90 degrees around Z
|
|
225799
225891
|
case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Right:
|
|
225800
225892
|
result = Matrix3d.createRowValues(0, 1, 0, 0, 0, 1, 1, 0, 0);
|
|
225801
225893
|
break;
|
|
225802
|
-
//
|
|
225894
|
+
// Start with TOP view, ccw rotation by -90 degrees around X
|
|
225803
225895
|
case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Front:
|
|
225804
225896
|
result = Matrix3d.createRowValues(1, 0, 0, 0, 0, 1, 0, -1, 0);
|
|
225805
225897
|
break;
|
|
225806
|
-
//
|
|
225898
|
+
// Start with TOP view, ccw rotation by -90 degrees around X and by 180 degrees around Z
|
|
225807
225899
|
case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Back:
|
|
225808
225900
|
result = Matrix3d.createRowValues(-1, 0, 0, 0, 0, 1, 0, 1, 0);
|
|
225809
225901
|
break;
|
|
225902
|
+
/**
|
|
225903
|
+
* Isometric view
|
|
225904
|
+
* Start with FRONT view, ccw rotation by -45 degrees around Y and by arctan(1/sqrt(2)) ~ 35.264 degrees around X
|
|
225905
|
+
* cos(45) = 1/sqrt(2) = 0.70710678118 and sin(45) = 1/sqrt(2) = 0.70710678118
|
|
225906
|
+
* cos(35.264) = 2/sqrt(6) = 0.81649658092 and sin(35.264) = 1/sqrt(3) = 0.57735026919
|
|
225907
|
+
* More info: https://en.wikipedia.org/wiki/Isometric_projection
|
|
225908
|
+
*/
|
|
225810
225909
|
case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Iso:
|
|
225811
|
-
// start with FRONT view, ccw rotation by -45 degrees around Y and by 35.264 degrees around X
|
|
225812
225910
|
result = Matrix3d.createRowValues(0.707106781186548, -0.70710678118654757, 0.00000000000000000, 0.408248290463863, 0.40824829046386302, 0.81649658092772603, -0.577350269189626, -0.57735026918962573, 0.57735026918962573);
|
|
225813
225911
|
break;
|
|
225912
|
+
// Start with FRONT view, ccw rotation by 45 degrees around Y and by 35.264 degrees around X
|
|
225814
225913
|
case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.RightIso:
|
|
225815
225914
|
result = Matrix3d.createRowValues(0.707106781186548, 0.70710678118654757, 0.00000000000000000, -0.408248290463863, 0.40824829046386302, 0.81649658092772603, 0.577350269189626, -0.57735026918962573, 0.57735026918962573);
|
|
225816
225915
|
break;
|
|
225817
|
-
|
|
225916
|
+
// no rotation
|
|
225917
|
+
case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Top:
|
|
225818
225918
|
default:
|
|
225819
225919
|
result = Matrix3d.createIdentity(result);
|
|
225820
225920
|
}
|
|
225821
225921
|
if (invert)
|
|
225822
|
-
result.transposeInPlace();
|
|
225922
|
+
result.transposeInPlace(); // matrix is rigid so transpose and inverse are the same
|
|
225823
225923
|
return result;
|
|
225824
225924
|
}
|
|
225825
|
-
|
|
225826
|
-
|
|
225827
|
-
|
|
225828
|
-
|
|
225829
|
-
|
|
225830
|
-
|
|
225831
|
-
|
|
225832
|
-
|
|
225833
|
-
|
|
225834
|
-
|
|
225835
|
-
|
|
225836
|
-
|
|
225837
|
-
|
|
225838
|
-
|
|
225839
|
-
|
|
225840
|
-
|
|
225841
|
-
|
|
225842
|
-
|
|
225843
|
-
|
|
225844
|
-
|
|
225845
|
-
|
|
225846
|
-
|
|
225847
|
-
|
|
225848
|
-
|
|
225849
|
-
|
|
225850
|
-
|
|
225851
|
-
|
|
225852
|
-
|
|
225853
|
-
|
|
225854
|
-
|
|
225855
|
-
|
|
225856
|
-
|
|
225857
|
-
|
|
225858
|
-
|
|
225859
|
-
|
|
225860
|
-
|
|
225861
|
-
|
|
225862
|
-
|
|
225863
|
-
|
|
225864
|
-
|
|
225865
|
-
|
|
225866
|
-
|
|
225867
|
-
|
|
225868
|
-
|
|
225869
|
-
|
|
225870
|
-
|
|
225871
|
-
|
|
225872
|
-
|
|
225873
|
-
|
|
225874
|
-
|
|
225875
|
-
|
|
225876
|
-
|
|
225877
|
-
|
|
225878
|
-
|
|
225879
|
-
|
|
225880
|
-
|
|
225881
|
-
|
|
225882
|
-
|
|
225883
|
-
|
|
225884
|
-
|
|
225885
|
-
|
|
225886
|
-
|
|
225887
|
-
|
|
225888
|
-
result.error = !result.axis.tryNormalizeInPlace();
|
|
225889
|
-
return result
|
|
225925
|
+
/**
|
|
225926
|
+
* Apply (in place) a jacobi update that zeros out this.at(i,j).
|
|
225927
|
+
* @param i row index of zeroed member
|
|
225928
|
+
* @param j column index of zeroed member
|
|
225929
|
+
* @param k other row/column index (different from i and j)
|
|
225930
|
+
* @param leftEigenVectors a matrix that its columns will be filled by eigenvectors of this Matrix3d
|
|
225931
|
+
* (allocated by caller, computed and filled by this function)
|
|
225932
|
+
*/
|
|
225933
|
+
applyFastSymmetricJacobiUpdate(i, j, k, leftEigenVectors) {
|
|
225934
|
+
const indexII = 4 * i;
|
|
225935
|
+
const indexJJ = 4 * j;
|
|
225936
|
+
const indexIJ = 3 * i + j;
|
|
225937
|
+
const indexIK = 3 * i + k;
|
|
225938
|
+
const indexJK = 3 * j + k;
|
|
225939
|
+
const dotUU = this.coffs[indexII];
|
|
225940
|
+
const dotVV = this.coffs[indexJJ];
|
|
225941
|
+
const dotUV = this.coffs[indexIJ];
|
|
225942
|
+
const jacobi = _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.trigValuesToHalfAngleTrigValues(dotUU - dotVV, 2.0 * dotUV);
|
|
225943
|
+
if (Math.abs(dotUV) < 1.0e-15 * (dotUU + dotVV))
|
|
225944
|
+
return 0.0;
|
|
225945
|
+
const c = jacobi.c;
|
|
225946
|
+
const s = jacobi.s;
|
|
225947
|
+
const cc = c * c;
|
|
225948
|
+
const ss = s * s;
|
|
225949
|
+
const sc2 = 2.0 * c * s;
|
|
225950
|
+
this.coffs[indexII] = cc * dotUU + sc2 * dotUV + ss * dotVV;
|
|
225951
|
+
this.coffs[indexJJ] = ss * dotUU - sc2 * dotUV + cc * dotVV;
|
|
225952
|
+
this.coffs[indexIJ] = 0.0;
|
|
225953
|
+
const a = this.coffs[indexIK];
|
|
225954
|
+
const b = this.coffs[indexJK];
|
|
225955
|
+
this.coffs[indexIK] = a * c + b * s;
|
|
225956
|
+
this.coffs[indexJK] = -s * a + c * b;
|
|
225957
|
+
this.coffs[3 * j + i] = 0.0;
|
|
225958
|
+
this.coffs[3 * k + i] = this.coffs[indexIK];
|
|
225959
|
+
this.coffs[3 * k + j] = this.coffs[indexJK];
|
|
225960
|
+
leftEigenVectors.applyGivensColumnOp(i, j, c, s);
|
|
225961
|
+
return Math.abs(dotUV);
|
|
225962
|
+
}
|
|
225963
|
+
/**
|
|
225964
|
+
* Factor this (symmetrized) as a product U * lambda * UT where U is orthogonal, lambda is diagonal.
|
|
225965
|
+
* The upper triangle is mirrored to lower triangle to enforce symmetry.
|
|
225966
|
+
* @param leftEigenvectors a matrix that its columns will be filled by eigenvectors of this Matrix3d
|
|
225967
|
+
* (allocated by caller, computed and filled by this function)
|
|
225968
|
+
* @param lambda a vector that its entries will be filled by eigenvalues of this Matrix3d
|
|
225969
|
+
* (allocated by caller, computed and filled by this function)
|
|
225970
|
+
*/
|
|
225971
|
+
fastSymmetricEigenvalues(leftEigenvectors, lambda) {
|
|
225972
|
+
const matrix = this.clone();
|
|
225973
|
+
leftEigenvectors.setIdentity();
|
|
225974
|
+
const tolerance = 1.0e-12 * this.sumSquares();
|
|
225975
|
+
for (let iteration = 0; iteration < 7; iteration++) {
|
|
225976
|
+
const sum = matrix.applyFastSymmetricJacobiUpdate(0, 1, 2, leftEigenvectors)
|
|
225977
|
+
+ matrix.applyFastSymmetricJacobiUpdate(0, 2, 1, leftEigenvectors)
|
|
225978
|
+
+ matrix.applyFastSymmetricJacobiUpdate(1, 2, 0, leftEigenvectors);
|
|
225979
|
+
// console.log("symmetric sum", sum);
|
|
225980
|
+
// console.log ("sum", sum);
|
|
225981
|
+
if (sum < tolerance) {
|
|
225982
|
+
// console.log("symmetric iterations", iteration);
|
|
225983
|
+
lambda.set(matrix.at(0, 0), matrix.at(1, 1), matrix.at(2, 2));
|
|
225984
|
+
return true;
|
|
225985
|
+
}
|
|
225986
|
+
}
|
|
225987
|
+
return false;
|
|
225890
225988
|
}
|
|
225891
|
-
*/
|
|
225892
225989
|
/**
|
|
225893
225990
|
* Compute the (unit vector) axis and angle of rotation.
|
|
225991
|
+
* * math details can be found at docs/learning/geometry/Angle.md
|
|
225894
225992
|
* @returns Returns axis and angle of rotation with result.ok === true when the conversion succeeded.
|
|
225895
225993
|
*/
|
|
225896
225994
|
getAxisAndAngleOfRotation() {
|
|
225897
225995
|
const trace = this.coffs[0] + this.coffs[4] + this.coffs[8];
|
|
225898
|
-
|
|
225899
|
-
const
|
|
225900
|
-
const
|
|
225901
|
-
|
|
225902
|
-
const c = (trace - 1.0) / 2.0;
|
|
225903
|
-
const s = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(skewXY, skewYZ, skewZX) / 2.0;
|
|
225904
|
-
const e = c * c + s * s - 1.0;
|
|
225996
|
+
const skewXY = this.coffs[3] - this.coffs[1]; // 2*z*sin
|
|
225997
|
+
const skewYZ = this.coffs[7] - this.coffs[5]; // 2*y*sin
|
|
225998
|
+
const skewZX = this.coffs[2] - this.coffs[6]; // 2*x*sin
|
|
225999
|
+
// trace = (m00^2 + m11^2 + m22^2) * (1-cos) + 3cos = (1-cos) + 3cos = 1 + 2cos ==> cos = (trace-1) / 2
|
|
226000
|
+
const c = (trace - 1.0) / 2.0; // cosine
|
|
226001
|
+
const s = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(skewXY, skewYZ, skewZX) / 2.0; // sine
|
|
226002
|
+
const e = c * c + s * s - 1.0; // s^2 + c^2 = 1
|
|
226003
|
+
// if s^2 + c^2 != 1 then we have a bad matrix so return false
|
|
225905
226004
|
if (Math.abs(e) > _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallAngleRadians) {
|
|
225906
|
-
// the sine and cosine are not a unit circle point. bad matrix . ..
|
|
225907
226005
|
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(0), ok: false };
|
|
225908
226006
|
}
|
|
226007
|
+
// sin is close to 0 then we got to special cases (angle 0 or 180) which needs to be handled differently
|
|
225909
226008
|
if (Math.abs(s) < _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallAngleRadians) {
|
|
225910
|
-
//
|
|
225911
|
-
// The matrix is symmetric
|
|
225912
|
-
// So it has simple eigenvalues -- either (1,1,1) or (1,-1,-1).
|
|
225913
|
-
if (c > 0) // no rotation
|
|
226009
|
+
if (c > 0) // sin = 0 and cos = 1 so angle = 0 (i.e., no rotation)
|
|
225914
226010
|
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(0), ok: true };
|
|
225915
|
-
|
|
225916
|
-
|
|
225917
|
-
|
|
226011
|
+
/**
|
|
226012
|
+
* If sin = 0 and cos = -1 then angle = 180 (i.e., 180 degree rotation around some axis)
|
|
226013
|
+
* then the rotation matrix becomes
|
|
226014
|
+
* 2x^2-1 2xy 2xz
|
|
226015
|
+
* 2xy 2y^2-1 2yz
|
|
226016
|
+
* 2xz 2yz 2z^2-1
|
|
226017
|
+
* Note that the matrix is symmetric.
|
|
226018
|
+
* If rotation is around one the standard basis then non-diagonal entries become 0 and we
|
|
226019
|
+
* have one 1 and two -1s on the diagonal.
|
|
226020
|
+
* If rotation is around an axis other than standard basis, then the axis is the eigenvector
|
|
226021
|
+
* of the rotation matrix with eigenvalue = 1.
|
|
226022
|
+
*/
|
|
225918
226023
|
const axx = this.coffs[0];
|
|
225919
226024
|
const ayy = this.coffs[4];
|
|
225920
226025
|
const azz = this.coffs[8];
|
|
225921
|
-
|
|
225922
|
-
// Look for principal axis flips as a special case . ..
|
|
226026
|
+
// Look for a pair of "-1" entries on the diagonal (for rotation around the basis X,Y,Z axis)
|
|
225923
226027
|
if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1.0, ayy) && _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1, azz)) {
|
|
225924
|
-
|
|
225925
|
-
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(1, 0, 0), angle: theta180, ok: true };
|
|
226028
|
+
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(1, 0, 0), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createDegrees(180), ok: true };
|
|
225926
226029
|
}
|
|
225927
226030
|
else if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1.0, axx) && _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1, azz)) {
|
|
225928
|
-
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 1, 0), angle:
|
|
226031
|
+
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 1, 0), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createDegrees(180), ok: true };
|
|
225929
226032
|
}
|
|
225930
226033
|
else if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1.0, axx) && _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1, ayy)) {
|
|
225931
|
-
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle:
|
|
226034
|
+
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createDegrees(180), ok: true };
|
|
225932
226035
|
}
|
|
225933
|
-
//
|
|
225934
|
-
// eigenvalues will have 1.0 once, -1.0 twice.
|
|
225935
|
-
// These cases look for each place (x,y,z) that the 1.0 might appear.
|
|
225936
|
-
// But fastSymmetricEigenvalues reliably always seems to put the 1.0 as the x eigenvalue.
|
|
225937
|
-
// so only the getColumn(0) return seems reachable in unit tests.
|
|
226036
|
+
// Look for eigenvector with eigenvalue = 1
|
|
225938
226037
|
const eigenvectors = Matrix3d.createIdentity();
|
|
225939
226038
|
const eigenvalues = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 0);
|
|
225940
226039
|
if (this.fastSymmetricEigenvalues(eigenvectors, eigenvalues)) {
|
|
225941
226040
|
for (let axisIndex = 0; axisIndex < 2; axisIndex++) {
|
|
225942
226041
|
const lambda = eigenvalues.at(axisIndex);
|
|
225943
226042
|
if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(1, lambda))
|
|
225944
|
-
return { axis: eigenvectors.getColumn(axisIndex), angle:
|
|
226043
|
+
return { axis: eigenvectors.getColumn(axisIndex), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createDegrees(180), ok: true };
|
|
225945
226044
|
}
|
|
225946
|
-
//
|
|
226045
|
+
// if no eigenvalue = 1 was found return false
|
|
225947
226046
|
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(0), ok: false };
|
|
225948
226047
|
}
|
|
226048
|
+
// if no axis was found return false
|
|
225949
226049
|
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(0), ok: false };
|
|
225950
226050
|
}
|
|
226051
|
+
// good matrix and non-zero sine
|
|
225951
226052
|
const a = 1.0 / (2.0 * s);
|
|
225952
|
-
const result = {
|
|
225953
|
-
|
|
225954
|
-
|
|
225955
|
-
|
|
225956
|
-
|
|
225957
|
-
*/
|
|
225958
|
-
static createRotationVectorToVector(vectorA, vectorB, result) {
|
|
225959
|
-
return this.createPartialRotationVectorToVector(vectorA, 1.0, vectorB, result);
|
|
225960
|
-
}
|
|
225961
|
-
/**
|
|
225962
|
-
* Return a matrix that rotates a fraction of the angular sweep from vectorA to vectorB.
|
|
225963
|
-
* @param vectorA initial vector position
|
|
225964
|
-
* @param fraction fractional rotation. 1.0 is "all the way"
|
|
225965
|
-
* @param vectorB final vector position
|
|
225966
|
-
* @param result optional result matrix.
|
|
225967
|
-
*/
|
|
225968
|
-
static createPartialRotationVectorToVector(vectorA, fraction, vectorB, result) {
|
|
225969
|
-
let upVector = vectorA.unitCrossProduct(vectorB);
|
|
225970
|
-
if (upVector) { // the usual case --
|
|
225971
|
-
return Matrix3d.createRotationAroundVector(upVector, _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(fraction * vectorA.planarAngleTo(vectorB, upVector).radians));
|
|
225972
|
-
}
|
|
225973
|
-
// fail if either vector is zero ...
|
|
225974
|
-
if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(vectorA.magnitude())
|
|
225975
|
-
|| _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(vectorB.magnitude()))
|
|
225976
|
-
return undefined;
|
|
225977
|
-
// nonzero but aligned vectors ...
|
|
225978
|
-
if (vectorA.dotProduct(vectorB) > 0.0)
|
|
225979
|
-
return Matrix3d.createIdentity(result);
|
|
225980
|
-
// nonzero opposing vectors ..
|
|
225981
|
-
upVector = Matrix3d.createPerpendicularVectorFavorPlaneContainingZ(vectorA, upVector);
|
|
225982
|
-
return Matrix3d.createRotationAroundVector(upVector, _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(fraction * Math.PI));
|
|
225983
|
-
}
|
|
225984
|
-
/** Create a 90 degree rotation around a principal axis */
|
|
225985
|
-
static create90DegreeRotationAroundAxis(axisIndex) {
|
|
225986
|
-
axisIndex = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.cyclic3dAxis(axisIndex);
|
|
225987
|
-
if (axisIndex === 0) {
|
|
225988
|
-
const retVal = Matrix3d.createRowValues(1, 0, 0, 0, 0, -1, 0, 1, 0);
|
|
225989
|
-
retVal.setupInverseTranspose();
|
|
225990
|
-
return retVal;
|
|
225991
|
-
}
|
|
225992
|
-
else if (axisIndex === 1) {
|
|
225993
|
-
const retVal = Matrix3d.createRowValues(0, 0, 1, 0, 1, 0, -1, 0, 0);
|
|
225994
|
-
retVal.setupInverseTranspose();
|
|
225995
|
-
return retVal;
|
|
225996
|
-
}
|
|
225997
|
-
else {
|
|
225998
|
-
const retVal = Matrix3d.createRowValues(0, -1, 0, 1, 0, 0, 0, 0, 1);
|
|
225999
|
-
retVal.setupInverseTranspose();
|
|
226000
|
-
return retVal;
|
|
226001
|
-
}
|
|
226002
|
-
}
|
|
226003
|
-
/** Return (a copy of) the X column */
|
|
226004
|
-
columnX(result) { return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[0], this.coffs[3], this.coffs[6], result); }
|
|
226005
|
-
/** Return (a copy of)the Y column */
|
|
226006
|
-
columnY(result) { return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[1], this.coffs[4], this.coffs[7], result); }
|
|
226007
|
-
/** Return (a copy of)the Z column */
|
|
226008
|
-
columnZ(result) { return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[2], this.coffs[5], this.coffs[8], result); }
|
|
226009
|
-
/** Return the X column magnitude squared */
|
|
226010
|
-
columnXMagnitudeSquared() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[0], this.coffs[3], this.coffs[6]); }
|
|
226011
|
-
/** Return the Y column magnitude squared */
|
|
226012
|
-
columnYMagnitudeSquared() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[1], this.coffs[4], this.coffs[7]); }
|
|
226013
|
-
/** Return the Z column magnitude squared */
|
|
226014
|
-
columnZMagnitudeSquared() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[2], this.coffs[5], this.coffs[8]); }
|
|
226015
|
-
/** Return the X column magnitude */
|
|
226016
|
-
columnXMagnitude() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[0], this.coffs[3], this.coffs[6]); }
|
|
226017
|
-
/** Return the Y column magnitude */
|
|
226018
|
-
columnYMagnitude() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[1], this.coffs[4], this.coffs[7]); }
|
|
226019
|
-
/** Return the Z column magnitude */
|
|
226020
|
-
columnZMagnitude() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[2], this.coffs[5], this.coffs[8]); }
|
|
226021
|
-
/** Return magnitude of columnX cross columnY. */
|
|
226022
|
-
columnXYCrossProductMagnitude() {
|
|
226023
|
-
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.crossProductMagnitude(this.coffs[0], this.coffs[3], this.coffs[6], this.coffs[1], this.coffs[4], this.coffs[7]);
|
|
226024
|
-
}
|
|
226025
|
-
/** Return the X row magnitude d */
|
|
226026
|
-
rowXMagnitude() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[0], this.coffs[1], this.coffs[2]); }
|
|
226027
|
-
/** Return the Y row magnitude */
|
|
226028
|
-
rowYMagnitude() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[3], this.coffs[4], this.coffs[5]); }
|
|
226029
|
-
/** Return the Z row magnitude */
|
|
226030
|
-
rowZMagnitude() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[6], this.coffs[7], this.coffs[8]); }
|
|
226031
|
-
/** Return the dot product of column X with column Y */
|
|
226032
|
-
/** Return the dot product of column X with column Y */
|
|
226033
|
-
columnXDotColumnY() {
|
|
226034
|
-
return this.coffs[0] * this.coffs[1]
|
|
226035
|
-
+ this.coffs[3] * this.coffs[4]
|
|
226036
|
-
+ this.coffs[6] * this.coffs[7];
|
|
226037
|
-
}
|
|
226038
|
-
/**
|
|
226039
|
-
* Dot product of an indexed column with a vector given as x,y,z
|
|
226040
|
-
* @param columnIndex index of column. Must be 0,1,2
|
|
226041
|
-
* @param x x component of vector
|
|
226042
|
-
* @param y y component of vector
|
|
226043
|
-
* @param z z component of vector
|
|
226044
|
-
*/
|
|
226045
|
-
columnDotXYZ(columnIndex, x, y, z) {
|
|
226046
|
-
return this.coffs[columnIndex] * x + this.coffs[columnIndex + 3] * y + this.coffs[columnIndex + 6] * z;
|
|
226047
|
-
}
|
|
226048
|
-
/** Return (a copy of) the X row */
|
|
226049
|
-
rowX(result) { return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[0], this.coffs[1], this.coffs[2], result); }
|
|
226050
|
-
/** Return (a copy of) the Y row */
|
|
226051
|
-
rowY(result) { return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[3], this.coffs[4], this.coffs[5], result); }
|
|
226052
|
-
/** Return (a copy of) the Z row */
|
|
226053
|
-
rowZ(result) { return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[6], this.coffs[7], this.coffs[8], result); }
|
|
226054
|
-
/** Return the dot product of the vector parameter with the X column. */
|
|
226055
|
-
dotColumnX(vector) { return vector.x * this.coffs[0] + vector.y * this.coffs[3] + vector.z * this.coffs[6]; }
|
|
226056
|
-
/** Return the dot product of the vector parameter with the Y column. */
|
|
226057
|
-
dotColumnY(vector) { return vector.x * this.coffs[1] + vector.y * this.coffs[4] + vector.z * this.coffs[7]; }
|
|
226058
|
-
/** Return the dot product of the vector parameter with the Z column. */
|
|
226059
|
-
dotColumnZ(vector) { return vector.x * this.coffs[2] + vector.y * this.coffs[5] + vector.z * this.coffs[8]; }
|
|
226060
|
-
/** Return the dot product of the vector parameter with the X row. */
|
|
226061
|
-
dotRowX(vector) { return vector.x * this.coffs[0] + vector.y * this.coffs[1] + vector.z * this.coffs[2]; }
|
|
226062
|
-
/** Return the dot product of the vector parameter with the Y row. */
|
|
226063
|
-
dotRowY(vector) { return vector.x * this.coffs[3] + vector.y * this.coffs[4] + vector.z * this.coffs[5]; }
|
|
226064
|
-
/** Return the dot product of the vector parameter with the Z row. */
|
|
226065
|
-
dotRowZ(vector) { return vector.x * this.coffs[6] + vector.y * this.coffs[7] + vector.z * this.coffs[8]; }
|
|
226066
|
-
// cSpell:words XXYZ YXYZ ZXYZ XYZAs Eigen
|
|
226067
|
-
/** Return the dot product of the x,y,z with the X row. */
|
|
226068
|
-
dotRowXXYZ(x, y, z) { return x * this.coffs[0] + y * this.coffs[1] + z * this.coffs[2]; }
|
|
226069
|
-
/** Return the dot product of the x,y,z with the Y row. */
|
|
226070
|
-
dotRowYXYZ(x, y, z) { return x * this.coffs[3] + y * this.coffs[4] + z * this.coffs[5]; }
|
|
226071
|
-
/** Return the dot product of the x,y,z with the Z row. */
|
|
226072
|
-
dotRowZXYZ(x, y, z) { return x * this.coffs[6] + y * this.coffs[7] + z * this.coffs[8]; }
|
|
226073
|
-
/** Return the (vector) cross product of the Z column with the vector parameter. */
|
|
226074
|
-
columnZCrossVector(vector, result) {
|
|
226075
|
-
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.crossProductXYZXYZ(this.coffs[2], this.coffs[5], this.coffs[8], vector.x, vector.y, vector.z, result);
|
|
226076
|
-
}
|
|
226077
|
-
/*
|
|
226078
|
-
* Replace current rows Ui Uj with (c*Ui - s*Uj) and (c*Uj + s*Ui).
|
|
226079
|
-
* @param i first row index. must be 0,1,2 (unchecked)
|
|
226080
|
-
* @param j second row index. must be 0,1,2 (unchecked)
|
|
226081
|
-
* @param c fist coefficient
|
|
226082
|
-
* @param s second coefficient
|
|
226083
|
-
*/
|
|
226084
|
-
applyGivensRowOp(i, j, c, s) {
|
|
226085
|
-
let ii = 3 * i;
|
|
226086
|
-
let jj = 3 * j;
|
|
226087
|
-
const limit = ii + 3;
|
|
226088
|
-
for (; ii < limit; ii++, jj++) {
|
|
226089
|
-
const a = this.coffs[ii];
|
|
226090
|
-
const b = this.coffs[jj];
|
|
226091
|
-
this.coffs[ii] = a * c + b * s;
|
|
226092
|
-
this.coffs[jj] = -a * s + b * c;
|
|
226093
|
-
}
|
|
226094
|
-
}
|
|
226095
|
-
/**
|
|
226096
|
-
* create a rigid coordinate frame column z parallel to (_x_,_y_,_z_) and column x in the xy plane.
|
|
226097
|
-
* * column z points from origin to x,y,z
|
|
226098
|
-
* * column x is perpendicular and in the xy plane
|
|
226099
|
-
* * column y is perpendicular to both. It is the "up" vector on the view plane.
|
|
226100
|
-
* * Multiplying a world vector times the transpose of this matrix transforms into the view xy
|
|
226101
|
-
* * Multiplying the matrix times the an in-view vector transforms the vector to world.
|
|
226102
|
-
* @param x eye x coordinate
|
|
226103
|
-
* @param y eye y coordinate
|
|
226104
|
-
* @param z eye z coordinate
|
|
226105
|
-
* @param result
|
|
226106
|
-
*/
|
|
226107
|
-
static createRigidViewAxesZTowardsEye(x, y, z, result) {
|
|
226108
|
-
result = Matrix3d.createIdentity(result);
|
|
226109
|
-
const rxy = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXY(x, y);
|
|
226110
|
-
if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(rxy)) {
|
|
226111
|
-
// special case for top or bottom view.
|
|
226112
|
-
if (z < 0.0)
|
|
226113
|
-
result.scaleColumnsInPlace(1.0, -1, -1.0);
|
|
226114
|
-
}
|
|
226115
|
-
else {
|
|
226116
|
-
// const d = Geometry.hypotenuseSquaredXYZ(x, y, z);
|
|
226117
|
-
const c = x / rxy;
|
|
226118
|
-
const s = y / rxy;
|
|
226119
|
-
result.setRowValues(-s, 0, c, c, 0, s, 0, 1, 0);
|
|
226120
|
-
if (z !== 0.0) {
|
|
226121
|
-
const r = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(x, y, z);
|
|
226122
|
-
const s1 = z / r;
|
|
226123
|
-
const c1 = rxy / r;
|
|
226124
|
-
result.applyGivensColumnOp(1, 2, c1, -s1);
|
|
226125
|
-
}
|
|
226126
|
-
}
|
|
226053
|
+
const result = {
|
|
226054
|
+
axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(skewYZ * a, skewZX * a, skewXY * a),
|
|
226055
|
+
angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createAtan2(s, c),
|
|
226056
|
+
ok: true,
|
|
226057
|
+
};
|
|
226127
226058
|
return result;
|
|
226128
226059
|
}
|
|
226129
226060
|
/** Rotate so columns i and j become perpendicular */
|
|
@@ -226155,8 +226086,7 @@ class Matrix3d {
|
|
|
226155
226086
|
factorPerpendicularColumns(matrixC, matrixU) {
|
|
226156
226087
|
matrixC.setFrom(this);
|
|
226157
226088
|
matrixU.setIdentity();
|
|
226158
|
-
const
|
|
226159
|
-
const tolerance = 1.0e-12 * ss;
|
|
226089
|
+
const tolerance = 1.0e-12 * this.sumSquares();
|
|
226160
226090
|
for (let iteration = 0; iteration < 7; iteration++) {
|
|
226161
226091
|
const sum = matrixC.applyJacobiColumnRotation(0, 1, matrixU)
|
|
226162
226092
|
+ matrixC.applyJacobiColumnRotation(0, 2, matrixU)
|
|
@@ -226247,8 +226177,7 @@ class Matrix3d {
|
|
|
226247
226177
|
matrix.coffs[3] = matrix.coffs[1];
|
|
226248
226178
|
matrix.coffs[6] = matrix.coffs[2];
|
|
226249
226179
|
matrix.coffs[7] = matrix.coffs[5];
|
|
226250
|
-
const
|
|
226251
|
-
const tolerance = 1.0e-12 * ss;
|
|
226180
|
+
const tolerance = 1.0e-12 * this.sumSquares();
|
|
226252
226181
|
for (let iteration = 0; iteration < 7; iteration++) {
|
|
226253
226182
|
const sum = leftEigenvectors.applySymmetricJacobi(0, 1, matrix)
|
|
226254
226183
|
+ leftEigenvectors.applySymmetricJacobi(0, 2, matrix)
|
|
@@ -226263,68 +226192,174 @@ class Matrix3d {
|
|
|
226263
226192
|
}
|
|
226264
226193
|
return false;
|
|
226265
226194
|
}
|
|
226266
|
-
/**
|
|
226267
|
-
*
|
|
226195
|
+
/**
|
|
226196
|
+
* Return a matrix that rotates a fraction of the angular sweep from vectorA to vectorB.
|
|
226197
|
+
* @param vectorA initial vector position
|
|
226198
|
+
* @param fraction fractional rotation (1 means rotate all the way)
|
|
226199
|
+
* @param vectorB final vector position
|
|
226200
|
+
* @param result optional result matrix.
|
|
226268
226201
|
*/
|
|
226269
|
-
|
|
226270
|
-
|
|
226271
|
-
|
|
226272
|
-
|
|
226273
|
-
|
|
226274
|
-
|
|
226275
|
-
|
|
226276
|
-
|
|
226277
|
-
|
|
226278
|
-
|
|
226279
|
-
|
|
226280
|
-
|
|
226281
|
-
|
|
226282
|
-
|
|
226283
|
-
|
|
226284
|
-
|
|
226285
|
-
|
|
226286
|
-
|
|
226287
|
-
|
|
226288
|
-
|
|
226289
|
-
|
|
226290
|
-
|
|
226291
|
-
|
|
226292
|
-
|
|
226293
|
-
|
|
226294
|
-
|
|
226295
|
-
|
|
226296
|
-
|
|
226297
|
-
|
|
226298
|
-
|
|
226299
|
-
|
|
226300
|
-
|
|
226202
|
+
static createPartialRotationVectorToVector(vectorA, fraction, vectorB, result) {
|
|
226203
|
+
let upVector = vectorA.unitCrossProduct(vectorB);
|
|
226204
|
+
// the usual case (both vectors and also their cross product is non-zero)
|
|
226205
|
+
if (upVector) {
|
|
226206
|
+
return Matrix3d.createRotationAroundVector(upVector, _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(fraction * vectorA.planarAngleTo(vectorB, upVector).radians));
|
|
226207
|
+
}
|
|
226208
|
+
// if either vector is zero
|
|
226209
|
+
if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(vectorA.magnitude())
|
|
226210
|
+
|| _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(vectorB.magnitude()))
|
|
226211
|
+
return undefined;
|
|
226212
|
+
// aligned vectors (cross product = 0, dot product > 0)
|
|
226213
|
+
if (vectorA.dotProduct(vectorB) > 0.0)
|
|
226214
|
+
return Matrix3d.createIdentity(result);
|
|
226215
|
+
// opposing vectors (cross product = 0, dot product < 0)
|
|
226216
|
+
upVector = Matrix3d.createPerpendicularVectorFavorPlaneContainingZ(vectorA, upVector);
|
|
226217
|
+
return Matrix3d.createRotationAroundVector(upVector, _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(fraction * Math.PI));
|
|
226218
|
+
}
|
|
226219
|
+
/** Returns a matrix that rotates from vectorA to vectorB. */
|
|
226220
|
+
static createRotationVectorToVector(vectorA, vectorB, result) {
|
|
226221
|
+
return this.createPartialRotationVectorToVector(vectorA, 1.0, vectorB, result);
|
|
226222
|
+
}
|
|
226223
|
+
/** Create a 90 degree rotation around a principal axis */
|
|
226224
|
+
static create90DegreeRotationAroundAxis(axisIndex) {
|
|
226225
|
+
axisIndex = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.cyclic3dAxis(axisIndex);
|
|
226226
|
+
if (axisIndex === 0) {
|
|
226227
|
+
const retVal = Matrix3d.createRowValues(1, 0, 0, 0, 0, -1, 0, 1, 0);
|
|
226228
|
+
retVal.setupInverseTranspose();
|
|
226229
|
+
return retVal;
|
|
226230
|
+
}
|
|
226231
|
+
else if (axisIndex === 1) {
|
|
226232
|
+
const retVal = Matrix3d.createRowValues(0, 0, 1, 0, 1, 0, -1, 0, 0);
|
|
226233
|
+
retVal.setupInverseTranspose();
|
|
226234
|
+
return retVal;
|
|
226235
|
+
}
|
|
226236
|
+
else {
|
|
226237
|
+
const retVal = Matrix3d.createRowValues(0, -1, 0, 1, 0, 0, 0, 0, 1);
|
|
226238
|
+
retVal.setupInverseTranspose();
|
|
226239
|
+
return retVal;
|
|
226240
|
+
}
|
|
226241
|
+
}
|
|
226242
|
+
/** Return (a copy of) the X column */
|
|
226243
|
+
columnX(result) {
|
|
226244
|
+
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[0], this.coffs[3], this.coffs[6], result);
|
|
226245
|
+
}
|
|
226246
|
+
/** Return (a copy of) the Y column */
|
|
226247
|
+
columnY(result) {
|
|
226248
|
+
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[1], this.coffs[4], this.coffs[7], result);
|
|
226249
|
+
}
|
|
226250
|
+
/** Return (a copy of) the Z column */
|
|
226251
|
+
columnZ(result) {
|
|
226252
|
+
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[2], this.coffs[5], this.coffs[8], result);
|
|
226253
|
+
}
|
|
226254
|
+
/** Return the X column magnitude squared */
|
|
226255
|
+
columnXMagnitudeSquared() {
|
|
226256
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[0], this.coffs[3], this.coffs[6]);
|
|
226257
|
+
}
|
|
226258
|
+
/** Return the Y column magnitude squared */
|
|
226259
|
+
columnYMagnitudeSquared() {
|
|
226260
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[1], this.coffs[4], this.coffs[7]);
|
|
226261
|
+
}
|
|
226262
|
+
/** Return the Z column magnitude squared */
|
|
226263
|
+
columnZMagnitudeSquared() {
|
|
226264
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[2], this.coffs[5], this.coffs[8]);
|
|
226265
|
+
}
|
|
226266
|
+
/** Return the X column magnitude */
|
|
226267
|
+
columnXMagnitude() {
|
|
226268
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[0], this.coffs[3], this.coffs[6]);
|
|
226269
|
+
}
|
|
226270
|
+
/** Return the Y column magnitude */
|
|
226271
|
+
columnYMagnitude() {
|
|
226272
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[1], this.coffs[4], this.coffs[7]);
|
|
226273
|
+
}
|
|
226274
|
+
/** Return the Z column magnitude */
|
|
226275
|
+
columnZMagnitude() {
|
|
226276
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[2], this.coffs[5], this.coffs[8]);
|
|
226277
|
+
}
|
|
226278
|
+
/** Return magnitude of columnX cross columnY. */
|
|
226279
|
+
columnXYCrossProductMagnitude() {
|
|
226280
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.crossProductMagnitude(this.coffs[0], this.coffs[3], this.coffs[6], this.coffs[1], this.coffs[4], this.coffs[7]);
|
|
226281
|
+
}
|
|
226282
|
+
/** Return the X row magnitude */
|
|
226283
|
+
rowXMagnitude() {
|
|
226284
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[0], this.coffs[1], this.coffs[2]);
|
|
226285
|
+
}
|
|
226286
|
+
/** Return the Y row magnitude */
|
|
226287
|
+
rowYMagnitude() {
|
|
226288
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[3], this.coffs[4], this.coffs[5]);
|
|
226289
|
+
}
|
|
226290
|
+
/** Return the Z row magnitude */
|
|
226291
|
+
rowZMagnitude() {
|
|
226292
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[6], this.coffs[7], this.coffs[8]);
|
|
226293
|
+
}
|
|
226294
|
+
/** Return the dot product of column X with column Y */
|
|
226295
|
+
columnXDotColumnY() {
|
|
226296
|
+
return this.coffs[0] * this.coffs[1]
|
|
226297
|
+
+ this.coffs[3] * this.coffs[4]
|
|
226298
|
+
+ this.coffs[6] * this.coffs[7];
|
|
226301
226299
|
}
|
|
226302
226300
|
/**
|
|
226303
|
-
*
|
|
226304
|
-
*
|
|
226305
|
-
* @param
|
|
226306
|
-
* @param
|
|
226301
|
+
* Dot product of an indexed column with a vector given as x,y,z
|
|
226302
|
+
* @param columnIndex index of column. Must be 0,1,2.
|
|
226303
|
+
* @param x x component of vector
|
|
226304
|
+
* @param y y component of vector
|
|
226305
|
+
* @param z z component of vector
|
|
226307
226306
|
*/
|
|
226308
|
-
|
|
226309
|
-
|
|
226310
|
-
|
|
226311
|
-
|
|
226312
|
-
|
|
226313
|
-
|
|
226314
|
-
|
|
226315
|
-
|
|
226316
|
-
|
|
226317
|
-
|
|
226318
|
-
|
|
226319
|
-
|
|
226320
|
-
|
|
226321
|
-
|
|
226322
|
-
return true;
|
|
226323
|
-
}
|
|
226324
|
-
}
|
|
226325
|
-
return false;
|
|
226307
|
+
columnDotXYZ(columnIndex, x, y, z) {
|
|
226308
|
+
return this.coffs[columnIndex] * x + this.coffs[columnIndex + 3] * y + this.coffs[columnIndex + 6] * z;
|
|
226309
|
+
}
|
|
226310
|
+
/** Return (a copy of) the X row */
|
|
226311
|
+
rowX(result) {
|
|
226312
|
+
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[0], this.coffs[1], this.coffs[2], result);
|
|
226313
|
+
}
|
|
226314
|
+
/** Return (a copy of) the Y row */
|
|
226315
|
+
rowY(result) {
|
|
226316
|
+
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[3], this.coffs[4], this.coffs[5], result);
|
|
226317
|
+
}
|
|
226318
|
+
/** Return (a copy of) the Z row */
|
|
226319
|
+
rowZ(result) {
|
|
226320
|
+
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[6], this.coffs[7], this.coffs[8], result);
|
|
226326
226321
|
}
|
|
226327
|
-
/**
|
|
226322
|
+
/** Return the dot product of the vector parameter with the X column. */
|
|
226323
|
+
dotColumnX(vector) {
|
|
226324
|
+
return vector.x * this.coffs[0] + vector.y * this.coffs[3] + vector.z * this.coffs[6];
|
|
226325
|
+
}
|
|
226326
|
+
/** Return the dot product of the vector parameter with the Y column. */
|
|
226327
|
+
dotColumnY(vector) {
|
|
226328
|
+
return vector.x * this.coffs[1] + vector.y * this.coffs[4] + vector.z * this.coffs[7];
|
|
226329
|
+
}
|
|
226330
|
+
/** Return the dot product of the vector parameter with the Z column. */
|
|
226331
|
+
dotColumnZ(vector) {
|
|
226332
|
+
return vector.x * this.coffs[2] + vector.y * this.coffs[5] + vector.z * this.coffs[8];
|
|
226333
|
+
}
|
|
226334
|
+
/** Return the dot product of the vector parameter with the X row. */
|
|
226335
|
+
dotRowX(vector) {
|
|
226336
|
+
return vector.x * this.coffs[0] + vector.y * this.coffs[1] + vector.z * this.coffs[2];
|
|
226337
|
+
}
|
|
226338
|
+
/** Return the dot product of the vector parameter with the Y row. */
|
|
226339
|
+
dotRowY(vector) {
|
|
226340
|
+
return vector.x * this.coffs[3] + vector.y * this.coffs[4] + vector.z * this.coffs[5];
|
|
226341
|
+
}
|
|
226342
|
+
/** Return the dot product of the vector parameter with the Z row. */
|
|
226343
|
+
dotRowZ(vector) {
|
|
226344
|
+
return vector.x * this.coffs[6] + vector.y * this.coffs[7] + vector.z * this.coffs[8];
|
|
226345
|
+
}
|
|
226346
|
+
/** Return the dot product of the x,y,z with the X row. */
|
|
226347
|
+
dotRowXXYZ(x, y, z) {
|
|
226348
|
+
return x * this.coffs[0] + y * this.coffs[1] + z * this.coffs[2];
|
|
226349
|
+
}
|
|
226350
|
+
/** Return the dot product of the x,y,z with the Y row. */
|
|
226351
|
+
dotRowYXYZ(x, y, z) {
|
|
226352
|
+
return x * this.coffs[3] + y * this.coffs[4] + z * this.coffs[5];
|
|
226353
|
+
}
|
|
226354
|
+
/** Return the dot product of the x,y,z with the Z row. */
|
|
226355
|
+
dotRowZXYZ(x, y, z) {
|
|
226356
|
+
return x * this.coffs[6] + y * this.coffs[7] + z * this.coffs[8];
|
|
226357
|
+
}
|
|
226358
|
+
/** Return the cross product of the Z column with the vector parameter. */
|
|
226359
|
+
columnZCrossVector(vector, result) {
|
|
226360
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.crossProductXYZXYZ(this.coffs[2], this.coffs[5], this.coffs[8], vector.x, vector.y, vector.z, result);
|
|
226361
|
+
}
|
|
226362
|
+
/** Set data from xyz parts of Point4d (w part of Point4d ignored) */
|
|
226328
226363
|
setColumnsPoint4dXYZ(vectorU, vectorV, vectorW) {
|
|
226329
226364
|
this.inverseState = InverseMatrixState.unknown;
|
|
226330
226365
|
this.setRowValues(vectorU.x, vectorV.x, vectorW.x, vectorU.y, vectorV.y, vectorW.y, vectorU.z, vectorV.z, vectorW.z);
|
|
@@ -226348,16 +226383,22 @@ class Matrix3d {
|
|
|
226348
226383
|
this.coffs[index + 6] = 0.0;
|
|
226349
226384
|
}
|
|
226350
226385
|
}
|
|
226351
|
-
/**
|
|
226386
|
+
/**
|
|
226387
|
+
* Set all columns of the matrix. Any undefined vector is zeros.
|
|
226388
|
+
* @param vectorX values for column 0
|
|
226389
|
+
* @param vectorY values for column 1
|
|
226390
|
+
* @param vectorZ optional values for column 2 (it's optional in case column 2 is 000, which is a
|
|
226391
|
+
* projection onto the xy-plane)
|
|
226392
|
+
*/
|
|
226352
226393
|
setColumns(vectorX, vectorY, vectorZ) {
|
|
226353
226394
|
this.setColumn(0, vectorX);
|
|
226354
226395
|
this.setColumn(1, vectorY);
|
|
226355
226396
|
this.setColumn(2, vectorZ);
|
|
226356
226397
|
}
|
|
226357
226398
|
/**
|
|
226358
|
-
*
|
|
226359
|
-
* @param rowIndex row index.
|
|
226360
|
-
* @param value x,
|
|
226399
|
+
* Set entries in one row of the matrix.
|
|
226400
|
+
* @param rowIndex row index. This is interpreted cyclically (using Geometry.cyclic3dAxis).
|
|
226401
|
+
* @param value x,y,z values for row.
|
|
226361
226402
|
*/
|
|
226362
226403
|
setRow(rowIndex, value) {
|
|
226363
226404
|
const index = 3 * _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.cyclic3dAxis(rowIndex);
|
|
@@ -226366,21 +226407,26 @@ class Matrix3d {
|
|
|
226366
226407
|
this.coffs[index + 2] = value.z;
|
|
226367
226408
|
this.inverseState = InverseMatrixState.unknown;
|
|
226368
226409
|
}
|
|
226369
|
-
/**
|
|
226370
|
-
*
|
|
226410
|
+
/**
|
|
226411
|
+
* Return (a copy of) a column of the matrix.
|
|
226412
|
+
* @param i column index. This is interpreted cyclically (using Geometry.cyclic3dAxis).
|
|
226413
|
+
* @param result optional preallocated result.
|
|
226371
226414
|
*/
|
|
226372
226415
|
getColumn(columnIndex, result) {
|
|
226373
226416
|
const index = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.cyclic3dAxis(columnIndex);
|
|
226374
226417
|
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[index], this.coffs[index + 3], this.coffs[index + 6], result);
|
|
226375
226418
|
}
|
|
226376
|
-
/**
|
|
226377
|
-
*
|
|
226419
|
+
/**
|
|
226420
|
+
* Return a (copy of) a row of the matrix.
|
|
226421
|
+
* @param i row index. This is interpreted cyclically (using Geometry.cyclic3dAxis).
|
|
226422
|
+
* @param result optional preallocated result.
|
|
226378
226423
|
*/
|
|
226379
226424
|
getRow(columnIndex, result) {
|
|
226380
226425
|
const index = 3 * _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.cyclic3dAxis(columnIndex);
|
|
226381
226426
|
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[index], this.coffs[index + 1], this.coffs[index + 2], result);
|
|
226382
226427
|
}
|
|
226383
|
-
/**
|
|
226428
|
+
/**
|
|
226429
|
+
* Create a matrix from row vectors.
|
|
226384
226430
|
* ```
|
|
226385
226431
|
* equation
|
|
226386
226432
|
* \begin{bmatrix}U_x & U_y & U_z \\ V_x & V_y & V_z \\ W_x & W_y & W_z \end{bmatrix}
|
|
@@ -226389,13 +226435,18 @@ class Matrix3d {
|
|
|
226389
226435
|
static createRows(vectorU, vectorV, vectorW, result) {
|
|
226390
226436
|
return Matrix3d.createRowValues(vectorU.x, vectorU.y, vectorU.z, vectorV.x, vectorV.y, vectorV.z, vectorW.x, vectorW.y, vectorW.z, result);
|
|
226391
226437
|
}
|
|
226392
|
-
/**
|
|
226393
|
-
*
|
|
226394
|
-
*
|
|
226438
|
+
/**
|
|
226439
|
+
* Create a matrix that scales along a specified `direction`. This means if you multiply the returned matrix
|
|
226440
|
+
* by a `vector`, you get `directional scale` of that `vector`. Suppose `plane` is the plane perpendicular
|
|
226441
|
+
* to the `direction`. When scale = 0, `directional scale` is projection of the `vector` to the `plane`.
|
|
226442
|
+
* When scale = 1, `directional scale` is the `vector` itself. When scale = -1, `directional scale` is
|
|
226443
|
+
* mirror of the `vector` across the `plane`. In general, When scale != 0, the result is computed by first
|
|
226444
|
+
* projecting the `vector` to the `plane`, then translating that projection along the `direction` (if scale > 0)
|
|
226445
|
+
* or in opposite direction (if scale < 0).
|
|
226395
226446
|
* ```
|
|
226396
226447
|
* equation
|
|
226397
|
-
* \text{The matrix is } I
|
|
226398
|
-
* \\ \text{with }
|
|
226448
|
+
* \text{The matrix is } I + (s-1) D D^T
|
|
226449
|
+
* \\ \text{with }D\text{ being the normalized direction vector and }s\text{ being the scale.}
|
|
226399
226450
|
* ```
|
|
226400
226451
|
*/
|
|
226401
226452
|
static createDirectionalScale(direction, scale, result) {
|
|
@@ -226404,19 +226455,13 @@ class Matrix3d {
|
|
|
226404
226455
|
const x = unit.x;
|
|
226405
226456
|
const y = unit.y;
|
|
226406
226457
|
const z = unit.z;
|
|
226407
|
-
const a =
|
|
226458
|
+
const a = scale - 1;
|
|
226408
226459
|
return Matrix3d.createRowValues(1 + a * x * x, a * x * y, a * x * z, a * y * x, 1 + a * y * y, a * y * z, a * z * x, a * z * y, 1 + a * z * z, result);
|
|
226409
226460
|
}
|
|
226410
226461
|
return Matrix3d.createUniformScale(scale);
|
|
226411
226462
|
}
|
|
226412
|
-
|
|
226413
|
-
* *
|
|
226414
|
-
* * If the direction vector is not close to Z, the "next" column ((axisIndex + 1) mod 3) will be in the XY plane in the direction of (direction cross Z)
|
|
226415
|
-
* * If the direction vector is close to Z, the "next" column ((axisIndex + 1) mode 3) will be in the direction of (direction cross Y)
|
|
226416
|
-
*/
|
|
226417
|
-
// static create1Vector(direction: Vector3d, axisIndex: number): Matrix3d;
|
|
226418
|
-
// static createFromXYVectors(vectorX: Vector3d, vectorY: Vector3d, axisIndex: number): Matrix3d;
|
|
226419
|
-
/** Multiply the matrix * vector, treating the vector is a column vector on the right.
|
|
226463
|
+
/**
|
|
226464
|
+
* Multiply `matrix * vector`, treating the vector is a column vector on the right.
|
|
226420
226465
|
* ```
|
|
226421
226466
|
* equation
|
|
226422
226467
|
* \matrixXY{A}\columnSubXYZ{U}
|
|
@@ -226427,36 +226472,38 @@ class Matrix3d {
|
|
|
226427
226472
|
const x = vectorU.x;
|
|
226428
226473
|
const y = vectorU.y;
|
|
226429
226474
|
const z = vectorU.z;
|
|
226430
|
-
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(
|
|
226475
|
+
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[0] * x + this.coffs[1] * y + this.coffs[2] * z, this.coffs[3] * x + this.coffs[4] * y + this.coffs[5] * z, this.coffs[6] * x + this.coffs[7] * y + this.coffs[8] * z, result);
|
|
226431
226476
|
}
|
|
226432
|
-
/**
|
|
226433
|
-
*
|
|
226477
|
+
/**
|
|
226478
|
+
* Multiply `matrix * vector` in place for vector in the array, i.e. treating the vector is a column
|
|
226479
|
+
* vector on the right.
|
|
226480
|
+
* * Each `vector` is updated to be `matrix * vector`
|
|
226434
226481
|
*/
|
|
226435
226482
|
multiplyVectorArrayInPlace(data) {
|
|
226436
226483
|
for (const v of data)
|
|
226437
|
-
v.set(
|
|
226484
|
+
v.set(this.coffs[0] * v.x + this.coffs[1] * v.y + this.coffs[2] * v.z, this.coffs[3] * v.x + this.coffs[4] * v.y + this.coffs[5] * v.z, this.coffs[6] * v.x + this.coffs[7] * v.y + this.coffs[8] * v.z);
|
|
226438
226485
|
}
|
|
226439
|
-
/**
|
|
226486
|
+
/** Compute `origin - matrix * vector` */
|
|
226440
226487
|
static xyzMinusMatrixTimesXYZ(origin, matrix, vector, result) {
|
|
226441
226488
|
const x = vector.x;
|
|
226442
226489
|
const y = vector.y;
|
|
226443
226490
|
const z = vector.z;
|
|
226444
226491
|
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(origin.x - (matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z), origin.y - (matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z), origin.z - (matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z), result);
|
|
226445
226492
|
}
|
|
226446
|
-
/**
|
|
226493
|
+
/** Compute `origin + matrix * vector` using only the xy parts of the inputs. */
|
|
226447
226494
|
static xyPlusMatrixTimesXY(origin, matrix, vector, result) {
|
|
226448
226495
|
const x = vector.x;
|
|
226449
226496
|
const y = vector.y;
|
|
226450
226497
|
return _Point2dVector2d__WEBPACK_IMPORTED_MODULE_3__.Point2d.create(origin.x + matrix.coffs[0] * x + matrix.coffs[1] * y, origin.y + matrix.coffs[3] * x + matrix.coffs[4] * y, result);
|
|
226451
226498
|
}
|
|
226452
|
-
/**
|
|
226499
|
+
/** Compute `origin + matrix * vector` using all xyz parts of the inputs. */
|
|
226453
226500
|
static xyzPlusMatrixTimesXYZ(origin, matrix, vector, result) {
|
|
226454
226501
|
const x = vector.x;
|
|
226455
226502
|
const y = vector.y;
|
|
226456
226503
|
const z = vector.z;
|
|
226457
226504
|
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(origin.x + matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z, origin.y + matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z, origin.z + matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z, result);
|
|
226458
226505
|
}
|
|
226459
|
-
/**
|
|
226506
|
+
/** Updates vector to be `origin + matrix * vector` using all xyz parts of the inputs. */
|
|
226460
226507
|
static xyzPlusMatrixTimesXYZInPlace(origin, matrix, vector) {
|
|
226461
226508
|
const x = vector.x;
|
|
226462
226509
|
const y = vector.y;
|
|
@@ -226465,61 +226512,72 @@ class Matrix3d {
|
|
|
226465
226512
|
vector.y = origin.y + matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z;
|
|
226466
226513
|
vector.z = origin.z + matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z;
|
|
226467
226514
|
}
|
|
226468
|
-
/**
|
|
226515
|
+
/** Compute `origin + matrix * vector` where the final vector is given as direct x,y,z coordinates */
|
|
226469
226516
|
static xyzPlusMatrixTimesCoordinates(origin, matrix, x, y, z, result) {
|
|
226470
226517
|
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(origin.x + matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z, origin.y + matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z, origin.z + matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z, result);
|
|
226471
226518
|
}
|
|
226472
226519
|
/**
|
|
226473
226520
|
* Treat the 3x3 matrix and origin as upper 3x4 part of a 4x4 matrix, with 0001 as the final row.
|
|
226474
|
-
* Multiply
|
|
226521
|
+
* Multiply the 4x4 matrix by `[x,y,z,w]`
|
|
226522
|
+
* ```
|
|
226523
|
+
* equation
|
|
226524
|
+
* \begin{bmatrix}M_0 & M_1 & M_2 & Ox \\ M_3 & M_4 & M_5 & Oy \\ M_6 & M_7 & M_8 & Oz \\ 0 & 0 & 0 & 1\end{bmatrix} * \begin{bmatrix}x \\ y \\ z \\ w\end{bmatrix}
|
|
226525
|
+
* ```
|
|
226475
226526
|
* @param origin translation part (xyz in column 3)
|
|
226476
226527
|
* @param matrix matrix part (leading 3x3)
|
|
226477
226528
|
* @param x x part of multiplied point
|
|
226478
226529
|
* @param y y part of multiplied point
|
|
226479
226530
|
* @param z z part of multiplied point
|
|
226480
226531
|
* @param w w part of multiplied point
|
|
226481
|
-
* @param result optional result.
|
|
226532
|
+
* @param result optional preallocated result.
|
|
226482
226533
|
*/
|
|
226483
226534
|
static xyzPlusMatrixTimesWeightedCoordinates(origin, matrix, x, y, z, w, result) {
|
|
226484
|
-
return _geometry4d_Point4d__WEBPACK_IMPORTED_MODULE_4__.Point4d.create(
|
|
226535
|
+
return _geometry4d_Point4d__WEBPACK_IMPORTED_MODULE_4__.Point4d.create(matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z + origin.x * w, matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z + origin.y * w, matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z + origin.z * w, w, result);
|
|
226485
226536
|
}
|
|
226486
226537
|
/**
|
|
226487
226538
|
* Treat the 3x3 matrix and origin as upper 3x4 part of a 4x4 matrix, with 0001 as the final row.
|
|
226488
|
-
* Multiply
|
|
226539
|
+
* Multiply the 4x4 matrix by `[x,y,z,w]`
|
|
226540
|
+
* ```
|
|
226541
|
+
* equation
|
|
226542
|
+
* \begin{bmatrix}M_0 & M_1 & M_2 & Ox \\ M_3 & M_4 & M_5 & Oy \\ M_6 & M_7 & M_8 & Oz \\ 0 & 0 & 0 & 1\end{bmatrix} * \begin{bmatrix}x \\ y \\ z \\ w\end{bmatrix}
|
|
226543
|
+
* ```
|
|
226489
226544
|
* @param origin translation part (xyz in column 3)
|
|
226490
226545
|
* @param matrix matrix part (leading 3x3)
|
|
226491
226546
|
* @param x x part of multiplied point
|
|
226492
226547
|
* @param y y part of multiplied point
|
|
226493
226548
|
* @param z z part of multiplied point
|
|
226494
226549
|
* @param w w part of multiplied point
|
|
226495
|
-
* @param result optional result.
|
|
226550
|
+
* @param result optional preallocated result.
|
|
226496
226551
|
*/
|
|
226497
226552
|
static xyzPlusMatrixTimesWeightedCoordinatesToFloat64Array(origin, matrix, x, y, z, w, result) {
|
|
226498
226553
|
if (!result)
|
|
226499
226554
|
result = new Float64Array(4);
|
|
226500
|
-
result[0] =
|
|
226501
|
-
result[1] =
|
|
226502
|
-
result[2] =
|
|
226555
|
+
result[0] = matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z + origin.x * w;
|
|
226556
|
+
result[1] = matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z + origin.y * w;
|
|
226557
|
+
result[2] = matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z + origin.z * w;
|
|
226503
226558
|
result[3] = w;
|
|
226504
226559
|
return result;
|
|
226505
226560
|
}
|
|
226506
226561
|
/**
|
|
226507
|
-
* Treat the 3x3 matrix and origin as
|
|
226508
|
-
* Multiply
|
|
226562
|
+
* Treat the 3x3 matrix and origin as a 3x4 matrix.
|
|
226563
|
+
* * Multiply the 3x4 matrix by `[x,y,z,1]`
|
|
226564
|
+
* ```
|
|
226565
|
+
* equation
|
|
226566
|
+
* \begin{bmatrix}M_0 & M_1 & M_2 & Ox \\ M_3 & M_4 & M_5 & Oy \\ M_6 & M_7 & M_8 & Oz\end{bmatrix} * \begin{bmatrix}x \\ y \\ z \\ 1\end{bmatrix}
|
|
226567
|
+
* ```
|
|
226509
226568
|
* @param origin translation part (xyz in column 3)
|
|
226510
226569
|
* @param matrix matrix part (leading 3x3)
|
|
226511
226570
|
* @param x x part of multiplied point
|
|
226512
226571
|
* @param y y part of multiplied point
|
|
226513
226572
|
* @param z z part of multiplied point
|
|
226514
|
-
* @param
|
|
226515
|
-
* @param result optional result.
|
|
226573
|
+
* @param result optional preallocated result.
|
|
226516
226574
|
*/
|
|
226517
226575
|
static xyzPlusMatrixTimesCoordinatesToFloat64Array(origin, matrix, x, y, z, result) {
|
|
226518
226576
|
if (!result)
|
|
226519
226577
|
result = new Float64Array(3);
|
|
226520
|
-
result[0] =
|
|
226521
|
-
result[1] =
|
|
226522
|
-
result[2] =
|
|
226578
|
+
result[0] = matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z + origin.x;
|
|
226579
|
+
result[1] = matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z + origin.y;
|
|
226580
|
+
result[2] = matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z + origin.z;
|
|
226523
226581
|
return result;
|
|
226524
226582
|
}
|
|
226525
226583
|
/**
|
|
@@ -226539,9 +226597,9 @@ class Matrix3d {
|
|
|
226539
226597
|
const x = vector.x;
|
|
226540
226598
|
const y = vector.y;
|
|
226541
226599
|
const z = vector.z;
|
|
226542
|
-
result.x =
|
|
226543
|
-
result.y =
|
|
226544
|
-
result.z =
|
|
226600
|
+
result.x = this.coffs[0] * x + this.coffs[3] * y + this.coffs[6] * z;
|
|
226601
|
+
result.y = this.coffs[1] * x + this.coffs[4] * y + this.coffs[7] * z;
|
|
226602
|
+
result.z = this.coffs[2] * x + this.coffs[5] * y + this.coffs[8] * z;
|
|
226545
226603
|
return result;
|
|
226546
226604
|
}
|
|
226547
226605
|
/** Multiply the matrix * (x,y,z), i.e. the vector (x,y,z) is a column vector on the right.
|
|
@@ -227069,7 +227127,7 @@ class Matrix3d {
|
|
|
227069
227127
|
* @param scaleX scale factor for column x
|
|
227070
227128
|
* @param scaleY scale factor for column y
|
|
227071
227129
|
* @param scaleZ scale factor for column z
|
|
227072
|
-
* @param result optional result.
|
|
227130
|
+
* @param result optional preallocated result.
|
|
227073
227131
|
*/
|
|
227074
227132
|
scaleColumns(scaleX, scaleY, scaleZ, result) {
|
|
227075
227133
|
return Matrix3d.createRowValues(this.coffs[0] * scaleX, this.coffs[1] * scaleY, this.coffs[2] * scaleZ, this.coffs[3] * scaleX, this.coffs[4] * scaleY, this.coffs[5] * scaleZ, this.coffs[6] * scaleX, this.coffs[7] * scaleY, this.coffs[8] * scaleZ, result);
|
|
@@ -227090,7 +227148,7 @@ class Matrix3d {
|
|
|
227090
227148
|
this.coffs[7] *= scaleY;
|
|
227091
227149
|
this.coffs[8] *= scaleZ;
|
|
227092
227150
|
if (this.inverseState === InverseMatrixState.inverseStored && this.inverseCoffs !== undefined) {
|
|
227093
|
-
// apply
|
|
227151
|
+
// apply reverse scales to the ROWS of the inverse
|
|
227094
227152
|
const divX = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.conditionalDivideFraction(1.0, scaleX);
|
|
227095
227153
|
const divY = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.conditionalDivideFraction(1.0, scaleY);
|
|
227096
227154
|
const divZ = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.conditionalDivideFraction(1.0, scaleZ);
|
|
@@ -227113,7 +227171,7 @@ class Matrix3d {
|
|
|
227113
227171
|
* @param scaleX scale factor for row x
|
|
227114
227172
|
* @param scaleY scale factor for row y
|
|
227115
227173
|
* @param scaleZ scale factor for row z
|
|
227116
|
-
* @param result optional result.
|
|
227174
|
+
* @param result optional preallocated result.
|
|
227117
227175
|
*/
|
|
227118
227176
|
scaleRows(scaleX, scaleY, scaleZ, result) {
|
|
227119
227177
|
return Matrix3d.createRowValues(this.coffs[0] * scaleX, this.coffs[1] * scaleX, this.coffs[2] * scaleX, this.coffs[3] * scaleY, this.coffs[4] * scaleY, this.coffs[5] * scaleY, this.coffs[6] * scaleZ, this.coffs[7] * scaleZ, this.coffs[8] * scaleZ, result);
|
|
@@ -227157,12 +227215,49 @@ class Matrix3d {
|
|
|
227157
227215
|
}
|
|
227158
227216
|
/** create a Matrix3d whose values are uniformly scaled from this.
|
|
227159
227217
|
* @param scale scale factor to apply.
|
|
227160
|
-
* @param result optional result.
|
|
227218
|
+
* @param result optional preallocated result.
|
|
227161
227219
|
* @returns Return the new or repopulated matrix
|
|
227162
227220
|
*/
|
|
227163
227221
|
scale(scale, result) {
|
|
227164
227222
|
return Matrix3d.createRowValues(this.coffs[0] * scale, this.coffs[1] * scale, this.coffs[2] * scale, this.coffs[3] * scale, this.coffs[4] * scale, this.coffs[5] * scale, this.coffs[6] * scale, this.coffs[7] * scale, this.coffs[8] * scale, result);
|
|
227165
227223
|
}
|
|
227224
|
+
/**
|
|
227225
|
+
* Create a rigid matrix (columns and rows are unit length and pairwise perpendicular) for
|
|
227226
|
+
* the given eye coordinate.
|
|
227227
|
+
* * column z is parallel to x,y,z
|
|
227228
|
+
* * column x is perpendicular to column z and is in the xy plane
|
|
227229
|
+
* * column y is perpendicular to both. It is the "up" vector on the view plane.
|
|
227230
|
+
* * Multiplying the returned matrix times a local (view) vector gives the world vector.
|
|
227231
|
+
* * Multiplying transpose of the returned matrix times a world vector gives the local
|
|
227232
|
+
* (view) vector.
|
|
227233
|
+
* @param x eye x coordinate
|
|
227234
|
+
* @param y eye y coordinate
|
|
227235
|
+
* @param z eye z coordinate
|
|
227236
|
+
* @param result optional preallocated result
|
|
227237
|
+
*/
|
|
227238
|
+
static createRigidViewAxesZTowardsEye(x, y, z, result) {
|
|
227239
|
+
result = Matrix3d.createIdentity(result);
|
|
227240
|
+
const rxy = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXY(x, y);
|
|
227241
|
+
// if coordinate is (0,0,z), i.e., Top or Bottom view
|
|
227242
|
+
if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(rxy)) {
|
|
227243
|
+
if (z < 0.0)
|
|
227244
|
+
result.scaleColumnsInPlace(1.0, -1.0, -1.0);
|
|
227245
|
+
}
|
|
227246
|
+
else {
|
|
227247
|
+
const c = x / rxy;
|
|
227248
|
+
const s = y / rxy;
|
|
227249
|
+
// if coordinate is (x,y,0), i.e., Front or Back or Left or Right view
|
|
227250
|
+
result.setRowValues(-s, 0, c, c, 0, s, 0, 1, 0);
|
|
227251
|
+
// if coordinate is (x,y,z), i.e., other views such as Iso or RightIso
|
|
227252
|
+
if (z !== 0.0) {
|
|
227253
|
+
const r = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(x, y, z);
|
|
227254
|
+
const s1 = z / r;
|
|
227255
|
+
const c1 = rxy / r;
|
|
227256
|
+
result.applyGivensColumnOp(1, 2, c1, -s1);
|
|
227257
|
+
}
|
|
227258
|
+
}
|
|
227259
|
+
return result;
|
|
227260
|
+
}
|
|
227166
227261
|
/** Return the determinant of this matrix. */
|
|
227167
227262
|
determinant() {
|
|
227168
227263
|
return this.coffs[0] * this.coffs[4] * this.coffs[8]
|
|
@@ -229328,9 +229423,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
229328
229423
|
* @module CartesianGeometry
|
|
229329
229424
|
*/
|
|
229330
229425
|
// cspell:word CWXY
|
|
229426
|
+
// cspell:word arctan
|
|
229427
|
+
// cspell:word Rodrigues
|
|
229331
229428
|
|
|
229332
229429
|
|
|
229333
229430
|
|
|
229431
|
+
// cspell:word CCWXY
|
|
229334
229432
|
/**
|
|
229335
229433
|
* * `XYZ` is a minimal object containing x,y,z and operations that are meaningful without change in both point and vector.
|
|
229336
229434
|
* * `XYZ` is not instantiable.
|
|
@@ -230167,7 +230265,7 @@ class Vector3d extends XYZ {
|
|
|
230167
230265
|
return { v: this.safeDivideOrNull(magnitude, result), mag: magnitude };
|
|
230168
230266
|
}
|
|
230169
230267
|
/**
|
|
230170
|
-
* Return a unit vector parallel with this.
|
|
230268
|
+
* Return a unit vector parallel with this. Return undefined if this.magnitude is near zero.
|
|
230171
230269
|
* @param result optional result.
|
|
230172
230270
|
*/
|
|
230173
230271
|
normalize(result) {
|
|
@@ -230673,18 +230771,17 @@ class Vector3d extends XYZ {
|
|
|
230673
230771
|
else
|
|
230674
230772
|
return theta;
|
|
230675
230773
|
}
|
|
230676
|
-
/**
|
|
230677
|
-
|
|
230678
|
-
|
|
230679
|
-
|
|
230680
|
-
|
|
230681
|
-
|
|
230682
|
-
|
|
230683
|
-
|
|
230684
|
-
|
|
230685
|
-
|
|
230686
|
-
|
|
230687
|
-
*/
|
|
230774
|
+
/** Return the (strongly typed Angle) angle from this vector to vectorB, measured in the plane containing both,
|
|
230775
|
+
* with vectorW indicating which side to view to control sign of the angle.
|
|
230776
|
+
* * The returned angle can range from negative 180 degrees (negative PI radians) to positive 180 degrees
|
|
230777
|
+
* * (positive PI radians), not closed on the negative side.
|
|
230778
|
+
* * The returned angle is "in the plane containing the two vectors"
|
|
230779
|
+
* * `vectorW` distinguishes between the sides of the plane, but does not have to be perpendicular.
|
|
230780
|
+
* * The returned angle has the same sign as vectorW dot product (thisVector cross vectorB)
|
|
230781
|
+
* * Use planarRadiansTo to measure the angle between vectors that are projected to another plane.
|
|
230782
|
+
* @param vectorB target vector.
|
|
230783
|
+
* @param vectorW distinguishes between the sides of the plane.
|
|
230784
|
+
*/
|
|
230688
230785
|
signedAngleTo(vectorB, vectorW) {
|
|
230689
230786
|
return _Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createRadians(this.signedRadiansTo(vectorB, vectorW));
|
|
230690
230787
|
}
|
|
@@ -235607,7 +235704,7 @@ class Segment1d {
|
|
|
235607
235704
|
*/
|
|
235608
235705
|
reverseInPlace() { const x = this.x0; this.x0 = this.x1; this.x1 = x; }
|
|
235609
235706
|
/**
|
|
235610
|
-
* * if `x1
|
|
235707
|
+
* * if `x1-x0` multiplied by the scale factor is (strictly) negative, swap the x0 and x1 member values.
|
|
235611
235708
|
* * This makes the fractionToPoint evaluates reverse direction.
|
|
235612
235709
|
*/
|
|
235613
235710
|
reverseIfNeededForDeltaSign(sign = 1) {
|
|
@@ -243421,6 +243518,20 @@ class SmallSystem {
|
|
|
243421
243518
|
}
|
|
243422
243519
|
return undefined;
|
|
243423
243520
|
}
|
|
243521
|
+
/**
|
|
243522
|
+
* Compute the intersection of three planes.
|
|
243523
|
+
* @param xyzA point on the first plane
|
|
243524
|
+
* @param normalA normal of the first plane
|
|
243525
|
+
* @param xyzB point on the second plane
|
|
243526
|
+
* @param normalB normal of the second plane
|
|
243527
|
+
* @param xyzC point on the third plane
|
|
243528
|
+
* @param normalC normal of the third plane
|
|
243529
|
+
* @param result optional result
|
|
243530
|
+
* @returns intersection point of the three planes (as a Vector3d), or undefined if at least two planes are parallel.
|
|
243531
|
+
*/
|
|
243532
|
+
static intersect3Planes(xyzA, normalA, xyzB, normalB, xyzC, normalC, result) {
|
|
243533
|
+
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);
|
|
243534
|
+
}
|
|
243424
243535
|
/**
|
|
243425
243536
|
* * in rowB, replace `rowB[j] += a * rowB[pivot] * rowA[j] / rowA[pivot]` for `j>pivot`
|
|
243426
243537
|
* @param rowA row that does not change
|
|
@@ -247532,10 +247643,29 @@ class PolyfaceBuilder extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
|
|
|
247532
247643
|
if (sector.uv)
|
|
247533
247644
|
sector.uvIndex = this._polyface.addParam(sector.uv);
|
|
247534
247645
|
}
|
|
247646
|
+
addSectorTriangle(sectorA0, sectorA1, sectorA2) {
|
|
247647
|
+
if (sectorA0.xyz.isAlmostEqual(sectorA1.xyz)
|
|
247648
|
+
|| sectorA1.xyz.isAlmostEqual(sectorA2.xyz)
|
|
247649
|
+
|| sectorA2.xyz.isAlmostEqual(sectorA0.xyz)) {
|
|
247650
|
+
// trivially degenerate triangle !!! skip !!!
|
|
247651
|
+
}
|
|
247652
|
+
else {
|
|
247653
|
+
if (this._options.needNormals)
|
|
247654
|
+
this.addIndexedTriangleNormalIndexes(sectorA0.normalIndex, sectorA1.normalIndex, sectorA2.normalIndex);
|
|
247655
|
+
if (this._options.needParams)
|
|
247656
|
+
this.addIndexedTriangleParamIndexes(sectorA0.uvIndex, sectorA1.uvIndex, sectorA2.uvIndex);
|
|
247657
|
+
this.addIndexedTrianglePointIndexes(sectorA0.xyzIndex, sectorA1.xyzIndex, sectorA2.xyzIndex);
|
|
247658
|
+
this._polyface.terminateFacet();
|
|
247659
|
+
}
|
|
247660
|
+
}
|
|
247535
247661
|
addSectorQuadA01B01(sectorA0, sectorA1, sectorB0, sectorB1) {
|
|
247536
247662
|
if (sectorA0.xyz.isAlmostEqual(sectorA1.xyz) && sectorB0.xyz.isAlmostEqual(sectorB1.xyz)) {
|
|
247537
247663
|
// ignore null quad !!
|
|
247538
247664
|
}
|
|
247665
|
+
else if (this._options.shouldTriangulate) {
|
|
247666
|
+
this.addSectorTriangle(sectorA0, sectorA1, sectorB1);
|
|
247667
|
+
this.addSectorTriangle(sectorB1, sectorB0, sectorA0);
|
|
247668
|
+
}
|
|
247539
247669
|
else {
|
|
247540
247670
|
if (this._options.needNormals)
|
|
247541
247671
|
this.addIndexedQuadNormalIndexes(sectorA0.normalIndex, sectorA1.normalIndex, sectorB0.normalIndex, sectorB1.normalIndex);
|
|
@@ -247612,12 +247742,30 @@ class PolyfaceBuilder extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
|
|
|
247612
247742
|
}
|
|
247613
247743
|
const numPoints = pointA.length;
|
|
247614
247744
|
for (let i = 1; i < numPoints; i++) {
|
|
247615
|
-
if (
|
|
247616
|
-
|
|
247617
|
-
|
|
247618
|
-
|
|
247619
|
-
|
|
247620
|
-
|
|
247745
|
+
if (this.options.shouldTriangulate) {
|
|
247746
|
+
if (distinctIndices(pointA.atUncheckedIndex(i - 1), pointA.atUncheckedIndex(i), pointB.atUncheckedIndex(i))) {
|
|
247747
|
+
this.addIndexedTrianglePointIndexes(pointA.atUncheckedIndex(i - 1), pointA.atUncheckedIndex(i), pointB.atUncheckedIndex(i));
|
|
247748
|
+
if (normalA && normalB)
|
|
247749
|
+
this.addIndexedTriangleNormalIndexes(normalA.atUncheckedIndex(i - 1), normalA.atUncheckedIndex(i), normalB.atUncheckedIndex(i - 1));
|
|
247750
|
+
if (paramA && paramB)
|
|
247751
|
+
this.addIndexedTriangleParamIndexes(paramA.atUncheckedIndex(i - 1), paramA.atUncheckedIndex(i), paramB.atUncheckedIndex(i - 1));
|
|
247752
|
+
}
|
|
247753
|
+
if (distinctIndices(pointB.atUncheckedIndex(i), pointB.atUncheckedIndex(i - 1), pointA.atUncheckedIndex(i - 1))) {
|
|
247754
|
+
this.addIndexedTrianglePointIndexes(pointA.atUncheckedIndex(i - 1), pointB.atUncheckedIndex(i), pointB.atUncheckedIndex(i - 1));
|
|
247755
|
+
if (normalA && normalB)
|
|
247756
|
+
this.addIndexedTriangleNormalIndexes(normalA.atUncheckedIndex(i - 1), normalB.atUncheckedIndex(i), normalB.atUncheckedIndex(i - 1));
|
|
247757
|
+
if (paramA && paramB)
|
|
247758
|
+
this.addIndexedTriangleParamIndexes(paramA.atUncheckedIndex(i - 1), paramB.atUncheckedIndex(i), paramB.atUncheckedIndex(i - 1));
|
|
247759
|
+
}
|
|
247760
|
+
}
|
|
247761
|
+
else {
|
|
247762
|
+
if (pointA.atUncheckedIndex(i - 1) !== pointA.atUncheckedIndex(i) || pointB.atUncheckedIndex(i - 1) !== pointB.atUncheckedIndex(i)) {
|
|
247763
|
+
this.addIndexedQuadPointIndexes(pointA.atUncheckedIndex(i - 1), pointA.atUncheckedIndex(i), pointB.atUncheckedIndex(i - 1), pointB.atUncheckedIndex(i));
|
|
247764
|
+
if (normalA && normalB)
|
|
247765
|
+
this.addIndexedQuadNormalIndexes(normalA.atUncheckedIndex(i - 1), normalA.atUncheckedIndex(i), normalB.atUncheckedIndex(i - 1), normalB.atUncheckedIndex(i));
|
|
247766
|
+
if (paramA && paramB)
|
|
247767
|
+
this.addIndexedQuadParamIndexes(paramA.atUncheckedIndex(i - 1), paramA.atUncheckedIndex(i), paramB.atUncheckedIndex(i - 1), paramB.atUncheckedIndex(i));
|
|
247768
|
+
}
|
|
247621
247769
|
this._polyface.terminateFacet();
|
|
247622
247770
|
}
|
|
247623
247771
|
}
|
|
@@ -248614,6 +248762,9 @@ function resolveToIndexedXYZCollectionOrCarrier(points) {
|
|
|
248614
248762
|
return points.packedPoints;
|
|
248615
248763
|
return points;
|
|
248616
248764
|
}
|
|
248765
|
+
function distinctIndices(i0, i1, i2) {
|
|
248766
|
+
return i0 !== i1 && i1 !== i2 && i2 !== i0;
|
|
248767
|
+
}
|
|
248617
248768
|
|
|
248618
248769
|
|
|
248619
248770
|
/***/ }),
|
|
@@ -249782,38 +249933,41 @@ function compressUnusedGrowableXYZArray(data: GrowableXYZArray, indices: number[
|
|
|
249782
249933
|
__webpack_require__.r(__webpack_exports__);
|
|
249783
249934
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
249784
249935
|
/* harmony export */ "DuplicateFacetClusterSelector": () => (/* binding */ DuplicateFacetClusterSelector),
|
|
249936
|
+
/* harmony export */ "OffsetMeshOptions": () => (/* binding */ OffsetMeshOptions),
|
|
249785
249937
|
/* harmony export */ "PolyfaceQuery": () => (/* binding */ PolyfaceQuery)
|
|
249786
249938
|
/* harmony export */ });
|
|
249787
249939
|
/* harmony import */ var _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../geometry3d/PointHelpers */ "../../core/geometry/lib/esm/geometry3d/PointHelpers.js");
|
|
249788
|
-
/* harmony import */ var
|
|
249940
|
+
/* harmony import */ var _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../curve/CurveCollection */ "../../core/geometry/lib/esm/curve/CurveCollection.js");
|
|
249789
249941
|
/* harmony import */ var _curve_internalContexts_MultiChainCollector__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../curve/internalContexts/MultiChainCollector */ "../../core/geometry/lib/esm/curve/internalContexts/MultiChainCollector.js");
|
|
249790
|
-
/* harmony import */ var
|
|
249791
|
-
/* harmony import */ var
|
|
249792
|
-
/* harmony import */ var
|
|
249942
|
+
/* harmony import */ var _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../curve/LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
|
|
249943
|
+
/* harmony import */ var _curve_LineString3d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../curve/LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
|
|
249944
|
+
/* harmony import */ var _curve_Loop__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../curve/Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
|
|
249793
249945
|
/* harmony import */ var _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../curve/StrokeOptions */ "../../core/geometry/lib/esm/curve/StrokeOptions.js");
|
|
249794
|
-
/* harmony import */ var
|
|
249795
|
-
/* harmony import */ var
|
|
249946
|
+
/* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
|
|
249947
|
+
/* harmony import */ var _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../geometry3d/Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
|
|
249796
249948
|
/* harmony import */ var _geometry3d_FrameBuilder__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../geometry3d/FrameBuilder */ "../../core/geometry/lib/esm/geometry3d/FrameBuilder.js");
|
|
249797
|
-
/* harmony import */ var
|
|
249798
|
-
/* harmony import */ var
|
|
249949
|
+
/* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
|
|
249950
|
+
/* harmony import */ var _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../geometry3d/PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
|
|
249799
249951
|
/* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
|
|
249800
|
-
/* harmony import */ var
|
|
249801
|
-
/* harmony import */ var
|
|
249802
|
-
/* harmony import */ var
|
|
249952
|
+
/* harmony import */ var _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../geometry4d/Matrix4d */ "../../core/geometry/lib/esm/geometry4d/Matrix4d.js");
|
|
249953
|
+
/* harmony import */ var _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../geometry4d/MomentData */ "../../core/geometry/lib/esm/geometry4d/MomentData.js");
|
|
249954
|
+
/* harmony import */ var _numerics_UnionFind__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../numerics/UnionFind */ "../../core/geometry/lib/esm/numerics/UnionFind.js");
|
|
249803
249955
|
/* harmony import */ var _topology_ChainMerge__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../topology/ChainMerge */ "../../core/geometry/lib/esm/topology/ChainMerge.js");
|
|
249804
249956
|
/* harmony import */ var _topology_Graph__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../topology/Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
|
|
249805
249957
|
/* harmony import */ var _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../topology/HalfEdgeGraphSearch */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphSearch.js");
|
|
249806
249958
|
/* harmony import */ var _topology_Merging__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../topology/Merging */ "../../core/geometry/lib/esm/topology/Merging.js");
|
|
249807
|
-
/* harmony import */ var
|
|
249808
|
-
/* harmony import */ var
|
|
249959
|
+
/* harmony import */ var _FacetOrientation__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./FacetOrientation */ "../../core/geometry/lib/esm/polyface/FacetOrientation.js");
|
|
249960
|
+
/* harmony import */ var _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./IndexedEdgeMatcher */ "../../core/geometry/lib/esm/polyface/IndexedEdgeMatcher.js");
|
|
249809
249961
|
/* harmony import */ var _IndexedPolyfaceVisitor__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./IndexedPolyfaceVisitor */ "../../core/geometry/lib/esm/polyface/IndexedPolyfaceVisitor.js");
|
|
249810
|
-
/* harmony import */ var
|
|
249811
|
-
/* harmony import */ var
|
|
249962
|
+
/* harmony import */ var _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./multiclip/BuildAverageNormalsContext */ "../../core/geometry/lib/esm/polyface/multiclip/BuildAverageNormalsContext.js");
|
|
249963
|
+
/* harmony import */ var _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./multiclip/SweepLineStringToFacetContext */ "../../core/geometry/lib/esm/polyface/multiclip/SweepLineStringToFacetContext.js");
|
|
249812
249964
|
/* harmony import */ var _multiclip_XYPointBuckets__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./multiclip/XYPointBuckets */ "../../core/geometry/lib/esm/polyface/multiclip/XYPointBuckets.js");
|
|
249813
|
-
/* harmony import */ var
|
|
249965
|
+
/* harmony import */ var _Polyface__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Polyface */ "../../core/geometry/lib/esm/polyface/Polyface.js");
|
|
249814
249966
|
/* harmony import */ var _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./PolyfaceBuilder */ "../../core/geometry/lib/esm/polyface/PolyfaceBuilder.js");
|
|
249815
249967
|
/* harmony import */ var _RangeLengthData__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./RangeLengthData */ "../../core/geometry/lib/esm/polyface/RangeLengthData.js");
|
|
249816
249968
|
/* harmony import */ var _topology_SpaceTriangulation__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../topology/SpaceTriangulation */ "../../core/geometry/lib/esm/topology/SpaceTriangulation.js");
|
|
249969
|
+
/* harmony import */ var _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../topology/HalfEdgeGraphFromIndexedLoopsContext */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js");
|
|
249970
|
+
/* harmony import */ var _multiclip_OffsetMeshContext__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./multiclip/OffsetMeshContext */ "../../core/geometry/lib/esm/polyface/multiclip/OffsetMeshContext.js");
|
|
249817
249971
|
/*---------------------------------------------------------------------------------------------
|
|
249818
249972
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
249819
249973
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
@@ -249853,6 +250007,41 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
249853
250007
|
|
|
249854
250008
|
|
|
249855
250009
|
|
|
250010
|
+
|
|
250011
|
+
|
|
250012
|
+
/**
|
|
250013
|
+
* Options carrier for [[PolyfaceQuery.cloneOffset]].
|
|
250014
|
+
* * Default options are strongly recommended.
|
|
250015
|
+
* * The option most likely to be changed is chamferTurnAngle
|
|
250016
|
+
* @public
|
|
250017
|
+
*/
|
|
250018
|
+
class OffsetMeshOptions {
|
|
250019
|
+
/** Constructor -- CAPTURE parameters ... */
|
|
250020
|
+
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)) {
|
|
250021
|
+
this.smoothSingleAngleBetweenNormals = smoothSingleAngleBetweenNormals.clone();
|
|
250022
|
+
this.smoothAccumulatedAngleBetweenNormals = smoothAccumulatedAngleBetweenNormals.clone();
|
|
250023
|
+
this.chamferAngleBetweenNormals = chamferTurnAngle.clone();
|
|
250024
|
+
}
|
|
250025
|
+
/** construct and return an OffsetMeshOptions with given parameters.
|
|
250026
|
+
* * Angles are forced to minimum values.
|
|
250027
|
+
* * Clones of the angles are given to the constructor.
|
|
250028
|
+
* @param smoothSingleRadiansBetweenNormals an angle larger than this (between facets) is considered a sharp edge
|
|
250029
|
+
* @param smoothAccumulatedAngleBetweenNormals angles that sum to this much may be consolidated for average normal
|
|
250030
|
+
* @param chamferTurnAngleBetweenNormals when facets meet with larger angle, a chamfer edge may be added if the angle between facet normals is larger than this.
|
|
250031
|
+
*/
|
|
250032
|
+
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)) {
|
|
250033
|
+
const mySmoothSingleRadiansBetweenNormals = smoothSingleAngleBetweenNormals.clone();
|
|
250034
|
+
const mySmoothAccumulatedRadiansBetweenNormals = smoothAccumulatedAngleBetweenNormals.clone();
|
|
250035
|
+
const myChamferTurnAngleBetweenNormals = chamferTurnAngleBetweenNormals.clone();
|
|
250036
|
+
if (mySmoothSingleRadiansBetweenNormals.degrees < 1)
|
|
250037
|
+
mySmoothAccumulatedRadiansBetweenNormals.setDegrees(1.0);
|
|
250038
|
+
if (mySmoothAccumulatedRadiansBetweenNormals.degrees < 1.0)
|
|
250039
|
+
mySmoothAccumulatedRadiansBetweenNormals.setDegrees(1.0);
|
|
250040
|
+
if (mySmoothAccumulatedRadiansBetweenNormals.degrees < 15.0)
|
|
250041
|
+
mySmoothAccumulatedRadiansBetweenNormals.setDegrees(15.0);
|
|
250042
|
+
return new OffsetMeshOptions(mySmoothSingleRadiansBetweenNormals, mySmoothAccumulatedRadiansBetweenNormals, myChamferTurnAngleBetweenNormals);
|
|
250043
|
+
}
|
|
250044
|
+
}
|
|
249856
250045
|
/**
|
|
249857
250046
|
* Enumeration of cases for retaining facets among duplicates
|
|
249858
250047
|
* @public
|
|
@@ -249874,12 +250063,12 @@ var DuplicateFacetClusterSelector;
|
|
|
249874
250063
|
class PolyfaceQuery {
|
|
249875
250064
|
/** copy the points from a visitor into a Linestring3d in a Loop object */
|
|
249876
250065
|
static visitorToLoop(visitor) {
|
|
249877
|
-
const ls =
|
|
249878
|
-
return
|
|
250066
|
+
const ls = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_1__.LineString3d.createPoints(visitor.point.getPoint3dArray());
|
|
250067
|
+
return _curve_Loop__WEBPACK_IMPORTED_MODULE_2__.Loop.create(ls);
|
|
249879
250068
|
}
|
|
249880
250069
|
/** Create a linestring loop for each facet of the polyface. */
|
|
249881
250070
|
static indexedPolyfaceToLoops(polyface) {
|
|
249882
|
-
const result =
|
|
250071
|
+
const result = _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_3__.BagOfCurves.create();
|
|
249883
250072
|
const visitor = polyface.createVisitor(1);
|
|
249884
250073
|
while (visitor.moveToNextFacet()) {
|
|
249885
250074
|
const loop = PolyfaceQuery.visitorToLoop(visitor);
|
|
@@ -249893,17 +250082,17 @@ class PolyfaceQuery {
|
|
|
249893
250082
|
static sumFacetAreas(source, vectorToEye) {
|
|
249894
250083
|
let s = 0;
|
|
249895
250084
|
if (source !== undefined) {
|
|
249896
|
-
if (source instanceof
|
|
250085
|
+
if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
|
|
249897
250086
|
return PolyfaceQuery.sumFacetAreas(source.createVisitor(1), vectorToEye);
|
|
249898
250087
|
let unitVectorToEye;
|
|
249899
250088
|
if (vectorToEye !== undefined)
|
|
249900
250089
|
unitVectorToEye = vectorToEye.normalize();
|
|
249901
250090
|
source.reset();
|
|
249902
250091
|
while (source.moveToNextFacet()) {
|
|
249903
|
-
const scaledNormal =
|
|
250092
|
+
const scaledNormal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.areaNormal(source.point.getPoint3dArray());
|
|
249904
250093
|
let area = scaledNormal.magnitude();
|
|
249905
250094
|
if (unitVectorToEye !== undefined) {
|
|
249906
|
-
const scale =
|
|
250095
|
+
const scale = _Geometry__WEBPACK_IMPORTED_MODULE_6__.Geometry.conditionalDivideCoordinate(1.0, area);
|
|
249907
250096
|
if (scale !== undefined)
|
|
249908
250097
|
area *= scaledNormal.dotProduct(unitVectorToEye) * scale;
|
|
249909
250098
|
}
|
|
@@ -249920,12 +250109,12 @@ class PolyfaceQuery {
|
|
|
249920
250109
|
*/
|
|
249921
250110
|
static sumTetrahedralVolumes(source, origin) {
|
|
249922
250111
|
let s = 0;
|
|
249923
|
-
if (source instanceof
|
|
250112
|
+
if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
|
|
249924
250113
|
return PolyfaceQuery.sumTetrahedralVolumes(source.createVisitor(0), origin);
|
|
249925
250114
|
let myOrigin = origin;
|
|
249926
|
-
const facetOrigin =
|
|
249927
|
-
const targetA =
|
|
249928
|
-
const targetB =
|
|
250115
|
+
const facetOrigin = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
250116
|
+
const targetA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
250117
|
+
const targetB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
249929
250118
|
source.reset();
|
|
249930
250119
|
while (source.moveToNextFacet()) {
|
|
249931
250120
|
if (myOrigin === undefined)
|
|
@@ -249946,20 +250135,20 @@ class PolyfaceQuery {
|
|
|
249946
250135
|
*
|
|
249947
250136
|
*/
|
|
249948
250137
|
static sumVolumeBetweenFacetsAndPlane(source, plane) {
|
|
249949
|
-
if (source instanceof
|
|
250138
|
+
if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
|
|
249950
250139
|
return PolyfaceQuery.sumVolumeBetweenFacetsAndPlane(source.createVisitor(0), plane);
|
|
249951
|
-
const facetOrigin =
|
|
249952
|
-
const targetA =
|
|
249953
|
-
const targetB =
|
|
249954
|
-
const triangleNormal =
|
|
250140
|
+
const facetOrigin = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
250141
|
+
const targetA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
250142
|
+
const targetB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
250143
|
+
const triangleNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
|
|
249955
250144
|
const planeNormal = plane.getNormalRef();
|
|
249956
250145
|
let h0, hA, hB;
|
|
249957
250146
|
let signedVolumeSum = 0.0;
|
|
249958
250147
|
let signedTriangleArea;
|
|
249959
250148
|
let singleFacetArea;
|
|
249960
|
-
const positiveAreaMomentSums =
|
|
249961
|
-
const negativeAreaMomentSums =
|
|
249962
|
-
const singleFacetProducts =
|
|
250149
|
+
const positiveAreaMomentSums = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.create(undefined, true);
|
|
250150
|
+
const negativeAreaMomentSums = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.create(undefined, true);
|
|
250151
|
+
const singleFacetProducts = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__.Matrix4d.createZero();
|
|
249963
250152
|
const projectToPlane = plane.getProjectionToPlane();
|
|
249964
250153
|
source.reset();
|
|
249965
250154
|
// For each facet ..
|
|
@@ -249986,7 +250175,7 @@ class PolyfaceQuery {
|
|
|
249986
250175
|
}
|
|
249987
250176
|
singleFacetProducts.setZero();
|
|
249988
250177
|
source.point.multiplyTransformInPlace(projectToPlane);
|
|
249989
|
-
|
|
250178
|
+
_geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.addSecondMomentAreaProducts(source.point, facetOrigin, singleFacetProducts);
|
|
249990
250179
|
if (singleFacetArea > 0) {
|
|
249991
250180
|
positiveAreaMomentSums.accumulateProductsFromOrigin(facetOrigin, singleFacetProducts, 1.0);
|
|
249992
250181
|
}
|
|
@@ -249996,8 +250185,8 @@ class PolyfaceQuery {
|
|
|
249996
250185
|
}
|
|
249997
250186
|
positiveAreaMomentSums.shiftOriginAndSumsToCentroidOfSums();
|
|
249998
250187
|
negativeAreaMomentSums.shiftOriginAndSumsToCentroidOfSums();
|
|
249999
|
-
const positiveAreaMoments =
|
|
250000
|
-
const negativeAreaMoments =
|
|
250188
|
+
const positiveAreaMoments = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.inertiaProductsToPrincipalAxes(positiveAreaMomentSums.origin, positiveAreaMomentSums.sums);
|
|
250189
|
+
const negativeAreaMoments = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.inertiaProductsToPrincipalAxes(negativeAreaMomentSums.origin, negativeAreaMomentSums.sums);
|
|
250001
250190
|
return {
|
|
250002
250191
|
volume: signedVolumeSum / 6.0,
|
|
250003
250192
|
positiveProjectedFacetAreaMoments: positiveAreaMoments,
|
|
@@ -250006,23 +250195,23 @@ class PolyfaceQuery {
|
|
|
250006
250195
|
}
|
|
250007
250196
|
/** Return the inertia products [xx,xy,xz,xw, yw, etc] integrated over all all facets, as viewed from origin. */
|
|
250008
250197
|
static sumFacetSecondAreaMomentProducts(source, origin) {
|
|
250009
|
-
if (source instanceof
|
|
250198
|
+
if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
|
|
250010
250199
|
return PolyfaceQuery.sumFacetSecondAreaMomentProducts(source.createVisitor(0), origin);
|
|
250011
|
-
const products =
|
|
250200
|
+
const products = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__.Matrix4d.createZero();
|
|
250012
250201
|
source.reset();
|
|
250013
250202
|
while (source.moveToNextFacet()) {
|
|
250014
|
-
|
|
250203
|
+
_geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.addSecondMomentAreaProducts(source.point, origin, products);
|
|
250015
250204
|
}
|
|
250016
250205
|
return products;
|
|
250017
250206
|
}
|
|
250018
250207
|
/** Return the inertia products [xx,xy,xz,xw, yw, etc] integrated over all tetrahedral volumes from origin */
|
|
250019
250208
|
static sumFacetSecondVolumeMomentProducts(source, origin) {
|
|
250020
|
-
if (source instanceof
|
|
250209
|
+
if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
|
|
250021
250210
|
return PolyfaceQuery.sumFacetSecondVolumeMomentProducts(source.createVisitor(0), origin);
|
|
250022
|
-
const products =
|
|
250211
|
+
const products = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__.Matrix4d.createZero();
|
|
250023
250212
|
source.reset();
|
|
250024
250213
|
while (source.moveToNextFacet()) {
|
|
250025
|
-
|
|
250214
|
+
_geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.addSecondMomentVolumeProducts(source.point, origin, products);
|
|
250026
250215
|
}
|
|
250027
250216
|
return products;
|
|
250028
250217
|
}
|
|
@@ -250036,7 +250225,7 @@ class PolyfaceQuery {
|
|
|
250036
250225
|
if (!origin)
|
|
250037
250226
|
return undefined;
|
|
250038
250227
|
const inertiaProducts = PolyfaceQuery.sumFacetSecondAreaMomentProducts(source, origin);
|
|
250039
|
-
return
|
|
250228
|
+
return _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.inertiaProductsToPrincipalAxes(origin, inertiaProducts);
|
|
250040
250229
|
}
|
|
250041
250230
|
/** Compute area moments for the mesh. In the returned MomentData:
|
|
250042
250231
|
* * origin is the centroid.
|
|
@@ -250050,7 +250239,7 @@ class PolyfaceQuery {
|
|
|
250050
250239
|
if (!origin)
|
|
250051
250240
|
return undefined;
|
|
250052
250241
|
const inertiaProducts = PolyfaceQuery.sumFacetSecondVolumeMomentProducts(source, origin);
|
|
250053
|
-
return
|
|
250242
|
+
return _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.inertiaProductsToPrincipalAxes(origin, inertiaProducts);
|
|
250054
250243
|
}
|
|
250055
250244
|
/**
|
|
250056
250245
|
* Test for convex volume by dihedral angle tests on all edges.
|
|
@@ -250082,14 +250271,14 @@ class PolyfaceQuery {
|
|
|
250082
250271
|
* * (but null edges are permitted -- These occur naturally at edges of quads at north or south pole)
|
|
250083
250272
|
*/
|
|
250084
250273
|
static dihedralAngleSummary(source, ignoreBoundaries = false) {
|
|
250085
|
-
const edges = new
|
|
250274
|
+
const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
|
|
250086
250275
|
const visitor = source.createVisitor(1);
|
|
250087
250276
|
visitor.reset();
|
|
250088
250277
|
const centroidNormal = [];
|
|
250089
250278
|
let normalCounter = 0;
|
|
250090
250279
|
while (visitor.moveToNextFacet()) {
|
|
250091
250280
|
const numEdges = visitor.pointCount - 1;
|
|
250092
|
-
const normal =
|
|
250281
|
+
const normal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.centroidAreaNormal(visitor.point);
|
|
250093
250282
|
if (normal === undefined)
|
|
250094
250283
|
return 0;
|
|
250095
250284
|
centroidNormal.push(normal);
|
|
@@ -250106,12 +250295,12 @@ class PolyfaceQuery {
|
|
|
250106
250295
|
let numPositive = 0;
|
|
250107
250296
|
let numPlanar = 0;
|
|
250108
250297
|
let numNegative = 0;
|
|
250109
|
-
const edgeVector =
|
|
250298
|
+
const edgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
|
|
250110
250299
|
for (const cluster of manifoldClusters) {
|
|
250111
250300
|
const sideA = cluster[0];
|
|
250112
250301
|
const sideB = cluster[1];
|
|
250113
|
-
if (sideA instanceof
|
|
250114
|
-
&& sideB instanceof
|
|
250302
|
+
if (sideA instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge
|
|
250303
|
+
&& sideB instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge
|
|
250115
250304
|
&& source.data.point.vectorIndexIndex(sideA.vertexIndexA, sideA.vertexIndexB, edgeVector)) {
|
|
250116
250305
|
const dihedralAngle = centroidNormal[sideA.facetIndex].direction.signedAngleTo(centroidNormal[sideB.facetIndex].direction, edgeVector);
|
|
250117
250306
|
if (dihedralAngle.isAlmostZero)
|
|
@@ -250144,7 +250333,7 @@ class PolyfaceQuery {
|
|
|
250144
250333
|
* * Any edge with 2 incident facets in the same direction triggers a `false` return.
|
|
250145
250334
|
*/
|
|
250146
250335
|
static isPolyfaceManifold(source, allowSimpleBoundaries = false) {
|
|
250147
|
-
const edges = new
|
|
250336
|
+
const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
|
|
250148
250337
|
const visitor = source.createVisitor(1);
|
|
250149
250338
|
visitor.reset();
|
|
250150
250339
|
while (visitor.moveToNextFacet()) {
|
|
@@ -250167,9 +250356,9 @@ class PolyfaceQuery {
|
|
|
250167
250356
|
* @returns
|
|
250168
250357
|
*/
|
|
250169
250358
|
static boundaryEdges(source, includeDanglers = true, includeMismatch = true, includeNull = true) {
|
|
250170
|
-
const result = new
|
|
250359
|
+
const result = new _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_3__.BagOfCurves();
|
|
250171
250360
|
const announceEdge = (pointA, pointB, _indexA, _indexB, _readIndex) => {
|
|
250172
|
-
result.tryAddChild(
|
|
250361
|
+
result.tryAddChild(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(pointA, pointB));
|
|
250173
250362
|
};
|
|
250174
250363
|
PolyfaceQuery.announceBoundaryEdges(source, announceEdge, includeDanglers, includeMismatch, includeNull);
|
|
250175
250364
|
if (result.children.length === 0)
|
|
@@ -250188,8 +250377,8 @@ class PolyfaceQuery {
|
|
|
250188
250377
|
static announceBoundaryEdges(source, announceEdge, includeDanglers = true, includeMismatch = true, includeNull = true) {
|
|
250189
250378
|
if (source === undefined)
|
|
250190
250379
|
return undefined;
|
|
250191
|
-
const edges = new
|
|
250192
|
-
const visitor = source instanceof
|
|
250380
|
+
const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
|
|
250381
|
+
const visitor = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface ? source.createVisitor(1) : source;
|
|
250193
250382
|
visitor.setNumWrap(1);
|
|
250194
250383
|
visitor.reset();
|
|
250195
250384
|
while (visitor.moveToNextFacet()) {
|
|
@@ -250214,7 +250403,7 @@ class PolyfaceQuery {
|
|
|
250214
250403
|
const sourcePolyface = visitor.clientPolyface();
|
|
250215
250404
|
for (const list of badList) {
|
|
250216
250405
|
for (const e of list) {
|
|
250217
|
-
const e1 = e instanceof
|
|
250406
|
+
const e1 = e instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge ? e : e[0];
|
|
250218
250407
|
const indexA = e1.vertexIndexA;
|
|
250219
250408
|
const indexB = e1.vertexIndexB;
|
|
250220
250409
|
const pointA = sourcePolyface.data.getPoint(indexA);
|
|
@@ -250229,7 +250418,7 @@ class PolyfaceQuery {
|
|
|
250229
250418
|
* * Facets are ASSUMED to be convex and planar.
|
|
250230
250419
|
*/
|
|
250231
250420
|
static announceSweepLinestringToConvexPolyfaceXY(linestringPoints, polyface, announce) {
|
|
250232
|
-
const context =
|
|
250421
|
+
const context = _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_12__.SweepLineStringToFacetContext.create(linestringPoints);
|
|
250233
250422
|
if (context) {
|
|
250234
250423
|
const visitor = polyface.createVisitor(0);
|
|
250235
250424
|
for (visitor.reset(); visitor.moveToNextFacet();) {
|
|
@@ -250262,7 +250451,7 @@ class PolyfaceQuery {
|
|
|
250262
250451
|
* @internal
|
|
250263
250452
|
*/
|
|
250264
250453
|
static async asyncAnnounceSweepLinestringToConvexPolyfaceXY(linestringPoints, polyface, announce) {
|
|
250265
|
-
const context =
|
|
250454
|
+
const context = _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_12__.SweepLineStringToFacetContext.create(linestringPoints);
|
|
250266
250455
|
this.awaitBlockCount = 0;
|
|
250267
250456
|
let workTotal = 0;
|
|
250268
250457
|
if (context) {
|
|
@@ -250282,11 +250471,11 @@ class PolyfaceQuery {
|
|
|
250282
250471
|
* * Return array of arrays of facet indices.
|
|
250283
250472
|
*/
|
|
250284
250473
|
static partitionFacetIndicesByVertexConnectedComponent(polyface) {
|
|
250285
|
-
if (polyface instanceof
|
|
250474
|
+
if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
|
|
250286
250475
|
return this.partitionFacetIndicesByVertexConnectedComponent(polyface.createVisitor(0));
|
|
250287
250476
|
}
|
|
250288
250477
|
// The polyface is really a visitor !!!
|
|
250289
|
-
const context = new
|
|
250478
|
+
const context = new _numerics_UnionFind__WEBPACK_IMPORTED_MODULE_13__.UnionFindContext(this.visitorClientPointCount(polyface));
|
|
250290
250479
|
for (polyface.reset(); polyface.moveToNextFacet();) {
|
|
250291
250480
|
const firstVertexIndexOnThisFacet = polyface.pointIndex[0];
|
|
250292
250481
|
for (const vertexIndex of polyface.pointIndex)
|
|
@@ -250319,7 +250508,7 @@ class PolyfaceQuery {
|
|
|
250319
250508
|
* * Return array of arrays of facet indices.
|
|
250320
250509
|
*/
|
|
250321
250510
|
static partitionFacetIndicesByVisibilityVector(polyface, vectorToEye, sideAngleTolerance) {
|
|
250322
|
-
if (polyface instanceof
|
|
250511
|
+
if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
|
|
250323
250512
|
return this.partitionFacetIndicesByVisibilityVector(polyface.createVisitor(0), vectorToEye, sideAngleTolerance);
|
|
250324
250513
|
}
|
|
250325
250514
|
const facetsInComponent = [];
|
|
@@ -250331,7 +250520,7 @@ class PolyfaceQuery {
|
|
|
250331
250520
|
const sideComponent = facetsInComponent[2];
|
|
250332
250521
|
const radiansTol = Math.max(sideAngleTolerance.radians, 1.0e-8);
|
|
250333
250522
|
for (polyface.reset(); polyface.moveToNextFacet();) {
|
|
250334
|
-
const areaNormal =
|
|
250523
|
+
const areaNormal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.areaNormalGo(polyface.point);
|
|
250335
250524
|
const index = polyface.currentReadIndex();
|
|
250336
250525
|
if (areaNormal) {
|
|
250337
250526
|
const angle = areaNormal.angleFromPerpendicular(vectorToEye);
|
|
@@ -250358,7 +250547,7 @@ class PolyfaceQuery {
|
|
|
250358
250547
|
* @param vectorToEye
|
|
250359
250548
|
* @param sideAngleTolerance
|
|
250360
250549
|
*/
|
|
250361
|
-
static boundaryOfVisibleSubset(polyface, visibilitySelect, vectorToEye, sideAngleTolerance =
|
|
250550
|
+
static boundaryOfVisibleSubset(polyface, visibilitySelect, vectorToEye, sideAngleTolerance = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(1.0e-3)) {
|
|
250362
250551
|
const partitionedIndices = this.partitionFacetIndicesByVisibilityVector(polyface, vectorToEye, sideAngleTolerance);
|
|
250363
250552
|
if (partitionedIndices[visibilitySelect].length === 0)
|
|
250364
250553
|
return undefined;
|
|
@@ -250372,8 +250561,8 @@ class PolyfaceQuery {
|
|
|
250372
250561
|
* @param mesh
|
|
250373
250562
|
*/
|
|
250374
250563
|
static announceBoundaryChainsAsLineString3d(mesh, announceLoop) {
|
|
250375
|
-
const collector = new _curve_internalContexts_MultiChainCollector__WEBPACK_IMPORTED_MODULE_15__.MultiChainCollector(
|
|
250376
|
-
PolyfaceQuery.announceBoundaryEdges(mesh, (pointA, pointB, _indexA, _indexB) => collector.captureCurve(
|
|
250564
|
+
const collector = new _curve_internalContexts_MultiChainCollector__WEBPACK_IMPORTED_MODULE_15__.MultiChainCollector(_Geometry__WEBPACK_IMPORTED_MODULE_6__.Geometry.smallMetricDistance, 1000);
|
|
250565
|
+
PolyfaceQuery.announceBoundaryEdges(mesh, (pointA, pointB, _indexA, _indexB) => collector.captureCurve(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(pointA, pointB)), true, false, false);
|
|
250377
250566
|
collector.announceChainsAsLineString3d(announceLoop);
|
|
250378
250567
|
}
|
|
250379
250568
|
/**
|
|
@@ -250384,7 +250573,7 @@ class PolyfaceQuery {
|
|
|
250384
250573
|
* @returns
|
|
250385
250574
|
*/
|
|
250386
250575
|
static cloneWithMaximalPlanarFacets(mesh) {
|
|
250387
|
-
if (mesh instanceof
|
|
250576
|
+
if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
|
|
250388
250577
|
return this.cloneWithMaximalPlanarFacets(mesh.createVisitor(0));
|
|
250389
250578
|
const numFacets = PolyfaceQuery.visitorClientFacetCount(mesh);
|
|
250390
250579
|
const smoothEdges = PolyfaceQuery.collectEdgesByDihedralAngle(mesh);
|
|
@@ -250409,7 +250598,7 @@ class PolyfaceQuery {
|
|
|
250409
250598
|
const edges = [];
|
|
250410
250599
|
const edgeStrings = [];
|
|
250411
250600
|
PolyfaceQuery.announceBoundaryEdges(fragment, (pointA, pointB, _indexA, _indexB) => {
|
|
250412
|
-
edges.push(
|
|
250601
|
+
edges.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(pointA, pointB));
|
|
250413
250602
|
edgeStrings.push([pointA.clone(), pointB.clone()]);
|
|
250414
250603
|
});
|
|
250415
250604
|
const chains = _curve_internalContexts_MultiChainCollector__WEBPACK_IMPORTED_MODULE_15__.OffsetHelpers.collectChains(edges, gapTolerance, planarityTolerance);
|
|
@@ -250450,7 +250639,7 @@ class PolyfaceQuery {
|
|
|
250450
250639
|
* @returns
|
|
250451
250640
|
*/
|
|
250452
250641
|
static fillSimpleHoles(mesh, options, unfilledChains) {
|
|
250453
|
-
if (mesh instanceof
|
|
250642
|
+
if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
|
|
250454
250643
|
return this.fillSimpleHoles(mesh.createVisitor(0), options, unfilledChains);
|
|
250455
250644
|
const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create();
|
|
250456
250645
|
const chains = [];
|
|
@@ -250464,7 +250653,7 @@ class PolyfaceQuery {
|
|
|
250464
250653
|
rejected = true;
|
|
250465
250654
|
else if (options.maxPerimeter !== undefined && _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_21__.Point3dArray.sumEdgeLengths(points, false) > options.maxPerimeter)
|
|
250466
250655
|
rejected = true;
|
|
250467
|
-
else if (options.upVector !== undefined &&
|
|
250656
|
+
else if (options.upVector !== undefined && _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.sumTriangleAreasPerpendicularToUpVector(points, options.upVector) <= 0.0)
|
|
250468
250657
|
rejected = true;
|
|
250469
250658
|
if (!rejected && _topology_SpaceTriangulation__WEBPACK_IMPORTED_MODULE_22__.SpacePolygonTriangulation.triangulateSimplestSpaceLoop(points, (_loop, triangles) => {
|
|
250470
250659
|
for (const t of triangles)
|
|
@@ -250487,7 +250676,7 @@ class PolyfaceQuery {
|
|
|
250487
250676
|
*
|
|
250488
250677
|
*/
|
|
250489
250678
|
static clonePartitions(polyface, partitions) {
|
|
250490
|
-
if (polyface instanceof
|
|
250679
|
+
if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
|
|
250491
250680
|
return this.clonePartitions(polyface.createVisitor(0), partitions);
|
|
250492
250681
|
}
|
|
250493
250682
|
polyface.setNumWrap(0);
|
|
@@ -250511,7 +250700,7 @@ class PolyfaceQuery {
|
|
|
250511
250700
|
/** Clone facets that pass an filter function
|
|
250512
250701
|
*/
|
|
250513
250702
|
static cloneFiltered(source, filter) {
|
|
250514
|
-
if (source instanceof
|
|
250703
|
+
if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
|
|
250515
250704
|
return this.cloneFiltered(source.createVisitor(0), filter);
|
|
250516
250705
|
}
|
|
250517
250706
|
source.setNumWrap(0);
|
|
@@ -250563,9 +250752,9 @@ class PolyfaceQuery {
|
|
|
250563
250752
|
* @return collection of facet index arrays, one array per connected component
|
|
250564
250753
|
*/
|
|
250565
250754
|
static partitionFacetIndicesBySortableEdgeClusters(edgeClusters, numFacets) {
|
|
250566
|
-
const context = new
|
|
250755
|
+
const context = new _numerics_UnionFind__WEBPACK_IMPORTED_MODULE_13__.UnionFindContext(numFacets);
|
|
250567
250756
|
for (const cluster of edgeClusters) {
|
|
250568
|
-
if (cluster instanceof
|
|
250757
|
+
if (cluster instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge) {
|
|
250569
250758
|
// this edge does not connect anywhere. Ignore it!!
|
|
250570
250759
|
}
|
|
250571
250760
|
else {
|
|
@@ -250597,11 +250786,11 @@ class PolyfaceQuery {
|
|
|
250597
250786
|
* @return collection of facet index arrays, one per connected component
|
|
250598
250787
|
*/
|
|
250599
250788
|
static partitionFacetIndicesByEdgeConnectedComponent(polyface, stopAtVisibleEdges = false) {
|
|
250600
|
-
if (polyface instanceof
|
|
250789
|
+
if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
|
|
250601
250790
|
return this.partitionFacetIndicesByEdgeConnectedComponent(polyface.createVisitor(0), stopAtVisibleEdges);
|
|
250602
250791
|
}
|
|
250603
250792
|
polyface.setNumWrap(1);
|
|
250604
|
-
const matcher = new
|
|
250793
|
+
const matcher = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
|
|
250605
250794
|
polyface.reset();
|
|
250606
250795
|
let numFacets = 0;
|
|
250607
250796
|
while (polyface.moveToNextFacet()) {
|
|
@@ -250639,7 +250828,7 @@ class PolyfaceQuery {
|
|
|
250639
250828
|
static sweepLinestringToFacetsXYReturnLines(linestringPoints, polyface) {
|
|
250640
250829
|
const drapeGeometry = [];
|
|
250641
250830
|
this.announceSweepLinestringToConvexPolyfaceXY(linestringPoints, polyface, (_linestring, _segmentIndex, _polyface, _facetIndex, points, indexA, indexB) => {
|
|
250642
|
-
drapeGeometry.push(
|
|
250831
|
+
drapeGeometry.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(points[indexA], points[indexB]));
|
|
250643
250832
|
});
|
|
250644
250833
|
return drapeGeometry;
|
|
250645
250834
|
}
|
|
@@ -250674,7 +250863,7 @@ class PolyfaceQuery {
|
|
|
250674
250863
|
* * Return statistical summary of x,y,z ranges.
|
|
250675
250864
|
*/
|
|
250676
250865
|
static collectRangeLengthData(polyface) {
|
|
250677
|
-
if (polyface instanceof
|
|
250866
|
+
if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
|
|
250678
250867
|
return this.collectRangeLengthData(polyface.createVisitor(0));
|
|
250679
250868
|
}
|
|
250680
250869
|
const rangeData = new _RangeLengthData__WEBPACK_IMPORTED_MODULE_25__.RangeLengthData();
|
|
@@ -250692,10 +250881,10 @@ class PolyfaceQuery {
|
|
|
250692
250881
|
const rangeSearcher = _multiclip_XYPointBuckets__WEBPACK_IMPORTED_MODULE_26__.XYPointBuckets.create(polyface.data.point, 30);
|
|
250693
250882
|
const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create();
|
|
250694
250883
|
const edgeRange = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_27__.Range3d.createNull();
|
|
250695
|
-
const point0 =
|
|
250696
|
-
const point1 =
|
|
250697
|
-
const spacePoint =
|
|
250698
|
-
const segment =
|
|
250884
|
+
const point0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
250885
|
+
const point1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
250886
|
+
const spacePoint = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
250887
|
+
const segment = _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(point0, point1);
|
|
250699
250888
|
for (oldFacetVisitor.reset(); oldFacetVisitor.moveToNextFacet();) {
|
|
250700
250889
|
newFacetVisitor.clearArrays();
|
|
250701
250890
|
for (let i = 0; i + 1 < oldFacetVisitor.point.length; i++) {
|
|
@@ -250704,7 +250893,7 @@ class PolyfaceQuery {
|
|
|
250704
250893
|
oldFacetVisitor.point.getPoint3dAtUncheckedPointIndex(i + 1, point1);
|
|
250705
250894
|
newFacetVisitor.pushDataFrom(oldFacetVisitor, i);
|
|
250706
250895
|
edgeRange.setNull();
|
|
250707
|
-
|
|
250896
|
+
_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(point0, point1, segment);
|
|
250708
250897
|
let detailArray;
|
|
250709
250898
|
edgeRange.extend(point0);
|
|
250710
250899
|
edgeRange.extend(point1);
|
|
@@ -250849,8 +251038,8 @@ class PolyfaceQuery {
|
|
|
250849
251038
|
const oldFacetVisitor = polyface.createVisitor(2); // This is to visit the existing facets.
|
|
250850
251039
|
const newFacetVisitor = polyface.createVisitor(0); // This is to build the new facets.
|
|
250851
251040
|
const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create();
|
|
250852
|
-
const vector01 =
|
|
250853
|
-
const vector12 =
|
|
251041
|
+
const vector01 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
|
|
251042
|
+
const vector12 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
|
|
250854
251043
|
const numPoint = polyface.data.point.length;
|
|
250855
251044
|
const pointState = new Int32Array(numPoint);
|
|
250856
251045
|
// FIRST PASS -- in each sector of each facet, determine if the sector has colinear incoming and outgoing vectors.
|
|
@@ -250897,7 +251086,7 @@ class PolyfaceQuery {
|
|
|
250897
251086
|
*/
|
|
250898
251087
|
static setEdgeVisibility(polyface, clusters, value) {
|
|
250899
251088
|
for (const cluster of clusters) {
|
|
250900
|
-
if (cluster instanceof
|
|
251089
|
+
if (cluster instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge) {
|
|
250901
251090
|
this.setSingleEdgeVisibility(polyface, cluster.facetIndex, cluster.vertexIndexA, value);
|
|
250902
251091
|
}
|
|
250903
251092
|
else if (Array.isArray(cluster)) {
|
|
@@ -250940,9 +251129,9 @@ class PolyfaceQuery {
|
|
|
250940
251129
|
* @param polyface a mesh, or a visitor assumed to have numWrap === 1
|
|
250941
251130
|
*/
|
|
250942
251131
|
static createIndexedEdges(polyface) {
|
|
250943
|
-
if (polyface instanceof
|
|
251132
|
+
if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
|
|
250944
251133
|
return this.createIndexedEdges(polyface.createVisitor(1));
|
|
250945
|
-
const edges = new
|
|
251134
|
+
const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
|
|
250946
251135
|
polyface.reset();
|
|
250947
251136
|
while (polyface.moveToNextFacet()) {
|
|
250948
251137
|
const numEdges = polyface.pointCount - 1;
|
|
@@ -250961,17 +251150,17 @@ class PolyfaceQuery {
|
|
|
250961
251150
|
* @param sharpEdges true to reverse the angle threshold test and return sharp edges; otherwise return smooth edges (default)
|
|
250962
251151
|
*/
|
|
250963
251152
|
static collectEdgesByDihedralAngle(mesh, maxSmoothEdgeAngle, sharpEdges = false) {
|
|
250964
|
-
if (mesh instanceof
|
|
251153
|
+
if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
|
|
250965
251154
|
return this.collectEdgesByDihedralAngle(mesh.createVisitor(1), maxSmoothEdgeAngle, sharpEdges);
|
|
250966
251155
|
mesh.setNumWrap(1);
|
|
250967
251156
|
const allEdges = this.createIndexedEdges(mesh);
|
|
250968
251157
|
const manifoldEdges = [];
|
|
250969
251158
|
allEdges.sortAndCollectClusters(manifoldEdges);
|
|
250970
251159
|
if (undefined === maxSmoothEdgeAngle || maxSmoothEdgeAngle.radians < 0)
|
|
250971
|
-
maxSmoothEdgeAngle =
|
|
251160
|
+
maxSmoothEdgeAngle = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createRadians(_Geometry__WEBPACK_IMPORTED_MODULE_6__.Geometry.smallAngleRadians);
|
|
250972
251161
|
const outEdges = [];
|
|
250973
|
-
const normal0 =
|
|
250974
|
-
const normal1 =
|
|
251162
|
+
const normal0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
|
|
251163
|
+
const normal1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
|
|
250975
251164
|
for (const pair of manifoldEdges) {
|
|
250976
251165
|
if (Array.isArray(pair) && pair.length === 2) {
|
|
250977
251166
|
const e0 = pair[0];
|
|
@@ -251010,8 +251199,8 @@ class PolyfaceQuery {
|
|
|
251010
251199
|
this.markAllEdgeVisibility(mesh, false);
|
|
251011
251200
|
this.setEdgeVisibility(mesh, boundaryEdges, true);
|
|
251012
251201
|
if (sharpEdgeAngle !== undefined) {
|
|
251013
|
-
const normal0 =
|
|
251014
|
-
const normal1 =
|
|
251202
|
+
const normal0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
|
|
251203
|
+
const normal1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
|
|
251015
251204
|
for (const pair of pairedEdges) {
|
|
251016
251205
|
if (Array.isArray(pair) && pair.length === 2) {
|
|
251017
251206
|
const e0 = pair[0];
|
|
@@ -251033,9 +251222,9 @@ class PolyfaceQuery {
|
|
|
251033
251222
|
*/
|
|
251034
251223
|
static computeFacetUnitNormal(visitor, facetIndex, result) {
|
|
251035
251224
|
if (!result)
|
|
251036
|
-
result =
|
|
251225
|
+
result = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
|
|
251037
251226
|
if (visitor.moveToReadIndex(facetIndex)) {
|
|
251038
|
-
if (
|
|
251227
|
+
if (_geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.unitNormal(visitor.point, result))
|
|
251039
251228
|
return result;
|
|
251040
251229
|
}
|
|
251041
251230
|
return undefined;
|
|
@@ -251050,20 +251239,41 @@ class PolyfaceQuery {
|
|
|
251050
251239
|
for (let i = 0; i < data.edgeVisible.length; i++)
|
|
251051
251240
|
data.edgeVisible[i] = value;
|
|
251052
251241
|
}
|
|
251242
|
+
/**
|
|
251243
|
+
* Create a HalfEdgeGraph with a face for each facet of the IndexedPolyface
|
|
251244
|
+
* @param mesh mesh to convert
|
|
251245
|
+
* @internal
|
|
251246
|
+
*/
|
|
251247
|
+
static convertToHalfEdgeGraph(mesh) {
|
|
251248
|
+
const builder = new _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_28__.HalfEdgeGraphFromIndexedLoopsContext();
|
|
251249
|
+
const visitor = mesh.createVisitor(0);
|
|
251250
|
+
for (visitor.reset(); visitor.moveToNextFacet();) {
|
|
251251
|
+
builder.insertLoop(visitor.pointIndex);
|
|
251252
|
+
}
|
|
251253
|
+
const graph = builder.graph;
|
|
251254
|
+
const xyz = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
251255
|
+
graph.announceNodes((_graph, halfEdge) => {
|
|
251256
|
+
const vertexIndex = halfEdge.i;
|
|
251257
|
+
mesh.data.getPoint(vertexIndex, xyz);
|
|
251258
|
+
halfEdge.setXYZ(xyz);
|
|
251259
|
+
return true;
|
|
251260
|
+
});
|
|
251261
|
+
return graph;
|
|
251262
|
+
}
|
|
251053
251263
|
/**
|
|
251054
251264
|
* * Examine adjacent facet orientations throughout the mesh
|
|
251055
251265
|
* * If possible, reverse a subset to achieve proper pairing.
|
|
251056
251266
|
* @param mesh
|
|
251057
251267
|
*/
|
|
251058
251268
|
static reorientVertexOrderAroundFacetsForConsistentOrientation(mesh) {
|
|
251059
|
-
return
|
|
251269
|
+
return _FacetOrientation__WEBPACK_IMPORTED_MODULE_29__.FacetOrientationFixup.doFixup(mesh);
|
|
251060
251270
|
}
|
|
251061
251271
|
/**
|
|
251062
251272
|
* Set up indexed normals with one normal in the plane of each facet of the mesh.
|
|
251063
251273
|
* @param polyface
|
|
251064
251274
|
*/
|
|
251065
251275
|
static buildPerFaceNormals(polyface) {
|
|
251066
|
-
|
|
251276
|
+
_multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_30__.BuildAverageNormalsContext.buildPerFaceNormals(polyface);
|
|
251067
251277
|
}
|
|
251068
251278
|
/**
|
|
251069
251279
|
* * At each vertex of the mesh
|
|
@@ -251075,8 +251285,21 @@ class PolyfaceQuery {
|
|
|
251075
251285
|
* @param polyface polyface to update.
|
|
251076
251286
|
* @param toleranceAngle averaging is done between normals up to this angle.
|
|
251077
251287
|
*/
|
|
251078
|
-
static buildAverageNormals(polyface, toleranceAngle =
|
|
251079
|
-
|
|
251288
|
+
static buildAverageNormals(polyface, toleranceAngle = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(31.0)) {
|
|
251289
|
+
_multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_30__.BuildAverageNormalsContext.buildFastAverageNormals(polyface, toleranceAngle);
|
|
251290
|
+
}
|
|
251291
|
+
/**
|
|
251292
|
+
* Offset the faces of the mesh.
|
|
251293
|
+
* @param source original mesh
|
|
251294
|
+
* @param signedOffsetDistance distance to offset
|
|
251295
|
+
* @param offsetOptions angle options. The default options are recommended.
|
|
251296
|
+
* @returns shifted mesh.
|
|
251297
|
+
*/
|
|
251298
|
+
static cloneOffset(source, signedOffsetDistance, offsetOptions = OffsetMeshOptions.create()) {
|
|
251299
|
+
const strokeOptions = _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_23__.StrokeOptions.createForFacets();
|
|
251300
|
+
const offsetBuilder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create(strokeOptions);
|
|
251301
|
+
_multiclip_OffsetMeshContext__WEBPACK_IMPORTED_MODULE_31__.OffsetMeshContext.buildOffsetMeshWithEdgeChamfers(source, offsetBuilder, signedOffsetDistance, offsetOptions);
|
|
251302
|
+
return offsetBuilder.claimPolyface();
|
|
251080
251303
|
}
|
|
251081
251304
|
}
|
|
251082
251305
|
// amount of computation to do per step of async methods.
|
|
@@ -251988,6 +252211,1064 @@ class LinearSearchRange2dArray {
|
|
|
251988
252211
|
}
|
|
251989
252212
|
|
|
251990
252213
|
|
|
252214
|
+
/***/ }),
|
|
252215
|
+
|
|
252216
|
+
/***/ "../../core/geometry/lib/esm/polyface/multiclip/OffsetMeshContext.js":
|
|
252217
|
+
/*!***************************************************************************!*\
|
|
252218
|
+
!*** ../../core/geometry/lib/esm/polyface/multiclip/OffsetMeshContext.js ***!
|
|
252219
|
+
\***************************************************************************/
|
|
252220
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
252221
|
+
|
|
252222
|
+
"use strict";
|
|
252223
|
+
__webpack_require__.r(__webpack_exports__);
|
|
252224
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
252225
|
+
/* harmony export */ "FacetOffsetProperties": () => (/* binding */ FacetOffsetProperties),
|
|
252226
|
+
/* harmony export */ "OffsetMeshContext": () => (/* binding */ OffsetMeshContext),
|
|
252227
|
+
/* harmony export */ "SectorOffsetProperties": () => (/* binding */ SectorOffsetProperties)
|
|
252228
|
+
/* harmony export */ });
|
|
252229
|
+
/* harmony import */ var _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../numerics/Polynomials */ "../../core/geometry/lib/esm/numerics/Polynomials.js");
|
|
252230
|
+
/* harmony import */ var _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../geometry3d/GrowableXYZArray */ "../../core/geometry/lib/esm/geometry3d/GrowableXYZArray.js");
|
|
252231
|
+
/* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
|
|
252232
|
+
/* harmony import */ var _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../geometry3d/PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
|
|
252233
|
+
/* harmony import */ var _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../geometry3d/Ray3d */ "../../core/geometry/lib/esm/geometry3d/Ray3d.js");
|
|
252234
|
+
/* harmony import */ var _topology_Graph__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../topology/Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
|
|
252235
|
+
/* harmony import */ var _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../topology/HalfEdgeGraphFromIndexedLoopsContext */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js");
|
|
252236
|
+
/* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
|
|
252237
|
+
/* harmony import */ var _geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../geometry3d/PolylineCompressionByEdgeOffset */ "../../core/geometry/lib/esm/geometry3d/PolylineCompressionByEdgeOffset.js");
|
|
252238
|
+
/* harmony import */ var _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../geometry3d/Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
|
|
252239
|
+
/*---------------------------------------------------------------------------------------------
|
|
252240
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
252241
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
252242
|
+
*--------------------------------------------------------------------------------------------*/
|
|
252243
|
+
/** @packageDocumentation
|
|
252244
|
+
* @module Polyface
|
|
252245
|
+
*/
|
|
252246
|
+
|
|
252247
|
+
|
|
252248
|
+
|
|
252249
|
+
|
|
252250
|
+
|
|
252251
|
+
|
|
252252
|
+
|
|
252253
|
+
|
|
252254
|
+
|
|
252255
|
+
|
|
252256
|
+
function isDefinedAndTrue(value) {
|
|
252257
|
+
if (value === undefined)
|
|
252258
|
+
return false;
|
|
252259
|
+
return value;
|
|
252260
|
+
}
|
|
252261
|
+
class AverageNormalData {
|
|
252262
|
+
constructor() {
|
|
252263
|
+
this.numActiveSectors = 0;
|
|
252264
|
+
this.numInactiveSectors = 0; // exterior and sling.
|
|
252265
|
+
this.averageNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create();
|
|
252266
|
+
this.radiansSum = 0.0;
|
|
252267
|
+
this.maxDeviationRadiansFromAverage = 0.0;
|
|
252268
|
+
}
|
|
252269
|
+
clear() {
|
|
252270
|
+
this.numActiveSectors = 0;
|
|
252271
|
+
this.numInactiveSectors = 0; // exterior and sling.
|
|
252272
|
+
this.averageNormal.setZero();
|
|
252273
|
+
this.radiansSum = 0.0;
|
|
252274
|
+
this.maxDeviationRadiansFromAverage = 0.0;
|
|
252275
|
+
}
|
|
252276
|
+
/** Add a normal to the evolving sum, scaled by radians in the corner */
|
|
252277
|
+
accumulateNormal(node, normal, inactiveMask) {
|
|
252278
|
+
if (node.isMaskSet(inactiveMask)) {
|
|
252279
|
+
this.numInactiveSectors++;
|
|
252280
|
+
}
|
|
252281
|
+
else {
|
|
252282
|
+
const sectorSweepRadians = _topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.sectorSweepRadiansXYZ(node, normal);
|
|
252283
|
+
this.averageNormal.addScaledInPlace(normal, sectorSweepRadians);
|
|
252284
|
+
this.radiansSum += sectorSweepRadians;
|
|
252285
|
+
this.numActiveSectors++;
|
|
252286
|
+
}
|
|
252287
|
+
}
|
|
252288
|
+
/** normalize the accumulated normals. */
|
|
252289
|
+
finishNormalAveraging() {
|
|
252290
|
+
if (this.numActiveSectors > 0 && this.averageNormal.normalizeInPlace()) {
|
|
252291
|
+
return true;
|
|
252292
|
+
}
|
|
252293
|
+
return false;
|
|
252294
|
+
}
|
|
252295
|
+
/** Compute the deviation from average. update max deviation member */
|
|
252296
|
+
recordDeviation(normal, isActive) {
|
|
252297
|
+
if (isActive) {
|
|
252298
|
+
const radians = this.averageNormal.radiansTo(normal);
|
|
252299
|
+
this.maxDeviationRadiansFromAverage = Math.max(Math.abs(this.maxDeviationRadiansFromAverage), radians);
|
|
252300
|
+
}
|
|
252301
|
+
else {
|
|
252302
|
+
}
|
|
252303
|
+
}
|
|
252304
|
+
/** Return the max deviation as computed on prior calls to recordDeviation */
|
|
252305
|
+
get maxDeviationRadians() { return this.maxDeviationRadiansFromAverage; }
|
|
252306
|
+
}
|
|
252307
|
+
function emitSector(sector) {
|
|
252308
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined) {
|
|
252309
|
+
OffsetMeshContext.stringDebugFunction(` Sector xyz ${sector.xyz.x},${sector.xyz.y},${sector.xyz.z} `);
|
|
252310
|
+
OffsetMeshContext.stringDebugFunction(` normal ${sector.normal.x},${sector.normal.y},${sector.normal.z} `);
|
|
252311
|
+
}
|
|
252312
|
+
}
|
|
252313
|
+
// facet properties used during offset.
|
|
252314
|
+
//
|
|
252315
|
+
class FacetOffsetProperties {
|
|
252316
|
+
constructor(facetIndex, normal) {
|
|
252317
|
+
this.facetIndex = facetIndex;
|
|
252318
|
+
this.facetNormal = normal;
|
|
252319
|
+
}
|
|
252320
|
+
}
|
|
252321
|
+
/**
|
|
252322
|
+
* Sector properties during offset.
|
|
252323
|
+
* * this.normal may be initially assigned as the facet normal but can mutate by
|
|
252324
|
+
* averaging with neighbors.
|
|
252325
|
+
* * this.xyz is initially the base mesh xyz but is expected to move along the normal.
|
|
252326
|
+
* * this.count is used locally in computations.
|
|
252327
|
+
*/
|
|
252328
|
+
class SectorOffsetProperties {
|
|
252329
|
+
constructor(normal, xyz) {
|
|
252330
|
+
this.xyz = xyz;
|
|
252331
|
+
this.normal = normal;
|
|
252332
|
+
this.count = 0;
|
|
252333
|
+
}
|
|
252334
|
+
/**
|
|
252335
|
+
* Compute the angle between plane normals on opposite sides of the edge.
|
|
252336
|
+
* * parallel normals have zero angle.
|
|
252337
|
+
* * if the edge cuts inward to the volume behind the faces, the angle is negative.
|
|
252338
|
+
* * if the edge is outward (a convex edge) the the volume, the angle is positive.
|
|
252339
|
+
* @param edgeNodeA node on one side of the edge
|
|
252340
|
+
* @param edgeVector pre-allocated vector to receive vector along edge.
|
|
252341
|
+
* @param averageNormal pre-allocated vector to receive the average normal for a chamfer of the offset edge.
|
|
252342
|
+
* @param offsetDistance distance of offset being constructed. The sign of this resolves angle ambiguity.
|
|
252343
|
+
* @param radiansTolerance tolerance for large angle between normals.
|
|
252344
|
+
* @returns true if this edge has SectorOffsetProperties on both sides and the angle between normals angle exceeds radiansTolerance.
|
|
252345
|
+
*/
|
|
252346
|
+
static edgeHasLargeExteriorAngleBetweenNormals(edgeNodeA, edgeVector, averageNormal, offsetDistance, radiansTolerance = Math.PI * 0.5) {
|
|
252347
|
+
const propsA = edgeNodeA.edgeTag;
|
|
252348
|
+
const edgeNodeB = edgeNodeA.edgeMate;
|
|
252349
|
+
const propsB = edgeNodeB.edgeTag;
|
|
252350
|
+
if (propsA !== undefined && propsB !== undefined) {
|
|
252351
|
+
edgeNodeA.vectorToFaceSuccessor(edgeVector);
|
|
252352
|
+
const radians = propsA.normal.signedRadiansTo(propsB.normal, edgeVector);
|
|
252353
|
+
if (_Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.split3WaySign(offsetDistance, -1, 1, 1) * radians >= radiansTolerance) {
|
|
252354
|
+
_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.createAdd2Scaled(propsA.normal, 1.0, propsB.normal, 1.0, averageNormal);
|
|
252355
|
+
if (averageNormal.normalizeInPlace())
|
|
252356
|
+
return true;
|
|
252357
|
+
}
|
|
252358
|
+
}
|
|
252359
|
+
return false;
|
|
252360
|
+
}
|
|
252361
|
+
static almostEqualNormals(sectorA, sectorB, radiansTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallAngleRadians) {
|
|
252362
|
+
return sectorA.normal.radiansTo(sectorB.normal) <= radiansTolerance;
|
|
252363
|
+
}
|
|
252364
|
+
static radiansBetweenNormals(sectorA, sectorB) {
|
|
252365
|
+
return sectorA.normal.radiansTo(sectorB.normal);
|
|
252366
|
+
}
|
|
252367
|
+
// Set the offset point this.xyz as sum of the nodeXyz + distance * this.normal
|
|
252368
|
+
setOffsetPointAtDistanceAtHalfEdge(halfEdge, distance) {
|
|
252369
|
+
halfEdge.getPoint3d(this.xyz);
|
|
252370
|
+
this.xyz.addScaledInPlace(this.normal, distance);
|
|
252371
|
+
}
|
|
252372
|
+
// Copy xyz from parameter into (preexisting object) xyz
|
|
252373
|
+
static setXYZAtHalfEdge(halfEdge, xyz) {
|
|
252374
|
+
const props = halfEdge.edgeTag;
|
|
252375
|
+
if (props !== undefined && xyz !== undefined)
|
|
252376
|
+
props.xyz.set(xyz.x, xyz.y, xyz.z);
|
|
252377
|
+
}
|
|
252378
|
+
// Set the offset point this.xyz directly
|
|
252379
|
+
setXYAndZ(xyz) {
|
|
252380
|
+
this.xyz.set(xyz.x, xyz.y, xyz.z);
|
|
252381
|
+
}
|
|
252382
|
+
// Look through the half edge to its properties. Set the normal there. Optionally set xyz from node xyz and offset distance
|
|
252383
|
+
static setNormalAtHalfEdge(halfEdge, uvw, distance) {
|
|
252384
|
+
const props = halfEdge.edgeTag;
|
|
252385
|
+
if (props !== undefined) {
|
|
252386
|
+
props.normal.set(uvw.x, uvw.y, uvw.z);
|
|
252387
|
+
if (distance !== undefined)
|
|
252388
|
+
props.setOffsetPointAtDistanceAtHalfEdge(halfEdge, distance);
|
|
252389
|
+
}
|
|
252390
|
+
}
|
|
252391
|
+
// Look through the half edge and its vertex successor to properties. Get the two normals. Return the angle sweeping from one to the next
|
|
252392
|
+
static sweepRadiansAroundNormal(nodeA, upVector) {
|
|
252393
|
+
const propsA = nodeA.edgeTag;
|
|
252394
|
+
const propsB = nodeA.vertexSuccessor.edgeTag;
|
|
252395
|
+
if (propsA !== undefined && propsB !== undefined) {
|
|
252396
|
+
return propsA.normal.planarRadiansTo(propsB.normal, upVector);
|
|
252397
|
+
}
|
|
252398
|
+
return undefined;
|
|
252399
|
+
}
|
|
252400
|
+
// Look through the half edge to its properties. return (if possible) the coordinates
|
|
252401
|
+
static getSectorPointAtHalfEdge(halfEdge, xyz, xyzArray) {
|
|
252402
|
+
const props = halfEdge.edgeTag;
|
|
252403
|
+
if (props !== undefined) {
|
|
252404
|
+
if (xyz !== undefined)
|
|
252405
|
+
xyz.setFromPoint3d(props.xyz);
|
|
252406
|
+
if (xyzArray !== undefined)
|
|
252407
|
+
xyzArray.push(props.xyz);
|
|
252408
|
+
return true;
|
|
252409
|
+
}
|
|
252410
|
+
return false;
|
|
252411
|
+
}
|
|
252412
|
+
// access the XYZ and push to the array (which makes copies, not reference)
|
|
252413
|
+
// return pointer to the SectorOffsetProperties
|
|
252414
|
+
static pushXYZ(xyzArray, halfEdge) {
|
|
252415
|
+
const sector = halfEdge.edgeTag;
|
|
252416
|
+
if (sector !== undefined)
|
|
252417
|
+
xyzArray.push(sector.xyz);
|
|
252418
|
+
return sector;
|
|
252419
|
+
}
|
|
252420
|
+
// Dereference to execute: accumulatingVector += halfEdge.edgeTag.normal * scale
|
|
252421
|
+
static accumulateScaledNormalAtHalfEdge(halfEdge, scale, accumulatingVector) {
|
|
252422
|
+
const sector = halfEdge.edgeTag;
|
|
252423
|
+
if (sector !== undefined)
|
|
252424
|
+
accumulatingVector.addScaledInPlace(sector.normal, scale);
|
|
252425
|
+
}
|
|
252426
|
+
}
|
|
252427
|
+
/*
|
|
252428
|
+
About Chamfer Edges ..... as constructed in addChamferTopologyToAllEdges
|
|
252429
|
+
|
|
252430
|
+
When edge vertex X to vertex Y has a sharp angle between normals, a "chamfer face" must be created to "fatten" it.
|
|
252431
|
+
|
|
252432
|
+
The original half edges (nodes) for the edge are AX and AY. These are "mates" in the halfEdge mental model. As always,
|
|
252433
|
+
AX is (as needed)
|
|
252434
|
+
(i) the preferred half edge for the left side of the edge moving from X to Y. (i.e. above the edge)
|
|
252435
|
+
(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
|
|
252436
|
+
(iii) a part of the vertex loop around X
|
|
252437
|
+
Likewise, AY is (as needed)
|
|
252438
|
+
(i) the preferred half edge for the left side of the edge moving from Y to X (i.e. below the edge)
|
|
252439
|
+
(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.
|
|
252440
|
+
(iii) a part of the vertex loop around Y
|
|
252441
|
+
|
|
252442
|
+
AX------>
|
|
252443
|
+
X______________________________________________________________________Y
|
|
252444
|
+
<---AY
|
|
252445
|
+
|
|
252446
|
+
When the chamfer face is created, it needs to have a sliver face "inside the edge" -- something in the space here
|
|
252447
|
+
|
|
252448
|
+
AX------>
|
|
252449
|
+
_____________________________________________________________________
|
|
252450
|
+
/ \
|
|
252451
|
+
X Y
|
|
252452
|
+
\_____________________________________________________________________/
|
|
252453
|
+
<---AY
|
|
252454
|
+
|
|
252455
|
+
The chamfer face will have a plane normal is the average of the two faces' plane normals.
|
|
252456
|
+
|
|
252457
|
+
The creation sequence for the chamfer face puts a slit "inside the edge" as above HalfEdges AX and AY remain as parts
|
|
252458
|
+
of their respective face loops. In addition, at each end a singleton edge "sling" face is inserted at each
|
|
252459
|
+
end of the sliver face.
|
|
252460
|
+
|
|
252461
|
+
The sequence is:
|
|
252462
|
+
|
|
252463
|
+
STEP 1: splitEdgeCreateSliver creates the sliver face with 2 half edges DX and DY
|
|
252464
|
+
STEP 2: splitEdge (with undefined as the "prior" edge) creates a sling with HalfEdge CX "inside" and BX "outside".
|
|
252465
|
+
(The sling face is not yet attached to X -- briefly floating in space)
|
|
252466
|
+
STEP 3: pinch of HalfEdges BX and DX inserts the sling face "inside" the slit face at the X end.
|
|
252467
|
+
|
|
252468
|
+
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.
|
|
252469
|
+
|
|
252470
|
+
AX------>
|
|
252471
|
+
_______________________________________________________________
|
|
252472
|
+
/ <---DY \
|
|
252473
|
+
/ \
|
|
252474
|
+
/ BX---> \
|
|
252475
|
+
/ _______________ _______________ \
|
|
252476
|
+
| / \ / <----CY \ |
|
|
252477
|
+
|/ \ / \|
|
|
252478
|
+
X | | Y
|
|
252479
|
+
|\ CX---> / \ /|
|
|
252480
|
+
| \_______________/ \_______________/ |
|
|
252481
|
+
\ <---BY /
|
|
252482
|
+
\ /
|
|
252483
|
+
\ DX---> /
|
|
252484
|
+
\ ______________________________________________________________/
|
|
252485
|
+
<---AY
|
|
252486
|
+
|
|
252487
|
+
During the construction, the letters ABCD are used as above, but with prefixes emphasizing their role
|
|
252488
|
+
outsideAX, outsideAY
|
|
252489
|
+
slingB, slingC, sliverD
|
|
252490
|
+
|
|
252491
|
+
The "inside" sling faces (CX and CY) each have their own FacetOffsetProperties and SectorOffsetProperties.
|
|
252492
|
+
The sliver face has its own FacetOffsetProperties which are referenced by DX, BY, DY, BX.
|
|
252493
|
+
Each of those 4 has its own SectorOffSetProperties.
|
|
252494
|
+
|
|
252495
|
+
Important properties during offset construction:
|
|
252496
|
+
1) the original graph always has original topology and coordinates
|
|
252497
|
+
2) Each face of the original graph has a FacetOffsetProperties with a representative point and a normal. These are unchanged during the computation.
|
|
252498
|
+
3) Each node has its own SectorOffsetProperties with a coordinate and normal independent of the parent node.
|
|
252499
|
+
3.1 The first offset coordinates in each node are directly offset by face normal.
|
|
252500
|
+
3.2 This creates mismatch across edges and around vertices.
|
|
252501
|
+
3.3 Various sweeps "around each vertex" try to do intersections among appropriate offset planes to find
|
|
252502
|
+
common coordinates in place of the initial mismatches.
|
|
252503
|
+
4) The independence of all the sectors allows the offset construction to fix things up in any order it chooses.
|
|
252504
|
+
5) During the construction, the xyz in SectorOffsetProperties around a single vertex do NOT have to match.
|
|
252505
|
+
6) At output time, there are three sweeps:
|
|
252506
|
+
6.1: By face: Go around the face and output a facet with the coordinates in the various sectors.
|
|
252507
|
+
6.2: By edge: For each edge, if the sector xyz match across both ends output nothing. If not, output a triangle or quad
|
|
252508
|
+
6.3: By vertex: At each vertex, if all vertex coordinates match output nothing. Otherwise output a facet with all the coordinates.
|
|
252509
|
+
*/
|
|
252510
|
+
class OffsetMeshContext {
|
|
252511
|
+
constructor(basePolyface, baseGraph, options) {
|
|
252512
|
+
this._basePolyface = basePolyface;
|
|
252513
|
+
this._baseGraph = baseGraph;
|
|
252514
|
+
this._breakMaskA = baseGraph.grabMask();
|
|
252515
|
+
this._breakMaskB = baseGraph.grabMask();
|
|
252516
|
+
this._insideOfChamferFace = baseGraph.grabMask();
|
|
252517
|
+
this._outsideOfChamferFace = baseGraph.grabMask();
|
|
252518
|
+
this._insideChamferSling = baseGraph.grabMask();
|
|
252519
|
+
this._outsideEndOfChamferFace = baseGraph.grabMask();
|
|
252520
|
+
this._exteriorMask = _topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdgeMask.EXTERIOR;
|
|
252521
|
+
this._offsetCoordinatesReassigned = baseGraph.grabMask();
|
|
252522
|
+
this._smoothRadiansBetweenNormals = options.smoothSingleAngleBetweenNormals.radians;
|
|
252523
|
+
this._chamferTurnRadians = options.chamferAngleBetweenNormals.radians;
|
|
252524
|
+
this._smoothAccumulatedRadiansBetweenNormals = options.smoothAccumulatedAngleBetweenNormals.radians;
|
|
252525
|
+
}
|
|
252526
|
+
/** "Exterior" side of a bare edge of the mesh */
|
|
252527
|
+
get exteriorMask() { return this._exteriorMask; }
|
|
252528
|
+
/** "First" sector of a smooth sequence. */
|
|
252529
|
+
get breakMaskA() { return this._breakMaskA; }
|
|
252530
|
+
/** "Last" sector of a smooth sequence. */
|
|
252531
|
+
get breakMaskB() { return this._breakMaskB; }
|
|
252532
|
+
/** This edge is on a chamfered face, and along the original edge */
|
|
252533
|
+
get insideOfChamferFace() { return this._insideOfChamferFace; }
|
|
252534
|
+
/** This is the original edge of a chamfer face */
|
|
252535
|
+
get outsideOfChamferFace() { return this._outsideOfChamferFace; }
|
|
252536
|
+
/** This edge is on a chamfered face, and at the end -- other side may be a sling */
|
|
252537
|
+
get insideChamferSling() { return this._insideChamferSling; }
|
|
252538
|
+
/** This is the outside of the end of a chamfer face -- i.e. the inside of a new face-at-vertex */
|
|
252539
|
+
get outsideEndOfChamferFace() { return this._outsideEndOfChamferFace; }
|
|
252540
|
+
// At each node . .
|
|
252541
|
+
// * Find the sector data
|
|
252542
|
+
// * recompute the sector point using node XYZ and sectorData normal.
|
|
252543
|
+
applyFaceNormalOffsetsToSectorData(distance) {
|
|
252544
|
+
this._baseGraph.announceNodes((_graph, node) => {
|
|
252545
|
+
const sectorData = node.edgeTag;
|
|
252546
|
+
if (sectorData !== undefined) {
|
|
252547
|
+
sectorData.setOffsetPointAtDistanceAtHalfEdge(node, distance);
|
|
252548
|
+
}
|
|
252549
|
+
return true;
|
|
252550
|
+
});
|
|
252551
|
+
}
|
|
252552
|
+
/**
|
|
252553
|
+
* * build a mesh offset by given distance.
|
|
252554
|
+
* * output the mesh to the given builder.
|
|
252555
|
+
* @param basePolyface original mesh
|
|
252556
|
+
* @param builder polyface builder to receive the new mesh.
|
|
252557
|
+
* @param distance signed offset distance.
|
|
252558
|
+
*/
|
|
252559
|
+
static buildOffsetMeshWithEdgeChamfers(basePolyface, builder, distance, options) {
|
|
252560
|
+
const baseGraph = this.buildBaseGraph(basePolyface);
|
|
252561
|
+
if (baseGraph !== undefined) {
|
|
252562
|
+
const offsetBuilder = new OffsetMeshContext(basePolyface, baseGraph, options);
|
|
252563
|
+
offsetBuilder.applyFaceNormalOffsetsToSectorData(distance);
|
|
252564
|
+
if (OffsetMeshContext.graphDebugFunction !== undefined)
|
|
252565
|
+
OffsetMeshContext.graphDebugFunction("BaseGraph", baseGraph, offsetBuilder._breakMaskA, offsetBuilder._breakMaskB);
|
|
252566
|
+
const outputSelector = options.outputSelector ? options.outputSelector : {
|
|
252567
|
+
outputOffsetsFromFaces: true,
|
|
252568
|
+
outputOffsetsFromEdges: true,
|
|
252569
|
+
outputOffsetsFromVertices: true,
|
|
252570
|
+
};
|
|
252571
|
+
if (isDefinedAndTrue(outputSelector.outputOffsetsFromFacesBeforeChamfers))
|
|
252572
|
+
offsetBuilder.announceFacetsWithSectorCoordinatesAroundFaces(builder);
|
|
252573
|
+
offsetBuilder.addChamferTopologyToAllEdges(options, distance);
|
|
252574
|
+
offsetBuilder.computeOffsetFacetIntersections(distance);
|
|
252575
|
+
if (OffsetMeshContext.graphDebugFunction !== undefined)
|
|
252576
|
+
OffsetMeshContext.graphDebugFunction("after computeEdgeChamfers", baseGraph, offsetBuilder._breakMaskA, offsetBuilder._breakMaskB);
|
|
252577
|
+
if (isDefinedAndTrue(outputSelector.outputOffsetsFromFaces))
|
|
252578
|
+
offsetBuilder.announceFacetsWithSectorCoordinatesAroundFaces(builder);
|
|
252579
|
+
if (isDefinedAndTrue(outputSelector.outputOffsetsFromEdges))
|
|
252580
|
+
offsetBuilder.announceFacetsWithSectorCoordinatesAroundEdges(builder);
|
|
252581
|
+
if (isDefinedAndTrue(outputSelector.outputOffsetsFromVertices))
|
|
252582
|
+
offsetBuilder.announceFacetsWithSectorCoordinatesAroundVertices(builder);
|
|
252583
|
+
}
|
|
252584
|
+
}
|
|
252585
|
+
/**
|
|
252586
|
+
* For each face of the graph, shift vertices by offsetDistance and emit to the builder as a facet
|
|
252587
|
+
* @param polyfaceBuilder
|
|
252588
|
+
*/
|
|
252589
|
+
announceSimpleOffsetFromFaces(polyfaceBuilder, offsetDistance) {
|
|
252590
|
+
const xyzLoop = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__.GrowableXYZArray();
|
|
252591
|
+
const xyz = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create(); // reused at each point around each facet.
|
|
252592
|
+
const uvw = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create(); // reused once per facet
|
|
252593
|
+
const announceNodeAroundFace = (node) => {
|
|
252594
|
+
node.getPoint3d(xyz);
|
|
252595
|
+
xyz.addInPlace(uvw);
|
|
252596
|
+
xyzLoop.push(xyz);
|
|
252597
|
+
return 0;
|
|
252598
|
+
};
|
|
252599
|
+
this._baseGraph.announceFaceLoops((_graph, seed) => {
|
|
252600
|
+
if (!seed.isMaskSet(_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdgeMask.EXTERIOR)) {
|
|
252601
|
+
const facetProperties = seed.faceTag;
|
|
252602
|
+
uvw.setFromVector3d(facetProperties.facetNormal.direction);
|
|
252603
|
+
uvw.scaleInPlace(offsetDistance);
|
|
252604
|
+
xyzLoop.length = 0;
|
|
252605
|
+
seed.sumAroundFace(announceNodeAroundFace);
|
|
252606
|
+
polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);
|
|
252607
|
+
}
|
|
252608
|
+
return true;
|
|
252609
|
+
});
|
|
252610
|
+
}
|
|
252611
|
+
/**
|
|
252612
|
+
* For each face of the graph, output the xyz of the sector data
|
|
252613
|
+
* @param polyfaceBuilder
|
|
252614
|
+
*/
|
|
252615
|
+
announceFacetsWithSectorCoordinatesAroundFaces(polyfaceBuilder) {
|
|
252616
|
+
const xyzLoop = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__.GrowableXYZArray();
|
|
252617
|
+
// For face loop visits .. get the point from the sector data.
|
|
252618
|
+
const announceNodeAroundFace = (node) => {
|
|
252619
|
+
const sectorData = node.edgeTag;
|
|
252620
|
+
if (sectorData !== undefined) {
|
|
252621
|
+
xyzLoop.push(sectorData.xyz);
|
|
252622
|
+
}
|
|
252623
|
+
return 0;
|
|
252624
|
+
};
|
|
252625
|
+
this._baseGraph.announceFaceLoops((_graph, seed) => {
|
|
252626
|
+
if (!seed.isMaskSet(_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdgeMask.EXTERIOR)) {
|
|
252627
|
+
xyzLoop.length = 0;
|
|
252628
|
+
seed.sumAroundFace(announceNodeAroundFace);
|
|
252629
|
+
if (xyzLoop.length > 2)
|
|
252630
|
+
polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);
|
|
252631
|
+
}
|
|
252632
|
+
return true;
|
|
252633
|
+
});
|
|
252634
|
+
}
|
|
252635
|
+
countBits(mask) {
|
|
252636
|
+
let n = 0;
|
|
252637
|
+
let mask1 = mask;
|
|
252638
|
+
while (mask1 !== 0) {
|
|
252639
|
+
if (mask1 & 0x01)
|
|
252640
|
+
n++;
|
|
252641
|
+
mask1 = mask1 >> 1;
|
|
252642
|
+
}
|
|
252643
|
+
return n;
|
|
252644
|
+
}
|
|
252645
|
+
/**
|
|
252646
|
+
* For each edge of the graph . .
|
|
252647
|
+
* * Collect coordinates in 4 sectors going around the edge
|
|
252648
|
+
* * Compress with tight tolerance so adjacent sectors with clean point match reduce to a single point.
|
|
252649
|
+
* * Emit as a facet.
|
|
252650
|
+
* @param polyfaceBuilder
|
|
252651
|
+
*/
|
|
252652
|
+
announceFacetsWithSectorCoordinatesAroundEdges(polyfaceBuilder) {
|
|
252653
|
+
const xyzLoop = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__.GrowableXYZArray();
|
|
252654
|
+
const primaryCompressionTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallMetricDistance;
|
|
252655
|
+
const allMasksForEdgesToIgnore = this._exteriorMask
|
|
252656
|
+
| this._outsideEndOfChamferFace
|
|
252657
|
+
| this._outsideOfChamferFace
|
|
252658
|
+
| this._insideOfChamferFace
|
|
252659
|
+
| this._insideChamferSling;
|
|
252660
|
+
this._baseGraph.announceEdges((_graph, nodeA) => {
|
|
252661
|
+
// This starts by looking for EXTERIOR on both sides ...
|
|
252662
|
+
if (nodeA.findMaskAroundEdge(this._exteriorMask) !== undefined) {
|
|
252663
|
+
return true;
|
|
252664
|
+
}
|
|
252665
|
+
else if (!nodeA.isMaskSet(allMasksForEdgesToIgnore)) { // By design, we believe that these two test for allMasksForEdgesToIgnore condition would catch the EXTERIOR case above
|
|
252666
|
+
const nodeB = nodeA.faceSuccessor;
|
|
252667
|
+
const nodeC = nodeA.edgeMate;
|
|
252668
|
+
if (!nodeC.isMaskSet(allMasksForEdgesToIgnore)) {
|
|
252669
|
+
const nodeD = nodeC.faceSuccessor;
|
|
252670
|
+
xyzLoop.clear();
|
|
252671
|
+
SectorOffsetProperties.getSectorPointAtHalfEdge(nodeA, undefined, xyzLoop);
|
|
252672
|
+
SectorOffsetProperties.getSectorPointAtHalfEdge(nodeB, undefined, xyzLoop);
|
|
252673
|
+
SectorOffsetProperties.getSectorPointAtHalfEdge(nodeC, undefined, xyzLoop);
|
|
252674
|
+
SectorOffsetProperties.getSectorPointAtHalfEdge(nodeD, undefined, xyzLoop);
|
|
252675
|
+
_geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_4__.PolylineCompressionContext.compressInPlaceByShortEdgeLength(xyzLoop, primaryCompressionTolerance);
|
|
252676
|
+
if (xyzLoop.length > 2) {
|
|
252677
|
+
polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);
|
|
252678
|
+
}
|
|
252679
|
+
}
|
|
252680
|
+
}
|
|
252681
|
+
else {
|
|
252682
|
+
return true;
|
|
252683
|
+
}
|
|
252684
|
+
return true;
|
|
252685
|
+
});
|
|
252686
|
+
}
|
|
252687
|
+
getCoordinateString(node, showXYZ = true, showFaceSuccessorXYZ = false) {
|
|
252688
|
+
if (showXYZ) {
|
|
252689
|
+
if (showFaceSuccessorXYZ) {
|
|
252690
|
+
return `${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(node)} ==> ${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(node.faceSuccessor)}`;
|
|
252691
|
+
}
|
|
252692
|
+
else {
|
|
252693
|
+
return `${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(node)}`;
|
|
252694
|
+
}
|
|
252695
|
+
}
|
|
252696
|
+
else {
|
|
252697
|
+
if (showFaceSuccessorXYZ) {
|
|
252698
|
+
return `==> ${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(node.faceSuccessor)}`;
|
|
252699
|
+
}
|
|
252700
|
+
else {
|
|
252701
|
+
return "";
|
|
252702
|
+
}
|
|
252703
|
+
}
|
|
252704
|
+
}
|
|
252705
|
+
inspectMasks(node, showXYZ = true, showFaceSuccessorXYZ = false) {
|
|
252706
|
+
const s = "[";
|
|
252707
|
+
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), "]");
|
|
252708
|
+
return v;
|
|
252709
|
+
}
|
|
252710
|
+
/**
|
|
252711
|
+
* For each face of the graph, output the xyz of the sector data
|
|
252712
|
+
* @param polyfaceBuilder
|
|
252713
|
+
*/
|
|
252714
|
+
announceFacetsWithSectorCoordinatesAroundVertices(polyfaceBuilder) {
|
|
252715
|
+
const xyzLoop = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__.GrowableXYZArray();
|
|
252716
|
+
const primaryCompressionTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallMetricDistance;
|
|
252717
|
+
this._baseGraph.announceVertexLoops((_graph, seed) => {
|
|
252718
|
+
if (!seed.findMaskAroundVertex(this._exteriorMask)) {
|
|
252719
|
+
xyzLoop.length = 0;
|
|
252720
|
+
seed.sumAroundVertex((node) => {
|
|
252721
|
+
if (!node.isMaskSet(this._insideChamferSling))
|
|
252722
|
+
SectorOffsetProperties.getSectorPointAtHalfEdge(node, undefined, xyzLoop);
|
|
252723
|
+
return 0.0;
|
|
252724
|
+
});
|
|
252725
|
+
_geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_4__.PolylineCompressionContext.compressInPlaceByShortEdgeLength(xyzLoop, primaryCompressionTolerance);
|
|
252726
|
+
if (xyzLoop.length > 2) {
|
|
252727
|
+
polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);
|
|
252728
|
+
}
|
|
252729
|
+
}
|
|
252730
|
+
return true;
|
|
252731
|
+
});
|
|
252732
|
+
}
|
|
252733
|
+
/**
|
|
252734
|
+
* * Exterior half edges have HalfEdgeMask.EXTERIOR
|
|
252735
|
+
* * All interior half edge around a facet have facetTag pointing to a facetProperties object for that facet.
|
|
252736
|
+
* * the facetOffsetProperties object has the simple facet normal.
|
|
252737
|
+
* * Each half edge has edgeTag pointing to to a sectorOffsetProperties object
|
|
252738
|
+
* * the sectorOffsetProperties has a copy of the facet normal.
|
|
252739
|
+
* @param polyface
|
|
252740
|
+
* @returns graph
|
|
252741
|
+
*/
|
|
252742
|
+
static buildBaseGraph(polyface) {
|
|
252743
|
+
const graphBuilder = new _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_5__.HalfEdgeGraphFromIndexedLoopsContext();
|
|
252744
|
+
const visitor = polyface.createVisitor();
|
|
252745
|
+
const xyzA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
|
|
252746
|
+
const xyzB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
|
|
252747
|
+
for (visitor.reset(); visitor.moveToNextFacet();) {
|
|
252748
|
+
const normal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_6__.PolygonOps.centroidAreaNormal(visitor.point);
|
|
252749
|
+
if (normal !== undefined) {
|
|
252750
|
+
const edgeA = graphBuilder.insertLoop(visitor.pointIndex, (insideHalfEdge) => {
|
|
252751
|
+
const mate = insideHalfEdge.edgeMate;
|
|
252752
|
+
polyface.data.getPoint(insideHalfEdge.i, xyzA);
|
|
252753
|
+
insideHalfEdge.setXYZ(xyzA);
|
|
252754
|
+
polyface.data.getPoint(mate.i, xyzB);
|
|
252755
|
+
mate.setXYZ(xyzB);
|
|
252756
|
+
});
|
|
252757
|
+
const facetProperties = new FacetOffsetProperties(visitor.currentReadIndex(), normal);
|
|
252758
|
+
if (edgeA !== undefined) {
|
|
252759
|
+
edgeA.sumAroundFace((edgeB) => {
|
|
252760
|
+
edgeB.faceTag = facetProperties;
|
|
252761
|
+
edgeB.edgeTag = new SectorOffsetProperties(normal.direction.clone(), edgeB.getPoint3d());
|
|
252762
|
+
return 0;
|
|
252763
|
+
});
|
|
252764
|
+
}
|
|
252765
|
+
}
|
|
252766
|
+
}
|
|
252767
|
+
return graphBuilder.graph;
|
|
252768
|
+
}
|
|
252769
|
+
setOffsetAtDistanceAroundVertex(vertexSeed, distance, ignoreChamfers = false) {
|
|
252770
|
+
vertexSeed.sumAroundVertex((nodeAroundVertex) => {
|
|
252771
|
+
const props = nodeAroundVertex.edgeTag;
|
|
252772
|
+
if (props !== undefined) {
|
|
252773
|
+
if (ignoreChamfers && this.isInsideChamferOrSling(vertexSeed)) {
|
|
252774
|
+
// SKIP !!
|
|
252775
|
+
}
|
|
252776
|
+
else {
|
|
252777
|
+
props.setOffsetPointAtDistanceAtHalfEdge(nodeAroundVertex, distance);
|
|
252778
|
+
}
|
|
252779
|
+
}
|
|
252780
|
+
return 0.0;
|
|
252781
|
+
});
|
|
252782
|
+
}
|
|
252783
|
+
setOffsetXYAndZAroundVertex(vertexSeed, xyz) {
|
|
252784
|
+
vertexSeed.sumAroundVertex((nodeAroundVertex) => {
|
|
252785
|
+
const props = nodeAroundVertex.edgeTag;
|
|
252786
|
+
if (props !== undefined) {
|
|
252787
|
+
props.setXYAndZ(xyz);
|
|
252788
|
+
nodeAroundVertex.setMask(this._offsetCoordinatesReassigned);
|
|
252789
|
+
}
|
|
252790
|
+
return 0.0;
|
|
252791
|
+
});
|
|
252792
|
+
}
|
|
252793
|
+
/**
|
|
252794
|
+
* * start at vertexSeed.
|
|
252795
|
+
* * set the offset point at up to (and including) one with (a) this._breakMaskB or (b) this._exteriorMask
|
|
252796
|
+
* *
|
|
252797
|
+
* @param vertexSeed first node to mark.
|
|
252798
|
+
* @param f function to call to announce each node and its sector properties.
|
|
252799
|
+
* @returns number of nodes marked.
|
|
252800
|
+
*/
|
|
252801
|
+
announceNodeAndSectorPropertiesInSmoothSector(vertexSeed, f) {
|
|
252802
|
+
let n = 0;
|
|
252803
|
+
for (let currentNode = vertexSeed;; currentNode = currentNode.vertexSuccessor) {
|
|
252804
|
+
const props = currentNode.edgeTag;
|
|
252805
|
+
if (props !== undefined) {
|
|
252806
|
+
f(currentNode, props);
|
|
252807
|
+
n++;
|
|
252808
|
+
}
|
|
252809
|
+
if (currentNode.isMaskSet(this._breakMaskB))
|
|
252810
|
+
return n;
|
|
252811
|
+
// REMARK: these additional exit conditions should not happen if (a) the graph is properly marked and (b) the start node is not exterior.
|
|
252812
|
+
if (currentNode.isMaskSet(this._exteriorMask))
|
|
252813
|
+
return n;
|
|
252814
|
+
if (currentNode === vertexSeed && n === 0)
|
|
252815
|
+
return n;
|
|
252816
|
+
}
|
|
252817
|
+
}
|
|
252818
|
+
computeAverageNormalAndMaxDeviationAroundVertex(vertexSeed, data) {
|
|
252819
|
+
data.clear();
|
|
252820
|
+
const inactiveNodeMask = this._exteriorMask | this._insideChamferSling;
|
|
252821
|
+
vertexSeed.sumAroundVertex((node) => {
|
|
252822
|
+
const sectorData = node.edgeTag;
|
|
252823
|
+
if (sectorData)
|
|
252824
|
+
data.accumulateNormal(node, sectorData.normal, inactiveNodeMask);
|
|
252825
|
+
return 0.0;
|
|
252826
|
+
});
|
|
252827
|
+
if (!data.finishNormalAveraging()) {
|
|
252828
|
+
return undefined;
|
|
252829
|
+
}
|
|
252830
|
+
vertexSeed.sumAroundVertex((node) => {
|
|
252831
|
+
const sectorData = node.edgeTag;
|
|
252832
|
+
if (sectorData)
|
|
252833
|
+
data.recordDeviation(sectorData.normal, !node.isMaskSet(inactiveNodeMask));
|
|
252834
|
+
return 0.0;
|
|
252835
|
+
});
|
|
252836
|
+
return data.maxDeviationRadians;
|
|
252837
|
+
}
|
|
252838
|
+
assignOffsetByAverageNormalAroundVertex(vertexSeed, maxAllowedDeviationRadians, data, distance) {
|
|
252839
|
+
const maxDeviationRadians = this.computeAverageNormalAndMaxDeviationAroundVertex(vertexSeed, data);
|
|
252840
|
+
if (OffsetMeshContext.stringDebugFunction) {
|
|
252841
|
+
OffsetMeshContext.stringDebugFunction(`XYZ ${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(vertexSeed)} Average Normal ${data.averageNormal.toJSON()}`);
|
|
252842
|
+
OffsetMeshContext.stringDebugFunction(` angle ratio ${data.radiansSum / (2 * Math.PI)} maxDeviation ${data.maxDeviationRadiansFromAverage}`);
|
|
252843
|
+
}
|
|
252844
|
+
if (maxDeviationRadians !== undefined && maxDeviationRadians <= maxAllowedDeviationRadians) {
|
|
252845
|
+
vertexSeed.sumAroundVertex((node) => {
|
|
252846
|
+
SectorOffsetProperties.setNormalAtHalfEdge(node, data.averageNormal, distance);
|
|
252847
|
+
return 0;
|
|
252848
|
+
});
|
|
252849
|
+
return true;
|
|
252850
|
+
}
|
|
252851
|
+
return false;
|
|
252852
|
+
}
|
|
252853
|
+
/** Search around a vertex for a sector which has a different normal from its vertexPredecessor.
|
|
252854
|
+
* * The seed will be the first candidate considered
|
|
252855
|
+
*/
|
|
252856
|
+
markBreakEdgesAndSaveAverageNormalsAroundVertex(vertexSeed) {
|
|
252857
|
+
vertexSeed.clearMaskAroundVertex(this._breakMaskA);
|
|
252858
|
+
vertexSeed.clearMaskAroundVertex(this._breakMaskB);
|
|
252859
|
+
const smoothSingleSmoothRadiansBetweenNormals = this._smoothRadiansBetweenNormals;
|
|
252860
|
+
const accumulatedRadiansBetweenNormals = this._smoothAccumulatedRadiansBetweenNormals;
|
|
252861
|
+
// Step 1: Examine the edge between nodeA and the sector on its vertex predecessor side. This (alone) determines single angle breaks.
|
|
252862
|
+
let numBreaks = 0;
|
|
252863
|
+
let nodeP = vertexSeed;
|
|
252864
|
+
let _numSmooth = 0;
|
|
252865
|
+
do {
|
|
252866
|
+
const nodeQ = nodeP.edgeMate;
|
|
252867
|
+
const nodeR = nodeQ.faceSuccessor; // same as nodeA.vertexPredecessor
|
|
252868
|
+
if (nodeP.isMaskSet(this._exteriorMask)) {
|
|
252869
|
+
if (!nodeQ.isMaskSet(this._exteriorMask)) {
|
|
252870
|
+
nodeR.setMask(this._breakMaskB);
|
|
252871
|
+
numBreaks++;
|
|
252872
|
+
}
|
|
252873
|
+
}
|
|
252874
|
+
else {
|
|
252875
|
+
if (nodeP.isMaskSet(this._outsideOfChamferFace)) {
|
|
252876
|
+
nodeP.setMask(this._breakMaskA);
|
|
252877
|
+
}
|
|
252878
|
+
else if (nodeP.isMaskSet(this._outsideEndOfChamferFace)) {
|
|
252879
|
+
nodeP.setMask(this._breakMaskA);
|
|
252880
|
+
nodeP.setMask(this._breakMaskB);
|
|
252881
|
+
}
|
|
252882
|
+
else if (nodeP.isMaskSet(this._insideChamferSling)) {
|
|
252883
|
+
// This is the sling. It's normal is along edge -- not really a break.
|
|
252884
|
+
}
|
|
252885
|
+
else if (nodeP.isMaskSet(this._insideOfChamferFace)) {
|
|
252886
|
+
nodeP.setMask(this._breakMaskA);
|
|
252887
|
+
nodeP.setMask(this._breakMaskB);
|
|
252888
|
+
nodeR.setMask(this._breakMaskB);
|
|
252889
|
+
}
|
|
252890
|
+
else if (nodeQ.isMaskSet(this._exteriorMask)) {
|
|
252891
|
+
numBreaks++;
|
|
252892
|
+
nodeP.setMask(this._breakMaskA);
|
|
252893
|
+
}
|
|
252894
|
+
else if (!SectorOffsetProperties.almostEqualNormals(nodeP.edgeTag, nodeR.edgeTag, smoothSingleSmoothRadiansBetweenNormals)) {
|
|
252895
|
+
nodeP.setMask(this._breakMaskA);
|
|
252896
|
+
numBreaks++;
|
|
252897
|
+
nodeR.setMask(this._breakMaskB);
|
|
252898
|
+
}
|
|
252899
|
+
else {
|
|
252900
|
+
_numSmooth++;
|
|
252901
|
+
}
|
|
252902
|
+
}
|
|
252903
|
+
nodeP = nodeP.vertexSuccessor;
|
|
252904
|
+
} while (nodeP !== vertexSeed);
|
|
252905
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined)
|
|
252906
|
+
OffsetMeshContext.stringDebugFunction(` numSkip ${_numSmooth} `);
|
|
252907
|
+
if (numBreaks === 0) {
|
|
252908
|
+
// make the first vertex a break so subsequent searches have a place to start
|
|
252909
|
+
vertexSeed.setMask(this._breakMaskA);
|
|
252910
|
+
vertexSeed.vertexPredecessor.setMask(this._breakMaskB);
|
|
252911
|
+
numBreaks = 1;
|
|
252912
|
+
}
|
|
252913
|
+
// Step 2: At each single break, sweep forward to its closing breakB. Insert breaks at accumulated angles.
|
|
252914
|
+
// (minor TODO: for the insertion case, try to split more equally.)
|
|
252915
|
+
const nodeAStart = nodeP.findMaskAroundVertex(this._breakMaskA);
|
|
252916
|
+
if (nodeAStart !== undefined) {
|
|
252917
|
+
nodeP = nodeAStart;
|
|
252918
|
+
do {
|
|
252919
|
+
if (nodeP.isMaskSet(this._breakMaskA) && !nodeP.isMaskSet(this._breakMaskB)) {
|
|
252920
|
+
let accumulatedRadians = 0.0;
|
|
252921
|
+
do {
|
|
252922
|
+
const nodeB = nodeP.vertexSuccessor;
|
|
252923
|
+
accumulatedRadians += SectorOffsetProperties.radiansBetweenNormals(nodeP.edgeTag, nodeB.edgeTag);
|
|
252924
|
+
if (accumulatedRadians > accumulatedRadiansBetweenNormals) {
|
|
252925
|
+
nodeP.setMask(this._breakMaskB);
|
|
252926
|
+
nodeB.setMask(this._breakMaskA);
|
|
252927
|
+
numBreaks++;
|
|
252928
|
+
accumulatedRadians = 0.0;
|
|
252929
|
+
}
|
|
252930
|
+
nodeP = nodeB;
|
|
252931
|
+
} while (!nodeP.isMaskSet(this._breakMaskB));
|
|
252932
|
+
}
|
|
252933
|
+
else {
|
|
252934
|
+
nodeP = nodeP.vertexSuccessor;
|
|
252935
|
+
}
|
|
252936
|
+
} while (nodeP !== nodeAStart);
|
|
252937
|
+
}
|
|
252938
|
+
if (numBreaks > 0 && nodeAStart !== undefined) {
|
|
252939
|
+
// In each compound sector, accumulate and install average normal.
|
|
252940
|
+
nodeP = nodeAStart;
|
|
252941
|
+
const averageNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create();
|
|
252942
|
+
const edgeVectorU = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create();
|
|
252943
|
+
const edgeVectorV = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create();
|
|
252944
|
+
averageNormal.setZero();
|
|
252945
|
+
do {
|
|
252946
|
+
if (nodeP.isMaskSet(this._breakMaskA) && !nodeP.isMaskSet(this._breakMaskB)) {
|
|
252947
|
+
let nodeQ = nodeP;
|
|
252948
|
+
averageNormal.setZero();
|
|
252949
|
+
for (;;) {
|
|
252950
|
+
nodeQ.vectorToFaceSuccessor(edgeVectorU);
|
|
252951
|
+
nodeQ.vectorToFacePredecessor(edgeVectorV);
|
|
252952
|
+
let singleSectorRadians = edgeVectorU.signedRadiansTo(edgeVectorV, nodeQ.faceTag.facetNormal.direction);
|
|
252953
|
+
if (singleSectorRadians < 0.0)
|
|
252954
|
+
singleSectorRadians += Math.PI * 2;
|
|
252955
|
+
SectorOffsetProperties.accumulateScaledNormalAtHalfEdge(nodeQ, singleSectorRadians, averageNormal);
|
|
252956
|
+
if (nodeQ.isMaskSet(this._breakMaskB))
|
|
252957
|
+
break;
|
|
252958
|
+
nodeQ = nodeQ.vertexSuccessor;
|
|
252959
|
+
}
|
|
252960
|
+
if (averageNormal.normalizeInPlace()) {
|
|
252961
|
+
nodeQ = nodeP;
|
|
252962
|
+
for (;;) {
|
|
252963
|
+
SectorOffsetProperties.setNormalAtHalfEdge(nodeQ, averageNormal);
|
|
252964
|
+
if (nodeQ.isMaskSet(this._breakMaskB))
|
|
252965
|
+
break;
|
|
252966
|
+
nodeQ = nodeQ.vertexSuccessor;
|
|
252967
|
+
}
|
|
252968
|
+
}
|
|
252969
|
+
}
|
|
252970
|
+
nodeP = nodeP.vertexSuccessor;
|
|
252971
|
+
} while (nodeP !== nodeAStart);
|
|
252972
|
+
}
|
|
252973
|
+
}
|
|
252974
|
+
/** Compute the point of intersection of the planes in the sectors of 3 half edges */
|
|
252975
|
+
compute3SectorIntersection(nodeA, nodeB, nodeC, result) {
|
|
252976
|
+
const sectorA = nodeA.edgeTag;
|
|
252977
|
+
const sectorB = nodeB.edgeTag;
|
|
252978
|
+
const sectorC = nodeC.edgeTag;
|
|
252979
|
+
const vector = _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_7__.SmallSystem.intersect3Planes(sectorA.xyz, sectorA.normal, sectorB.xyz, sectorB.normal, sectorC.xyz, sectorC.normal, result);
|
|
252980
|
+
return vector;
|
|
252981
|
+
}
|
|
252982
|
+
/** Compute the point of intersection of the planes in the sectors of 3 half edges */
|
|
252983
|
+
compute3SectorIntersectionDebug(nodeA, nodeB, nodeC, result) {
|
|
252984
|
+
const sectorA = nodeA.edgeTag;
|
|
252985
|
+
const sectorB = nodeB.edgeTag;
|
|
252986
|
+
const sectorC = nodeC.edgeTag;
|
|
252987
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined) {
|
|
252988
|
+
OffsetMeshContext.stringDebugFunction(`compute3${this.inspectMasks(nodeA)}${this.inspectMasks(nodeB)}${this.inspectMasks(nodeC)} `);
|
|
252989
|
+
for (const sector of [sectorA, sectorB, sectorC])
|
|
252990
|
+
emitSector(sector);
|
|
252991
|
+
}
|
|
252992
|
+
const vector = _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_7__.SmallSystem.intersect3Planes(sectorA.xyz, sectorA.normal, sectorB.xyz, sectorB.normal, sectorC.xyz, sectorC.normal, result);
|
|
252993
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined) {
|
|
252994
|
+
if (vector === undefined)
|
|
252995
|
+
OffsetMeshContext.stringDebugFunction(" NO INTERSECTION");
|
|
252996
|
+
else
|
|
252997
|
+
OffsetMeshContext.stringDebugFunction(` ComputedVector ${vector.x},${vector.y},${vector.z} `);
|
|
252998
|
+
}
|
|
252999
|
+
return vector;
|
|
253000
|
+
}
|
|
253001
|
+
/** Compute the point of intersection of the planes in the sectors of 2 half edges, using cross product of their normals to resolve */
|
|
253002
|
+
compute2SectorIntersection(nodeA, nodeB, result) {
|
|
253003
|
+
const sectorA = nodeA.edgeTag;
|
|
253004
|
+
const sectorB = nodeB.edgeTag;
|
|
253005
|
+
const normalC = sectorA.normal.crossProduct(sectorB.normal);
|
|
253006
|
+
return _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_7__.SmallSystem.intersect3Planes(sectorA.xyz, sectorA.normal, sectorB.xyz, sectorB.normal, sectorB.xyz, normalC, result);
|
|
253007
|
+
}
|
|
253008
|
+
/**
|
|
253009
|
+
* * at input, graph has all original faces and edges
|
|
253010
|
+
* * each sector points to a faceProperties with original facet normal
|
|
253011
|
+
* * at exit:
|
|
253012
|
+
* * new "chamfer faces" are added outside of edges with angle between normal sin excess of options.chamferTurnAngleBetweenNormals
|
|
253013
|
+
* * the original edge is split along its length to create space
|
|
253014
|
+
* * one edge "along" each direction inside the slit.
|
|
253015
|
+
* * a sling edge at each end of the slit.
|
|
253016
|
+
* * outside of the sling is part of the slit face loop.
|
|
253017
|
+
* * inside is a single-node face
|
|
253018
|
+
* * thus the slit itself has 4 nodes.
|
|
253019
|
+
* * the two nodes at each end can thus contain the two distinct points at that end of the chamfer.
|
|
253020
|
+
* * all 4 nodes of the slit face point to a new FacetOffsetProperties with the average normal.
|
|
253021
|
+
* * the inside of each sling face has
|
|
253022
|
+
* * original vertex coordinates in the node
|
|
253023
|
+
* * face properties with a normal pointing outward from that end of the original edge -- hence define a plane that can clip the chamfer
|
|
253024
|
+
* * the two points at each end of the chamfer are computed as the intersection of
|
|
253025
|
+
* * chamfer plane
|
|
253026
|
+
* * sling plane
|
|
253027
|
+
* * adjacent plane of the face on the other side of the edge being chamfered.
|
|
253028
|
+
* @param distance distance to offset. The sign of this is important in the chamfer construction.
|
|
253029
|
+
*/
|
|
253030
|
+
addChamferTopologyToAllEdges(options, distance) {
|
|
253031
|
+
const edgesToChamfer = [];
|
|
253032
|
+
const chamferRadians = options.chamferAngleBetweenNormals.radians;
|
|
253033
|
+
const vertexXYZ = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create(); // reuse
|
|
253034
|
+
const edgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create(); // reuse
|
|
253035
|
+
const outwardEdgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create(); // reuse
|
|
253036
|
+
const averageNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create(); // reuse
|
|
253037
|
+
// collect all the edges with sharp turn angle.
|
|
253038
|
+
this._baseGraph.announceEdges((_graph, edgeNode) => {
|
|
253039
|
+
if (SectorOffsetProperties.edgeHasLargeExteriorAngleBetweenNormals(edgeNode, edgeVector, averageNormal, distance, chamferRadians)) {
|
|
253040
|
+
edgesToChamfer.push(edgeNode);
|
|
253041
|
+
return true;
|
|
253042
|
+
}
|
|
253043
|
+
return true;
|
|
253044
|
+
});
|
|
253045
|
+
// Create sliver faces.
|
|
253046
|
+
// Sliver face gets an average normal from its neighbors.
|
|
253047
|
+
// outsideA is the HalfEdge labeled A in the diagram.
|
|
253048
|
+
// sliverDX and sliverDY are the edges "inside the sliver" at the respective X and Y ends.
|
|
253049
|
+
for (const outsideA of edgesToChamfer) {
|
|
253050
|
+
// remark: this recomputes as in collection round.
|
|
253051
|
+
if (SectorOffsetProperties.edgeHasLargeExteriorAngleBetweenNormals(outsideA, edgeVector, averageNormal, chamferRadians)) {
|
|
253052
|
+
// This copies coordinates and vertex id .... sectorOffsetProperties are delayed until late in the 2-pass loop below.
|
|
253053
|
+
// The returned HalfEdge is labeled D in the diagram
|
|
253054
|
+
const sliverDX = this._baseGraph.splitEdgeCreateSliverFace(outsideA);
|
|
253055
|
+
const sliverDY = sliverDX.facePredecessor;
|
|
253056
|
+
const offsetPoint = sliverDX.getPoint3d();
|
|
253057
|
+
offsetPoint.addScaledInPlace(averageNormal, distance);
|
|
253058
|
+
const ray = _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_8__.Ray3d.createCapture(offsetPoint, averageNormal.clone());
|
|
253059
|
+
const facetProperties = new FacetOffsetProperties(-1, ray);
|
|
253060
|
+
// for each side (hence end) of the sliver face, set mask and install a sling loop for the anticipated end of the chamfer face
|
|
253061
|
+
// new node names in the loop omit X or Y suffix because that is implied by which pass is running.
|
|
253062
|
+
let s = -1.0;
|
|
253063
|
+
for (const sliverD of [sliverDX, sliverDY]) {
|
|
253064
|
+
edgeVector.scale(s, outwardEdgeVector);
|
|
253065
|
+
sliverD.getPoint3d(vertexXYZ);
|
|
253066
|
+
sliverD.setMask(this._insideOfChamferFace);
|
|
253067
|
+
sliverD.edgeMate.setMask(this._outsideOfChamferFace);
|
|
253068
|
+
// mark and reference the chamfer face.
|
|
253069
|
+
sliverD.faceTag = facetProperties;
|
|
253070
|
+
// sling at this end
|
|
253071
|
+
const slingB = this._baseGraph.splitEdge(undefined, vertexXYZ.x, vertexXYZ.y, vertexXYZ.z, sliverD.i);
|
|
253072
|
+
const slingC = slingB.edgeMate;
|
|
253073
|
+
slingB.setMask(this._outsideEndOfChamferFace);
|
|
253074
|
+
slingB.faceTag = facetProperties;
|
|
253075
|
+
slingC.setMask(this._insideChamferSling);
|
|
253076
|
+
_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.pinch(sliverD, slingB);
|
|
253077
|
+
const endNormal = _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_8__.Ray3d.create(vertexXYZ, outwardEdgeVector); // clones the inputs
|
|
253078
|
+
const slingFaceProperties = new FacetOffsetProperties(-1, endNormal);
|
|
253079
|
+
slingC.faceTag = slingFaceProperties;
|
|
253080
|
+
// initialize sectors with existing vertex point.
|
|
253081
|
+
sliverD.edgeTag = new SectorOffsetProperties(averageNormal.clone(), offsetPoint.clone());
|
|
253082
|
+
slingB.edgeTag = new SectorOffsetProperties(averageNormal.clone(), offsetPoint.clone());
|
|
253083
|
+
slingC.edgeTag = new SectorOffsetProperties(outwardEdgeVector.clone(), vertexXYZ.clone());
|
|
253084
|
+
// OffsetMeshContext.stringDebugFunction("Chamfer Setup");
|
|
253085
|
+
const chamferPointE = this.compute3SectorIntersection(sliverD, sliverD.edgeMate, slingC);
|
|
253086
|
+
const chamferPointF = this.compute3SectorIntersection(slingB, slingB.vertexSuccessor, slingC);
|
|
253087
|
+
// sliverD.edgeTag = new SectorOffsetProperties(averageNormal.clone(), vertexXYZ.clone());
|
|
253088
|
+
SectorOffsetProperties.setXYZAtHalfEdge(sliverD, chamferPointE);
|
|
253089
|
+
SectorOffsetProperties.setXYZAtHalfEdge(slingB, chamferPointF);
|
|
253090
|
+
s *= -1.0;
|
|
253091
|
+
}
|
|
253092
|
+
}
|
|
253093
|
+
}
|
|
253094
|
+
}
|
|
253095
|
+
/**
|
|
253096
|
+
* * at input:
|
|
253097
|
+
* * Each node points to sectorOffsetProperties with previously computed XYZ (presumably mismatched)
|
|
253098
|
+
* * at exit:
|
|
253099
|
+
* * Each sectorOffsetProperties has an offset point computed with consideration of offset planes in the neighborhood.
|
|
253100
|
+
* @param distance distance to offset.
|
|
253101
|
+
*/
|
|
253102
|
+
computeOffsetFacetIntersections(distance) {
|
|
253103
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined)
|
|
253104
|
+
OffsetMeshContext.stringDebugFunction("***** recompute intersections");
|
|
253105
|
+
const breakEdges = [];
|
|
253106
|
+
const vertexXYZ = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
|
|
253107
|
+
const chamferXYZ = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
|
|
253108
|
+
const maxVertexMove = 2.0 * distance;
|
|
253109
|
+
const averageNormalData = new AverageNormalData();
|
|
253110
|
+
const maxAllowedNormalDeviationRadians = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_9__.Angle.degreesToRadians(25.0);
|
|
253111
|
+
//
|
|
253112
|
+
// FOR EACH VERTEX
|
|
253113
|
+
//
|
|
253114
|
+
this._baseGraph.announceVertexLoops((_graph, vertexSeedA) => {
|
|
253115
|
+
// reposition to an important vertex.
|
|
253116
|
+
// first choice: a chamfer face.
|
|
253117
|
+
let vertexSeed = vertexSeedA.findMaskAroundVertex(this._outsideEndOfChamferFace);
|
|
253118
|
+
if (vertexSeed === undefined)
|
|
253119
|
+
vertexSeed = vertexSeedA.findMaskAroundVertex(this._breakMaskA);
|
|
253120
|
+
if (vertexSeed === undefined)
|
|
253121
|
+
vertexSeed = vertexSeedA;
|
|
253122
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined) {
|
|
253123
|
+
OffsetMeshContext.stringDebugFunction("");
|
|
253124
|
+
OffsetMeshContext.stringDebugFunction(` VERTEX LOOP ${vertexSeed.getPoint3d().toJSON()} `);
|
|
253125
|
+
vertexSeed.sumAroundVertex((node) => { OffsetMeshContext.stringDebugFunction(this.inspectMasks(node, false, true)); return 0; });
|
|
253126
|
+
}
|
|
253127
|
+
// Take care of the easiest vertices directly . . . note that this returns from the lambda, not computeOffsetFacetIntersections
|
|
253128
|
+
if (this.assignOffsetByAverageNormalAroundVertex(vertexSeed, maxAllowedNormalDeviationRadians, averageNormalData, distance))
|
|
253129
|
+
return true;
|
|
253130
|
+
this.markBreakEdgesAndSaveAverageNormalsAroundVertex(vertexSeed);
|
|
253131
|
+
this.setOffsetAtDistanceAroundVertex(vertexSeed, distance, true);
|
|
253132
|
+
vertexSeed.collectMaskedEdgesAroundVertex(this._breakMaskA, true, breakEdges);
|
|
253133
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined) {
|
|
253134
|
+
OffsetMeshContext.stringDebugFunction(` BREAK EDGES from ${this.inspectMasks(vertexSeed, true, false)}`);
|
|
253135
|
+
for (const node of breakEdges) {
|
|
253136
|
+
OffsetMeshContext.stringDebugFunction(this.inspectMasks(node, false, true));
|
|
253137
|
+
}
|
|
253138
|
+
}
|
|
253139
|
+
if (breakEdges.length <= 1) {
|
|
253140
|
+
// just one smooth sequence.
|
|
253141
|
+
// everything is set already.
|
|
253142
|
+
}
|
|
253143
|
+
else if (breakEdges.length === 2) {
|
|
253144
|
+
// exterior vertex with two incident smooth
|
|
253145
|
+
const vectorFromOrigin = this.compute2SectorIntersection(breakEdges[0], breakEdges[1]);
|
|
253146
|
+
if (vectorFromOrigin !== undefined) {
|
|
253147
|
+
this.setOffsetXYAndZAroundVertex(vertexSeed, vectorFromOrigin);
|
|
253148
|
+
}
|
|
253149
|
+
}
|
|
253150
|
+
else if (breakEdges.length === 3) {
|
|
253151
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined)
|
|
253152
|
+
OffsetMeshContext.stringDebugFunction(` Vertex Update just ${breakEdges.length} `);
|
|
253153
|
+
const vectorFromOrigin = this.compute3SectorIntersection(breakEdges[0], breakEdges[1], breakEdges[2]);
|
|
253154
|
+
if (vectorFromOrigin !== undefined) {
|
|
253155
|
+
this.setOffsetXYAndZAroundVertex(vertexSeed, vectorFromOrigin);
|
|
253156
|
+
}
|
|
253157
|
+
// simple 3-face corner . . .
|
|
253158
|
+
}
|
|
253159
|
+
else {
|
|
253160
|
+
// Lots and Lots of edges
|
|
253161
|
+
// each set of 3 sectors independently generates an offset for its central sector.
|
|
253162
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined)
|
|
253163
|
+
OffsetMeshContext.stringDebugFunction(` Vertex Update breakEdges ${breakEdges.length} `);
|
|
253164
|
+
vertexSeed.getPoint3d(vertexXYZ);
|
|
253165
|
+
// Pass 1 -- look for intersection among multiple chamfers
|
|
253166
|
+
for (let i = 0; i < breakEdges.length; i++) {
|
|
253167
|
+
const i0 = i;
|
|
253168
|
+
const i1 = (i0 + 1) % breakEdges.length;
|
|
253169
|
+
const i2 = (i1 + 1) % breakEdges.length;
|
|
253170
|
+
if (breakEdges[i0].isMaskSet(this._outsideEndOfChamferFace)
|
|
253171
|
+
&& breakEdges[i1].isMaskSet(this._outsideOfChamferFace)
|
|
253172
|
+
&& breakEdges[i2].isMaskSet(this._insideOfChamferFace)) {
|
|
253173
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined)
|
|
253174
|
+
OffsetMeshContext.stringDebugFunction(` ChamferChamfer Fixup ${this.inspectMasks(breakEdges[i0])} ${this.inspectMasks(breakEdges[i1])} ${this.inspectMasks(breakEdges[i2])} `);
|
|
253175
|
+
const vectorFromOrigin = this.compute3SectorIntersection(breakEdges[i0], breakEdges[i1], breakEdges[i2]);
|
|
253176
|
+
if (vectorFromOrigin !== undefined) {
|
|
253177
|
+
// Treat all 3 spots as possibly compound sequences
|
|
253178
|
+
for (const iOutput of [i0, i1, i2]) {
|
|
253179
|
+
this.announceNodeAndSectorPropertiesInSmoothSector(breakEdges[iOutput], (node, properties) => {
|
|
253180
|
+
properties.setXYAndZ(vectorFromOrigin);
|
|
253181
|
+
node.setMask(this._offsetCoordinatesReassigned);
|
|
253182
|
+
});
|
|
253183
|
+
}
|
|
253184
|
+
// Since all three were reset, skip past. This is done on the acyclic integer that controls the loop.
|
|
253185
|
+
i += 2;
|
|
253186
|
+
}
|
|
253187
|
+
}
|
|
253188
|
+
}
|
|
253189
|
+
// Pass 2 -- look for unassigned nodes just before or after a chamfer.
|
|
253190
|
+
// The chamfer wins
|
|
253191
|
+
for (let i = 0; i < breakEdges.length; i++) {
|
|
253192
|
+
const i0 = i;
|
|
253193
|
+
const i1 = (i0 + 1) % breakEdges.length;
|
|
253194
|
+
if (this.isInsideSling(breakEdges[i0], breakEdges[i1]))
|
|
253195
|
+
continue;
|
|
253196
|
+
if (!this.isOffsetAssigned(breakEdges[i0])
|
|
253197
|
+
&& breakEdges[i1].isMaskSet(this.insideOfChamferFace)) {
|
|
253198
|
+
this.transferXYZFromNodeToSmoothSector(breakEdges[i1], breakEdges[i0], "push left from chamfer", chamferXYZ);
|
|
253199
|
+
}
|
|
253200
|
+
else if (!this.isOffsetAssigned(breakEdges[i1])
|
|
253201
|
+
&& breakEdges[i0].isMaskSet(this.outsideEndOfChamferFace)) {
|
|
253202
|
+
this.transferXYZFromNodeToSmoothSector(breakEdges[i0], breakEdges[i1], "push right from chamfer", chamferXYZ);
|
|
253203
|
+
}
|
|
253204
|
+
}
|
|
253205
|
+
// Pass 3 -- look for unassigned nodes as middle of 3-face intersections
|
|
253206
|
+
for (let i = 0; i < breakEdges.length; i++) {
|
|
253207
|
+
const i0 = i;
|
|
253208
|
+
const i1 = (i0 + 1) % breakEdges.length;
|
|
253209
|
+
const i2 = (i1 + 1) % breakEdges.length;
|
|
253210
|
+
if (this.isInsideSling(breakEdges[i0], breakEdges[i1], breakEdges[i2]))
|
|
253211
|
+
continue;
|
|
253212
|
+
if (this.isOffsetAssigned(breakEdges[i1]))
|
|
253213
|
+
continue;
|
|
253214
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined)
|
|
253215
|
+
OffsetMeshContext.stringDebugFunction(` Intersection Fixup ${this.inspectMasks(breakEdges[i0])} ${this.inspectMasks(breakEdges[i1])} ${this.inspectMasks(breakEdges[i2])} `);
|
|
253216
|
+
const vectorFromOrigin = this.compute3SectorIntersection(breakEdges[i0], breakEdges[i1], breakEdges[i2]);
|
|
253217
|
+
if (vectorFromOrigin !== undefined) {
|
|
253218
|
+
if (vertexXYZ.distance(vectorFromOrigin) < maxVertexMove) {
|
|
253219
|
+
this.announceNodeAndSectorPropertiesInSmoothSector(breakEdges[i1], (node, properties) => {
|
|
253220
|
+
properties.setXYAndZ(vectorFromOrigin);
|
|
253221
|
+
node.setMask(this._offsetCoordinatesReassigned);
|
|
253222
|
+
});
|
|
253223
|
+
}
|
|
253224
|
+
}
|
|
253225
|
+
}
|
|
253226
|
+
}
|
|
253227
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined) {
|
|
253228
|
+
const n0 = vertexSeed.countMaskAroundVertex(this._offsetCoordinatesReassigned, false);
|
|
253229
|
+
const n1 = vertexSeed.countMaskAroundVertex(this._offsetCoordinatesReassigned, true);
|
|
253230
|
+
const message = ` **** Vertex offset mask counts(TRUE ${n1})(FALSE ${n0})`;
|
|
253231
|
+
OffsetMeshContext.stringDebugFunction(message);
|
|
253232
|
+
}
|
|
253233
|
+
return true;
|
|
253234
|
+
});
|
|
253235
|
+
}
|
|
253236
|
+
// return true if any of these nodes is "inside" the sling at the end of a chamfer.
|
|
253237
|
+
isInsideSling(node0, node1, node2) {
|
|
253238
|
+
return node0.isMaskSet(this._insideChamferSling)
|
|
253239
|
+
|| (node1 !== undefined && node1.isMaskSet(this._insideChamferSling))
|
|
253240
|
+
|| (node2 !== undefined && node2.isMaskSet(this._insideChamferSling));
|
|
253241
|
+
}
|
|
253242
|
+
// return true if any of these nodes is "inside" the sling at the end of a chamfer.
|
|
253243
|
+
isInsideChamferOrSling(node0) {
|
|
253244
|
+
return node0.isMaskSet(this._insideChamferSling)
|
|
253245
|
+
|| node0.isMaskSet(this._insideOfChamferFace)
|
|
253246
|
+
|| node0.isMaskSet(this._outsideEndOfChamferFace);
|
|
253247
|
+
}
|
|
253248
|
+
isOffsetAssigned(node0, node1, node2) {
|
|
253249
|
+
return node0.isMaskSet(this._offsetCoordinatesReassigned)
|
|
253250
|
+
|| (node1 !== undefined && node1.isMaskSet(this._offsetCoordinatesReassigned))
|
|
253251
|
+
|| (node2 !== undefined && node2.isMaskSet(this._offsetCoordinatesReassigned));
|
|
253252
|
+
}
|
|
253253
|
+
/**
|
|
253254
|
+
*
|
|
253255
|
+
* @param sourceNode node with good xyz
|
|
253256
|
+
* @param destinationStartNode first of a sequence of nodes to set (delimited by masks)
|
|
253257
|
+
* @param description string for debug
|
|
253258
|
+
* @param workPoint point to use for coordinate transfer.
|
|
253259
|
+
*/
|
|
253260
|
+
transferXYZFromNodeToSmoothSector(sourceNode, destinationStartNode, description, workPoint) {
|
|
253261
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined)
|
|
253262
|
+
OffsetMeshContext.stringDebugFunction(` ${description} ${this.inspectMasks(sourceNode)} to ${this.inspectMasks(destinationStartNode)}} `);
|
|
253263
|
+
SectorOffsetProperties.getSectorPointAtHalfEdge(sourceNode, workPoint, undefined);
|
|
253264
|
+
this.announceNodeAndSectorPropertiesInSmoothSector(destinationStartNode, (node, properties) => {
|
|
253265
|
+
properties.setXYAndZ(workPoint);
|
|
253266
|
+
node.setMask(this._offsetCoordinatesReassigned);
|
|
253267
|
+
});
|
|
253268
|
+
}
|
|
253269
|
+
}
|
|
253270
|
+
|
|
253271
|
+
|
|
251991
253272
|
/***/ }),
|
|
251992
253273
|
|
|
251993
253274
|
/***/ "../../core/geometry/lib/esm/polyface/multiclip/RangeSearch.js":
|
|
@@ -261196,16 +262477,16 @@ class Sample {
|
|
|
261196
262477
|
_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)))));
|
|
261197
262478
|
result.push(_curve_CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_44__.CurveChainWithDistanceIndex.createCapture(_curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(// 2-pt Interpolation Curve
|
|
261198
262479
|
_bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3d.createCapture(_bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3dOptions.create({
|
|
261199
|
-
fitPoints: [pointsA[0], pointsA[1]]
|
|
262480
|
+
fitPoints: [pointsA[0], pointsA[1]],
|
|
261200
262481
|
})))));
|
|
261201
262482
|
result.push(_curve_CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_44__.CurveChainWithDistanceIndex.createCapture(_curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(// 3-pt Interpolation Curve
|
|
261202
262483
|
_bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3d.createCapture(_bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3dOptions.create({
|
|
261203
|
-
fitPoints: [pointsA[0], pointsA[1], pointsA[2]]
|
|
262484
|
+
fitPoints: [pointsA[0], pointsA[1], pointsA[2]],
|
|
261204
262485
|
})))));
|
|
261205
262486
|
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({
|
|
261206
262487
|
fitPoints: pointsA,
|
|
261207
262488
|
startTangent: _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(1, -1),
|
|
261208
|
-
endTangent: _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(-1, -1)
|
|
262489
|
+
endTangent: _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(-1, -1),
|
|
261209
262490
|
})))));
|
|
261210
262491
|
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"))));
|
|
261211
262492
|
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)))));
|
|
@@ -261319,8 +262600,11 @@ class Sample {
|
|
|
261319
262600
|
/** Create swept "solids" that can be capped.
|
|
261320
262601
|
* * At least one of each solid type.
|
|
261321
262602
|
* * each is within 10 of the origin all directions.
|
|
262603
|
+
* @param capped true to include caps
|
|
262604
|
+
* @param rotationAngle angle of rotation for the angular sweep. The default is 90 degrees.
|
|
262605
|
+
* Beware that the rotation sweep created with the default or any positive angle produces a mesh with inward normals.
|
|
261322
262606
|
*/
|
|
261323
|
-
static createClosedSolidSampler(capped) {
|
|
262607
|
+
static createClosedSolidSampler(capped, rotationAngle = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__.Angle.createDegrees(90)) {
|
|
261324
262608
|
const result = [];
|
|
261325
262609
|
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));
|
|
261326
262610
|
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));
|
|
@@ -261332,18 +262616,23 @@ class Sample {
|
|
|
261332
262616
|
const pointQ2 = arcA.fractionAndDistanceToPointOnTangent(1.0, 0.5);
|
|
261333
262617
|
const pointR1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(point0.x, pointQ1.y);
|
|
261334
262618
|
const pointR2 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(point0.x, pointQ1.y);
|
|
262619
|
+
const pointR3 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(pointQ1.x - 1, pointQ1.y);
|
|
262620
|
+
const pointR4 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(pointQ1.x - 3, pointQ1.y);
|
|
261335
262621
|
const linestringQ1 = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_15__.LineString3d.create(arcA.fractionToPoint(1.0), pointQ1, pointR1, point0);
|
|
261336
262622
|
const linestringQ2 = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_15__.LineString3d.create(arcA.fractionToPoint(1.0), pointQ2, pointR2, point0);
|
|
262623
|
+
const linestringQ3 = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_15__.LineString3d.create(arcA.fractionToPoint(1.0), pointQ2, pointR3, pointR4, point0);
|
|
261337
262624
|
const contourZ = _curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(linestringQ1.clone());
|
|
261338
262625
|
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());
|
|
261339
262626
|
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());
|
|
262627
|
+
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());
|
|
261340
262628
|
contourB.tryTransformInPlace(_geometry3d_Transform__WEBPACK_IMPORTED_MODULE_16__.Transform.createTranslationXYZ(1, 1, 3));
|
|
261341
262629
|
// const contourC = contourB.cloneTransformed(Transform.createTranslationXYZ(2, 1, 4))!;
|
|
261342
262630
|
result.push(_solid_LinearSweep__WEBPACK_IMPORTED_MODULE_30__.LinearSweep.create(contourA, _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(0, 0, 5), capped));
|
|
262631
|
+
result.push(_solid_LinearSweep__WEBPACK_IMPORTED_MODULE_30__.LinearSweep.create(contourC1, _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(0, 0, 5), capped));
|
|
261343
262632
|
const axis = _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_14__.Ray3d.createXYZUVW(0, 8, 0, 1, 0, 0);
|
|
261344
|
-
result.push(_solid_RotationalSweep__WEBPACK_IMPORTED_MODULE_31__.RotationalSweep.create(contourA.clone(), axis.clone(),
|
|
262633
|
+
result.push(_solid_RotationalSweep__WEBPACK_IMPORTED_MODULE_31__.RotationalSweep.create(contourA.clone(), axis.clone(), rotationAngle, capped));
|
|
261345
262634
|
if (!capped)
|
|
261346
|
-
result.push(_solid_RotationalSweep__WEBPACK_IMPORTED_MODULE_31__.RotationalSweep.create(contourZ.clone(), axis.clone(),
|
|
262635
|
+
result.push(_solid_RotationalSweep__WEBPACK_IMPORTED_MODULE_31__.RotationalSweep.create(contourZ.clone(), axis.clone(), rotationAngle, false));
|
|
261347
262636
|
result.push(_solid_RuledSweep__WEBPACK_IMPORTED_MODULE_36__.RuledSweep.create([contourA.clone(), contourB.clone()], capped));
|
|
261348
262637
|
const transformC = _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_16__.Transform.createScaleAboutPoint(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(0, 0, 8), 0.5);
|
|
261349
262638
|
const contourC = contourB.cloneTransformed(transformC);
|
|
@@ -265768,12 +267057,13 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
265768
267057
|
/* harmony export */ "HalfEdgeGraph": () => (/* binding */ HalfEdgeGraph),
|
|
265769
267058
|
/* harmony export */ "HalfEdgeMask": () => (/* binding */ HalfEdgeMask)
|
|
265770
267059
|
/* harmony export */ });
|
|
265771
|
-
/* harmony import */ var
|
|
267060
|
+
/* harmony import */ var _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../curve/LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
|
|
265772
267061
|
/* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
|
|
267062
|
+
/* harmony import */ var _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../geometry3d/Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
|
|
265773
267063
|
/* harmony import */ var _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../geometry3d/Point2dVector2d */ "../../core/geometry/lib/esm/geometry3d/Point2dVector2d.js");
|
|
265774
267064
|
/* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
|
|
265775
|
-
/* harmony import */ var
|
|
265776
|
-
/* harmony import */ var
|
|
267065
|
+
/* harmony import */ var _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../numerics/Polynomials */ "../../core/geometry/lib/esm/numerics/Polynomials.js");
|
|
267066
|
+
/* harmony import */ var _MaskManager__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./MaskManager */ "../../core/geometry/lib/esm/topology/MaskManager.js");
|
|
265777
267067
|
/*---------------------------------------------------------------------------------------------
|
|
265778
267068
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
265779
267069
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
@@ -265787,6 +267077,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
265787
267077
|
|
|
265788
267078
|
|
|
265789
267079
|
|
|
267080
|
+
|
|
265790
267081
|
// import { GraphChecker } from "../test/topology/Graph.test";
|
|
265791
267082
|
/* eslint-disable @typescript-eslint/no-this-alias */
|
|
265792
267083
|
// cspell:word CONSTU
|
|
@@ -265874,6 +267165,7 @@ class HalfEdge {
|
|
|
265874
267165
|
this.sortAngle = undefined;
|
|
265875
267166
|
this.sortData = undefined;
|
|
265876
267167
|
this.edgeTag = undefined;
|
|
267168
|
+
this.faceTag = undefined;
|
|
265877
267169
|
// Always created in pairs, init here to make TS compiler and JS runtime happy
|
|
265878
267170
|
this._facePredecessor = this;
|
|
265879
267171
|
this._faceSuccessor = this;
|
|
@@ -265994,6 +267286,36 @@ class HalfEdge {
|
|
|
265994
267286
|
}
|
|
265995
267287
|
return newA;
|
|
265996
267288
|
}
|
|
267289
|
+
/**
|
|
267290
|
+
* * Create a new sliver face "inside" an existing edge.
|
|
267291
|
+
* * Insert it "within" the base edge.
|
|
267292
|
+
* * This requires two new half edges.
|
|
267293
|
+
* * if the base is undefined, create a single-edge loop.
|
|
267294
|
+
* * This (unlike pinch) breaks the edgeMate pairing of the base edge.
|
|
267295
|
+
* * This preserves xyz and i properties at all existing vertices.
|
|
267296
|
+
* * The two new half edges are a sliver face (via their predecessor and successor)
|
|
267297
|
+
* * Each new edge mates to one existing edge.
|
|
267298
|
+
* @returns Returns the reference to the half edge created.
|
|
267299
|
+
*/
|
|
267300
|
+
static splitEdgeCreateSliverFace(baseA, heArray) {
|
|
267301
|
+
// raw edges ...
|
|
267302
|
+
const newA = new HalfEdge();
|
|
267303
|
+
const newB = new HalfEdge();
|
|
267304
|
+
const baseB = baseA.edgeMate;
|
|
267305
|
+
if (heArray) {
|
|
267306
|
+
heArray.push(newA);
|
|
267307
|
+
heArray.push(newB);
|
|
267308
|
+
}
|
|
267309
|
+
newA._faceSuccessor = newA._facePredecessor = newB;
|
|
267310
|
+
newB._faceSuccessor = newB._facePredecessor = newA;
|
|
267311
|
+
// newA is in vertex loop with baseA etc.
|
|
267312
|
+
// newA mates to baseB
|
|
267313
|
+
HalfEdge.setEdgeMates(newA, baseB);
|
|
267314
|
+
HalfEdge.setEdgeMates(newB, baseA);
|
|
267315
|
+
newA.copyDataFrom(baseA, true, true, false, false);
|
|
267316
|
+
newB.copyDataFrom(baseB, true, true, false, false);
|
|
267317
|
+
return newA;
|
|
267318
|
+
}
|
|
265997
267319
|
/**
|
|
265998
267320
|
* Copy "edge based" content of fromNode to toNode
|
|
265999
267321
|
* * edgeTag
|
|
@@ -266204,6 +267526,35 @@ class HalfEdge {
|
|
|
266204
267526
|
}
|
|
266205
267527
|
return count;
|
|
266206
267528
|
}
|
|
267529
|
+
/** Returns the first node with given mask value around this vertex loop. */
|
|
267530
|
+
findMaskAroundVertex(mask, value = true) {
|
|
267531
|
+
let node = this;
|
|
267532
|
+
do {
|
|
267533
|
+
if (node.isMaskSet(mask) === value)
|
|
267534
|
+
return node;
|
|
267535
|
+
node = node.vertexSuccessor;
|
|
267536
|
+
} while (node !== this);
|
|
267537
|
+
return undefined;
|
|
267538
|
+
}
|
|
267539
|
+
/** Returns the first node with given mask value around this face loop. */
|
|
267540
|
+
findMaskAroundFace(mask, value = true) {
|
|
267541
|
+
let node = this;
|
|
267542
|
+
do {
|
|
267543
|
+
if (node.isMaskSet(mask) === value)
|
|
267544
|
+
return node;
|
|
267545
|
+
node = node.faceSuccessor;
|
|
267546
|
+
} while (node !== this);
|
|
267547
|
+
return undefined;
|
|
267548
|
+
}
|
|
267549
|
+
/** Returns the first node with given mask value on this edge (i.e. examining this and this.mate) */
|
|
267550
|
+
findMaskAroundEdge(mask, value = true) {
|
|
267551
|
+
if (this.isMaskSet(mask) === value)
|
|
267552
|
+
return this;
|
|
267553
|
+
const mate = this.edgeMate;
|
|
267554
|
+
if (mate.isMaskSet(mask) === value)
|
|
267555
|
+
return mate;
|
|
267556
|
+
return undefined;
|
|
267557
|
+
}
|
|
266207
267558
|
/** Set a mask, and return prior value.
|
|
266208
267559
|
* @param mask mask to apply
|
|
266209
267560
|
*/
|
|
@@ -266221,6 +267572,15 @@ class HalfEdge {
|
|
|
266221
267572
|
this.y = node.y;
|
|
266222
267573
|
this.z = node.z;
|
|
266223
267574
|
}
|
|
267575
|
+
/**
|
|
267576
|
+
* Set (copy) the this.x, this.y, this.z from xyz.x, xyz.y, xyz.z
|
|
267577
|
+
* @param node source with x,y,z properties
|
|
267578
|
+
*/
|
|
267579
|
+
setXYZ(xyz) {
|
|
267580
|
+
this.x = xyz.x;
|
|
267581
|
+
this.y = xyz.y;
|
|
267582
|
+
this.z = xyz.z;
|
|
267583
|
+
}
|
|
266224
267584
|
/**
|
|
266225
267585
|
* Test if mask bits are set in the node's bitMask.
|
|
266226
267586
|
* @return Return true (as a simple boolean, not a mask) if any bits of the mask parameter match bits of the node's bitMask
|
|
@@ -266310,6 +267670,10 @@ class HalfEdge {
|
|
|
266310
267670
|
const s = `${node.id.toString()}+${HalfEdge.nodeToMaskString(node)}[${node.x},${node.y}]`;
|
|
266311
267671
|
return s;
|
|
266312
267672
|
}
|
|
267673
|
+
/** Return the [id, [x,y],z] of a node. Useful for collector methods. */
|
|
267674
|
+
static nodeToIdXYZString(node) {
|
|
267675
|
+
return `[${node.id.toString()}: ${node.x},${node.y},${node.z}]`;
|
|
267676
|
+
}
|
|
266313
267677
|
/** Create a string representation of the mask
|
|
266314
267678
|
* * Null mask is empty string.
|
|
266315
267679
|
* * Appended characters B,P,X for Boundary, Primary, Exterior mask bits.
|
|
@@ -266334,7 +267698,13 @@ class HalfEdge {
|
|
|
266334
267698
|
}
|
|
266335
267699
|
/** Return Vector3d to face successor */
|
|
266336
267700
|
vectorToFaceSuccessor(result) {
|
|
266337
|
-
|
|
267701
|
+
const other = this.faceSuccessor;
|
|
267702
|
+
return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(other.x - this.x, other.y - this.y, other.z - this.z, result);
|
|
267703
|
+
}
|
|
267704
|
+
/** Return Vector3d to face successor */
|
|
267705
|
+
vectorToFacePredecessor(result) {
|
|
267706
|
+
const other = this.facePredecessor;
|
|
267707
|
+
return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(other.x - this.x, other.y - this.y, other.z - this.z, result);
|
|
266338
267708
|
}
|
|
266339
267709
|
/** test if spaceNode is in the sector at sectorNode */
|
|
266340
267710
|
static isNodeVisibleInSector(spaceNode, sectorNode) {
|
|
@@ -266458,6 +267828,14 @@ class HalfEdge {
|
|
|
266458
267828
|
static testNodeMaskNotExterior(node) { return !node.isMaskSet(HalfEdgeMask.EXTERIOR); }
|
|
266459
267829
|
/** Returns Returns true if the node does NOT have Mask.EXTERIOR_MASK set. */
|
|
266460
267830
|
static testMateMaskExterior(node) { return node.edgeMate.isMaskSet(HalfEdgeMask.EXTERIOR); }
|
|
267831
|
+
/** Returns radians between this edge and its face predecessor edge, using all three coordinates x,y,z and given normal to resolve sweep direction.
|
|
267832
|
+
* * The returned angle is positive, i.e. may be larger than PI radians.
|
|
267833
|
+
*/
|
|
267834
|
+
static sectorSweepRadiansXYZ(node, normal) {
|
|
267835
|
+
const nodeB = node.faceSuccessor;
|
|
267836
|
+
const nodeC = node.facePredecessor;
|
|
267837
|
+
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);
|
|
267838
|
+
}
|
|
266461
267839
|
/** Returns Returns true if the face has positive area in xy parts. */
|
|
266462
267840
|
static testFacePositiveAreaXY(node) {
|
|
266463
267841
|
return node.countEdgesAroundFace() > 2 && node.signedFaceArea() > 0.0;
|
|
@@ -266489,6 +267867,26 @@ class HalfEdge {
|
|
|
266489
267867
|
} while (node !== this);
|
|
266490
267868
|
return nodes;
|
|
266491
267869
|
}
|
|
267870
|
+
/**
|
|
267871
|
+
* search around a vertex for nodes that have a specified mask setting.
|
|
267872
|
+
* @param vertexSeed first node to search
|
|
267873
|
+
* @param mask target mask
|
|
267874
|
+
* @param value target value for mask on half edges.
|
|
267875
|
+
* @param collectedNodes optional array to be cleared and receive masked nodes
|
|
267876
|
+
*/
|
|
267877
|
+
collectMaskedEdgesAroundVertex(mask, value = true, result) {
|
|
267878
|
+
if (result === undefined)
|
|
267879
|
+
result = [];
|
|
267880
|
+
else
|
|
267881
|
+
result.length = 0;
|
|
267882
|
+
let node = this;
|
|
267883
|
+
do {
|
|
267884
|
+
if (node.isMaskSet(mask) === value)
|
|
267885
|
+
result.push(node);
|
|
267886
|
+
node = node.vertexSuccessor;
|
|
267887
|
+
} while (node !== this);
|
|
267888
|
+
return result;
|
|
267889
|
+
}
|
|
266492
267890
|
/**
|
|
266493
267891
|
*
|
|
266494
267892
|
* * Evaluate f(node) at each outbound node around this node's vertex loop.
|
|
@@ -266672,7 +268070,7 @@ class HalfEdge {
|
|
|
266672
268070
|
const nodeB1 = nodeB0.faceSuccessor;
|
|
266673
268071
|
if (!result)
|
|
266674
268072
|
result = _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_0__.Vector2d.create();
|
|
266675
|
-
if (
|
|
268073
|
+
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))
|
|
266676
268074
|
return result;
|
|
266677
268075
|
return undefined;
|
|
266678
268076
|
}
|
|
@@ -266681,8 +268079,7 @@ class HalfEdge {
|
|
|
266681
268079
|
* * If the edge is horizontal with (approximate) identical y, return the node.
|
|
266682
268080
|
* * If the edge is horizontal with different y, return undefined.
|
|
266683
268081
|
* * If the edge is not horizontal, return the fractional position (possibly outside 0..1) of the intersection.
|
|
266684
|
-
* @param
|
|
266685
|
-
* @param result optional preallocated result
|
|
268082
|
+
* @param node0 Base node of edge
|
|
266686
268083
|
*/
|
|
266687
268084
|
static horizontalScanFraction(node0, y) {
|
|
266688
268085
|
const node1 = node0.faceSuccessor;
|
|
@@ -266697,8 +268094,7 @@ class HalfEdge {
|
|
|
266697
268094
|
* * Compute fractional coordinates of the intersection of a horizontal line with an edge.
|
|
266698
268095
|
* * If the edge is horizontal return undefined (no test for horizontal at y!!!)
|
|
266699
268096
|
* * If the edge is not horizontal and y is between its end y's, return the fraction
|
|
266700
|
-
* @param
|
|
266701
|
-
* @param result optional preallocated result
|
|
268097
|
+
* @param node0 Base node of edge
|
|
266702
268098
|
*/
|
|
266703
268099
|
static horizontalScanFraction01(node0, y) {
|
|
266704
268100
|
const node1 = node0.faceSuccessor;
|
|
@@ -266712,6 +268108,31 @@ class HalfEdge {
|
|
|
266712
268108
|
return fraction;
|
|
266713
268109
|
return undefined;
|
|
266714
268110
|
}
|
|
268111
|
+
/**
|
|
268112
|
+
* Copy various data from source to this.
|
|
268113
|
+
* @param source other half edge.
|
|
268114
|
+
* @param XYZ copy simple coordinates
|
|
268115
|
+
* @param copyVertexData true to copy data belonging to the vertex. (i.e. the "i" member)
|
|
268116
|
+
* @param copyVertexData true to copy data belonging to the edge. (i.e. call transferEdgeData)
|
|
268117
|
+
* @param copyFaceData true to copy faceTag
|
|
268118
|
+
*/
|
|
268119
|
+
copyDataFrom(source, copyXYZ, copyVertexData, copyEdgeData, copyFaceData) {
|
|
268120
|
+
if (copyXYZ) {
|
|
268121
|
+
this.x = source.x;
|
|
268122
|
+
this.y = source.y;
|
|
268123
|
+
this.z = source.z;
|
|
268124
|
+
}
|
|
268125
|
+
if (copyVertexData) {
|
|
268126
|
+
this.i = source.i;
|
|
268127
|
+
}
|
|
268128
|
+
if (copyEdgeData) {
|
|
268129
|
+
HalfEdge.transferEdgeProperties(source, this);
|
|
268130
|
+
this.edgeTag = source.edgeTag;
|
|
268131
|
+
}
|
|
268132
|
+
if (copyFaceData) {
|
|
268133
|
+
this.faceTag = source.faceTag;
|
|
268134
|
+
}
|
|
268135
|
+
}
|
|
266715
268136
|
}
|
|
266716
268137
|
HalfEdge._edgePropertyMasks = [HalfEdgeMask.BOUNDARY_EDGE, HalfEdgeMask.EXTERIOR, HalfEdgeMask.PRIMARY_EDGE, HalfEdgeMask.NULL_FACE];
|
|
266717
268138
|
HalfEdge._totalNodesCreated = 0;
|
|
@@ -266725,7 +268146,7 @@ class HalfEdgeGraph {
|
|
|
266725
268146
|
constructor() {
|
|
266726
268147
|
this._numNodesCreated = 0;
|
|
266727
268148
|
this.allHalfEdges = [];
|
|
266728
|
-
this._maskManager =
|
|
268149
|
+
this._maskManager = _MaskManager__WEBPACK_IMPORTED_MODULE_5__.MaskManager.create(HalfEdgeMask.ALL_GRAB_DROP_MASKS);
|
|
266729
268150
|
}
|
|
266730
268151
|
/** Ask for a mask (from the graph's free pool.) for caller's use.
|
|
266731
268152
|
* * Optionally clear the mask throughout the graph.
|
|
@@ -266752,6 +268173,19 @@ class HalfEdgeGraph {
|
|
|
266752
268173
|
const a = HalfEdge.createHalfEdgePairWithCoordinates(xA, yA, zA, iA, xB, yB, zB, iB, this.allHalfEdges);
|
|
266753
268174
|
return a;
|
|
266754
268175
|
}
|
|
268176
|
+
/**
|
|
268177
|
+
* * Create 2 half edges forming 2 vertices, 1 edge, and 1 face
|
|
268178
|
+
* * The two edges are joined as edgeMate pair.
|
|
268179
|
+
* * The two edges are a 2-half-edge face loop in both the faceSuccessor and facePredecessor directions.
|
|
268180
|
+
* * The two edges are added to the graph's HalfEdge set
|
|
268181
|
+
* * Coordinates are set to zero.
|
|
268182
|
+
* * ids are installed in the two half edges.
|
|
268183
|
+
* @returns Return pointer to the first half edge created. (This has idA as its id.)
|
|
268184
|
+
*/
|
|
268185
|
+
createEdgeIdId(iA = 0, iB = 0) {
|
|
268186
|
+
const a = HalfEdge.createHalfEdgePairWithCoordinates(0.0, 0.0, 0.0, iA, 0.0, 0.0, 0.0, iB, this.allHalfEdges);
|
|
268187
|
+
return a;
|
|
268188
|
+
}
|
|
266755
268189
|
/**
|
|
266756
268190
|
* * create an edge from coordinates x,y,z to (the tail of) an existing half edge.
|
|
266757
268191
|
* @returns Return pointer to the half edge with tail at x,y,z
|
|
@@ -266796,6 +268230,20 @@ class HalfEdgeGraph {
|
|
|
266796
268230
|
const he = HalfEdge.splitEdge(base, xA, yA, zA, iA, this.allHalfEdges);
|
|
266797
268231
|
return he;
|
|
266798
268232
|
}
|
|
268233
|
+
/**
|
|
268234
|
+
* * Create a sliver face "within" an edge.
|
|
268235
|
+
* * this creates two half edges.
|
|
268236
|
+
* * The existing edges both stay in their same face loops and retain coordinates and i value.
|
|
268237
|
+
* * Each existing edge's mate is a new edge (rather than original mate)
|
|
268238
|
+
* * Coordinates are copied to the new edges at respective vertices.
|
|
268239
|
+
* * New faceTag and edgeTag undefined.
|
|
268240
|
+
* * i members are copied around their respective vertices.
|
|
268241
|
+
* @returns Returns the reference to the half edge created.
|
|
268242
|
+
*/
|
|
268243
|
+
splitEdgeCreateSliverFace(base) {
|
|
268244
|
+
const he = HalfEdge.splitEdgeCreateSliverFace(base, this.allHalfEdges);
|
|
268245
|
+
return he;
|
|
268246
|
+
}
|
|
266799
268247
|
/**
|
|
266800
268248
|
* * Insert a vertex in the edge beginning at base, with coordinates specified as a fraction along the existing edge.
|
|
266801
268249
|
* * this creates two half edges.
|
|
@@ -266864,7 +268312,7 @@ class HalfEdgeGraph {
|
|
|
266864
268312
|
const segments = [];
|
|
266865
268313
|
for (const node of this.allHalfEdges) {
|
|
266866
268314
|
if (node.id < node.edgeMate.id)
|
|
266867
|
-
segments.push(
|
|
268315
|
+
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)));
|
|
266868
268316
|
}
|
|
266869
268317
|
return segments;
|
|
266870
268318
|
}
|
|
@@ -266933,6 +268381,26 @@ class HalfEdgeGraph {
|
|
|
266933
268381
|
break;
|
|
266934
268382
|
}
|
|
266935
268383
|
}
|
|
268384
|
+
/**
|
|
268385
|
+
* * Visit each edge of the graph once.
|
|
268386
|
+
* * Call the announceEdge function.
|
|
268387
|
+
* * the edge mate will NOT appear in an announceEdge call.
|
|
268388
|
+
* * continue search if announceEdge(graph, node) returns true
|
|
268389
|
+
* * terminate search if announceEdge (graph, node) returns false
|
|
268390
|
+
* @param announceEdge function to apply at one node of each edge.
|
|
268391
|
+
*/
|
|
268392
|
+
announceEdges(announceEdge) {
|
|
268393
|
+
this.clearMask(HalfEdgeMask.VISITED);
|
|
268394
|
+
for (const node of this.allHalfEdges) {
|
|
268395
|
+
if (node.getMask(HalfEdgeMask.VISITED))
|
|
268396
|
+
continue;
|
|
268397
|
+
const mate = node.edgeMate;
|
|
268398
|
+
node.setMask(HalfEdgeMask.VISITED);
|
|
268399
|
+
mate.setMask(HalfEdgeMask.VISITED);
|
|
268400
|
+
if (!announceEdge(this, node))
|
|
268401
|
+
break;
|
|
268402
|
+
}
|
|
268403
|
+
}
|
|
266936
268404
|
/**
|
|
266937
268405
|
* * Visit each vertex loop of the graph once.
|
|
266938
268406
|
* * Call the announceVertex function
|
|
@@ -266951,8 +268419,8 @@ class HalfEdgeGraph {
|
|
|
266951
268419
|
}
|
|
266952
268420
|
}
|
|
266953
268421
|
/**
|
|
266954
|
-
* * Visit each
|
|
266955
|
-
* * Call the
|
|
268422
|
+
* * Visit each half edge (node) of the graph once.
|
|
268423
|
+
* * Call the announceNode function
|
|
266956
268424
|
* * continue search if announceNode(graph, node) returns true
|
|
266957
268425
|
* * terminate search if announce face (graph, node) returns false
|
|
266958
268426
|
* @param announceNode function to apply at one node of each face.
|
|
@@ -267011,6 +268479,99 @@ class HalfEdgeGraph {
|
|
|
267011
268479
|
}
|
|
267012
268480
|
|
|
267013
268481
|
|
|
268482
|
+
/***/ }),
|
|
268483
|
+
|
|
268484
|
+
/***/ "../../core/geometry/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js":
|
|
268485
|
+
/*!************************************************************************************!*\
|
|
268486
|
+
!*** ../../core/geometry/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js ***!
|
|
268487
|
+
\************************************************************************************/
|
|
268488
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
268489
|
+
|
|
268490
|
+
"use strict";
|
|
268491
|
+
__webpack_require__.r(__webpack_exports__);
|
|
268492
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
268493
|
+
/* harmony export */ "HalfEdgeGraphFromIndexedLoopsContext": () => (/* binding */ HalfEdgeGraphFromIndexedLoopsContext)
|
|
268494
|
+
/* harmony export */ });
|
|
268495
|
+
/* harmony import */ var _Graph__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
|
|
268496
|
+
/*---------------------------------------------------------------------------------------------
|
|
268497
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
268498
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
268499
|
+
*--------------------------------------------------------------------------------------------*/
|
|
268500
|
+
|
|
268501
|
+
/** @packageDocumentation
|
|
268502
|
+
* @module Topology
|
|
268503
|
+
*/
|
|
268504
|
+
/**
|
|
268505
|
+
* Context for building a half edge graph from loops defined only by indices.
|
|
268506
|
+
* * Direct use case:
|
|
268507
|
+
* * Create the context.
|
|
268508
|
+
* * Repeatedly call insertLoop(indicesAroundLoop) to announce various loops.
|
|
268509
|
+
* * Finish by accessing the graph property.
|
|
268510
|
+
* @internal
|
|
268511
|
+
*/
|
|
268512
|
+
class HalfEdgeGraphFromIndexedLoopsContext {
|
|
268513
|
+
constructor() {
|
|
268514
|
+
this._unmatchedEdges = new Map();
|
|
268515
|
+
this._graph = new _Graph__WEBPACK_IMPORTED_MODULE_0__.HalfEdgeGraph();
|
|
268516
|
+
this._halfEdgesAroundCurrentLoop = [];
|
|
268517
|
+
}
|
|
268518
|
+
get graph() { return this._graph; }
|
|
268519
|
+
indexPairToString(index0, index1) {
|
|
268520
|
+
return `${index0.toString()},${index1.toString()}`;
|
|
268521
|
+
}
|
|
268522
|
+
/** Create a loop with specified indices at its vertices.
|
|
268523
|
+
* * For an edge with index pair [indexA, indexB]:
|
|
268524
|
+
* * if [indexB, indexA] has never appeared, a HalfEdge mated pair is created.
|
|
268525
|
+
* * One of that mated pair becomes a HalfEdge in this loop.
|
|
268526
|
+
* * The other is "unmatched"
|
|
268527
|
+
* * When announceMatedHalfEdges(halfEdge) is called:
|
|
268528
|
+
* * halfEdge and its mate are "new"
|
|
268529
|
+
* * all coordinates are zeros.
|
|
268530
|
+
* * each contains (as its halfEdge.id property) one index of the [indexA,indexB] pair.
|
|
268531
|
+
* * those coordinates and indices will never be referenced again by this construction sequence -- the caller is free to mutate them as needed.
|
|
268532
|
+
* * if [indexB, indexA] appeared previously (and its outer HalfEdge was left "unmatched"),
|
|
268533
|
+
* the "unmatched" HalfEdge is used in the loop being constructed.
|
|
268534
|
+
* @param indices Array of indices around the edge. This is accessed cyclically.
|
|
268535
|
+
* @param announceMatedHalfEdges optional function to be called as mated pairs are created. At the call,
|
|
268536
|
+
* the given HalfEdge and its mate will have a pair of successive indices from the array.
|
|
268537
|
+
*/
|
|
268538
|
+
insertLoop(indices, announceMatedHalfEdges) {
|
|
268539
|
+
const n = indices.length;
|
|
268540
|
+
if (n > 1) {
|
|
268541
|
+
let index0 = indices[indices.length - 1];
|
|
268542
|
+
this._halfEdgesAroundCurrentLoop.length = 0;
|
|
268543
|
+
for (const index1 of indices) {
|
|
268544
|
+
const insideString = this.indexPairToString(index0, index1);
|
|
268545
|
+
const halfEdgePreviouslyConstructedFromOppositeSide = this._unmatchedEdges.get(insideString);
|
|
268546
|
+
if (halfEdgePreviouslyConstructedFromOppositeSide === undefined) {
|
|
268547
|
+
// This is the first appearance of this edge in either direction.
|
|
268548
|
+
const outsideString = this.indexPairToString(index1, index0); // string referencing the "other" side of the new edge.
|
|
268549
|
+
const newHalfEdgeAroundLoop = this._graph.createEdgeIdId(index0, index1);
|
|
268550
|
+
if (announceMatedHalfEdges !== undefined)
|
|
268551
|
+
announceMatedHalfEdges(newHalfEdgeAroundLoop);
|
|
268552
|
+
this._unmatchedEdges.set(outsideString, newHalfEdgeAroundLoop.edgeMate);
|
|
268553
|
+
this._halfEdgesAroundCurrentLoop.push(newHalfEdgeAroundLoop);
|
|
268554
|
+
newHalfEdgeAroundLoop.edgeMate.setMask(_Graph__WEBPACK_IMPORTED_MODULE_0__.HalfEdgeMask.EXTERIOR);
|
|
268555
|
+
}
|
|
268556
|
+
else {
|
|
268557
|
+
this._halfEdgesAroundCurrentLoop.push(halfEdgePreviouslyConstructedFromOppositeSide);
|
|
268558
|
+
halfEdgePreviouslyConstructedFromOppositeSide.clearMask(_Graph__WEBPACK_IMPORTED_MODULE_0__.HalfEdgeMask.EXTERIOR);
|
|
268559
|
+
}
|
|
268560
|
+
index0 = index1;
|
|
268561
|
+
}
|
|
268562
|
+
let halfEdgeA = this._halfEdgesAroundCurrentLoop[this._halfEdgesAroundCurrentLoop.length - 1];
|
|
268563
|
+
for (const halfEdgeB of this._halfEdgesAroundCurrentLoop) {
|
|
268564
|
+
const halfEdgeC = halfEdgeA.faceSuccessor;
|
|
268565
|
+
_Graph__WEBPACK_IMPORTED_MODULE_0__.HalfEdge.pinch(halfEdgeB, halfEdgeC);
|
|
268566
|
+
halfEdgeA = halfEdgeB;
|
|
268567
|
+
}
|
|
268568
|
+
return this._halfEdgesAroundCurrentLoop[0];
|
|
268569
|
+
}
|
|
268570
|
+
return undefined;
|
|
268571
|
+
}
|
|
268572
|
+
}
|
|
268573
|
+
|
|
268574
|
+
|
|
267014
268575
|
/***/ }),
|
|
267015
268576
|
|
|
267016
268577
|
/***/ "../../core/geometry/lib/esm/topology/HalfEdgeGraphSearch.js":
|
|
@@ -301943,7 +303504,7 @@ module.exports = JSON.parse('{"name":"axios","version":"0.21.4","description":"P
|
|
|
301943
303504
|
/***/ ((module) => {
|
|
301944
303505
|
|
|
301945
303506
|
"use strict";
|
|
301946
|
-
module.exports = JSON.parse('{"name":"@itwin/core-frontend","version":"4.0.0-dev.
|
|
303507
|
+
module.exports = JSON.parse('{"name":"@itwin/core-frontend","version":"4.0.0-dev.8","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.8","@itwin/core-bentley":"workspace:^4.0.0-dev.8","@itwin/core-common":"workspace:^4.0.0-dev.8","@itwin/core-geometry":"workspace:^4.0.0-dev.8","@itwin/core-orbitgt":"workspace:^4.0.0-dev.8","@itwin/core-quantity":"workspace:^4.0.0-dev.8"},"//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"}}]}}');
|
|
301947
303508
|
|
|
301948
303509
|
/***/ })
|
|
301949
303510
|
|