@itwin/rpcinterface-full-stack-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 +2175 -614
- 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 +14 -14
|
@@ -183333,9 +183333,9 @@ class Geometry {
|
|
|
183333
183333
|
return 2 - ((-axis - 1) % 3);
|
|
183334
183334
|
}
|
|
183335
183335
|
/** Return the AxisOrder for which axisIndex is the first named axis.
|
|
183336
|
-
* * `axisIndex===0`returns AxisOrder.XYZ
|
|
183337
|
-
* * `axisIndex===1`returns AxisOrder.YZX
|
|
183338
|
-
* * `axisIndex===2`returns AxisOrder.ZXY
|
|
183336
|
+
* * `axisIndex === 0` returns `AxisOrder.XYZ`
|
|
183337
|
+
* * `axisIndex === 1` returns `AxisOrder.YZX`
|
|
183338
|
+
* * `axisIndex === 2` returns `AxisOrder.ZXY`
|
|
183339
183339
|
*/
|
|
183340
183340
|
static axisIndexToRightHandedAxisOrder(axisIndex) {
|
|
183341
183341
|
if (axisIndex === 0)
|
|
@@ -183347,7 +183347,9 @@ class Geometry {
|
|
|
183347
183347
|
return Geometry.axisIndexToRightHandedAxisOrder(Geometry.cyclic3dAxis(axisIndex));
|
|
183348
183348
|
}
|
|
183349
183349
|
/** Return the largest absolute distance from a to either of b0 or b1 */
|
|
183350
|
-
static maxAbsDiff(a, b0, b1) {
|
|
183350
|
+
static maxAbsDiff(a, b0, b1) {
|
|
183351
|
+
return Math.max(Math.abs(a - b0), Math.abs(a - b1));
|
|
183352
|
+
}
|
|
183351
183353
|
/** Return the largest absolute absolute value among x,y,z */
|
|
183352
183354
|
static maxAbsXYZ(x, y, z) {
|
|
183353
183355
|
return Geometry.maxXYZ(Math.abs(x), Math.abs(y), Math.abs(z));
|
|
@@ -183392,19 +183394,33 @@ class Geometry {
|
|
|
183392
183394
|
return q;
|
|
183393
183395
|
}
|
|
183394
183396
|
/** Return the hypotenuse `sqrt(x*x + y*y)`. This is much faster than `Math.hypot(x,y)`. */
|
|
183395
|
-
static hypotenuseXY(x, y) {
|
|
183397
|
+
static hypotenuseXY(x, y) {
|
|
183398
|
+
return Math.sqrt(x * x + y * y);
|
|
183399
|
+
}
|
|
183396
183400
|
/** Return the squared `hypotenuse (x*x + y*y)`. */
|
|
183397
|
-
static hypotenuseSquaredXY(x, y) {
|
|
183401
|
+
static hypotenuseSquaredXY(x, y) {
|
|
183402
|
+
return x * x + y * y;
|
|
183403
|
+
}
|
|
183398
183404
|
/** Return the square of x */
|
|
183399
|
-
static square(x) {
|
|
183405
|
+
static square(x) {
|
|
183406
|
+
return x * x;
|
|
183407
|
+
}
|
|
183400
183408
|
/** Return the hypotenuse `sqrt(x*x + y*y + z*z)`. This is much faster than `Math.hypot(x,y,z)`. */
|
|
183401
|
-
static hypotenuseXYZ(x, y, z) {
|
|
183409
|
+
static hypotenuseXYZ(x, y, z) {
|
|
183410
|
+
return Math.sqrt(x * x + y * y + z * z);
|
|
183411
|
+
}
|
|
183402
183412
|
/** Return the squared hypotenuse `(x*x + y*y + z*z)`. This is much faster than `Math.hypot(x,y,z)`. */
|
|
183403
|
-
static hypotenuseSquaredXYZ(x, y, z) {
|
|
183413
|
+
static hypotenuseSquaredXYZ(x, y, z) {
|
|
183414
|
+
return x * x + y * y + z * z;
|
|
183415
|
+
}
|
|
183404
183416
|
/** 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)`. */
|
|
183405
|
-
static hypotenuseXYZW(x, y, z, w) {
|
|
183417
|
+
static hypotenuseXYZW(x, y, z, w) {
|
|
183418
|
+
return Math.sqrt(x * x + y * y + z * z + w * w);
|
|
183419
|
+
}
|
|
183406
183420
|
/** Return the squared hypotenuse `(x*x + y*y + z*z+w*w)`. This is much faster than `Math.hypot(x,y,z)`. */
|
|
183407
|
-
static hypotenuseSquaredXYZW(x, y, z, w) {
|
|
183421
|
+
static hypotenuseSquaredXYZW(x, y, z, w) {
|
|
183422
|
+
return x * x + y * y + z * z + w * w;
|
|
183423
|
+
}
|
|
183408
183424
|
/**
|
|
183409
183425
|
* Return the distance between xy points given as numbers.
|
|
183410
183426
|
* @param x0 x coordinate of point 0
|
|
@@ -194261,6 +194277,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
194261
194277
|
/* harmony export */ "NewtonEvaluatorRtoRD": () => (/* reexport safe */ _numerics_Newton__WEBPACK_IMPORTED_MODULE_51__.NewtonEvaluatorRtoRD),
|
|
194262
194278
|
/* harmony export */ "NullGeometryHandler": () => (/* reexport safe */ _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODULE_8__.NullGeometryHandler),
|
|
194263
194279
|
/* harmony export */ "NumberArray": () => (/* reexport safe */ _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_23__.NumberArray),
|
|
194280
|
+
/* harmony export */ "OffsetMeshOptions": () => (/* reexport safe */ _polyface_PolyfaceQuery__WEBPACK_IMPORTED_MODULE_116__.OffsetMeshOptions),
|
|
194264
194281
|
/* harmony export */ "OffsetOptions": () => (/* reexport safe */ _curve_internalContexts_PolygonOffsetContext__WEBPACK_IMPORTED_MODULE_79__.OffsetOptions),
|
|
194265
194282
|
/* harmony export */ "Order2Bezier": () => (/* reexport safe */ _numerics_BezierPolynomials__WEBPACK_IMPORTED_MODULE_49__.Order2Bezier),
|
|
194266
194283
|
/* harmony export */ "Order3Bezier": () => (/* reexport safe */ _numerics_BezierPolynomials__WEBPACK_IMPORTED_MODULE_49__.Order3Bezier),
|
|
@@ -197272,11 +197289,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
197272
197289
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
197273
197290
|
/* harmony export */ "CurveCurve": () => (/* binding */ CurveCurve)
|
|
197274
197291
|
/* harmony export */ });
|
|
197275
|
-
/* harmony import */ var
|
|
197276
|
-
/* harmony import */ var
|
|
197277
|
-
/* harmony import */ var
|
|
197278
|
-
/* harmony import */ var
|
|
197279
|
-
/* harmony import */ var
|
|
197292
|
+
/* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
|
|
197293
|
+
/* harmony import */ var _CurveCollection__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./CurveCollection */ "../../core/geometry/lib/esm/curve/CurveCollection.js");
|
|
197294
|
+
/* harmony import */ var _CurveCurveCloseApproachXY__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./CurveCurveCloseApproachXY */ "../../core/geometry/lib/esm/curve/CurveCurveCloseApproachXY.js");
|
|
197295
|
+
/* harmony import */ var _CurveCurveIntersectXY__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./CurveCurveIntersectXY */ "../../core/geometry/lib/esm/curve/CurveCurveIntersectXY.js");
|
|
197296
|
+
/* harmony import */ var _CurveCurveIntersectXYZ__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./CurveCurveIntersectXYZ */ "../../core/geometry/lib/esm/curve/CurveCurveIntersectXYZ.js");
|
|
197297
|
+
/* harmony import */ var _CurvePrimitive__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./CurvePrimitive */ "../../core/geometry/lib/esm/curve/CurvePrimitive.js");
|
|
197280
197298
|
/*---------------------------------------------------------------------------------------------
|
|
197281
197299
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
197282
197300
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
@@ -197289,6 +197307,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
197289
197307
|
|
|
197290
197308
|
|
|
197291
197309
|
|
|
197310
|
+
|
|
197292
197311
|
/**
|
|
197293
197312
|
* `CurveCurve` has static method for various computations that work on a pair of curves or curve collections.
|
|
197294
197313
|
* @public
|
|
@@ -197296,17 +197315,18 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
197296
197315
|
class CurveCurve {
|
|
197297
197316
|
/**
|
|
197298
197317
|
* Return xy intersections of 2 curves.
|
|
197299
|
-
* @param geometryA
|
|
197318
|
+
* @param geometryA first geometry
|
|
197300
197319
|
* @param extendA true to allow geometryA to extend
|
|
197301
197320
|
* @param geometryB second geometry
|
|
197302
197321
|
* @param extendB true to allow geometryB to extend
|
|
197322
|
+
* @param tolerance optional distance tolerance for coincidence
|
|
197303
197323
|
*/
|
|
197304
|
-
static intersectionXYPairs(geometryA, extendA, geometryB, extendB) {
|
|
197305
|
-
const handler = new
|
|
197306
|
-
if (geometryB instanceof
|
|
197324
|
+
static intersectionXYPairs(geometryA, extendA, geometryB, extendB, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
|
|
197325
|
+
const handler = new _CurveCurveIntersectXY__WEBPACK_IMPORTED_MODULE_1__.CurveCurveIntersectXY(undefined, geometryA, extendA, geometryB, extendB, tolerance);
|
|
197326
|
+
if (geometryB instanceof _CurvePrimitive__WEBPACK_IMPORTED_MODULE_2__.CurvePrimitive) {
|
|
197307
197327
|
geometryA.dispatchToGeometryHandler(handler);
|
|
197308
197328
|
}
|
|
197309
|
-
else if (geometryB instanceof
|
|
197329
|
+
else if (geometryB instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_3__.CurveCollection) {
|
|
197310
197330
|
const allCurves = geometryB.collectCurvePrimitives();
|
|
197311
197331
|
for (const child of allCurves) {
|
|
197312
197332
|
handler.resetGeometry(geometryA, false, child, false);
|
|
@@ -197317,13 +197337,14 @@ class CurveCurve {
|
|
|
197317
197337
|
}
|
|
197318
197338
|
/**
|
|
197319
197339
|
* Return xy intersections of 2 projected curves
|
|
197320
|
-
* @param geometryA
|
|
197340
|
+
* @param geometryA first geometry
|
|
197321
197341
|
* @param extendA true to allow geometryA to extend
|
|
197322
197342
|
* @param geometryB second geometry
|
|
197323
197343
|
* @param extendB true to allow geometryB to extend
|
|
197344
|
+
* @param tolerance optional distance tolerance for coincidence
|
|
197324
197345
|
*/
|
|
197325
|
-
static intersectionProjectedXYPairs(worldToLocal, geometryA, extendA, geometryB, extendB) {
|
|
197326
|
-
const handler = new
|
|
197346
|
+
static intersectionProjectedXYPairs(worldToLocal, geometryA, extendA, geometryB, extendB, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
|
|
197347
|
+
const handler = new _CurveCurveIntersectXY__WEBPACK_IMPORTED_MODULE_1__.CurveCurveIntersectXY(worldToLocal, geometryA, extendA, geometryB, extendB, tolerance);
|
|
197327
197348
|
geometryA.dispatchToGeometryHandler(handler);
|
|
197328
197349
|
return handler.grabPairedResults();
|
|
197329
197350
|
}
|
|
@@ -197332,25 +197353,26 @@ class CurveCurve {
|
|
|
197332
197353
|
* * Implemented for combinations of LineSegment3d, LineString3d, Arc3d.
|
|
197333
197354
|
* * Not Implemented for bspline and bezier curves.
|
|
197334
197355
|
* @beta
|
|
197335
|
-
* @param geometryA
|
|
197356
|
+
* @param geometryA first geometry
|
|
197336
197357
|
* @param extendA true to allow geometryA to extend
|
|
197337
197358
|
* @param geometryB second geometry
|
|
197338
197359
|
* @param extendB true to allow geometryB to extend
|
|
197339
197360
|
*/
|
|
197340
197361
|
static intersectionXYZ(geometryA, extendA, geometryB, extendB) {
|
|
197341
|
-
const handler = new
|
|
197362
|
+
const handler = new _CurveCurveIntersectXYZ__WEBPACK_IMPORTED_MODULE_4__.CurveCurveIntersectXYZ(geometryA, extendA, geometryB, extendB);
|
|
197342
197363
|
geometryA.dispatchToGeometryHandler(handler);
|
|
197343
197364
|
return handler.grabResults();
|
|
197344
197365
|
}
|
|
197345
197366
|
/**
|
|
197346
197367
|
* Return xy intersections of 2 curves.
|
|
197347
|
-
* @param geometryA
|
|
197368
|
+
* @param geometryA first geometry
|
|
197348
197369
|
* @param extendA true to allow geometryA to extend
|
|
197349
197370
|
* @param geometryB second geometry
|
|
197350
197371
|
* @param extendB true to allow geometryB to extend
|
|
197372
|
+
* @param tolerance optional distance tolerance for coincidence
|
|
197351
197373
|
*/
|
|
197352
|
-
static allIntersectionsAmongPrimitivesXY(primitives) {
|
|
197353
|
-
const handler = new
|
|
197374
|
+
static allIntersectionsAmongPrimitivesXY(primitives, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
|
|
197375
|
+
const handler = new _CurveCurveIntersectXY__WEBPACK_IMPORTED_MODULE_1__.CurveCurveIntersectXY(undefined, undefined, false, undefined, false, tolerance);
|
|
197354
197376
|
for (let i = 0; i < primitives.length; i++) {
|
|
197355
197377
|
const geometryA = primitives[i];
|
|
197356
197378
|
for (let j = i + 1; j < primitives.length; j++) {
|
|
@@ -197362,11 +197384,11 @@ class CurveCurve {
|
|
|
197362
197384
|
}
|
|
197363
197385
|
/**
|
|
197364
197386
|
* Return xy close approaches of 2 projected curves
|
|
197365
|
-
* @param geometryA
|
|
197387
|
+
* @param geometryA first geometry
|
|
197366
197388
|
* @param geometryB second geometry
|
|
197367
197389
|
*/
|
|
197368
197390
|
static closeApproachProjectedXYPairs(geometryA, geometryB, maxDistance) {
|
|
197369
|
-
const handler = new
|
|
197391
|
+
const handler = new _CurveCurveCloseApproachXY__WEBPACK_IMPORTED_MODULE_5__.CurveCurveCloseApproachXY(geometryA, geometryB);
|
|
197370
197392
|
handler.maxDistanceToAccept = maxDistance;
|
|
197371
197393
|
geometryA.dispatchToGeometryHandler(handler);
|
|
197372
197394
|
return handler.grabPairedResults();
|
|
@@ -198135,8 +198157,8 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
198135
198157
|
/* harmony export */ "CurveLocationDetailArrayPair": () => (/* binding */ CurveLocationDetailArrayPair)
|
|
198136
198158
|
/* harmony export */ });
|
|
198137
198159
|
/* harmony import */ var _bspline_BSplineCurve__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../bspline/BSplineCurve */ "../../core/geometry/lib/esm/bspline/BSplineCurve.js");
|
|
198138
|
-
/* harmony import */ var
|
|
198139
|
-
/* harmony import */ var
|
|
198160
|
+
/* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
|
|
198161
|
+
/* harmony import */ var _geometry3d_CoincidentGeometryOps__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../geometry3d/CoincidentGeometryOps */ "../../core/geometry/lib/esm/geometry3d/CoincidentGeometryOps.js");
|
|
198140
198162
|
/* harmony import */ var _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../geometry3d/GeometryHandler */ "../../core/geometry/lib/esm/geometry3d/GeometryHandler.js");
|
|
198141
198163
|
/* harmony import */ var _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../geometry3d/GrowableFloat64Array */ "../../core/geometry/lib/esm/geometry3d/GrowableFloat64Array.js");
|
|
198142
198164
|
/* harmony import */ var _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../geometry3d/Matrix3d */ "../../core/geometry/lib/esm/geometry3d/Matrix3d.js");
|
|
@@ -198161,14 +198183,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
198161
198183
|
|
|
198162
198184
|
|
|
198163
198185
|
|
|
198164
|
-
// import { Arc3d } from "./Arc3d";
|
|
198165
198186
|
|
|
198166
198187
|
|
|
198167
198188
|
|
|
198168
198189
|
|
|
198169
198190
|
|
|
198170
198191
|
|
|
198171
|
-
// import { LineString3d } from "./LineString3d";
|
|
198172
198192
|
|
|
198173
198193
|
|
|
198174
198194
|
|
|
@@ -198221,8 +198241,9 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
198221
198241
|
* @param extendA flag to enable using extension of geometryA.
|
|
198222
198242
|
* @param geometryB second curve for intersection. Saved for reference by specific handler methods.
|
|
198223
198243
|
* @param extendB flag for extension of geometryB.
|
|
198244
|
+
* @param tolerance optional distance tolerance for coincidence
|
|
198224
198245
|
*/
|
|
198225
|
-
constructor(worldToLocal, _geometryA, extendA, geometryB, extendB) {
|
|
198246
|
+
constructor(worldToLocal, _geometryA, extendA, geometryB, extendB, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistance) {
|
|
198226
198247
|
super();
|
|
198227
198248
|
// this.geometryA = _geometryA;
|
|
198228
198249
|
this._extendA = extendA;
|
|
@@ -198235,7 +198256,7 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
198235
198256
|
if (!this._worldToLocalAffine)
|
|
198236
198257
|
this._worldToLocalPerspective = worldToLocal.clone();
|
|
198237
198258
|
}
|
|
198238
|
-
this._coincidentGeometryContext =
|
|
198259
|
+
this._coincidentGeometryContext = _geometry3d_CoincidentGeometryOps__WEBPACK_IMPORTED_MODULE_4__.CoincidentGeometryQuery.create(tolerance);
|
|
198239
198260
|
this.reinitialize();
|
|
198240
198261
|
}
|
|
198241
198262
|
reinitialize() {
|
|
@@ -198254,13 +198275,15 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
198254
198275
|
return false;
|
|
198255
198276
|
return true;
|
|
198256
198277
|
}
|
|
198257
|
-
|
|
198258
|
-
|
|
198278
|
+
/** Test the fraction by strict parameter, but allow toleranced distance test at ends.
|
|
198279
|
+
* @param tolerance optional distance tolerance to check proximity to start/end point
|
|
198280
|
+
*/
|
|
198281
|
+
acceptFractionOnLine(extend0, fraction, extend1, pointA, pointB, tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.smallMetricDistance) {
|
|
198259
198282
|
if (!extend0 && fraction < 0) {
|
|
198260
|
-
return
|
|
198283
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.isDistanceWithinTol(fraction * pointA.distanceXY(pointB), tolerance);
|
|
198261
198284
|
}
|
|
198262
198285
|
else if (!extend1 && fraction > 1.0)
|
|
198263
|
-
return
|
|
198286
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.isDistanceWithinTol((fraction - 1.0) * pointA.distanceXY(pointB), tolerance);
|
|
198264
198287
|
return true;
|
|
198265
198288
|
}
|
|
198266
198289
|
/**
|
|
@@ -198275,7 +198298,7 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
198275
198298
|
return result;
|
|
198276
198299
|
}
|
|
198277
198300
|
sameCurveAndFraction(cp, fraction, detail) {
|
|
198278
|
-
return cp === detail.curve &&
|
|
198301
|
+
return cp === detail.curve && _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.isAlmostEqualNumber(fraction, detail.fraction);
|
|
198279
198302
|
}
|
|
198280
198303
|
/** compute intersection of two line segments.
|
|
198281
198304
|
* filter by extension rules.
|
|
@@ -198287,14 +198310,14 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
198287
198310
|
let globalFractionA1, globalFractionB1;
|
|
198288
198311
|
const isInterval = intervalDetails !== undefined && intervalDetails.detailA.hasFraction1 && intervalDetails.detailB.hasFraction1;
|
|
198289
198312
|
if (isInterval) {
|
|
198290
|
-
globalFractionA =
|
|
198291
|
-
globalFractionB =
|
|
198292
|
-
globalFractionA1 =
|
|
198293
|
-
globalFractionB1 =
|
|
198313
|
+
globalFractionA = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionA0, intervalDetails.detailA.fraction, fractionA1);
|
|
198314
|
+
globalFractionB = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionB0, intervalDetails.detailB.fraction, fractionB1);
|
|
198315
|
+
globalFractionA1 = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionA0, intervalDetails.detailA.fraction1, fractionA1);
|
|
198316
|
+
globalFractionB1 = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionB0, intervalDetails.detailB.fraction1, fractionB1);
|
|
198294
198317
|
}
|
|
198295
198318
|
else {
|
|
198296
|
-
globalFractionA = globalFractionA1 =
|
|
198297
|
-
globalFractionB = globalFractionB1 =
|
|
198319
|
+
globalFractionA = globalFractionA1 = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionA0, localFractionA, fractionA1);
|
|
198320
|
+
globalFractionB = globalFractionB1 = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(fractionB0, localFractionB, fractionB1);
|
|
198298
198321
|
}
|
|
198299
198322
|
// ignore duplicate of most recent point . ..
|
|
198300
198323
|
const numPrevious = this._results.length;
|
|
@@ -198356,8 +198379,8 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
198356
198379
|
this.recordPointWithLocalFractions(overlap.detailA.fraction, cpA, fractionA0, fractionA1, overlap.detailB.fraction, cpB, fractionB0, fractionB1, reversed, overlap);
|
|
198357
198380
|
}
|
|
198358
198381
|
else if (_numerics_Polynomials__WEBPACK_IMPORTED_MODULE_6__.SmallSystem.lineSegment3dXYTransverseIntersectionUnbounded(pointA0, pointA1, pointB0, pointB1, uv)) {
|
|
198359
|
-
if (this.acceptFractionOnLine(extendA0, uv.x, extendA1, pointA0, pointA1)
|
|
198360
|
-
&& this.acceptFractionOnLine(extendB0, uv.y, extendB1, pointB0, pointB1)) {
|
|
198382
|
+
if (this.acceptFractionOnLine(extendA0, uv.x, extendA1, pointA0, pointA1, this._coincidentGeometryContext.tolerance)
|
|
198383
|
+
&& this.acceptFractionOnLine(extendB0, uv.y, extendB1, pointB0, pointB1, this._coincidentGeometryContext.tolerance)) {
|
|
198361
198384
|
this.recordPointWithLocalFractions(uv.x, cpA, fractionA0, fractionA1, uv.y, cpB, fractionB0, fractionB1, reversed);
|
|
198362
198385
|
}
|
|
198363
198386
|
}
|
|
@@ -198415,9 +198438,9 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
198415
198438
|
const data = arc.toTransformedPoint4d(this._worldToLocalPerspective);
|
|
198416
198439
|
const pointA0H = this._worldToLocalPerspective.multiplyPoint3d(pointA0, 1);
|
|
198417
198440
|
const pointA1H = this._worldToLocalPerspective.multiplyPoint3d(pointA1, 1);
|
|
198418
|
-
const alpha =
|
|
198419
|
-
const beta =
|
|
198420
|
-
const gamma =
|
|
198441
|
+
const alpha = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.center);
|
|
198442
|
+
const beta = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.vector0);
|
|
198443
|
+
const gamma = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.vector90);
|
|
198421
198444
|
const cosines = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array(2);
|
|
198422
198445
|
const sines = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array(2);
|
|
198423
198446
|
const radians = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array(2);
|
|
@@ -198439,9 +198462,9 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
198439
198462
|
pointA0Local = this._worldToLocalAffine.multiplyPoint3d(pointA0);
|
|
198440
198463
|
pointA1Local = this._worldToLocalAffine.multiplyPoint3d(pointA1);
|
|
198441
198464
|
}
|
|
198442
|
-
const alpha =
|
|
198443
|
-
const beta =
|
|
198444
|
-
const gamma =
|
|
198465
|
+
const alpha = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.center, 1);
|
|
198466
|
+
const beta = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector0, 0);
|
|
198467
|
+
const gamma = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector90, 0);
|
|
198445
198468
|
const cosines = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array(2);
|
|
198446
198469
|
const sines = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array(2);
|
|
198447
198470
|
const radians = new _geometry3d_GrowableFloat64Array__WEBPACK_IMPORTED_MODULE_7__.GrowableFloat64Array(2);
|
|
@@ -198666,8 +198689,8 @@ class CurveCurveIntersectXY extends _geometry3d_GeometryHandler__WEBPACK_IMPORTE
|
|
|
198666
198689
|
let bezierBFraction = r;
|
|
198667
198690
|
bezierB.fractionToPoint4d(bezierBFraction, this._xyzwB);
|
|
198668
198691
|
const segmentAFraction = _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_6__.SmallSystem.lineSegment3dHXYClosestPointUnbounded(this._xyzwA0, this._xyzwA1, this._xyzwB);
|
|
198669
|
-
if (segmentAFraction &&
|
|
198670
|
-
let bezierAFraction =
|
|
198692
|
+
if (segmentAFraction && _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.isIn01WithTolerance(segmentAFraction, intervalTolerance)) {
|
|
198693
|
+
let bezierAFraction = _Geometry__WEBPACK_IMPORTED_MODULE_3__.Geometry.interpolate(f0, segmentAFraction, f1);
|
|
198671
198694
|
const xyMatchingFunction = new BezierBezierIntersectionXYRRToRRD(bezierA, bezierB);
|
|
198672
198695
|
const newtonSearcher = new _numerics_Newton__WEBPACK_IMPORTED_MODULE_0__.Newton2dUnboundedWithDerivative(xyMatchingFunction);
|
|
198673
198696
|
newtonSearcher.setUV(bezierAFraction, bezierBFraction);
|
|
@@ -212656,6 +212679,44 @@ class Angle {
|
|
|
212656
212679
|
const uDotV = ux * vx + uy * vy + uz * vz;
|
|
212657
212680
|
return Math.atan2(_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.crossProductMagnitude(ux, uy, uz, vx, vy, vz), uDotV);
|
|
212658
212681
|
}
|
|
212682
|
+
/**
|
|
212683
|
+
* * 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.
|
|
212684
|
+
* * The returned angle is (-PI < radians <= PI) or (0 <= radians < 2 * PI)
|
|
212685
|
+
* * The angle is in the plane of the U and V vectors.
|
|
212686
|
+
* * The upVector determines a positive side of the plane but need not be strictly perpendicular to the plane.
|
|
212687
|
+
*
|
|
212688
|
+
* @param ux x component of vector u
|
|
212689
|
+
* @param uy y component of vector u
|
|
212690
|
+
* @param uz z component of vector u
|
|
212691
|
+
* @param vx x component of vector v
|
|
212692
|
+
* @param vy y component of vector v
|
|
212693
|
+
* @param vz z component of vector v
|
|
212694
|
+
* @param upVectorX x component of vector to positive side of plane.
|
|
212695
|
+
* @param upVectorY y component of vector to positive side of plane.
|
|
212696
|
+
* @param upVectorZ z component of vector to positive side of plane.
|
|
212697
|
+
* @param adjustToAllPositive if true, return strictly non-negative sweep (0 <= radians < 2*PI). If false, return signed (-PI < radians <= PI)
|
|
212698
|
+
*/
|
|
212699
|
+
static orientedRadiansBetweenVectorsXYZ(ux, uy, uz, vx, vy, vz, upVectorX, upVectorY, upVectorZ, adjustToPositive = false) {
|
|
212700
|
+
const uDotV = ux * vx + uy * vy + uz * vz;
|
|
212701
|
+
const wx = uy * vz - uz * vy;
|
|
212702
|
+
const wy = uz * vx - ux * vz;
|
|
212703
|
+
const wz = ux * vy - uy * vx;
|
|
212704
|
+
const upDotW = upVectorX * wx + upVectorY * wy + upVectorZ * wz;
|
|
212705
|
+
const crossMagnitude = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(wx, wy, wz);
|
|
212706
|
+
if (upDotW < 0.0) {
|
|
212707
|
+
if (adjustToPositive) {
|
|
212708
|
+
// The turn is greater than 180 degrees. Take a peculiarly oriented atan2 to get the excess-180 part as addition to PI.
|
|
212709
|
+
// This gives the smoothest numerical transition passing PI.
|
|
212710
|
+
return Math.PI + Math.atan2(crossMagnitude, -uDotV);
|
|
212711
|
+
}
|
|
212712
|
+
else {
|
|
212713
|
+
return -Math.atan2(crossMagnitude, uDotV);
|
|
212714
|
+
}
|
|
212715
|
+
}
|
|
212716
|
+
else {
|
|
212717
|
+
return Math.atan2(crossMagnitude, uDotV);
|
|
212718
|
+
}
|
|
212719
|
+
}
|
|
212659
212720
|
/**
|
|
212660
212721
|
* Add a multiple of a full circle angle (360 degrees, 2PI) in place.
|
|
212661
212722
|
* @param multiple multiplier factor
|
|
@@ -213483,6 +213544,9 @@ class CoincidentGeometryQuery {
|
|
|
213483
213544
|
constructor(tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
|
|
213484
213545
|
this._tolerance = tolerance;
|
|
213485
213546
|
}
|
|
213547
|
+
get tolerance() {
|
|
213548
|
+
return this._tolerance;
|
|
213549
|
+
}
|
|
213486
213550
|
static create(tolerance = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallMetricDistance) {
|
|
213487
213551
|
return new CoincidentGeometryQuery(tolerance);
|
|
213488
213552
|
}
|
|
@@ -218032,6 +218096,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
218032
218096
|
|
|
218033
218097
|
|
|
218034
218098
|
/* eslint-disable @itwin/prefer-get */
|
|
218099
|
+
// cSpell:words XXYZ YXYZ ZXYZ
|
|
218035
218100
|
/**
|
|
218036
218101
|
* PackedMatrix3dOps contains static methods for matrix operations where the matrix is a Float64Array.
|
|
218037
218102
|
* * The Float64Array contains the matrix entries in row-major order
|
|
@@ -218659,7 +218724,8 @@ class Matrix3d {
|
|
|
218659
218724
|
return undefined;
|
|
218660
218725
|
}
|
|
218661
218726
|
/**
|
|
218662
|
-
* Construct a rigid matrix using vectorA and its 2 perpendicular.
|
|
218727
|
+
* Construct a rigid matrix (orthogonal matrix with +1 determinant) using vectorA and its 2 perpendicular.
|
|
218728
|
+
* * If axisOrder is not passed then `AxisOrder = AxisOrder.ZXY` is used as default.
|
|
218663
218729
|
* * This function internally uses createPerpendicularVectorFavorXYPlane and createRigidFromColumns.
|
|
218664
218730
|
*/
|
|
218665
218731
|
static createRigidHeadsUp(vectorA, axisOrder = _Geometry__WEBPACK_IMPORTED_MODULE_0__.AxisOrder.ZXY, result) {
|
|
@@ -218671,7 +218737,7 @@ class Matrix3d {
|
|
|
218671
218737
|
}
|
|
218672
218738
|
return Matrix3d.createIdentity(result);
|
|
218673
218739
|
}
|
|
218674
|
-
/** Return the matrix for rotation of `angle` around `axis` */
|
|
218740
|
+
/** Return the matrix for rotation of `angle` around desired `axis` */
|
|
218675
218741
|
static createRotationAroundVector(axis, angle, result) {
|
|
218676
218742
|
// Rodriguez formula (matrix form), https://mathworld.wolfram.com/RodriguesRotationFormula.html
|
|
218677
218743
|
const c = angle.cos();
|
|
@@ -218685,7 +218751,7 @@ class Matrix3d {
|
|
|
218685
218751
|
}
|
|
218686
218752
|
return undefined;
|
|
218687
218753
|
}
|
|
218688
|
-
/** Returns a rotation of specified angle around
|
|
218754
|
+
/** Returns a rotation of specified angle around one of the main axis (X,Y,Z).
|
|
218689
218755
|
* @param axisIndex index of axis (AxisIndex.X, AxisIndex.Y, AxisIndex.Z) kept fixed by the rotation.
|
|
218690
218756
|
* @param angle angle of rotation
|
|
218691
218757
|
* @param result optional result matrix.
|
|
@@ -218708,14 +218774,33 @@ class Matrix3d {
|
|
|
218708
218774
|
return myResult;
|
|
218709
218775
|
}
|
|
218710
218776
|
/**
|
|
218711
|
-
|
|
218712
|
-
|
|
218713
|
-
|
|
218714
|
-
|
|
218715
|
-
|
|
218716
|
-
|
|
218717
|
-
|
|
218718
|
-
|
|
218777
|
+
* Replace current rows Ui and Uj with (c*Ui + s*Uj) and (c*Uj - s*Ui).
|
|
218778
|
+
* * There is no checking for i,j being 0,1,2.
|
|
218779
|
+
* @param i first row index. **must be 0,1,2** (unchecked)
|
|
218780
|
+
* @param j second row index. **must be 0,1,2** (unchecked)
|
|
218781
|
+
* @param c fist coefficient
|
|
218782
|
+
* @param s second coefficient
|
|
218783
|
+
*/
|
|
218784
|
+
applyGivensRowOp(i, j, c, s) {
|
|
218785
|
+
let ii = 3 * i;
|
|
218786
|
+
let jj = 3 * j;
|
|
218787
|
+
const limit = ii + 3;
|
|
218788
|
+
for (; ii < limit; ii++, jj++) {
|
|
218789
|
+
const a = this.coffs[ii];
|
|
218790
|
+
const b = this.coffs[jj];
|
|
218791
|
+
this.coffs[ii] = a * c + b * s;
|
|
218792
|
+
this.coffs[jj] = -a * s + b * c;
|
|
218793
|
+
}
|
|
218794
|
+
}
|
|
218795
|
+
/**
|
|
218796
|
+
* Replace current columns Ui and Uj with (c*Ui + s*Uj) and (c*Uj - s*Ui).
|
|
218797
|
+
* * There is no checking for i,j being 0,1,2.
|
|
218798
|
+
* * This is used in compute intensive inner loops
|
|
218799
|
+
* @param i first row index. **must be 0,1,2** (unchecked)
|
|
218800
|
+
* @param j second row index. **must be 0,1,2** (unchecked)
|
|
218801
|
+
* @param c fist coefficient
|
|
218802
|
+
* @param s second coefficient
|
|
218803
|
+
*/
|
|
218719
218804
|
applyGivensColumnOp(i, j, c, s) {
|
|
218720
218805
|
const limit = i + 9;
|
|
218721
218806
|
for (; i < limit; i += 3, j += 3) {
|
|
@@ -218726,12 +218811,12 @@ class Matrix3d {
|
|
|
218726
218811
|
}
|
|
218727
218812
|
}
|
|
218728
218813
|
/**
|
|
218729
|
-
|
|
218730
|
-
|
|
218731
|
-
|
|
218732
|
-
|
|
218733
|
-
|
|
218734
|
-
|
|
218814
|
+
* Create a matrix from column vectors.
|
|
218815
|
+
* ```
|
|
218816
|
+
* equation
|
|
218817
|
+
* \begin{bmatrix}U_x & V_x & W_x \\ U_y & V_y & W_y \\ U_z & V_z & W_z \end{bmatrix}
|
|
218818
|
+
* ```
|
|
218819
|
+
*/
|
|
218735
218820
|
static createColumns(vectorU, vectorV, vectorW, result) {
|
|
218736
218821
|
return Matrix3d.createRowValues(vectorU.x, vectorV.x, vectorW.x, vectorU.y, vectorV.y, vectorW.y, vectorU.z, vectorV.z, vectorW.z, result);
|
|
218737
218822
|
}
|
|
@@ -218748,8 +218833,9 @@ class Matrix3d {
|
|
|
218748
218833
|
* * ColumnX points in the rightVector direction
|
|
218749
218834
|
* * ColumnY points in the upVector direction
|
|
218750
218835
|
* * ColumnZ is a unit cross product of ColumnX and ColumnY.
|
|
218751
|
-
* * Optionally rotate
|
|
218752
|
-
* * Optionally rotate
|
|
218836
|
+
* * Optionally rotate by 45 degrees around `upVector` to bring its left or right vertical edge to center.
|
|
218837
|
+
* * Optionally rotate by arctan(1/sqrt(2)) ~ 35.264 degrees around `rightVector` to bring the top or bottom
|
|
218838
|
+
* horizontal edge of the view to the center (for isometric views).
|
|
218753
218839
|
* * This is expected to be used with various principal unit vectors that are perpendicular to each other.
|
|
218754
218840
|
* * STANDARD TOP VIEW: createViewedAxes(Vector3d.unitX(), Vector3d.unitY(), 0, 0)
|
|
218755
218841
|
* * STANDARD FRONT VIEW: createViewedAxes(Vector3d.unitX(), Vector3d.unitZ(), 0, 0)
|
|
@@ -218757,16 +218843,20 @@ class Matrix3d {
|
|
|
218757
218843
|
* * STANDARD RIGHT VIEW: createViewedAxes(Vector3d.unitY(), Vector3d.unitZ(), 0, 0)
|
|
218758
218844
|
* * STANDARD LEFT VIEW: createViewedAxes(Vector3d.unitY(-1), Vector3d.unitZ(), 0, 0)
|
|
218759
218845
|
* * STANDARD BOTTOM VIEW: createViewedAxes(Vector3d.unitX(), Vector3d.unitY(-1), 0, 0)
|
|
218846
|
+
* * STANDARD ISO VIEW: createViewedAxes(Vector3d.unitX(), Vector3d.unitZ(), -1, 1)
|
|
218847
|
+
* * STANDARD RIGHT ISO VIEW: createViewedAxes(Vector3d.unitX(), Vector3d.unitZ(), 1, 1)
|
|
218848
|
+
* * Front, right, back, left, top, and bottom standard views are views from faces of the cube
|
|
218849
|
+
* and iso and right iso standard views are views from corners of the cube.
|
|
218760
218850
|
* * Note: createViewedAxes is column-based so always returns local to world
|
|
218761
218851
|
*
|
|
218762
218852
|
* @param rightVector ColumnX of the returned matrix. Expected to be perpendicular to upVector.
|
|
218763
218853
|
* @param upVector ColumnY of the returned matrix. Expected to be perpendicular to rightVector.
|
|
218764
|
-
* @param leftNoneRight Specifies the ccw rotation around
|
|
218765
|
-
* "-1" indicates rotation by 45 degrees to bring the left vertical edge to center, "0" means no rotation,
|
|
218854
|
+
* @param leftNoneRight Specifies the ccw rotation around `upVector` axis. Normally one of "-1", "0", and "1",
|
|
218855
|
+
* where "-1" indicates rotation by 45 degrees to bring the left vertical edge to center, "0" means no rotation,
|
|
218766
218856
|
* and "1" indicates rotation by 45 degrees to bring the right vertical edge to center. Other numbers are
|
|
218767
218857
|
* used as multiplier for this 45 degree rotation.
|
|
218768
|
-
* @param topNoneBottom Specifies the ccw rotation around
|
|
218769
|
-
* "-1" indicates isometric rotation (35.264 degrees) to bring the bottom upward, "0" means no rotation,
|
|
218858
|
+
* @param topNoneBottom Specifies the ccw rotation around `rightVector` axis. Normally one of "-1", "0", and "1",
|
|
218859
|
+
* where "-1" indicates isometric rotation (35.264 degrees) to bring the bottom upward, "0" means no rotation,
|
|
218770
218860
|
* and "1" indicates isometric rotation (35.264 degrees) to bring the top downward. Other numbers are
|
|
218771
218861
|
* used as multiplier for the 35.264 degree rotation.
|
|
218772
218862
|
* @returns matrix = [rightVector, upVector, rightVector cross upVector] with the applied rotations specified
|
|
@@ -218804,9 +218894,11 @@ class Matrix3d {
|
|
|
218804
218894
|
* * Default is TOP view (`local X = world X`, `local Y = world Y`, `local Z = world Z`).
|
|
218805
218895
|
* * To change view from the TOP to one of the other 7 standard views, we need to multiply "world data" to
|
|
218806
218896
|
* the corresponding matrix1 provided by `createStandardWorldToView(index, false)` and then
|
|
218807
|
-
* `matrix1.multiply(world data)` will
|
|
218897
|
+
* `matrix1.multiply(world data)` will return "local data".
|
|
218808
218898
|
* * To change view back to the TOP, we need to multiply "local data" to the corresponding matrix2 provided
|
|
218809
218899
|
* by `createStandardWorldToView(index, true)` and then `matrix2.multiply(local data)` will returns "world data".
|
|
218900
|
+
* * Note: No matter how you rotate the world axis, local X is always pointing right, local Y is always pointing up,
|
|
218901
|
+
* and local Z is always pointing toward you.
|
|
218810
218902
|
*
|
|
218811
218903
|
* @param index standard view index `StandardViewIndex.Top, Bottom, Left, Right, Front, Back, Iso, RightIso`
|
|
218812
218904
|
* @param invert if false (default), the return matrix is world to local (view) and if true, the the return
|
|
@@ -218815,343 +218907,182 @@ class Matrix3d {
|
|
|
218815
218907
|
*/
|
|
218816
218908
|
static createStandardWorldToView(index, invert = false, result) {
|
|
218817
218909
|
switch (index) {
|
|
218818
|
-
//
|
|
218910
|
+
// Start with TOP view, ccw rotation by 180 degrees around X
|
|
218819
218911
|
case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Bottom:
|
|
218820
218912
|
result = Matrix3d.createRowValues(1, 0, 0, 0, -1, 0, 0, 0, -1);
|
|
218821
218913
|
break;
|
|
218822
|
-
//
|
|
218914
|
+
// Start with TOP view, ccw rotation by -90 degrees around X and by 90 degrees around Z
|
|
218823
218915
|
case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Left:
|
|
218824
218916
|
result = Matrix3d.createRowValues(0, -1, 0, 0, 0, 1, -1, 0, 0);
|
|
218825
218917
|
break;
|
|
218826
|
-
//
|
|
218918
|
+
// Start with TOP view, ccw rotation by -90 degrees around X and by -90 degrees around Z
|
|
218827
218919
|
case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Right:
|
|
218828
218920
|
result = Matrix3d.createRowValues(0, 1, 0, 0, 0, 1, 1, 0, 0);
|
|
218829
218921
|
break;
|
|
218830
|
-
//
|
|
218922
|
+
// Start with TOP view, ccw rotation by -90 degrees around X
|
|
218831
218923
|
case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Front:
|
|
218832
218924
|
result = Matrix3d.createRowValues(1, 0, 0, 0, 0, 1, 0, -1, 0);
|
|
218833
218925
|
break;
|
|
218834
|
-
//
|
|
218926
|
+
// Start with TOP view, ccw rotation by -90 degrees around X and by 180 degrees around Z
|
|
218835
218927
|
case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Back:
|
|
218836
218928
|
result = Matrix3d.createRowValues(-1, 0, 0, 0, 0, 1, 0, 1, 0);
|
|
218837
218929
|
break;
|
|
218930
|
+
/**
|
|
218931
|
+
* Isometric view
|
|
218932
|
+
* Start with FRONT view, ccw rotation by -45 degrees around Y and by arctan(1/sqrt(2)) ~ 35.264 degrees around X
|
|
218933
|
+
* cos(45) = 1/sqrt(2) = 0.70710678118 and sin(45) = 1/sqrt(2) = 0.70710678118
|
|
218934
|
+
* cos(35.264) = 2/sqrt(6) = 0.81649658092 and sin(35.264) = 1/sqrt(3) = 0.57735026919
|
|
218935
|
+
* More info: https://en.wikipedia.org/wiki/Isometric_projection
|
|
218936
|
+
*/
|
|
218838
218937
|
case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Iso:
|
|
218839
|
-
// start with FRONT view, ccw rotation by -45 degrees around Y and by 35.264 degrees around X
|
|
218840
218938
|
result = Matrix3d.createRowValues(0.707106781186548, -0.70710678118654757, 0.00000000000000000, 0.408248290463863, 0.40824829046386302, 0.81649658092772603, -0.577350269189626, -0.57735026918962573, 0.57735026918962573);
|
|
218841
218939
|
break;
|
|
218940
|
+
// Start with FRONT view, ccw rotation by 45 degrees around Y and by 35.264 degrees around X
|
|
218842
218941
|
case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.RightIso:
|
|
218843
218942
|
result = Matrix3d.createRowValues(0.707106781186548, 0.70710678118654757, 0.00000000000000000, -0.408248290463863, 0.40824829046386302, 0.81649658092772603, 0.577350269189626, -0.57735026918962573, 0.57735026918962573);
|
|
218844
218943
|
break;
|
|
218845
|
-
|
|
218944
|
+
// no rotation
|
|
218945
|
+
case _Geometry__WEBPACK_IMPORTED_MODULE_0__.StandardViewIndex.Top:
|
|
218846
218946
|
default:
|
|
218847
218947
|
result = Matrix3d.createIdentity(result);
|
|
218848
218948
|
}
|
|
218849
218949
|
if (invert)
|
|
218850
|
-
result.transposeInPlace();
|
|
218950
|
+
result.transposeInPlace(); // matrix is rigid so transpose and inverse are the same
|
|
218851
218951
|
return result;
|
|
218852
218952
|
}
|
|
218853
|
-
|
|
218854
|
-
|
|
218855
|
-
|
|
218856
|
-
|
|
218857
|
-
|
|
218858
|
-
|
|
218859
|
-
|
|
218860
|
-
|
|
218861
|
-
|
|
218862
|
-
|
|
218863
|
-
|
|
218864
|
-
|
|
218865
|
-
|
|
218866
|
-
|
|
218867
|
-
|
|
218868
|
-
|
|
218869
|
-
|
|
218870
|
-
|
|
218871
|
-
|
|
218872
|
-
|
|
218873
|
-
|
|
218874
|
-
|
|
218875
|
-
|
|
218876
|
-
|
|
218877
|
-
|
|
218878
|
-
|
|
218879
|
-
|
|
218880
|
-
|
|
218881
|
-
|
|
218882
|
-
|
|
218883
|
-
|
|
218884
|
-
|
|
218885
|
-
|
|
218886
|
-
|
|
218887
|
-
|
|
218888
|
-
|
|
218889
|
-
|
|
218890
|
-
|
|
218891
|
-
|
|
218892
|
-
|
|
218893
|
-
|
|
218894
|
-
|
|
218895
|
-
|
|
218896
|
-
|
|
218897
|
-
|
|
218898
|
-
|
|
218899
|
-
|
|
218900
|
-
|
|
218901
|
-
|
|
218902
|
-
|
|
218903
|
-
|
|
218904
|
-
|
|
218905
|
-
|
|
218906
|
-
|
|
218907
|
-
|
|
218908
|
-
|
|
218909
|
-
|
|
218910
|
-
|
|
218911
|
-
|
|
218912
|
-
|
|
218913
|
-
|
|
218914
|
-
|
|
218915
|
-
|
|
218916
|
-
result.error = !result.axis.tryNormalizeInPlace();
|
|
218917
|
-
return result
|
|
218953
|
+
/**
|
|
218954
|
+
* Apply (in place) a jacobi update that zeros out this.at(i,j).
|
|
218955
|
+
* @param i row index of zeroed member
|
|
218956
|
+
* @param j column index of zeroed member
|
|
218957
|
+
* @param k other row/column index (different from i and j)
|
|
218958
|
+
* @param leftEigenVectors a matrix that its columns will be filled by eigenvectors of this Matrix3d
|
|
218959
|
+
* (allocated by caller, computed and filled by this function)
|
|
218960
|
+
*/
|
|
218961
|
+
applyFastSymmetricJacobiUpdate(i, j, k, leftEigenVectors) {
|
|
218962
|
+
const indexII = 4 * i;
|
|
218963
|
+
const indexJJ = 4 * j;
|
|
218964
|
+
const indexIJ = 3 * i + j;
|
|
218965
|
+
const indexIK = 3 * i + k;
|
|
218966
|
+
const indexJK = 3 * j + k;
|
|
218967
|
+
const dotUU = this.coffs[indexII];
|
|
218968
|
+
const dotVV = this.coffs[indexJJ];
|
|
218969
|
+
const dotUV = this.coffs[indexIJ];
|
|
218970
|
+
const jacobi = _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.trigValuesToHalfAngleTrigValues(dotUU - dotVV, 2.0 * dotUV);
|
|
218971
|
+
if (Math.abs(dotUV) < 1.0e-15 * (dotUU + dotVV))
|
|
218972
|
+
return 0.0;
|
|
218973
|
+
const c = jacobi.c;
|
|
218974
|
+
const s = jacobi.s;
|
|
218975
|
+
const cc = c * c;
|
|
218976
|
+
const ss = s * s;
|
|
218977
|
+
const sc2 = 2.0 * c * s;
|
|
218978
|
+
this.coffs[indexII] = cc * dotUU + sc2 * dotUV + ss * dotVV;
|
|
218979
|
+
this.coffs[indexJJ] = ss * dotUU - sc2 * dotUV + cc * dotVV;
|
|
218980
|
+
this.coffs[indexIJ] = 0.0;
|
|
218981
|
+
const a = this.coffs[indexIK];
|
|
218982
|
+
const b = this.coffs[indexJK];
|
|
218983
|
+
this.coffs[indexIK] = a * c + b * s;
|
|
218984
|
+
this.coffs[indexJK] = -s * a + c * b;
|
|
218985
|
+
this.coffs[3 * j + i] = 0.0;
|
|
218986
|
+
this.coffs[3 * k + i] = this.coffs[indexIK];
|
|
218987
|
+
this.coffs[3 * k + j] = this.coffs[indexJK];
|
|
218988
|
+
leftEigenVectors.applyGivensColumnOp(i, j, c, s);
|
|
218989
|
+
return Math.abs(dotUV);
|
|
218990
|
+
}
|
|
218991
|
+
/**
|
|
218992
|
+
* Factor this (symmetrized) as a product U * lambda * UT where U is orthogonal, lambda is diagonal.
|
|
218993
|
+
* The upper triangle is mirrored to lower triangle to enforce symmetry.
|
|
218994
|
+
* @param leftEigenvectors a matrix that its columns will be filled by eigenvectors of this Matrix3d
|
|
218995
|
+
* (allocated by caller, computed and filled by this function)
|
|
218996
|
+
* @param lambda a vector that its entries will be filled by eigenvalues of this Matrix3d
|
|
218997
|
+
* (allocated by caller, computed and filled by this function)
|
|
218998
|
+
*/
|
|
218999
|
+
fastSymmetricEigenvalues(leftEigenvectors, lambda) {
|
|
219000
|
+
const matrix = this.clone();
|
|
219001
|
+
leftEigenvectors.setIdentity();
|
|
219002
|
+
const tolerance = 1.0e-12 * this.sumSquares();
|
|
219003
|
+
for (let iteration = 0; iteration < 7; iteration++) {
|
|
219004
|
+
const sum = matrix.applyFastSymmetricJacobiUpdate(0, 1, 2, leftEigenvectors)
|
|
219005
|
+
+ matrix.applyFastSymmetricJacobiUpdate(0, 2, 1, leftEigenvectors)
|
|
219006
|
+
+ matrix.applyFastSymmetricJacobiUpdate(1, 2, 0, leftEigenvectors);
|
|
219007
|
+
// console.log("symmetric sum", sum);
|
|
219008
|
+
// console.log ("sum", sum);
|
|
219009
|
+
if (sum < tolerance) {
|
|
219010
|
+
// console.log("symmetric iterations", iteration);
|
|
219011
|
+
lambda.set(matrix.at(0, 0), matrix.at(1, 1), matrix.at(2, 2));
|
|
219012
|
+
return true;
|
|
219013
|
+
}
|
|
219014
|
+
}
|
|
219015
|
+
return false;
|
|
218918
219016
|
}
|
|
218919
|
-
*/
|
|
218920
219017
|
/**
|
|
218921
219018
|
* Compute the (unit vector) axis and angle of rotation.
|
|
219019
|
+
* * math details can be found at docs/learning/geometry/Angle.md
|
|
218922
219020
|
* @returns Returns axis and angle of rotation with result.ok === true when the conversion succeeded.
|
|
218923
219021
|
*/
|
|
218924
219022
|
getAxisAndAngleOfRotation() {
|
|
218925
219023
|
const trace = this.coffs[0] + this.coffs[4] + this.coffs[8];
|
|
218926
|
-
|
|
218927
|
-
const
|
|
218928
|
-
const
|
|
218929
|
-
|
|
218930
|
-
const c = (trace - 1.0) / 2.0;
|
|
218931
|
-
const s = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(skewXY, skewYZ, skewZX) / 2.0;
|
|
218932
|
-
const e = c * c + s * s - 1.0;
|
|
219024
|
+
const skewXY = this.coffs[3] - this.coffs[1]; // 2*z*sin
|
|
219025
|
+
const skewYZ = this.coffs[7] - this.coffs[5]; // 2*y*sin
|
|
219026
|
+
const skewZX = this.coffs[2] - this.coffs[6]; // 2*x*sin
|
|
219027
|
+
// trace = (m00^2 + m11^2 + m22^2) * (1-cos) + 3cos = (1-cos) + 3cos = 1 + 2cos ==> cos = (trace-1) / 2
|
|
219028
|
+
const c = (trace - 1.0) / 2.0; // cosine
|
|
219029
|
+
const s = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(skewXY, skewYZ, skewZX) / 2.0; // sine
|
|
219030
|
+
const e = c * c + s * s - 1.0; // s^2 + c^2 = 1
|
|
219031
|
+
// if s^2 + c^2 != 1 then we have a bad matrix so return false
|
|
218933
219032
|
if (Math.abs(e) > _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallAngleRadians) {
|
|
218934
|
-
// the sine and cosine are not a unit circle point. bad matrix . ..
|
|
218935
219033
|
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(0), ok: false };
|
|
218936
219034
|
}
|
|
219035
|
+
// sin is close to 0 then we got to special cases (angle 0 or 180) which needs to be handled differently
|
|
218937
219036
|
if (Math.abs(s) < _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallAngleRadians) {
|
|
218938
|
-
//
|
|
218939
|
-
// The matrix is symmetric
|
|
218940
|
-
// So it has simple eigenvalues -- either (1,1,1) or (1,-1,-1).
|
|
218941
|
-
if (c > 0) // no rotation
|
|
219037
|
+
if (c > 0) // sin = 0 and cos = 1 so angle = 0 (i.e., no rotation)
|
|
218942
219038
|
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(0), ok: true };
|
|
218943
|
-
|
|
218944
|
-
|
|
218945
|
-
|
|
219039
|
+
/**
|
|
219040
|
+
* If sin = 0 and cos = -1 then angle = 180 (i.e., 180 degree rotation around some axis)
|
|
219041
|
+
* then the rotation matrix becomes
|
|
219042
|
+
* 2x^2-1 2xy 2xz
|
|
219043
|
+
* 2xy 2y^2-1 2yz
|
|
219044
|
+
* 2xz 2yz 2z^2-1
|
|
219045
|
+
* Note that the matrix is symmetric.
|
|
219046
|
+
* If rotation is around one the standard basis then non-diagonal entries become 0 and we
|
|
219047
|
+
* have one 1 and two -1s on the diagonal.
|
|
219048
|
+
* If rotation is around an axis other than standard basis, then the axis is the eigenvector
|
|
219049
|
+
* of the rotation matrix with eigenvalue = 1.
|
|
219050
|
+
*/
|
|
218946
219051
|
const axx = this.coffs[0];
|
|
218947
219052
|
const ayy = this.coffs[4];
|
|
218948
219053
|
const azz = this.coffs[8];
|
|
218949
|
-
|
|
218950
|
-
// Look for principal axis flips as a special case . ..
|
|
219054
|
+
// Look for a pair of "-1" entries on the diagonal (for rotation around the basis X,Y,Z axis)
|
|
218951
219055
|
if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1.0, ayy) && _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1, azz)) {
|
|
218952
|
-
|
|
218953
|
-
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(1, 0, 0), angle: theta180, ok: true };
|
|
219056
|
+
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(1, 0, 0), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createDegrees(180), ok: true };
|
|
218954
219057
|
}
|
|
218955
219058
|
else if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1.0, axx) && _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1, azz)) {
|
|
218956
|
-
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 1, 0), angle:
|
|
219059
|
+
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 1, 0), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createDegrees(180), ok: true };
|
|
218957
219060
|
}
|
|
218958
219061
|
else if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1.0, axx) && _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(-1, ayy)) {
|
|
218959
|
-
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle:
|
|
219062
|
+
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createDegrees(180), ok: true };
|
|
218960
219063
|
}
|
|
218961
|
-
//
|
|
218962
|
-
// eigenvalues will have 1.0 once, -1.0 twice.
|
|
218963
|
-
// These cases look for each place (x,y,z) that the 1.0 might appear.
|
|
218964
|
-
// But fastSymmetricEigenvalues reliably always seems to put the 1.0 as the x eigenvalue.
|
|
218965
|
-
// so only the getColumn(0) return seems reachable in unit tests.
|
|
219064
|
+
// Look for eigenvector with eigenvalue = 1
|
|
218966
219065
|
const eigenvectors = Matrix3d.createIdentity();
|
|
218967
219066
|
const eigenvalues = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 0);
|
|
218968
219067
|
if (this.fastSymmetricEigenvalues(eigenvectors, eigenvalues)) {
|
|
218969
219068
|
for (let axisIndex = 0; axisIndex < 2; axisIndex++) {
|
|
218970
219069
|
const lambda = eigenvalues.at(axisIndex);
|
|
218971
219070
|
if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(1, lambda))
|
|
218972
|
-
return { axis: eigenvectors.getColumn(axisIndex), angle:
|
|
219071
|
+
return { axis: eigenvectors.getColumn(axisIndex), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createDegrees(180), ok: true };
|
|
218973
219072
|
}
|
|
218974
|
-
//
|
|
219073
|
+
// if no eigenvalue = 1 was found return false
|
|
218975
219074
|
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(0), ok: false };
|
|
218976
219075
|
}
|
|
219076
|
+
// if no axis was found return false
|
|
218977
219077
|
return { axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 1), angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(0), ok: false };
|
|
218978
219078
|
}
|
|
219079
|
+
// good matrix and non-zero sine
|
|
218979
219080
|
const a = 1.0 / (2.0 * s);
|
|
218980
|
-
const result = {
|
|
218981
|
-
|
|
218982
|
-
|
|
218983
|
-
|
|
218984
|
-
|
|
218985
|
-
*/
|
|
218986
|
-
static createRotationVectorToVector(vectorA, vectorB, result) {
|
|
218987
|
-
return this.createPartialRotationVectorToVector(vectorA, 1.0, vectorB, result);
|
|
218988
|
-
}
|
|
218989
|
-
/**
|
|
218990
|
-
* Return a matrix that rotates a fraction of the angular sweep from vectorA to vectorB.
|
|
218991
|
-
* @param vectorA initial vector position
|
|
218992
|
-
* @param fraction fractional rotation. 1.0 is "all the way"
|
|
218993
|
-
* @param vectorB final vector position
|
|
218994
|
-
* @param result optional result matrix.
|
|
218995
|
-
*/
|
|
218996
|
-
static createPartialRotationVectorToVector(vectorA, fraction, vectorB, result) {
|
|
218997
|
-
let upVector = vectorA.unitCrossProduct(vectorB);
|
|
218998
|
-
if (upVector) { // the usual case --
|
|
218999
|
-
return Matrix3d.createRotationAroundVector(upVector, _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(fraction * vectorA.planarAngleTo(vectorB, upVector).radians));
|
|
219000
|
-
}
|
|
219001
|
-
// fail if either vector is zero ...
|
|
219002
|
-
if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(vectorA.magnitude())
|
|
219003
|
-
|| _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(vectorB.magnitude()))
|
|
219004
|
-
return undefined;
|
|
219005
|
-
// nonzero but aligned vectors ...
|
|
219006
|
-
if (vectorA.dotProduct(vectorB) > 0.0)
|
|
219007
|
-
return Matrix3d.createIdentity(result);
|
|
219008
|
-
// nonzero opposing vectors ..
|
|
219009
|
-
upVector = Matrix3d.createPerpendicularVectorFavorPlaneContainingZ(vectorA, upVector);
|
|
219010
|
-
return Matrix3d.createRotationAroundVector(upVector, _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(fraction * Math.PI));
|
|
219011
|
-
}
|
|
219012
|
-
/** Create a 90 degree rotation around a principal axis */
|
|
219013
|
-
static create90DegreeRotationAroundAxis(axisIndex) {
|
|
219014
|
-
axisIndex = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.cyclic3dAxis(axisIndex);
|
|
219015
|
-
if (axisIndex === 0) {
|
|
219016
|
-
const retVal = Matrix3d.createRowValues(1, 0, 0, 0, 0, -1, 0, 1, 0);
|
|
219017
|
-
retVal.setupInverseTranspose();
|
|
219018
|
-
return retVal;
|
|
219019
|
-
}
|
|
219020
|
-
else if (axisIndex === 1) {
|
|
219021
|
-
const retVal = Matrix3d.createRowValues(0, 0, 1, 0, 1, 0, -1, 0, 0);
|
|
219022
|
-
retVal.setupInverseTranspose();
|
|
219023
|
-
return retVal;
|
|
219024
|
-
}
|
|
219025
|
-
else {
|
|
219026
|
-
const retVal = Matrix3d.createRowValues(0, -1, 0, 1, 0, 0, 0, 0, 1);
|
|
219027
|
-
retVal.setupInverseTranspose();
|
|
219028
|
-
return retVal;
|
|
219029
|
-
}
|
|
219030
|
-
}
|
|
219031
|
-
/** Return (a copy of) the X column */
|
|
219032
|
-
columnX(result) { return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[0], this.coffs[3], this.coffs[6], result); }
|
|
219033
|
-
/** Return (a copy of)the Y column */
|
|
219034
|
-
columnY(result) { return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[1], this.coffs[4], this.coffs[7], result); }
|
|
219035
|
-
/** Return (a copy of)the Z column */
|
|
219036
|
-
columnZ(result) { return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[2], this.coffs[5], this.coffs[8], result); }
|
|
219037
|
-
/** Return the X column magnitude squared */
|
|
219038
|
-
columnXMagnitudeSquared() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[0], this.coffs[3], this.coffs[6]); }
|
|
219039
|
-
/** Return the Y column magnitude squared */
|
|
219040
|
-
columnYMagnitudeSquared() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[1], this.coffs[4], this.coffs[7]); }
|
|
219041
|
-
/** Return the Z column magnitude squared */
|
|
219042
|
-
columnZMagnitudeSquared() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[2], this.coffs[5], this.coffs[8]); }
|
|
219043
|
-
/** Return the X column magnitude */
|
|
219044
|
-
columnXMagnitude() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[0], this.coffs[3], this.coffs[6]); }
|
|
219045
|
-
/** Return the Y column magnitude */
|
|
219046
|
-
columnYMagnitude() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[1], this.coffs[4], this.coffs[7]); }
|
|
219047
|
-
/** Return the Z column magnitude */
|
|
219048
|
-
columnZMagnitude() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[2], this.coffs[5], this.coffs[8]); }
|
|
219049
|
-
/** Return magnitude of columnX cross columnY. */
|
|
219050
|
-
columnXYCrossProductMagnitude() {
|
|
219051
|
-
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]);
|
|
219052
|
-
}
|
|
219053
|
-
/** Return the X row magnitude d */
|
|
219054
|
-
rowXMagnitude() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[0], this.coffs[1], this.coffs[2]); }
|
|
219055
|
-
/** Return the Y row magnitude */
|
|
219056
|
-
rowYMagnitude() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[3], this.coffs[4], this.coffs[5]); }
|
|
219057
|
-
/** Return the Z row magnitude */
|
|
219058
|
-
rowZMagnitude() { return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[6], this.coffs[7], this.coffs[8]); }
|
|
219059
|
-
/** Return the dot product of column X with column Y */
|
|
219060
|
-
/** Return the dot product of column X with column Y */
|
|
219061
|
-
columnXDotColumnY() {
|
|
219062
|
-
return this.coffs[0] * this.coffs[1]
|
|
219063
|
-
+ this.coffs[3] * this.coffs[4]
|
|
219064
|
-
+ this.coffs[6] * this.coffs[7];
|
|
219065
|
-
}
|
|
219066
|
-
/**
|
|
219067
|
-
* Dot product of an indexed column with a vector given as x,y,z
|
|
219068
|
-
* @param columnIndex index of column. Must be 0,1,2
|
|
219069
|
-
* @param x x component of vector
|
|
219070
|
-
* @param y y component of vector
|
|
219071
|
-
* @param z z component of vector
|
|
219072
|
-
*/
|
|
219073
|
-
columnDotXYZ(columnIndex, x, y, z) {
|
|
219074
|
-
return this.coffs[columnIndex] * x + this.coffs[columnIndex + 3] * y + this.coffs[columnIndex + 6] * z;
|
|
219075
|
-
}
|
|
219076
|
-
/** Return (a copy of) the X row */
|
|
219077
|
-
rowX(result) { return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[0], this.coffs[1], this.coffs[2], result); }
|
|
219078
|
-
/** Return (a copy of) the Y row */
|
|
219079
|
-
rowY(result) { return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[3], this.coffs[4], this.coffs[5], result); }
|
|
219080
|
-
/** Return (a copy of) the Z row */
|
|
219081
|
-
rowZ(result) { return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[6], this.coffs[7], this.coffs[8], result); }
|
|
219082
|
-
/** Return the dot product of the vector parameter with the X column. */
|
|
219083
|
-
dotColumnX(vector) { return vector.x * this.coffs[0] + vector.y * this.coffs[3] + vector.z * this.coffs[6]; }
|
|
219084
|
-
/** Return the dot product of the vector parameter with the Y column. */
|
|
219085
|
-
dotColumnY(vector) { return vector.x * this.coffs[1] + vector.y * this.coffs[4] + vector.z * this.coffs[7]; }
|
|
219086
|
-
/** Return the dot product of the vector parameter with the Z column. */
|
|
219087
|
-
dotColumnZ(vector) { return vector.x * this.coffs[2] + vector.y * this.coffs[5] + vector.z * this.coffs[8]; }
|
|
219088
|
-
/** Return the dot product of the vector parameter with the X row. */
|
|
219089
|
-
dotRowX(vector) { return vector.x * this.coffs[0] + vector.y * this.coffs[1] + vector.z * this.coffs[2]; }
|
|
219090
|
-
/** Return the dot product of the vector parameter with the Y row. */
|
|
219091
|
-
dotRowY(vector) { return vector.x * this.coffs[3] + vector.y * this.coffs[4] + vector.z * this.coffs[5]; }
|
|
219092
|
-
/** Return the dot product of the vector parameter with the Z row. */
|
|
219093
|
-
dotRowZ(vector) { return vector.x * this.coffs[6] + vector.y * this.coffs[7] + vector.z * this.coffs[8]; }
|
|
219094
|
-
// cSpell:words XXYZ YXYZ ZXYZ XYZAs Eigen
|
|
219095
|
-
/** Return the dot product of the x,y,z with the X row. */
|
|
219096
|
-
dotRowXXYZ(x, y, z) { return x * this.coffs[0] + y * this.coffs[1] + z * this.coffs[2]; }
|
|
219097
|
-
/** Return the dot product of the x,y,z with the Y row. */
|
|
219098
|
-
dotRowYXYZ(x, y, z) { return x * this.coffs[3] + y * this.coffs[4] + z * this.coffs[5]; }
|
|
219099
|
-
/** Return the dot product of the x,y,z with the Z row. */
|
|
219100
|
-
dotRowZXYZ(x, y, z) { return x * this.coffs[6] + y * this.coffs[7] + z * this.coffs[8]; }
|
|
219101
|
-
/** Return the (vector) cross product of the Z column with the vector parameter. */
|
|
219102
|
-
columnZCrossVector(vector, result) {
|
|
219103
|
-
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.crossProductXYZXYZ(this.coffs[2], this.coffs[5], this.coffs[8], vector.x, vector.y, vector.z, result);
|
|
219104
|
-
}
|
|
219105
|
-
/*
|
|
219106
|
-
* Replace current rows Ui Uj with (c*Ui - s*Uj) and (c*Uj + s*Ui).
|
|
219107
|
-
* @param i first row index. must be 0,1,2 (unchecked)
|
|
219108
|
-
* @param j second row index. must be 0,1,2 (unchecked)
|
|
219109
|
-
* @param c fist coefficient
|
|
219110
|
-
* @param s second coefficient
|
|
219111
|
-
*/
|
|
219112
|
-
applyGivensRowOp(i, j, c, s) {
|
|
219113
|
-
let ii = 3 * i;
|
|
219114
|
-
let jj = 3 * j;
|
|
219115
|
-
const limit = ii + 3;
|
|
219116
|
-
for (; ii < limit; ii++, jj++) {
|
|
219117
|
-
const a = this.coffs[ii];
|
|
219118
|
-
const b = this.coffs[jj];
|
|
219119
|
-
this.coffs[ii] = a * c + b * s;
|
|
219120
|
-
this.coffs[jj] = -a * s + b * c;
|
|
219121
|
-
}
|
|
219122
|
-
}
|
|
219123
|
-
/**
|
|
219124
|
-
* create a rigid coordinate frame column z parallel to (_x_,_y_,_z_) and column x in the xy plane.
|
|
219125
|
-
* * column z points from origin to x,y,z
|
|
219126
|
-
* * column x is perpendicular and in the xy plane
|
|
219127
|
-
* * column y is perpendicular to both. It is the "up" vector on the view plane.
|
|
219128
|
-
* * Multiplying a world vector times the transpose of this matrix transforms into the view xy
|
|
219129
|
-
* * Multiplying the matrix times the an in-view vector transforms the vector to world.
|
|
219130
|
-
* @param x eye x coordinate
|
|
219131
|
-
* @param y eye y coordinate
|
|
219132
|
-
* @param z eye z coordinate
|
|
219133
|
-
* @param result
|
|
219134
|
-
*/
|
|
219135
|
-
static createRigidViewAxesZTowardsEye(x, y, z, result) {
|
|
219136
|
-
result = Matrix3d.createIdentity(result);
|
|
219137
|
-
const rxy = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXY(x, y);
|
|
219138
|
-
if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(rxy)) {
|
|
219139
|
-
// special case for top or bottom view.
|
|
219140
|
-
if (z < 0.0)
|
|
219141
|
-
result.scaleColumnsInPlace(1.0, -1, -1.0);
|
|
219142
|
-
}
|
|
219143
|
-
else {
|
|
219144
|
-
// const d = Geometry.hypotenuseSquaredXYZ(x, y, z);
|
|
219145
|
-
const c = x / rxy;
|
|
219146
|
-
const s = y / rxy;
|
|
219147
|
-
result.setRowValues(-s, 0, c, c, 0, s, 0, 1, 0);
|
|
219148
|
-
if (z !== 0.0) {
|
|
219149
|
-
const r = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(x, y, z);
|
|
219150
|
-
const s1 = z / r;
|
|
219151
|
-
const c1 = rxy / r;
|
|
219152
|
-
result.applyGivensColumnOp(1, 2, c1, -s1);
|
|
219153
|
-
}
|
|
219154
|
-
}
|
|
219081
|
+
const result = {
|
|
219082
|
+
axis: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(skewYZ * a, skewZX * a, skewXY * a),
|
|
219083
|
+
angle: _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createAtan2(s, c),
|
|
219084
|
+
ok: true,
|
|
219085
|
+
};
|
|
219155
219086
|
return result;
|
|
219156
219087
|
}
|
|
219157
219088
|
/** Rotate so columns i and j become perpendicular */
|
|
@@ -219183,8 +219114,7 @@ class Matrix3d {
|
|
|
219183
219114
|
factorPerpendicularColumns(matrixC, matrixU) {
|
|
219184
219115
|
matrixC.setFrom(this);
|
|
219185
219116
|
matrixU.setIdentity();
|
|
219186
|
-
const
|
|
219187
|
-
const tolerance = 1.0e-12 * ss;
|
|
219117
|
+
const tolerance = 1.0e-12 * this.sumSquares();
|
|
219188
219118
|
for (let iteration = 0; iteration < 7; iteration++) {
|
|
219189
219119
|
const sum = matrixC.applyJacobiColumnRotation(0, 1, matrixU)
|
|
219190
219120
|
+ matrixC.applyJacobiColumnRotation(0, 2, matrixU)
|
|
@@ -219275,8 +219205,7 @@ class Matrix3d {
|
|
|
219275
219205
|
matrix.coffs[3] = matrix.coffs[1];
|
|
219276
219206
|
matrix.coffs[6] = matrix.coffs[2];
|
|
219277
219207
|
matrix.coffs[7] = matrix.coffs[5];
|
|
219278
|
-
const
|
|
219279
|
-
const tolerance = 1.0e-12 * ss;
|
|
219208
|
+
const tolerance = 1.0e-12 * this.sumSquares();
|
|
219280
219209
|
for (let iteration = 0; iteration < 7; iteration++) {
|
|
219281
219210
|
const sum = leftEigenvectors.applySymmetricJacobi(0, 1, matrix)
|
|
219282
219211
|
+ leftEigenvectors.applySymmetricJacobi(0, 2, matrix)
|
|
@@ -219291,68 +219220,174 @@ class Matrix3d {
|
|
|
219291
219220
|
}
|
|
219292
219221
|
return false;
|
|
219293
219222
|
}
|
|
219294
|
-
/**
|
|
219295
|
-
*
|
|
219223
|
+
/**
|
|
219224
|
+
* Return a matrix that rotates a fraction of the angular sweep from vectorA to vectorB.
|
|
219225
|
+
* @param vectorA initial vector position
|
|
219226
|
+
* @param fraction fractional rotation (1 means rotate all the way)
|
|
219227
|
+
* @param vectorB final vector position
|
|
219228
|
+
* @param result optional result matrix.
|
|
219296
219229
|
*/
|
|
219297
|
-
|
|
219298
|
-
|
|
219299
|
-
|
|
219300
|
-
|
|
219301
|
-
|
|
219302
|
-
|
|
219303
|
-
|
|
219304
|
-
|
|
219305
|
-
|
|
219306
|
-
|
|
219307
|
-
|
|
219308
|
-
|
|
219309
|
-
|
|
219310
|
-
|
|
219311
|
-
|
|
219312
|
-
|
|
219313
|
-
|
|
219314
|
-
|
|
219315
|
-
|
|
219316
|
-
|
|
219317
|
-
|
|
219318
|
-
|
|
219319
|
-
|
|
219320
|
-
|
|
219321
|
-
|
|
219322
|
-
|
|
219323
|
-
|
|
219324
|
-
|
|
219325
|
-
|
|
219326
|
-
|
|
219327
|
-
|
|
219328
|
-
|
|
219230
|
+
static createPartialRotationVectorToVector(vectorA, fraction, vectorB, result) {
|
|
219231
|
+
let upVector = vectorA.unitCrossProduct(vectorB);
|
|
219232
|
+
// the usual case (both vectors and also their cross product is non-zero)
|
|
219233
|
+
if (upVector) {
|
|
219234
|
+
return Matrix3d.createRotationAroundVector(upVector, _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(fraction * vectorA.planarAngleTo(vectorB, upVector).radians));
|
|
219235
|
+
}
|
|
219236
|
+
// if either vector is zero
|
|
219237
|
+
if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(vectorA.magnitude())
|
|
219238
|
+
|| _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(vectorB.magnitude()))
|
|
219239
|
+
return undefined;
|
|
219240
|
+
// aligned vectors (cross product = 0, dot product > 0)
|
|
219241
|
+
if (vectorA.dotProduct(vectorB) > 0.0)
|
|
219242
|
+
return Matrix3d.createIdentity(result);
|
|
219243
|
+
// opposing vectors (cross product = 0, dot product < 0)
|
|
219244
|
+
upVector = Matrix3d.createPerpendicularVectorFavorPlaneContainingZ(vectorA, upVector);
|
|
219245
|
+
return Matrix3d.createRotationAroundVector(upVector, _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.createRadians(fraction * Math.PI));
|
|
219246
|
+
}
|
|
219247
|
+
/** Returns a matrix that rotates from vectorA to vectorB. */
|
|
219248
|
+
static createRotationVectorToVector(vectorA, vectorB, result) {
|
|
219249
|
+
return this.createPartialRotationVectorToVector(vectorA, 1.0, vectorB, result);
|
|
219250
|
+
}
|
|
219251
|
+
/** Create a 90 degree rotation around a principal axis */
|
|
219252
|
+
static create90DegreeRotationAroundAxis(axisIndex) {
|
|
219253
|
+
axisIndex = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.cyclic3dAxis(axisIndex);
|
|
219254
|
+
if (axisIndex === 0) {
|
|
219255
|
+
const retVal = Matrix3d.createRowValues(1, 0, 0, 0, 0, -1, 0, 1, 0);
|
|
219256
|
+
retVal.setupInverseTranspose();
|
|
219257
|
+
return retVal;
|
|
219258
|
+
}
|
|
219259
|
+
else if (axisIndex === 1) {
|
|
219260
|
+
const retVal = Matrix3d.createRowValues(0, 0, 1, 0, 1, 0, -1, 0, 0);
|
|
219261
|
+
retVal.setupInverseTranspose();
|
|
219262
|
+
return retVal;
|
|
219263
|
+
}
|
|
219264
|
+
else {
|
|
219265
|
+
const retVal = Matrix3d.createRowValues(0, -1, 0, 1, 0, 0, 0, 0, 1);
|
|
219266
|
+
retVal.setupInverseTranspose();
|
|
219267
|
+
return retVal;
|
|
219268
|
+
}
|
|
219269
|
+
}
|
|
219270
|
+
/** Return (a copy of) the X column */
|
|
219271
|
+
columnX(result) {
|
|
219272
|
+
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[0], this.coffs[3], this.coffs[6], result);
|
|
219273
|
+
}
|
|
219274
|
+
/** Return (a copy of) the Y column */
|
|
219275
|
+
columnY(result) {
|
|
219276
|
+
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[1], this.coffs[4], this.coffs[7], result);
|
|
219277
|
+
}
|
|
219278
|
+
/** Return (a copy of) the Z column */
|
|
219279
|
+
columnZ(result) {
|
|
219280
|
+
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[2], this.coffs[5], this.coffs[8], result);
|
|
219281
|
+
}
|
|
219282
|
+
/** Return the X column magnitude squared */
|
|
219283
|
+
columnXMagnitudeSquared() {
|
|
219284
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[0], this.coffs[3], this.coffs[6]);
|
|
219285
|
+
}
|
|
219286
|
+
/** Return the Y column magnitude squared */
|
|
219287
|
+
columnYMagnitudeSquared() {
|
|
219288
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[1], this.coffs[4], this.coffs[7]);
|
|
219289
|
+
}
|
|
219290
|
+
/** Return the Z column magnitude squared */
|
|
219291
|
+
columnZMagnitudeSquared() {
|
|
219292
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[2], this.coffs[5], this.coffs[8]);
|
|
219293
|
+
}
|
|
219294
|
+
/** Return the X column magnitude */
|
|
219295
|
+
columnXMagnitude() {
|
|
219296
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[0], this.coffs[3], this.coffs[6]);
|
|
219297
|
+
}
|
|
219298
|
+
/** Return the Y column magnitude */
|
|
219299
|
+
columnYMagnitude() {
|
|
219300
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[1], this.coffs[4], this.coffs[7]);
|
|
219301
|
+
}
|
|
219302
|
+
/** Return the Z column magnitude */
|
|
219303
|
+
columnZMagnitude() {
|
|
219304
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[2], this.coffs[5], this.coffs[8]);
|
|
219305
|
+
}
|
|
219306
|
+
/** Return magnitude of columnX cross columnY. */
|
|
219307
|
+
columnXYCrossProductMagnitude() {
|
|
219308
|
+
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]);
|
|
219309
|
+
}
|
|
219310
|
+
/** Return the X row magnitude */
|
|
219311
|
+
rowXMagnitude() {
|
|
219312
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[0], this.coffs[1], this.coffs[2]);
|
|
219313
|
+
}
|
|
219314
|
+
/** Return the Y row magnitude */
|
|
219315
|
+
rowYMagnitude() {
|
|
219316
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[3], this.coffs[4], this.coffs[5]);
|
|
219317
|
+
}
|
|
219318
|
+
/** Return the Z row magnitude */
|
|
219319
|
+
rowZMagnitude() {
|
|
219320
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(this.coffs[6], this.coffs[7], this.coffs[8]);
|
|
219321
|
+
}
|
|
219322
|
+
/** Return the dot product of column X with column Y */
|
|
219323
|
+
columnXDotColumnY() {
|
|
219324
|
+
return this.coffs[0] * this.coffs[1]
|
|
219325
|
+
+ this.coffs[3] * this.coffs[4]
|
|
219326
|
+
+ this.coffs[6] * this.coffs[7];
|
|
219329
219327
|
}
|
|
219330
219328
|
/**
|
|
219331
|
-
*
|
|
219332
|
-
*
|
|
219333
|
-
* @param
|
|
219334
|
-
* @param
|
|
219329
|
+
* Dot product of an indexed column with a vector given as x,y,z
|
|
219330
|
+
* @param columnIndex index of column. Must be 0,1,2.
|
|
219331
|
+
* @param x x component of vector
|
|
219332
|
+
* @param y y component of vector
|
|
219333
|
+
* @param z z component of vector
|
|
219335
219334
|
*/
|
|
219336
|
-
|
|
219337
|
-
|
|
219338
|
-
|
|
219339
|
-
|
|
219340
|
-
|
|
219341
|
-
|
|
219342
|
-
|
|
219343
|
-
|
|
219344
|
-
|
|
219345
|
-
|
|
219346
|
-
|
|
219347
|
-
|
|
219348
|
-
|
|
219349
|
-
|
|
219350
|
-
return true;
|
|
219351
|
-
}
|
|
219352
|
-
}
|
|
219353
|
-
return false;
|
|
219335
|
+
columnDotXYZ(columnIndex, x, y, z) {
|
|
219336
|
+
return this.coffs[columnIndex] * x + this.coffs[columnIndex + 3] * y + this.coffs[columnIndex + 6] * z;
|
|
219337
|
+
}
|
|
219338
|
+
/** Return (a copy of) the X row */
|
|
219339
|
+
rowX(result) {
|
|
219340
|
+
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[0], this.coffs[1], this.coffs[2], result);
|
|
219341
|
+
}
|
|
219342
|
+
/** Return (a copy of) the Y row */
|
|
219343
|
+
rowY(result) {
|
|
219344
|
+
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[3], this.coffs[4], this.coffs[5], result);
|
|
219345
|
+
}
|
|
219346
|
+
/** Return (a copy of) the Z row */
|
|
219347
|
+
rowZ(result) {
|
|
219348
|
+
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[6], this.coffs[7], this.coffs[8], result);
|
|
219354
219349
|
}
|
|
219355
|
-
/**
|
|
219350
|
+
/** Return the dot product of the vector parameter with the X column. */
|
|
219351
|
+
dotColumnX(vector) {
|
|
219352
|
+
return vector.x * this.coffs[0] + vector.y * this.coffs[3] + vector.z * this.coffs[6];
|
|
219353
|
+
}
|
|
219354
|
+
/** Return the dot product of the vector parameter with the Y column. */
|
|
219355
|
+
dotColumnY(vector) {
|
|
219356
|
+
return vector.x * this.coffs[1] + vector.y * this.coffs[4] + vector.z * this.coffs[7];
|
|
219357
|
+
}
|
|
219358
|
+
/** Return the dot product of the vector parameter with the Z column. */
|
|
219359
|
+
dotColumnZ(vector) {
|
|
219360
|
+
return vector.x * this.coffs[2] + vector.y * this.coffs[5] + vector.z * this.coffs[8];
|
|
219361
|
+
}
|
|
219362
|
+
/** Return the dot product of the vector parameter with the X row. */
|
|
219363
|
+
dotRowX(vector) {
|
|
219364
|
+
return vector.x * this.coffs[0] + vector.y * this.coffs[1] + vector.z * this.coffs[2];
|
|
219365
|
+
}
|
|
219366
|
+
/** Return the dot product of the vector parameter with the Y row. */
|
|
219367
|
+
dotRowY(vector) {
|
|
219368
|
+
return vector.x * this.coffs[3] + vector.y * this.coffs[4] + vector.z * this.coffs[5];
|
|
219369
|
+
}
|
|
219370
|
+
/** Return the dot product of the vector parameter with the Z row. */
|
|
219371
|
+
dotRowZ(vector) {
|
|
219372
|
+
return vector.x * this.coffs[6] + vector.y * this.coffs[7] + vector.z * this.coffs[8];
|
|
219373
|
+
}
|
|
219374
|
+
/** Return the dot product of the x,y,z with the X row. */
|
|
219375
|
+
dotRowXXYZ(x, y, z) {
|
|
219376
|
+
return x * this.coffs[0] + y * this.coffs[1] + z * this.coffs[2];
|
|
219377
|
+
}
|
|
219378
|
+
/** Return the dot product of the x,y,z with the Y row. */
|
|
219379
|
+
dotRowYXYZ(x, y, z) {
|
|
219380
|
+
return x * this.coffs[3] + y * this.coffs[4] + z * this.coffs[5];
|
|
219381
|
+
}
|
|
219382
|
+
/** Return the dot product of the x,y,z with the Z row. */
|
|
219383
|
+
dotRowZXYZ(x, y, z) {
|
|
219384
|
+
return x * this.coffs[6] + y * this.coffs[7] + z * this.coffs[8];
|
|
219385
|
+
}
|
|
219386
|
+
/** Return the cross product of the Z column with the vector parameter. */
|
|
219387
|
+
columnZCrossVector(vector, result) {
|
|
219388
|
+
return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.crossProductXYZXYZ(this.coffs[2], this.coffs[5], this.coffs[8], vector.x, vector.y, vector.z, result);
|
|
219389
|
+
}
|
|
219390
|
+
/** Set data from xyz parts of Point4d (w part of Point4d ignored) */
|
|
219356
219391
|
setColumnsPoint4dXYZ(vectorU, vectorV, vectorW) {
|
|
219357
219392
|
this.inverseState = InverseMatrixState.unknown;
|
|
219358
219393
|
this.setRowValues(vectorU.x, vectorV.x, vectorW.x, vectorU.y, vectorV.y, vectorW.y, vectorU.z, vectorV.z, vectorW.z);
|
|
@@ -219376,16 +219411,22 @@ class Matrix3d {
|
|
|
219376
219411
|
this.coffs[index + 6] = 0.0;
|
|
219377
219412
|
}
|
|
219378
219413
|
}
|
|
219379
|
-
/**
|
|
219414
|
+
/**
|
|
219415
|
+
* Set all columns of the matrix. Any undefined vector is zeros.
|
|
219416
|
+
* @param vectorX values for column 0
|
|
219417
|
+
* @param vectorY values for column 1
|
|
219418
|
+
* @param vectorZ optional values for column 2 (it's optional in case column 2 is 000, which is a
|
|
219419
|
+
* projection onto the xy-plane)
|
|
219420
|
+
*/
|
|
219380
219421
|
setColumns(vectorX, vectorY, vectorZ) {
|
|
219381
219422
|
this.setColumn(0, vectorX);
|
|
219382
219423
|
this.setColumn(1, vectorY);
|
|
219383
219424
|
this.setColumn(2, vectorZ);
|
|
219384
219425
|
}
|
|
219385
219426
|
/**
|
|
219386
|
-
*
|
|
219387
|
-
* @param rowIndex row index.
|
|
219388
|
-
* @param value x,
|
|
219427
|
+
* Set entries in one row of the matrix.
|
|
219428
|
+
* @param rowIndex row index. This is interpreted cyclically (using Geometry.cyclic3dAxis).
|
|
219429
|
+
* @param value x,y,z values for row.
|
|
219389
219430
|
*/
|
|
219390
219431
|
setRow(rowIndex, value) {
|
|
219391
219432
|
const index = 3 * _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.cyclic3dAxis(rowIndex);
|
|
@@ -219394,21 +219435,26 @@ class Matrix3d {
|
|
|
219394
219435
|
this.coffs[index + 2] = value.z;
|
|
219395
219436
|
this.inverseState = InverseMatrixState.unknown;
|
|
219396
219437
|
}
|
|
219397
|
-
/**
|
|
219398
|
-
*
|
|
219438
|
+
/**
|
|
219439
|
+
* Return (a copy of) a column of the matrix.
|
|
219440
|
+
* @param i column index. This is interpreted cyclically (using Geometry.cyclic3dAxis).
|
|
219441
|
+
* @param result optional preallocated result.
|
|
219399
219442
|
*/
|
|
219400
219443
|
getColumn(columnIndex, result) {
|
|
219401
219444
|
const index = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.cyclic3dAxis(columnIndex);
|
|
219402
219445
|
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[index], this.coffs[index + 3], this.coffs[index + 6], result);
|
|
219403
219446
|
}
|
|
219404
|
-
/**
|
|
219405
|
-
*
|
|
219447
|
+
/**
|
|
219448
|
+
* Return a (copy of) a row of the matrix.
|
|
219449
|
+
* @param i row index. This is interpreted cyclically (using Geometry.cyclic3dAxis).
|
|
219450
|
+
* @param result optional preallocated result.
|
|
219406
219451
|
*/
|
|
219407
219452
|
getRow(columnIndex, result) {
|
|
219408
219453
|
const index = 3 * _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.cyclic3dAxis(columnIndex);
|
|
219409
219454
|
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(this.coffs[index], this.coffs[index + 1], this.coffs[index + 2], result);
|
|
219410
219455
|
}
|
|
219411
|
-
/**
|
|
219456
|
+
/**
|
|
219457
|
+
* Create a matrix from row vectors.
|
|
219412
219458
|
* ```
|
|
219413
219459
|
* equation
|
|
219414
219460
|
* \begin{bmatrix}U_x & U_y & U_z \\ V_x & V_y & V_z \\ W_x & W_y & W_z \end{bmatrix}
|
|
@@ -219417,13 +219463,18 @@ class Matrix3d {
|
|
|
219417
219463
|
static createRows(vectorU, vectorV, vectorW, result) {
|
|
219418
219464
|
return Matrix3d.createRowValues(vectorU.x, vectorU.y, vectorU.z, vectorV.x, vectorV.y, vectorV.z, vectorW.x, vectorW.y, vectorW.z, result);
|
|
219419
219465
|
}
|
|
219420
|
-
/**
|
|
219421
|
-
*
|
|
219422
|
-
*
|
|
219466
|
+
/**
|
|
219467
|
+
* Create a matrix that scales along a specified `direction`. This means if you multiply the returned matrix
|
|
219468
|
+
* by a `vector`, you get `directional scale` of that `vector`. Suppose `plane` is the plane perpendicular
|
|
219469
|
+
* to the `direction`. When scale = 0, `directional scale` is projection of the `vector` to the `plane`.
|
|
219470
|
+
* When scale = 1, `directional scale` is the `vector` itself. When scale = -1, `directional scale` is
|
|
219471
|
+
* mirror of the `vector` across the `plane`. In general, When scale != 0, the result is computed by first
|
|
219472
|
+
* projecting the `vector` to the `plane`, then translating that projection along the `direction` (if scale > 0)
|
|
219473
|
+
* or in opposite direction (if scale < 0).
|
|
219423
219474
|
* ```
|
|
219424
219475
|
* equation
|
|
219425
|
-
* \text{The matrix is } I
|
|
219426
|
-
* \\ \text{with }
|
|
219476
|
+
* \text{The matrix is } I + (s-1) D D^T
|
|
219477
|
+
* \\ \text{with }D\text{ being the normalized direction vector and }s\text{ being the scale.}
|
|
219427
219478
|
* ```
|
|
219428
219479
|
*/
|
|
219429
219480
|
static createDirectionalScale(direction, scale, result) {
|
|
@@ -219432,19 +219483,13 @@ class Matrix3d {
|
|
|
219432
219483
|
const x = unit.x;
|
|
219433
219484
|
const y = unit.y;
|
|
219434
219485
|
const z = unit.z;
|
|
219435
|
-
const a =
|
|
219486
|
+
const a = scale - 1;
|
|
219436
219487
|
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);
|
|
219437
219488
|
}
|
|
219438
219489
|
return Matrix3d.createUniformScale(scale);
|
|
219439
219490
|
}
|
|
219440
|
-
|
|
219441
|
-
* *
|
|
219442
|
-
* * 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)
|
|
219443
|
-
* * If the direction vector is close to Z, the "next" column ((axisIndex + 1) mode 3) will be in the direction of (direction cross Y)
|
|
219444
|
-
*/
|
|
219445
|
-
// static create1Vector(direction: Vector3d, axisIndex: number): Matrix3d;
|
|
219446
|
-
// static createFromXYVectors(vectorX: Vector3d, vectorY: Vector3d, axisIndex: number): Matrix3d;
|
|
219447
|
-
/** Multiply the matrix * vector, treating the vector is a column vector on the right.
|
|
219491
|
+
/**
|
|
219492
|
+
* Multiply `matrix * vector`, treating the vector is a column vector on the right.
|
|
219448
219493
|
* ```
|
|
219449
219494
|
* equation
|
|
219450
219495
|
* \matrixXY{A}\columnSubXYZ{U}
|
|
@@ -219455,36 +219500,38 @@ class Matrix3d {
|
|
|
219455
219500
|
const x = vectorU.x;
|
|
219456
219501
|
const y = vectorU.y;
|
|
219457
219502
|
const z = vectorU.z;
|
|
219458
|
-
return _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(
|
|
219503
|
+
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);
|
|
219459
219504
|
}
|
|
219460
|
-
/**
|
|
219461
|
-
*
|
|
219505
|
+
/**
|
|
219506
|
+
* Multiply `matrix * vector` in place for vector in the array, i.e. treating the vector is a column
|
|
219507
|
+
* vector on the right.
|
|
219508
|
+
* * Each `vector` is updated to be `matrix * vector`
|
|
219462
219509
|
*/
|
|
219463
219510
|
multiplyVectorArrayInPlace(data) {
|
|
219464
219511
|
for (const v of data)
|
|
219465
|
-
v.set(
|
|
219512
|
+
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);
|
|
219466
219513
|
}
|
|
219467
|
-
/**
|
|
219514
|
+
/** Compute `origin - matrix * vector` */
|
|
219468
219515
|
static xyzMinusMatrixTimesXYZ(origin, matrix, vector, result) {
|
|
219469
219516
|
const x = vector.x;
|
|
219470
219517
|
const y = vector.y;
|
|
219471
219518
|
const z = vector.z;
|
|
219472
219519
|
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);
|
|
219473
219520
|
}
|
|
219474
|
-
/**
|
|
219521
|
+
/** Compute `origin + matrix * vector` using only the xy parts of the inputs. */
|
|
219475
219522
|
static xyPlusMatrixTimesXY(origin, matrix, vector, result) {
|
|
219476
219523
|
const x = vector.x;
|
|
219477
219524
|
const y = vector.y;
|
|
219478
219525
|
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);
|
|
219479
219526
|
}
|
|
219480
|
-
/**
|
|
219527
|
+
/** Compute `origin + matrix * vector` using all xyz parts of the inputs. */
|
|
219481
219528
|
static xyzPlusMatrixTimesXYZ(origin, matrix, vector, result) {
|
|
219482
219529
|
const x = vector.x;
|
|
219483
219530
|
const y = vector.y;
|
|
219484
219531
|
const z = vector.z;
|
|
219485
219532
|
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);
|
|
219486
219533
|
}
|
|
219487
|
-
/**
|
|
219534
|
+
/** Updates vector to be `origin + matrix * vector` using all xyz parts of the inputs. */
|
|
219488
219535
|
static xyzPlusMatrixTimesXYZInPlace(origin, matrix, vector) {
|
|
219489
219536
|
const x = vector.x;
|
|
219490
219537
|
const y = vector.y;
|
|
@@ -219493,61 +219540,72 @@ class Matrix3d {
|
|
|
219493
219540
|
vector.y = origin.y + matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z;
|
|
219494
219541
|
vector.z = origin.z + matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z;
|
|
219495
219542
|
}
|
|
219496
|
-
/**
|
|
219543
|
+
/** Compute `origin + matrix * vector` where the final vector is given as direct x,y,z coordinates */
|
|
219497
219544
|
static xyzPlusMatrixTimesCoordinates(origin, matrix, x, y, z, result) {
|
|
219498
219545
|
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);
|
|
219499
219546
|
}
|
|
219500
219547
|
/**
|
|
219501
219548
|
* Treat the 3x3 matrix and origin as upper 3x4 part of a 4x4 matrix, with 0001 as the final row.
|
|
219502
|
-
* Multiply
|
|
219549
|
+
* Multiply the 4x4 matrix by `[x,y,z,w]`
|
|
219550
|
+
* ```
|
|
219551
|
+
* equation
|
|
219552
|
+
* \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}
|
|
219553
|
+
* ```
|
|
219503
219554
|
* @param origin translation part (xyz in column 3)
|
|
219504
219555
|
* @param matrix matrix part (leading 3x3)
|
|
219505
219556
|
* @param x x part of multiplied point
|
|
219506
219557
|
* @param y y part of multiplied point
|
|
219507
219558
|
* @param z z part of multiplied point
|
|
219508
219559
|
* @param w w part of multiplied point
|
|
219509
|
-
* @param result optional result.
|
|
219560
|
+
* @param result optional preallocated result.
|
|
219510
219561
|
*/
|
|
219511
219562
|
static xyzPlusMatrixTimesWeightedCoordinates(origin, matrix, x, y, z, w, result) {
|
|
219512
|
-
return _geometry4d_Point4d__WEBPACK_IMPORTED_MODULE_4__.Point4d.create(
|
|
219563
|
+
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);
|
|
219513
219564
|
}
|
|
219514
219565
|
/**
|
|
219515
219566
|
* Treat the 3x3 matrix and origin as upper 3x4 part of a 4x4 matrix, with 0001 as the final row.
|
|
219516
|
-
* Multiply
|
|
219567
|
+
* Multiply the 4x4 matrix by `[x,y,z,w]`
|
|
219568
|
+
* ```
|
|
219569
|
+
* equation
|
|
219570
|
+
* \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}
|
|
219571
|
+
* ```
|
|
219517
219572
|
* @param origin translation part (xyz in column 3)
|
|
219518
219573
|
* @param matrix matrix part (leading 3x3)
|
|
219519
219574
|
* @param x x part of multiplied point
|
|
219520
219575
|
* @param y y part of multiplied point
|
|
219521
219576
|
* @param z z part of multiplied point
|
|
219522
219577
|
* @param w w part of multiplied point
|
|
219523
|
-
* @param result optional result.
|
|
219578
|
+
* @param result optional preallocated result.
|
|
219524
219579
|
*/
|
|
219525
219580
|
static xyzPlusMatrixTimesWeightedCoordinatesToFloat64Array(origin, matrix, x, y, z, w, result) {
|
|
219526
219581
|
if (!result)
|
|
219527
219582
|
result = new Float64Array(4);
|
|
219528
|
-
result[0] =
|
|
219529
|
-
result[1] =
|
|
219530
|
-
result[2] =
|
|
219583
|
+
result[0] = matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z + origin.x * w;
|
|
219584
|
+
result[1] = matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z + origin.y * w;
|
|
219585
|
+
result[2] = matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z + origin.z * w;
|
|
219531
219586
|
result[3] = w;
|
|
219532
219587
|
return result;
|
|
219533
219588
|
}
|
|
219534
219589
|
/**
|
|
219535
|
-
* Treat the 3x3 matrix and origin as
|
|
219536
|
-
* Multiply
|
|
219590
|
+
* Treat the 3x3 matrix and origin as a 3x4 matrix.
|
|
219591
|
+
* * Multiply the 3x4 matrix by `[x,y,z,1]`
|
|
219592
|
+
* ```
|
|
219593
|
+
* equation
|
|
219594
|
+
* \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}
|
|
219595
|
+
* ```
|
|
219537
219596
|
* @param origin translation part (xyz in column 3)
|
|
219538
219597
|
* @param matrix matrix part (leading 3x3)
|
|
219539
219598
|
* @param x x part of multiplied point
|
|
219540
219599
|
* @param y y part of multiplied point
|
|
219541
219600
|
* @param z z part of multiplied point
|
|
219542
|
-
* @param
|
|
219543
|
-
* @param result optional result.
|
|
219601
|
+
* @param result optional preallocated result.
|
|
219544
219602
|
*/
|
|
219545
219603
|
static xyzPlusMatrixTimesCoordinatesToFloat64Array(origin, matrix, x, y, z, result) {
|
|
219546
219604
|
if (!result)
|
|
219547
219605
|
result = new Float64Array(3);
|
|
219548
|
-
result[0] =
|
|
219549
|
-
result[1] =
|
|
219550
|
-
result[2] =
|
|
219606
|
+
result[0] = matrix.coffs[0] * x + matrix.coffs[1] * y + matrix.coffs[2] * z + origin.x;
|
|
219607
|
+
result[1] = matrix.coffs[3] * x + matrix.coffs[4] * y + matrix.coffs[5] * z + origin.y;
|
|
219608
|
+
result[2] = matrix.coffs[6] * x + matrix.coffs[7] * y + matrix.coffs[8] * z + origin.z;
|
|
219551
219609
|
return result;
|
|
219552
219610
|
}
|
|
219553
219611
|
/**
|
|
@@ -219567,9 +219625,9 @@ class Matrix3d {
|
|
|
219567
219625
|
const x = vector.x;
|
|
219568
219626
|
const y = vector.y;
|
|
219569
219627
|
const z = vector.z;
|
|
219570
|
-
result.x =
|
|
219571
|
-
result.y =
|
|
219572
|
-
result.z =
|
|
219628
|
+
result.x = this.coffs[0] * x + this.coffs[3] * y + this.coffs[6] * z;
|
|
219629
|
+
result.y = this.coffs[1] * x + this.coffs[4] * y + this.coffs[7] * z;
|
|
219630
|
+
result.z = this.coffs[2] * x + this.coffs[5] * y + this.coffs[8] * z;
|
|
219573
219631
|
return result;
|
|
219574
219632
|
}
|
|
219575
219633
|
/** Multiply the matrix * (x,y,z), i.e. the vector (x,y,z) is a column vector on the right.
|
|
@@ -220097,7 +220155,7 @@ class Matrix3d {
|
|
|
220097
220155
|
* @param scaleX scale factor for column x
|
|
220098
220156
|
* @param scaleY scale factor for column y
|
|
220099
220157
|
* @param scaleZ scale factor for column z
|
|
220100
|
-
* @param result optional result.
|
|
220158
|
+
* @param result optional preallocated result.
|
|
220101
220159
|
*/
|
|
220102
220160
|
scaleColumns(scaleX, scaleY, scaleZ, result) {
|
|
220103
220161
|
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);
|
|
@@ -220118,7 +220176,7 @@ class Matrix3d {
|
|
|
220118
220176
|
this.coffs[7] *= scaleY;
|
|
220119
220177
|
this.coffs[8] *= scaleZ;
|
|
220120
220178
|
if (this.inverseState === InverseMatrixState.inverseStored && this.inverseCoffs !== undefined) {
|
|
220121
|
-
// apply
|
|
220179
|
+
// apply reverse scales to the ROWS of the inverse
|
|
220122
220180
|
const divX = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.conditionalDivideFraction(1.0, scaleX);
|
|
220123
220181
|
const divY = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.conditionalDivideFraction(1.0, scaleY);
|
|
220124
220182
|
const divZ = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.conditionalDivideFraction(1.0, scaleZ);
|
|
@@ -220141,7 +220199,7 @@ class Matrix3d {
|
|
|
220141
220199
|
* @param scaleX scale factor for row x
|
|
220142
220200
|
* @param scaleY scale factor for row y
|
|
220143
220201
|
* @param scaleZ scale factor for row z
|
|
220144
|
-
* @param result optional result.
|
|
220202
|
+
* @param result optional preallocated result.
|
|
220145
220203
|
*/
|
|
220146
220204
|
scaleRows(scaleX, scaleY, scaleZ, result) {
|
|
220147
220205
|
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);
|
|
@@ -220185,12 +220243,49 @@ class Matrix3d {
|
|
|
220185
220243
|
}
|
|
220186
220244
|
/** create a Matrix3d whose values are uniformly scaled from this.
|
|
220187
220245
|
* @param scale scale factor to apply.
|
|
220188
|
-
* @param result optional result.
|
|
220246
|
+
* @param result optional preallocated result.
|
|
220189
220247
|
* @returns Return the new or repopulated matrix
|
|
220190
220248
|
*/
|
|
220191
220249
|
scale(scale, result) {
|
|
220192
220250
|
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);
|
|
220193
220251
|
}
|
|
220252
|
+
/**
|
|
220253
|
+
* Create a rigid matrix (columns and rows are unit length and pairwise perpendicular) for
|
|
220254
|
+
* the given eye coordinate.
|
|
220255
|
+
* * column z is parallel to x,y,z
|
|
220256
|
+
* * column x is perpendicular to column z and is in the xy plane
|
|
220257
|
+
* * column y is perpendicular to both. It is the "up" vector on the view plane.
|
|
220258
|
+
* * Multiplying the returned matrix times a local (view) vector gives the world vector.
|
|
220259
|
+
* * Multiplying transpose of the returned matrix times a world vector gives the local
|
|
220260
|
+
* (view) vector.
|
|
220261
|
+
* @param x eye x coordinate
|
|
220262
|
+
* @param y eye y coordinate
|
|
220263
|
+
* @param z eye z coordinate
|
|
220264
|
+
* @param result optional preallocated result
|
|
220265
|
+
*/
|
|
220266
|
+
static createRigidViewAxesZTowardsEye(x, y, z, result) {
|
|
220267
|
+
result = Matrix3d.createIdentity(result);
|
|
220268
|
+
const rxy = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXY(x, y);
|
|
220269
|
+
// if coordinate is (0,0,z), i.e., Top or Bottom view
|
|
220270
|
+
if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isSmallMetricDistance(rxy)) {
|
|
220271
|
+
if (z < 0.0)
|
|
220272
|
+
result.scaleColumnsInPlace(1.0, -1.0, -1.0);
|
|
220273
|
+
}
|
|
220274
|
+
else {
|
|
220275
|
+
const c = x / rxy;
|
|
220276
|
+
const s = y / rxy;
|
|
220277
|
+
// if coordinate is (x,y,0), i.e., Front or Back or Left or Right view
|
|
220278
|
+
result.setRowValues(-s, 0, c, c, 0, s, 0, 1, 0);
|
|
220279
|
+
// if coordinate is (x,y,z), i.e., other views such as Iso or RightIso
|
|
220280
|
+
if (z !== 0.0) {
|
|
220281
|
+
const r = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseXYZ(x, y, z);
|
|
220282
|
+
const s1 = z / r;
|
|
220283
|
+
const c1 = rxy / r;
|
|
220284
|
+
result.applyGivensColumnOp(1, 2, c1, -s1);
|
|
220285
|
+
}
|
|
220286
|
+
}
|
|
220287
|
+
return result;
|
|
220288
|
+
}
|
|
220194
220289
|
/** Return the determinant of this matrix. */
|
|
220195
220290
|
determinant() {
|
|
220196
220291
|
return this.coffs[0] * this.coffs[4] * this.coffs[8]
|
|
@@ -222356,9 +222451,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
222356
222451
|
* @module CartesianGeometry
|
|
222357
222452
|
*/
|
|
222358
222453
|
// cspell:word CWXY
|
|
222454
|
+
// cspell:word arctan
|
|
222455
|
+
// cspell:word Rodrigues
|
|
222359
222456
|
|
|
222360
222457
|
|
|
222361
222458
|
|
|
222459
|
+
// cspell:word CCWXY
|
|
222362
222460
|
/**
|
|
222363
222461
|
* * `XYZ` is a minimal object containing x,y,z and operations that are meaningful without change in both point and vector.
|
|
222364
222462
|
* * `XYZ` is not instantiable.
|
|
@@ -223195,7 +223293,7 @@ class Vector3d extends XYZ {
|
|
|
223195
223293
|
return { v: this.safeDivideOrNull(magnitude, result), mag: magnitude };
|
|
223196
223294
|
}
|
|
223197
223295
|
/**
|
|
223198
|
-
* Return a unit vector parallel with this.
|
|
223296
|
+
* Return a unit vector parallel with this. Return undefined if this.magnitude is near zero.
|
|
223199
223297
|
* @param result optional result.
|
|
223200
223298
|
*/
|
|
223201
223299
|
normalize(result) {
|
|
@@ -223701,18 +223799,17 @@ class Vector3d extends XYZ {
|
|
|
223701
223799
|
else
|
|
223702
223800
|
return theta;
|
|
223703
223801
|
}
|
|
223704
|
-
/**
|
|
223705
|
-
|
|
223706
|
-
|
|
223707
|
-
|
|
223708
|
-
|
|
223709
|
-
|
|
223710
|
-
|
|
223711
|
-
|
|
223712
|
-
|
|
223713
|
-
|
|
223714
|
-
|
|
223715
|
-
*/
|
|
223802
|
+
/** Return the (strongly typed Angle) angle from this vector to vectorB, measured in the plane containing both,
|
|
223803
|
+
* with vectorW indicating which side to view to control sign of the angle.
|
|
223804
|
+
* * The returned angle can range from negative 180 degrees (negative PI radians) to positive 180 degrees
|
|
223805
|
+
* * (positive PI radians), not closed on the negative side.
|
|
223806
|
+
* * The returned angle is "in the plane containing the two vectors"
|
|
223807
|
+
* * `vectorW` distinguishes between the sides of the plane, but does not have to be perpendicular.
|
|
223808
|
+
* * The returned angle has the same sign as vectorW dot product (thisVector cross vectorB)
|
|
223809
|
+
* * Use planarRadiansTo to measure the angle between vectors that are projected to another plane.
|
|
223810
|
+
* @param vectorB target vector.
|
|
223811
|
+
* @param vectorW distinguishes between the sides of the plane.
|
|
223812
|
+
*/
|
|
223716
223813
|
signedAngleTo(vectorB, vectorW) {
|
|
223717
223814
|
return _Angle__WEBPACK_IMPORTED_MODULE_2__.Angle.createRadians(this.signedRadiansTo(vectorB, vectorW));
|
|
223718
223815
|
}
|
|
@@ -228635,7 +228732,7 @@ class Segment1d {
|
|
|
228635
228732
|
*/
|
|
228636
228733
|
reverseInPlace() { const x = this.x0; this.x0 = this.x1; this.x1 = x; }
|
|
228637
228734
|
/**
|
|
228638
|
-
* * if `x1
|
|
228735
|
+
* * if `x1-x0` multiplied by the scale factor is (strictly) negative, swap the x0 and x1 member values.
|
|
228639
228736
|
* * This makes the fractionToPoint evaluates reverse direction.
|
|
228640
228737
|
*/
|
|
228641
228738
|
reverseIfNeededForDeltaSign(sign = 1) {
|
|
@@ -236449,6 +236546,20 @@ class SmallSystem {
|
|
|
236449
236546
|
}
|
|
236450
236547
|
return undefined;
|
|
236451
236548
|
}
|
|
236549
|
+
/**
|
|
236550
|
+
* Compute the intersection of three planes.
|
|
236551
|
+
* @param xyzA point on the first plane
|
|
236552
|
+
* @param normalA normal of the first plane
|
|
236553
|
+
* @param xyzB point on the second plane
|
|
236554
|
+
* @param normalB normal of the second plane
|
|
236555
|
+
* @param xyzC point on the third plane
|
|
236556
|
+
* @param normalC normal of the third plane
|
|
236557
|
+
* @param result optional result
|
|
236558
|
+
* @returns intersection point of the three planes (as a Vector3d), or undefined if at least two planes are parallel.
|
|
236559
|
+
*/
|
|
236560
|
+
static intersect3Planes(xyzA, normalA, xyzB, normalB, xyzC, normalC, result) {
|
|
236561
|
+
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);
|
|
236562
|
+
}
|
|
236452
236563
|
/**
|
|
236453
236564
|
* * in rowB, replace `rowB[j] += a * rowB[pivot] * rowA[j] / rowA[pivot]` for `j>pivot`
|
|
236454
236565
|
* @param rowA row that does not change
|
|
@@ -240560,10 +240671,29 @@ class PolyfaceBuilder extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
|
|
|
240560
240671
|
if (sector.uv)
|
|
240561
240672
|
sector.uvIndex = this._polyface.addParam(sector.uv);
|
|
240562
240673
|
}
|
|
240674
|
+
addSectorTriangle(sectorA0, sectorA1, sectorA2) {
|
|
240675
|
+
if (sectorA0.xyz.isAlmostEqual(sectorA1.xyz)
|
|
240676
|
+
|| sectorA1.xyz.isAlmostEqual(sectorA2.xyz)
|
|
240677
|
+
|| sectorA2.xyz.isAlmostEqual(sectorA0.xyz)) {
|
|
240678
|
+
// trivially degenerate triangle !!! skip !!!
|
|
240679
|
+
}
|
|
240680
|
+
else {
|
|
240681
|
+
if (this._options.needNormals)
|
|
240682
|
+
this.addIndexedTriangleNormalIndexes(sectorA0.normalIndex, sectorA1.normalIndex, sectorA2.normalIndex);
|
|
240683
|
+
if (this._options.needParams)
|
|
240684
|
+
this.addIndexedTriangleParamIndexes(sectorA0.uvIndex, sectorA1.uvIndex, sectorA2.uvIndex);
|
|
240685
|
+
this.addIndexedTrianglePointIndexes(sectorA0.xyzIndex, sectorA1.xyzIndex, sectorA2.xyzIndex);
|
|
240686
|
+
this._polyface.terminateFacet();
|
|
240687
|
+
}
|
|
240688
|
+
}
|
|
240563
240689
|
addSectorQuadA01B01(sectorA0, sectorA1, sectorB0, sectorB1) {
|
|
240564
240690
|
if (sectorA0.xyz.isAlmostEqual(sectorA1.xyz) && sectorB0.xyz.isAlmostEqual(sectorB1.xyz)) {
|
|
240565
240691
|
// ignore null quad !!
|
|
240566
240692
|
}
|
|
240693
|
+
else if (this._options.shouldTriangulate) {
|
|
240694
|
+
this.addSectorTriangle(sectorA0, sectorA1, sectorB1);
|
|
240695
|
+
this.addSectorTriangle(sectorB1, sectorB0, sectorA0);
|
|
240696
|
+
}
|
|
240567
240697
|
else {
|
|
240568
240698
|
if (this._options.needNormals)
|
|
240569
240699
|
this.addIndexedQuadNormalIndexes(sectorA0.normalIndex, sectorA1.normalIndex, sectorB0.normalIndex, sectorB1.normalIndex);
|
|
@@ -240640,12 +240770,30 @@ class PolyfaceBuilder extends _geometry3d_GeometryHandler__WEBPACK_IMPORTED_MODU
|
|
|
240640
240770
|
}
|
|
240641
240771
|
const numPoints = pointA.length;
|
|
240642
240772
|
for (let i = 1; i < numPoints; i++) {
|
|
240643
|
-
if (
|
|
240644
|
-
|
|
240645
|
-
|
|
240646
|
-
|
|
240647
|
-
|
|
240648
|
-
|
|
240773
|
+
if (this.options.shouldTriangulate) {
|
|
240774
|
+
if (distinctIndices(pointA.atUncheckedIndex(i - 1), pointA.atUncheckedIndex(i), pointB.atUncheckedIndex(i))) {
|
|
240775
|
+
this.addIndexedTrianglePointIndexes(pointA.atUncheckedIndex(i - 1), pointA.atUncheckedIndex(i), pointB.atUncheckedIndex(i));
|
|
240776
|
+
if (normalA && normalB)
|
|
240777
|
+
this.addIndexedTriangleNormalIndexes(normalA.atUncheckedIndex(i - 1), normalA.atUncheckedIndex(i), normalB.atUncheckedIndex(i - 1));
|
|
240778
|
+
if (paramA && paramB)
|
|
240779
|
+
this.addIndexedTriangleParamIndexes(paramA.atUncheckedIndex(i - 1), paramA.atUncheckedIndex(i), paramB.atUncheckedIndex(i - 1));
|
|
240780
|
+
}
|
|
240781
|
+
if (distinctIndices(pointB.atUncheckedIndex(i), pointB.atUncheckedIndex(i - 1), pointA.atUncheckedIndex(i - 1))) {
|
|
240782
|
+
this.addIndexedTrianglePointIndexes(pointA.atUncheckedIndex(i - 1), pointB.atUncheckedIndex(i), pointB.atUncheckedIndex(i - 1));
|
|
240783
|
+
if (normalA && normalB)
|
|
240784
|
+
this.addIndexedTriangleNormalIndexes(normalA.atUncheckedIndex(i - 1), normalB.atUncheckedIndex(i), normalB.atUncheckedIndex(i - 1));
|
|
240785
|
+
if (paramA && paramB)
|
|
240786
|
+
this.addIndexedTriangleParamIndexes(paramA.atUncheckedIndex(i - 1), paramB.atUncheckedIndex(i), paramB.atUncheckedIndex(i - 1));
|
|
240787
|
+
}
|
|
240788
|
+
}
|
|
240789
|
+
else {
|
|
240790
|
+
if (pointA.atUncheckedIndex(i - 1) !== pointA.atUncheckedIndex(i) || pointB.atUncheckedIndex(i - 1) !== pointB.atUncheckedIndex(i)) {
|
|
240791
|
+
this.addIndexedQuadPointIndexes(pointA.atUncheckedIndex(i - 1), pointA.atUncheckedIndex(i), pointB.atUncheckedIndex(i - 1), pointB.atUncheckedIndex(i));
|
|
240792
|
+
if (normalA && normalB)
|
|
240793
|
+
this.addIndexedQuadNormalIndexes(normalA.atUncheckedIndex(i - 1), normalA.atUncheckedIndex(i), normalB.atUncheckedIndex(i - 1), normalB.atUncheckedIndex(i));
|
|
240794
|
+
if (paramA && paramB)
|
|
240795
|
+
this.addIndexedQuadParamIndexes(paramA.atUncheckedIndex(i - 1), paramA.atUncheckedIndex(i), paramB.atUncheckedIndex(i - 1), paramB.atUncheckedIndex(i));
|
|
240796
|
+
}
|
|
240649
240797
|
this._polyface.terminateFacet();
|
|
240650
240798
|
}
|
|
240651
240799
|
}
|
|
@@ -241642,6 +241790,9 @@ function resolveToIndexedXYZCollectionOrCarrier(points) {
|
|
|
241642
241790
|
return points.packedPoints;
|
|
241643
241791
|
return points;
|
|
241644
241792
|
}
|
|
241793
|
+
function distinctIndices(i0, i1, i2) {
|
|
241794
|
+
return i0 !== i1 && i1 !== i2 && i2 !== i0;
|
|
241795
|
+
}
|
|
241645
241796
|
|
|
241646
241797
|
|
|
241647
241798
|
/***/ }),
|
|
@@ -242810,38 +242961,41 @@ function compressUnusedGrowableXYZArray(data: GrowableXYZArray, indices: number[
|
|
|
242810
242961
|
__webpack_require__.r(__webpack_exports__);
|
|
242811
242962
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
242812
242963
|
/* harmony export */ "DuplicateFacetClusterSelector": () => (/* binding */ DuplicateFacetClusterSelector),
|
|
242964
|
+
/* harmony export */ "OffsetMeshOptions": () => (/* binding */ OffsetMeshOptions),
|
|
242813
242965
|
/* harmony export */ "PolyfaceQuery": () => (/* binding */ PolyfaceQuery)
|
|
242814
242966
|
/* harmony export */ });
|
|
242815
242967
|
/* harmony import */ var _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../geometry3d/PointHelpers */ "../../core/geometry/lib/esm/geometry3d/PointHelpers.js");
|
|
242816
|
-
/* harmony import */ var
|
|
242968
|
+
/* harmony import */ var _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../curve/CurveCollection */ "../../core/geometry/lib/esm/curve/CurveCollection.js");
|
|
242817
242969
|
/* harmony import */ var _curve_internalContexts_MultiChainCollector__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../curve/internalContexts/MultiChainCollector */ "../../core/geometry/lib/esm/curve/internalContexts/MultiChainCollector.js");
|
|
242818
|
-
/* harmony import */ var
|
|
242819
|
-
/* harmony import */ var
|
|
242820
|
-
/* harmony import */ var
|
|
242970
|
+
/* harmony import */ var _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../curve/LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
|
|
242971
|
+
/* harmony import */ var _curve_LineString3d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../curve/LineString3d */ "../../core/geometry/lib/esm/curve/LineString3d.js");
|
|
242972
|
+
/* harmony import */ var _curve_Loop__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../curve/Loop */ "../../core/geometry/lib/esm/curve/Loop.js");
|
|
242821
242973
|
/* harmony import */ var _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../curve/StrokeOptions */ "../../core/geometry/lib/esm/curve/StrokeOptions.js");
|
|
242822
|
-
/* harmony import */ var
|
|
242823
|
-
/* harmony import */ var
|
|
242974
|
+
/* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
|
|
242975
|
+
/* harmony import */ var _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../geometry3d/Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
|
|
242824
242976
|
/* harmony import */ var _geometry3d_FrameBuilder__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../geometry3d/FrameBuilder */ "../../core/geometry/lib/esm/geometry3d/FrameBuilder.js");
|
|
242825
|
-
/* harmony import */ var
|
|
242826
|
-
/* harmony import */ var
|
|
242977
|
+
/* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
|
|
242978
|
+
/* harmony import */ var _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../geometry3d/PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
|
|
242827
242979
|
/* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
|
|
242828
|
-
/* harmony import */ var
|
|
242829
|
-
/* harmony import */ var
|
|
242830
|
-
/* harmony import */ var
|
|
242980
|
+
/* harmony import */ var _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../geometry4d/Matrix4d */ "../../core/geometry/lib/esm/geometry4d/Matrix4d.js");
|
|
242981
|
+
/* harmony import */ var _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../geometry4d/MomentData */ "../../core/geometry/lib/esm/geometry4d/MomentData.js");
|
|
242982
|
+
/* harmony import */ var _numerics_UnionFind__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../numerics/UnionFind */ "../../core/geometry/lib/esm/numerics/UnionFind.js");
|
|
242831
242983
|
/* harmony import */ var _topology_ChainMerge__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../topology/ChainMerge */ "../../core/geometry/lib/esm/topology/ChainMerge.js");
|
|
242832
242984
|
/* harmony import */ var _topology_Graph__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../topology/Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
|
|
242833
242985
|
/* harmony import */ var _topology_HalfEdgeGraphSearch__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../topology/HalfEdgeGraphSearch */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphSearch.js");
|
|
242834
242986
|
/* harmony import */ var _topology_Merging__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../topology/Merging */ "../../core/geometry/lib/esm/topology/Merging.js");
|
|
242835
|
-
/* harmony import */ var
|
|
242836
|
-
/* harmony import */ var
|
|
242987
|
+
/* harmony import */ var _FacetOrientation__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./FacetOrientation */ "../../core/geometry/lib/esm/polyface/FacetOrientation.js");
|
|
242988
|
+
/* harmony import */ var _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./IndexedEdgeMatcher */ "../../core/geometry/lib/esm/polyface/IndexedEdgeMatcher.js");
|
|
242837
242989
|
/* harmony import */ var _IndexedPolyfaceVisitor__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./IndexedPolyfaceVisitor */ "../../core/geometry/lib/esm/polyface/IndexedPolyfaceVisitor.js");
|
|
242838
|
-
/* harmony import */ var
|
|
242839
|
-
/* harmony import */ var
|
|
242990
|
+
/* harmony import */ var _multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./multiclip/BuildAverageNormalsContext */ "../../core/geometry/lib/esm/polyface/multiclip/BuildAverageNormalsContext.js");
|
|
242991
|
+
/* harmony import */ var _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./multiclip/SweepLineStringToFacetContext */ "../../core/geometry/lib/esm/polyface/multiclip/SweepLineStringToFacetContext.js");
|
|
242840
242992
|
/* harmony import */ var _multiclip_XYPointBuckets__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./multiclip/XYPointBuckets */ "../../core/geometry/lib/esm/polyface/multiclip/XYPointBuckets.js");
|
|
242841
|
-
/* harmony import */ var
|
|
242993
|
+
/* harmony import */ var _Polyface__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Polyface */ "../../core/geometry/lib/esm/polyface/Polyface.js");
|
|
242842
242994
|
/* harmony import */ var _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./PolyfaceBuilder */ "../../core/geometry/lib/esm/polyface/PolyfaceBuilder.js");
|
|
242843
242995
|
/* harmony import */ var _RangeLengthData__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./RangeLengthData */ "../../core/geometry/lib/esm/polyface/RangeLengthData.js");
|
|
242844
242996
|
/* harmony import */ var _topology_SpaceTriangulation__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../topology/SpaceTriangulation */ "../../core/geometry/lib/esm/topology/SpaceTriangulation.js");
|
|
242997
|
+
/* harmony import */ var _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../topology/HalfEdgeGraphFromIndexedLoopsContext */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js");
|
|
242998
|
+
/* harmony import */ var _multiclip_OffsetMeshContext__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./multiclip/OffsetMeshContext */ "../../core/geometry/lib/esm/polyface/multiclip/OffsetMeshContext.js");
|
|
242845
242999
|
/*---------------------------------------------------------------------------------------------
|
|
242846
243000
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
242847
243001
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
@@ -242881,6 +243035,41 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
242881
243035
|
|
|
242882
243036
|
|
|
242883
243037
|
|
|
243038
|
+
|
|
243039
|
+
|
|
243040
|
+
/**
|
|
243041
|
+
* Options carrier for [[PolyfaceQuery.cloneOffset]].
|
|
243042
|
+
* * Default options are strongly recommended.
|
|
243043
|
+
* * The option most likely to be changed is chamferTurnAngle
|
|
243044
|
+
* @public
|
|
243045
|
+
*/
|
|
243046
|
+
class OffsetMeshOptions {
|
|
243047
|
+
/** Constructor -- CAPTURE parameters ... */
|
|
243048
|
+
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)) {
|
|
243049
|
+
this.smoothSingleAngleBetweenNormals = smoothSingleAngleBetweenNormals.clone();
|
|
243050
|
+
this.smoothAccumulatedAngleBetweenNormals = smoothAccumulatedAngleBetweenNormals.clone();
|
|
243051
|
+
this.chamferAngleBetweenNormals = chamferTurnAngle.clone();
|
|
243052
|
+
}
|
|
243053
|
+
/** construct and return an OffsetMeshOptions with given parameters.
|
|
243054
|
+
* * Angles are forced to minimum values.
|
|
243055
|
+
* * Clones of the angles are given to the constructor.
|
|
243056
|
+
* @param smoothSingleRadiansBetweenNormals an angle larger than this (between facets) is considered a sharp edge
|
|
243057
|
+
* @param smoothAccumulatedAngleBetweenNormals angles that sum to this much may be consolidated for average normal
|
|
243058
|
+
* @param chamferTurnAngleBetweenNormals when facets meet with larger angle, a chamfer edge may be added if the angle between facet normals is larger than this.
|
|
243059
|
+
*/
|
|
243060
|
+
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)) {
|
|
243061
|
+
const mySmoothSingleRadiansBetweenNormals = smoothSingleAngleBetweenNormals.clone();
|
|
243062
|
+
const mySmoothAccumulatedRadiansBetweenNormals = smoothAccumulatedAngleBetweenNormals.clone();
|
|
243063
|
+
const myChamferTurnAngleBetweenNormals = chamferTurnAngleBetweenNormals.clone();
|
|
243064
|
+
if (mySmoothSingleRadiansBetweenNormals.degrees < 1)
|
|
243065
|
+
mySmoothAccumulatedRadiansBetweenNormals.setDegrees(1.0);
|
|
243066
|
+
if (mySmoothAccumulatedRadiansBetweenNormals.degrees < 1.0)
|
|
243067
|
+
mySmoothAccumulatedRadiansBetweenNormals.setDegrees(1.0);
|
|
243068
|
+
if (mySmoothAccumulatedRadiansBetweenNormals.degrees < 15.0)
|
|
243069
|
+
mySmoothAccumulatedRadiansBetweenNormals.setDegrees(15.0);
|
|
243070
|
+
return new OffsetMeshOptions(mySmoothSingleRadiansBetweenNormals, mySmoothAccumulatedRadiansBetweenNormals, myChamferTurnAngleBetweenNormals);
|
|
243071
|
+
}
|
|
243072
|
+
}
|
|
242884
243073
|
/**
|
|
242885
243074
|
* Enumeration of cases for retaining facets among duplicates
|
|
242886
243075
|
* @public
|
|
@@ -242902,12 +243091,12 @@ var DuplicateFacetClusterSelector;
|
|
|
242902
243091
|
class PolyfaceQuery {
|
|
242903
243092
|
/** copy the points from a visitor into a Linestring3d in a Loop object */
|
|
242904
243093
|
static visitorToLoop(visitor) {
|
|
242905
|
-
const ls =
|
|
242906
|
-
return
|
|
243094
|
+
const ls = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_1__.LineString3d.createPoints(visitor.point.getPoint3dArray());
|
|
243095
|
+
return _curve_Loop__WEBPACK_IMPORTED_MODULE_2__.Loop.create(ls);
|
|
242907
243096
|
}
|
|
242908
243097
|
/** Create a linestring loop for each facet of the polyface. */
|
|
242909
243098
|
static indexedPolyfaceToLoops(polyface) {
|
|
242910
|
-
const result =
|
|
243099
|
+
const result = _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_3__.BagOfCurves.create();
|
|
242911
243100
|
const visitor = polyface.createVisitor(1);
|
|
242912
243101
|
while (visitor.moveToNextFacet()) {
|
|
242913
243102
|
const loop = PolyfaceQuery.visitorToLoop(visitor);
|
|
@@ -242921,17 +243110,17 @@ class PolyfaceQuery {
|
|
|
242921
243110
|
static sumFacetAreas(source, vectorToEye) {
|
|
242922
243111
|
let s = 0;
|
|
242923
243112
|
if (source !== undefined) {
|
|
242924
|
-
if (source instanceof
|
|
243113
|
+
if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
|
|
242925
243114
|
return PolyfaceQuery.sumFacetAreas(source.createVisitor(1), vectorToEye);
|
|
242926
243115
|
let unitVectorToEye;
|
|
242927
243116
|
if (vectorToEye !== undefined)
|
|
242928
243117
|
unitVectorToEye = vectorToEye.normalize();
|
|
242929
243118
|
source.reset();
|
|
242930
243119
|
while (source.moveToNextFacet()) {
|
|
242931
|
-
const scaledNormal =
|
|
243120
|
+
const scaledNormal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.areaNormal(source.point.getPoint3dArray());
|
|
242932
243121
|
let area = scaledNormal.magnitude();
|
|
242933
243122
|
if (unitVectorToEye !== undefined) {
|
|
242934
|
-
const scale =
|
|
243123
|
+
const scale = _Geometry__WEBPACK_IMPORTED_MODULE_6__.Geometry.conditionalDivideCoordinate(1.0, area);
|
|
242935
243124
|
if (scale !== undefined)
|
|
242936
243125
|
area *= scaledNormal.dotProduct(unitVectorToEye) * scale;
|
|
242937
243126
|
}
|
|
@@ -242948,12 +243137,12 @@ class PolyfaceQuery {
|
|
|
242948
243137
|
*/
|
|
242949
243138
|
static sumTetrahedralVolumes(source, origin) {
|
|
242950
243139
|
let s = 0;
|
|
242951
|
-
if (source instanceof
|
|
243140
|
+
if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
|
|
242952
243141
|
return PolyfaceQuery.sumTetrahedralVolumes(source.createVisitor(0), origin);
|
|
242953
243142
|
let myOrigin = origin;
|
|
242954
|
-
const facetOrigin =
|
|
242955
|
-
const targetA =
|
|
242956
|
-
const targetB =
|
|
243143
|
+
const facetOrigin = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
243144
|
+
const targetA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
243145
|
+
const targetB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
242957
243146
|
source.reset();
|
|
242958
243147
|
while (source.moveToNextFacet()) {
|
|
242959
243148
|
if (myOrigin === undefined)
|
|
@@ -242974,20 +243163,20 @@ class PolyfaceQuery {
|
|
|
242974
243163
|
*
|
|
242975
243164
|
*/
|
|
242976
243165
|
static sumVolumeBetweenFacetsAndPlane(source, plane) {
|
|
242977
|
-
if (source instanceof
|
|
243166
|
+
if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
|
|
242978
243167
|
return PolyfaceQuery.sumVolumeBetweenFacetsAndPlane(source.createVisitor(0), plane);
|
|
242979
|
-
const facetOrigin =
|
|
242980
|
-
const targetA =
|
|
242981
|
-
const targetB =
|
|
242982
|
-
const triangleNormal =
|
|
243168
|
+
const facetOrigin = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
243169
|
+
const targetA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
243170
|
+
const targetB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
243171
|
+
const triangleNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
|
|
242983
243172
|
const planeNormal = plane.getNormalRef();
|
|
242984
243173
|
let h0, hA, hB;
|
|
242985
243174
|
let signedVolumeSum = 0.0;
|
|
242986
243175
|
let signedTriangleArea;
|
|
242987
243176
|
let singleFacetArea;
|
|
242988
|
-
const positiveAreaMomentSums =
|
|
242989
|
-
const negativeAreaMomentSums =
|
|
242990
|
-
const singleFacetProducts =
|
|
243177
|
+
const positiveAreaMomentSums = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.create(undefined, true);
|
|
243178
|
+
const negativeAreaMomentSums = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.create(undefined, true);
|
|
243179
|
+
const singleFacetProducts = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__.Matrix4d.createZero();
|
|
242991
243180
|
const projectToPlane = plane.getProjectionToPlane();
|
|
242992
243181
|
source.reset();
|
|
242993
243182
|
// For each facet ..
|
|
@@ -243014,7 +243203,7 @@ class PolyfaceQuery {
|
|
|
243014
243203
|
}
|
|
243015
243204
|
singleFacetProducts.setZero();
|
|
243016
243205
|
source.point.multiplyTransformInPlace(projectToPlane);
|
|
243017
|
-
|
|
243206
|
+
_geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.addSecondMomentAreaProducts(source.point, facetOrigin, singleFacetProducts);
|
|
243018
243207
|
if (singleFacetArea > 0) {
|
|
243019
243208
|
positiveAreaMomentSums.accumulateProductsFromOrigin(facetOrigin, singleFacetProducts, 1.0);
|
|
243020
243209
|
}
|
|
@@ -243024,8 +243213,8 @@ class PolyfaceQuery {
|
|
|
243024
243213
|
}
|
|
243025
243214
|
positiveAreaMomentSums.shiftOriginAndSumsToCentroidOfSums();
|
|
243026
243215
|
negativeAreaMomentSums.shiftOriginAndSumsToCentroidOfSums();
|
|
243027
|
-
const positiveAreaMoments =
|
|
243028
|
-
const negativeAreaMoments =
|
|
243216
|
+
const positiveAreaMoments = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.inertiaProductsToPrincipalAxes(positiveAreaMomentSums.origin, positiveAreaMomentSums.sums);
|
|
243217
|
+
const negativeAreaMoments = _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.inertiaProductsToPrincipalAxes(negativeAreaMomentSums.origin, negativeAreaMomentSums.sums);
|
|
243029
243218
|
return {
|
|
243030
243219
|
volume: signedVolumeSum / 6.0,
|
|
243031
243220
|
positiveProjectedFacetAreaMoments: positiveAreaMoments,
|
|
@@ -243034,23 +243223,23 @@ class PolyfaceQuery {
|
|
|
243034
243223
|
}
|
|
243035
243224
|
/** Return the inertia products [xx,xy,xz,xw, yw, etc] integrated over all all facets, as viewed from origin. */
|
|
243036
243225
|
static sumFacetSecondAreaMomentProducts(source, origin) {
|
|
243037
|
-
if (source instanceof
|
|
243226
|
+
if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
|
|
243038
243227
|
return PolyfaceQuery.sumFacetSecondAreaMomentProducts(source.createVisitor(0), origin);
|
|
243039
|
-
const products =
|
|
243228
|
+
const products = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__.Matrix4d.createZero();
|
|
243040
243229
|
source.reset();
|
|
243041
243230
|
while (source.moveToNextFacet()) {
|
|
243042
|
-
|
|
243231
|
+
_geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.addSecondMomentAreaProducts(source.point, origin, products);
|
|
243043
243232
|
}
|
|
243044
243233
|
return products;
|
|
243045
243234
|
}
|
|
243046
243235
|
/** Return the inertia products [xx,xy,xz,xw, yw, etc] integrated over all tetrahedral volumes from origin */
|
|
243047
243236
|
static sumFacetSecondVolumeMomentProducts(source, origin) {
|
|
243048
|
-
if (source instanceof
|
|
243237
|
+
if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
|
|
243049
243238
|
return PolyfaceQuery.sumFacetSecondVolumeMomentProducts(source.createVisitor(0), origin);
|
|
243050
|
-
const products =
|
|
243239
|
+
const products = _geometry4d_Matrix4d__WEBPACK_IMPORTED_MODULE_9__.Matrix4d.createZero();
|
|
243051
243240
|
source.reset();
|
|
243052
243241
|
while (source.moveToNextFacet()) {
|
|
243053
|
-
|
|
243242
|
+
_geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.addSecondMomentVolumeProducts(source.point, origin, products);
|
|
243054
243243
|
}
|
|
243055
243244
|
return products;
|
|
243056
243245
|
}
|
|
@@ -243064,7 +243253,7 @@ class PolyfaceQuery {
|
|
|
243064
243253
|
if (!origin)
|
|
243065
243254
|
return undefined;
|
|
243066
243255
|
const inertiaProducts = PolyfaceQuery.sumFacetSecondAreaMomentProducts(source, origin);
|
|
243067
|
-
return
|
|
243256
|
+
return _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.inertiaProductsToPrincipalAxes(origin, inertiaProducts);
|
|
243068
243257
|
}
|
|
243069
243258
|
/** Compute area moments for the mesh. In the returned MomentData:
|
|
243070
243259
|
* * origin is the centroid.
|
|
@@ -243078,7 +243267,7 @@ class PolyfaceQuery {
|
|
|
243078
243267
|
if (!origin)
|
|
243079
243268
|
return undefined;
|
|
243080
243269
|
const inertiaProducts = PolyfaceQuery.sumFacetSecondVolumeMomentProducts(source, origin);
|
|
243081
|
-
return
|
|
243270
|
+
return _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_8__.MomentData.inertiaProductsToPrincipalAxes(origin, inertiaProducts);
|
|
243082
243271
|
}
|
|
243083
243272
|
/**
|
|
243084
243273
|
* Test for convex volume by dihedral angle tests on all edges.
|
|
@@ -243110,14 +243299,14 @@ class PolyfaceQuery {
|
|
|
243110
243299
|
* * (but null edges are permitted -- These occur naturally at edges of quads at north or south pole)
|
|
243111
243300
|
*/
|
|
243112
243301
|
static dihedralAngleSummary(source, ignoreBoundaries = false) {
|
|
243113
|
-
const edges = new
|
|
243302
|
+
const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
|
|
243114
243303
|
const visitor = source.createVisitor(1);
|
|
243115
243304
|
visitor.reset();
|
|
243116
243305
|
const centroidNormal = [];
|
|
243117
243306
|
let normalCounter = 0;
|
|
243118
243307
|
while (visitor.moveToNextFacet()) {
|
|
243119
243308
|
const numEdges = visitor.pointCount - 1;
|
|
243120
|
-
const normal =
|
|
243309
|
+
const normal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.centroidAreaNormal(visitor.point);
|
|
243121
243310
|
if (normal === undefined)
|
|
243122
243311
|
return 0;
|
|
243123
243312
|
centroidNormal.push(normal);
|
|
@@ -243134,12 +243323,12 @@ class PolyfaceQuery {
|
|
|
243134
243323
|
let numPositive = 0;
|
|
243135
243324
|
let numPlanar = 0;
|
|
243136
243325
|
let numNegative = 0;
|
|
243137
|
-
const edgeVector =
|
|
243326
|
+
const edgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
|
|
243138
243327
|
for (const cluster of manifoldClusters) {
|
|
243139
243328
|
const sideA = cluster[0];
|
|
243140
243329
|
const sideB = cluster[1];
|
|
243141
|
-
if (sideA instanceof
|
|
243142
|
-
&& sideB instanceof
|
|
243330
|
+
if (sideA instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge
|
|
243331
|
+
&& sideB instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge
|
|
243143
243332
|
&& source.data.point.vectorIndexIndex(sideA.vertexIndexA, sideA.vertexIndexB, edgeVector)) {
|
|
243144
243333
|
const dihedralAngle = centroidNormal[sideA.facetIndex].direction.signedAngleTo(centroidNormal[sideB.facetIndex].direction, edgeVector);
|
|
243145
243334
|
if (dihedralAngle.isAlmostZero)
|
|
@@ -243172,7 +243361,7 @@ class PolyfaceQuery {
|
|
|
243172
243361
|
* * Any edge with 2 incident facets in the same direction triggers a `false` return.
|
|
243173
243362
|
*/
|
|
243174
243363
|
static isPolyfaceManifold(source, allowSimpleBoundaries = false) {
|
|
243175
|
-
const edges = new
|
|
243364
|
+
const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
|
|
243176
243365
|
const visitor = source.createVisitor(1);
|
|
243177
243366
|
visitor.reset();
|
|
243178
243367
|
while (visitor.moveToNextFacet()) {
|
|
@@ -243195,9 +243384,9 @@ class PolyfaceQuery {
|
|
|
243195
243384
|
* @returns
|
|
243196
243385
|
*/
|
|
243197
243386
|
static boundaryEdges(source, includeDanglers = true, includeMismatch = true, includeNull = true) {
|
|
243198
|
-
const result = new
|
|
243387
|
+
const result = new _curve_CurveCollection__WEBPACK_IMPORTED_MODULE_3__.BagOfCurves();
|
|
243199
243388
|
const announceEdge = (pointA, pointB, _indexA, _indexB, _readIndex) => {
|
|
243200
|
-
result.tryAddChild(
|
|
243389
|
+
result.tryAddChild(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(pointA, pointB));
|
|
243201
243390
|
};
|
|
243202
243391
|
PolyfaceQuery.announceBoundaryEdges(source, announceEdge, includeDanglers, includeMismatch, includeNull);
|
|
243203
243392
|
if (result.children.length === 0)
|
|
@@ -243216,8 +243405,8 @@ class PolyfaceQuery {
|
|
|
243216
243405
|
static announceBoundaryEdges(source, announceEdge, includeDanglers = true, includeMismatch = true, includeNull = true) {
|
|
243217
243406
|
if (source === undefined)
|
|
243218
243407
|
return undefined;
|
|
243219
|
-
const edges = new
|
|
243220
|
-
const visitor = source instanceof
|
|
243408
|
+
const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
|
|
243409
|
+
const visitor = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface ? source.createVisitor(1) : source;
|
|
243221
243410
|
visitor.setNumWrap(1);
|
|
243222
243411
|
visitor.reset();
|
|
243223
243412
|
while (visitor.moveToNextFacet()) {
|
|
@@ -243242,7 +243431,7 @@ class PolyfaceQuery {
|
|
|
243242
243431
|
const sourcePolyface = visitor.clientPolyface();
|
|
243243
243432
|
for (const list of badList) {
|
|
243244
243433
|
for (const e of list) {
|
|
243245
|
-
const e1 = e instanceof
|
|
243434
|
+
const e1 = e instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge ? e : e[0];
|
|
243246
243435
|
const indexA = e1.vertexIndexA;
|
|
243247
243436
|
const indexB = e1.vertexIndexB;
|
|
243248
243437
|
const pointA = sourcePolyface.data.getPoint(indexA);
|
|
@@ -243257,7 +243446,7 @@ class PolyfaceQuery {
|
|
|
243257
243446
|
* * Facets are ASSUMED to be convex and planar.
|
|
243258
243447
|
*/
|
|
243259
243448
|
static announceSweepLinestringToConvexPolyfaceXY(linestringPoints, polyface, announce) {
|
|
243260
|
-
const context =
|
|
243449
|
+
const context = _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_12__.SweepLineStringToFacetContext.create(linestringPoints);
|
|
243261
243450
|
if (context) {
|
|
243262
243451
|
const visitor = polyface.createVisitor(0);
|
|
243263
243452
|
for (visitor.reset(); visitor.moveToNextFacet();) {
|
|
@@ -243290,7 +243479,7 @@ class PolyfaceQuery {
|
|
|
243290
243479
|
* @internal
|
|
243291
243480
|
*/
|
|
243292
243481
|
static async asyncAnnounceSweepLinestringToConvexPolyfaceXY(linestringPoints, polyface, announce) {
|
|
243293
|
-
const context =
|
|
243482
|
+
const context = _multiclip_SweepLineStringToFacetContext__WEBPACK_IMPORTED_MODULE_12__.SweepLineStringToFacetContext.create(linestringPoints);
|
|
243294
243483
|
this.awaitBlockCount = 0;
|
|
243295
243484
|
let workTotal = 0;
|
|
243296
243485
|
if (context) {
|
|
@@ -243310,11 +243499,11 @@ class PolyfaceQuery {
|
|
|
243310
243499
|
* * Return array of arrays of facet indices.
|
|
243311
243500
|
*/
|
|
243312
243501
|
static partitionFacetIndicesByVertexConnectedComponent(polyface) {
|
|
243313
|
-
if (polyface instanceof
|
|
243502
|
+
if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
|
|
243314
243503
|
return this.partitionFacetIndicesByVertexConnectedComponent(polyface.createVisitor(0));
|
|
243315
243504
|
}
|
|
243316
243505
|
// The polyface is really a visitor !!!
|
|
243317
|
-
const context = new
|
|
243506
|
+
const context = new _numerics_UnionFind__WEBPACK_IMPORTED_MODULE_13__.UnionFindContext(this.visitorClientPointCount(polyface));
|
|
243318
243507
|
for (polyface.reset(); polyface.moveToNextFacet();) {
|
|
243319
243508
|
const firstVertexIndexOnThisFacet = polyface.pointIndex[0];
|
|
243320
243509
|
for (const vertexIndex of polyface.pointIndex)
|
|
@@ -243347,7 +243536,7 @@ class PolyfaceQuery {
|
|
|
243347
243536
|
* * Return array of arrays of facet indices.
|
|
243348
243537
|
*/
|
|
243349
243538
|
static partitionFacetIndicesByVisibilityVector(polyface, vectorToEye, sideAngleTolerance) {
|
|
243350
|
-
if (polyface instanceof
|
|
243539
|
+
if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
|
|
243351
243540
|
return this.partitionFacetIndicesByVisibilityVector(polyface.createVisitor(0), vectorToEye, sideAngleTolerance);
|
|
243352
243541
|
}
|
|
243353
243542
|
const facetsInComponent = [];
|
|
@@ -243359,7 +243548,7 @@ class PolyfaceQuery {
|
|
|
243359
243548
|
const sideComponent = facetsInComponent[2];
|
|
243360
243549
|
const radiansTol = Math.max(sideAngleTolerance.radians, 1.0e-8);
|
|
243361
243550
|
for (polyface.reset(); polyface.moveToNextFacet();) {
|
|
243362
|
-
const areaNormal =
|
|
243551
|
+
const areaNormal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.areaNormalGo(polyface.point);
|
|
243363
243552
|
const index = polyface.currentReadIndex();
|
|
243364
243553
|
if (areaNormal) {
|
|
243365
243554
|
const angle = areaNormal.angleFromPerpendicular(vectorToEye);
|
|
@@ -243386,7 +243575,7 @@ class PolyfaceQuery {
|
|
|
243386
243575
|
* @param vectorToEye
|
|
243387
243576
|
* @param sideAngleTolerance
|
|
243388
243577
|
*/
|
|
243389
|
-
static boundaryOfVisibleSubset(polyface, visibilitySelect, vectorToEye, sideAngleTolerance =
|
|
243578
|
+
static boundaryOfVisibleSubset(polyface, visibilitySelect, vectorToEye, sideAngleTolerance = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(1.0e-3)) {
|
|
243390
243579
|
const partitionedIndices = this.partitionFacetIndicesByVisibilityVector(polyface, vectorToEye, sideAngleTolerance);
|
|
243391
243580
|
if (partitionedIndices[visibilitySelect].length === 0)
|
|
243392
243581
|
return undefined;
|
|
@@ -243400,8 +243589,8 @@ class PolyfaceQuery {
|
|
|
243400
243589
|
* @param mesh
|
|
243401
243590
|
*/
|
|
243402
243591
|
static announceBoundaryChainsAsLineString3d(mesh, announceLoop) {
|
|
243403
|
-
const collector = new _curve_internalContexts_MultiChainCollector__WEBPACK_IMPORTED_MODULE_15__.MultiChainCollector(
|
|
243404
|
-
PolyfaceQuery.announceBoundaryEdges(mesh, (pointA, pointB, _indexA, _indexB) => collector.captureCurve(
|
|
243592
|
+
const collector = new _curve_internalContexts_MultiChainCollector__WEBPACK_IMPORTED_MODULE_15__.MultiChainCollector(_Geometry__WEBPACK_IMPORTED_MODULE_6__.Geometry.smallMetricDistance, 1000);
|
|
243593
|
+
PolyfaceQuery.announceBoundaryEdges(mesh, (pointA, pointB, _indexA, _indexB) => collector.captureCurve(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(pointA, pointB)), true, false, false);
|
|
243405
243594
|
collector.announceChainsAsLineString3d(announceLoop);
|
|
243406
243595
|
}
|
|
243407
243596
|
/**
|
|
@@ -243412,7 +243601,7 @@ class PolyfaceQuery {
|
|
|
243412
243601
|
* @returns
|
|
243413
243602
|
*/
|
|
243414
243603
|
static cloneWithMaximalPlanarFacets(mesh) {
|
|
243415
|
-
if (mesh instanceof
|
|
243604
|
+
if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
|
|
243416
243605
|
return this.cloneWithMaximalPlanarFacets(mesh.createVisitor(0));
|
|
243417
243606
|
const numFacets = PolyfaceQuery.visitorClientFacetCount(mesh);
|
|
243418
243607
|
const smoothEdges = PolyfaceQuery.collectEdgesByDihedralAngle(mesh);
|
|
@@ -243437,7 +243626,7 @@ class PolyfaceQuery {
|
|
|
243437
243626
|
const edges = [];
|
|
243438
243627
|
const edgeStrings = [];
|
|
243439
243628
|
PolyfaceQuery.announceBoundaryEdges(fragment, (pointA, pointB, _indexA, _indexB) => {
|
|
243440
|
-
edges.push(
|
|
243629
|
+
edges.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(pointA, pointB));
|
|
243441
243630
|
edgeStrings.push([pointA.clone(), pointB.clone()]);
|
|
243442
243631
|
});
|
|
243443
243632
|
const chains = _curve_internalContexts_MultiChainCollector__WEBPACK_IMPORTED_MODULE_15__.OffsetHelpers.collectChains(edges, gapTolerance, planarityTolerance);
|
|
@@ -243478,7 +243667,7 @@ class PolyfaceQuery {
|
|
|
243478
243667
|
* @returns
|
|
243479
243668
|
*/
|
|
243480
243669
|
static fillSimpleHoles(mesh, options, unfilledChains) {
|
|
243481
|
-
if (mesh instanceof
|
|
243670
|
+
if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
|
|
243482
243671
|
return this.fillSimpleHoles(mesh.createVisitor(0), options, unfilledChains);
|
|
243483
243672
|
const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create();
|
|
243484
243673
|
const chains = [];
|
|
@@ -243492,7 +243681,7 @@ class PolyfaceQuery {
|
|
|
243492
243681
|
rejected = true;
|
|
243493
243682
|
else if (options.maxPerimeter !== undefined && _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_21__.Point3dArray.sumEdgeLengths(points, false) > options.maxPerimeter)
|
|
243494
243683
|
rejected = true;
|
|
243495
|
-
else if (options.upVector !== undefined &&
|
|
243684
|
+
else if (options.upVector !== undefined && _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.sumTriangleAreasPerpendicularToUpVector(points, options.upVector) <= 0.0)
|
|
243496
243685
|
rejected = true;
|
|
243497
243686
|
if (!rejected && _topology_SpaceTriangulation__WEBPACK_IMPORTED_MODULE_22__.SpacePolygonTriangulation.triangulateSimplestSpaceLoop(points, (_loop, triangles) => {
|
|
243498
243687
|
for (const t of triangles)
|
|
@@ -243515,7 +243704,7 @@ class PolyfaceQuery {
|
|
|
243515
243704
|
*
|
|
243516
243705
|
*/
|
|
243517
243706
|
static clonePartitions(polyface, partitions) {
|
|
243518
|
-
if (polyface instanceof
|
|
243707
|
+
if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
|
|
243519
243708
|
return this.clonePartitions(polyface.createVisitor(0), partitions);
|
|
243520
243709
|
}
|
|
243521
243710
|
polyface.setNumWrap(0);
|
|
@@ -243539,7 +243728,7 @@ class PolyfaceQuery {
|
|
|
243539
243728
|
/** Clone facets that pass an filter function
|
|
243540
243729
|
*/
|
|
243541
243730
|
static cloneFiltered(source, filter) {
|
|
243542
|
-
if (source instanceof
|
|
243731
|
+
if (source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
|
|
243543
243732
|
return this.cloneFiltered(source.createVisitor(0), filter);
|
|
243544
243733
|
}
|
|
243545
243734
|
source.setNumWrap(0);
|
|
@@ -243591,9 +243780,9 @@ class PolyfaceQuery {
|
|
|
243591
243780
|
* @return collection of facet index arrays, one array per connected component
|
|
243592
243781
|
*/
|
|
243593
243782
|
static partitionFacetIndicesBySortableEdgeClusters(edgeClusters, numFacets) {
|
|
243594
|
-
const context = new
|
|
243783
|
+
const context = new _numerics_UnionFind__WEBPACK_IMPORTED_MODULE_13__.UnionFindContext(numFacets);
|
|
243595
243784
|
for (const cluster of edgeClusters) {
|
|
243596
|
-
if (cluster instanceof
|
|
243785
|
+
if (cluster instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge) {
|
|
243597
243786
|
// this edge does not connect anywhere. Ignore it!!
|
|
243598
243787
|
}
|
|
243599
243788
|
else {
|
|
@@ -243625,11 +243814,11 @@ class PolyfaceQuery {
|
|
|
243625
243814
|
* @return collection of facet index arrays, one per connected component
|
|
243626
243815
|
*/
|
|
243627
243816
|
static partitionFacetIndicesByEdgeConnectedComponent(polyface, stopAtVisibleEdges = false) {
|
|
243628
|
-
if (polyface instanceof
|
|
243817
|
+
if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
|
|
243629
243818
|
return this.partitionFacetIndicesByEdgeConnectedComponent(polyface.createVisitor(0), stopAtVisibleEdges);
|
|
243630
243819
|
}
|
|
243631
243820
|
polyface.setNumWrap(1);
|
|
243632
|
-
const matcher = new
|
|
243821
|
+
const matcher = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
|
|
243633
243822
|
polyface.reset();
|
|
243634
243823
|
let numFacets = 0;
|
|
243635
243824
|
while (polyface.moveToNextFacet()) {
|
|
@@ -243667,7 +243856,7 @@ class PolyfaceQuery {
|
|
|
243667
243856
|
static sweepLinestringToFacetsXYReturnLines(linestringPoints, polyface) {
|
|
243668
243857
|
const drapeGeometry = [];
|
|
243669
243858
|
this.announceSweepLinestringToConvexPolyfaceXY(linestringPoints, polyface, (_linestring, _segmentIndex, _polyface, _facetIndex, points, indexA, indexB) => {
|
|
243670
|
-
drapeGeometry.push(
|
|
243859
|
+
drapeGeometry.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(points[indexA], points[indexB]));
|
|
243671
243860
|
});
|
|
243672
243861
|
return drapeGeometry;
|
|
243673
243862
|
}
|
|
@@ -243702,7 +243891,7 @@ class PolyfaceQuery {
|
|
|
243702
243891
|
* * Return statistical summary of x,y,z ranges.
|
|
243703
243892
|
*/
|
|
243704
243893
|
static collectRangeLengthData(polyface) {
|
|
243705
|
-
if (polyface instanceof
|
|
243894
|
+
if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface) {
|
|
243706
243895
|
return this.collectRangeLengthData(polyface.createVisitor(0));
|
|
243707
243896
|
}
|
|
243708
243897
|
const rangeData = new _RangeLengthData__WEBPACK_IMPORTED_MODULE_25__.RangeLengthData();
|
|
@@ -243720,10 +243909,10 @@ class PolyfaceQuery {
|
|
|
243720
243909
|
const rangeSearcher = _multiclip_XYPointBuckets__WEBPACK_IMPORTED_MODULE_26__.XYPointBuckets.create(polyface.data.point, 30);
|
|
243721
243910
|
const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create();
|
|
243722
243911
|
const edgeRange = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_27__.Range3d.createNull();
|
|
243723
|
-
const point0 =
|
|
243724
|
-
const point1 =
|
|
243725
|
-
const spacePoint =
|
|
243726
|
-
const segment =
|
|
243912
|
+
const point0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
243913
|
+
const point1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
243914
|
+
const spacePoint = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
243915
|
+
const segment = _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(point0, point1);
|
|
243727
243916
|
for (oldFacetVisitor.reset(); oldFacetVisitor.moveToNextFacet();) {
|
|
243728
243917
|
newFacetVisitor.clearArrays();
|
|
243729
243918
|
for (let i = 0; i + 1 < oldFacetVisitor.point.length; i++) {
|
|
@@ -243732,7 +243921,7 @@ class PolyfaceQuery {
|
|
|
243732
243921
|
oldFacetVisitor.point.getPoint3dAtUncheckedPointIndex(i + 1, point1);
|
|
243733
243922
|
newFacetVisitor.pushDataFrom(oldFacetVisitor, i);
|
|
243734
243923
|
edgeRange.setNull();
|
|
243735
|
-
|
|
243924
|
+
_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_11__.LineSegment3d.create(point0, point1, segment);
|
|
243736
243925
|
let detailArray;
|
|
243737
243926
|
edgeRange.extend(point0);
|
|
243738
243927
|
edgeRange.extend(point1);
|
|
@@ -243877,8 +244066,8 @@ class PolyfaceQuery {
|
|
|
243877
244066
|
const oldFacetVisitor = polyface.createVisitor(2); // This is to visit the existing facets.
|
|
243878
244067
|
const newFacetVisitor = polyface.createVisitor(0); // This is to build the new facets.
|
|
243879
244068
|
const builder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create();
|
|
243880
|
-
const vector01 =
|
|
243881
|
-
const vector12 =
|
|
244069
|
+
const vector01 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
|
|
244070
|
+
const vector12 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
|
|
243882
244071
|
const numPoint = polyface.data.point.length;
|
|
243883
244072
|
const pointState = new Int32Array(numPoint);
|
|
243884
244073
|
// FIRST PASS -- in each sector of each facet, determine if the sector has colinear incoming and outgoing vectors.
|
|
@@ -243925,7 +244114,7 @@ class PolyfaceQuery {
|
|
|
243925
244114
|
*/
|
|
243926
244115
|
static setEdgeVisibility(polyface, clusters, value) {
|
|
243927
244116
|
for (const cluster of clusters) {
|
|
243928
|
-
if (cluster instanceof
|
|
244117
|
+
if (cluster instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.SortableEdge) {
|
|
243929
244118
|
this.setSingleEdgeVisibility(polyface, cluster.facetIndex, cluster.vertexIndexA, value);
|
|
243930
244119
|
}
|
|
243931
244120
|
else if (Array.isArray(cluster)) {
|
|
@@ -243968,9 +244157,9 @@ class PolyfaceQuery {
|
|
|
243968
244157
|
* @param polyface a mesh, or a visitor assumed to have numWrap === 1
|
|
243969
244158
|
*/
|
|
243970
244159
|
static createIndexedEdges(polyface) {
|
|
243971
|
-
if (polyface instanceof
|
|
244160
|
+
if (polyface instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
|
|
243972
244161
|
return this.createIndexedEdges(polyface.createVisitor(1));
|
|
243973
|
-
const edges = new
|
|
244162
|
+
const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_10__.IndexedEdgeMatcher();
|
|
243974
244163
|
polyface.reset();
|
|
243975
244164
|
while (polyface.moveToNextFacet()) {
|
|
243976
244165
|
const numEdges = polyface.pointCount - 1;
|
|
@@ -243989,17 +244178,17 @@ class PolyfaceQuery {
|
|
|
243989
244178
|
* @param sharpEdges true to reverse the angle threshold test and return sharp edges; otherwise return smooth edges (default)
|
|
243990
244179
|
*/
|
|
243991
244180
|
static collectEdgesByDihedralAngle(mesh, maxSmoothEdgeAngle, sharpEdges = false) {
|
|
243992
|
-
if (mesh instanceof
|
|
244181
|
+
if (mesh instanceof _Polyface__WEBPACK_IMPORTED_MODULE_4__.Polyface)
|
|
243993
244182
|
return this.collectEdgesByDihedralAngle(mesh.createVisitor(1), maxSmoothEdgeAngle, sharpEdges);
|
|
243994
244183
|
mesh.setNumWrap(1);
|
|
243995
244184
|
const allEdges = this.createIndexedEdges(mesh);
|
|
243996
244185
|
const manifoldEdges = [];
|
|
243997
244186
|
allEdges.sortAndCollectClusters(manifoldEdges);
|
|
243998
244187
|
if (undefined === maxSmoothEdgeAngle || maxSmoothEdgeAngle.radians < 0)
|
|
243999
|
-
maxSmoothEdgeAngle =
|
|
244188
|
+
maxSmoothEdgeAngle = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createRadians(_Geometry__WEBPACK_IMPORTED_MODULE_6__.Geometry.smallAngleRadians);
|
|
244000
244189
|
const outEdges = [];
|
|
244001
|
-
const normal0 =
|
|
244002
|
-
const normal1 =
|
|
244190
|
+
const normal0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
|
|
244191
|
+
const normal1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
|
|
244003
244192
|
for (const pair of manifoldEdges) {
|
|
244004
244193
|
if (Array.isArray(pair) && pair.length === 2) {
|
|
244005
244194
|
const e0 = pair[0];
|
|
@@ -244038,8 +244227,8 @@ class PolyfaceQuery {
|
|
|
244038
244227
|
this.markAllEdgeVisibility(mesh, false);
|
|
244039
244228
|
this.setEdgeVisibility(mesh, boundaryEdges, true);
|
|
244040
244229
|
if (sharpEdgeAngle !== undefined) {
|
|
244041
|
-
const normal0 =
|
|
244042
|
-
const normal1 =
|
|
244230
|
+
const normal0 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
|
|
244231
|
+
const normal1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
|
|
244043
244232
|
for (const pair of pairedEdges) {
|
|
244044
244233
|
if (Array.isArray(pair) && pair.length === 2) {
|
|
244045
244234
|
const e0 = pair[0];
|
|
@@ -244061,9 +244250,9 @@ class PolyfaceQuery {
|
|
|
244061
244250
|
*/
|
|
244062
244251
|
static computeFacetUnitNormal(visitor, facetIndex, result) {
|
|
244063
244252
|
if (!result)
|
|
244064
|
-
result =
|
|
244253
|
+
result = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Vector3d.create();
|
|
244065
244254
|
if (visitor.moveToReadIndex(facetIndex)) {
|
|
244066
|
-
if (
|
|
244255
|
+
if (_geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_5__.PolygonOps.unitNormal(visitor.point, result))
|
|
244067
244256
|
return result;
|
|
244068
244257
|
}
|
|
244069
244258
|
return undefined;
|
|
@@ -244078,20 +244267,41 @@ class PolyfaceQuery {
|
|
|
244078
244267
|
for (let i = 0; i < data.edgeVisible.length; i++)
|
|
244079
244268
|
data.edgeVisible[i] = value;
|
|
244080
244269
|
}
|
|
244270
|
+
/**
|
|
244271
|
+
* Create a HalfEdgeGraph with a face for each facet of the IndexedPolyface
|
|
244272
|
+
* @param mesh mesh to convert
|
|
244273
|
+
* @internal
|
|
244274
|
+
*/
|
|
244275
|
+
static convertToHalfEdgeGraph(mesh) {
|
|
244276
|
+
const builder = new _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_28__.HalfEdgeGraphFromIndexedLoopsContext();
|
|
244277
|
+
const visitor = mesh.createVisitor(0);
|
|
244278
|
+
for (visitor.reset(); visitor.moveToNextFacet();) {
|
|
244279
|
+
builder.insertLoop(visitor.pointIndex);
|
|
244280
|
+
}
|
|
244281
|
+
const graph = builder.graph;
|
|
244282
|
+
const xyz = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_7__.Point3d.create();
|
|
244283
|
+
graph.announceNodes((_graph, halfEdge) => {
|
|
244284
|
+
const vertexIndex = halfEdge.i;
|
|
244285
|
+
mesh.data.getPoint(vertexIndex, xyz);
|
|
244286
|
+
halfEdge.setXYZ(xyz);
|
|
244287
|
+
return true;
|
|
244288
|
+
});
|
|
244289
|
+
return graph;
|
|
244290
|
+
}
|
|
244081
244291
|
/**
|
|
244082
244292
|
* * Examine adjacent facet orientations throughout the mesh
|
|
244083
244293
|
* * If possible, reverse a subset to achieve proper pairing.
|
|
244084
244294
|
* @param mesh
|
|
244085
244295
|
*/
|
|
244086
244296
|
static reorientVertexOrderAroundFacetsForConsistentOrientation(mesh) {
|
|
244087
|
-
return
|
|
244297
|
+
return _FacetOrientation__WEBPACK_IMPORTED_MODULE_29__.FacetOrientationFixup.doFixup(mesh);
|
|
244088
244298
|
}
|
|
244089
244299
|
/**
|
|
244090
244300
|
* Set up indexed normals with one normal in the plane of each facet of the mesh.
|
|
244091
244301
|
* @param polyface
|
|
244092
244302
|
*/
|
|
244093
244303
|
static buildPerFaceNormals(polyface) {
|
|
244094
|
-
|
|
244304
|
+
_multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_30__.BuildAverageNormalsContext.buildPerFaceNormals(polyface);
|
|
244095
244305
|
}
|
|
244096
244306
|
/**
|
|
244097
244307
|
* * At each vertex of the mesh
|
|
@@ -244103,8 +244313,21 @@ class PolyfaceQuery {
|
|
|
244103
244313
|
* @param polyface polyface to update.
|
|
244104
244314
|
* @param toleranceAngle averaging is done between normals up to this angle.
|
|
244105
244315
|
*/
|
|
244106
|
-
static buildAverageNormals(polyface, toleranceAngle =
|
|
244107
|
-
|
|
244316
|
+
static buildAverageNormals(polyface, toleranceAngle = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(31.0)) {
|
|
244317
|
+
_multiclip_BuildAverageNormalsContext__WEBPACK_IMPORTED_MODULE_30__.BuildAverageNormalsContext.buildFastAverageNormals(polyface, toleranceAngle);
|
|
244318
|
+
}
|
|
244319
|
+
/**
|
|
244320
|
+
* Offset the faces of the mesh.
|
|
244321
|
+
* @param source original mesh
|
|
244322
|
+
* @param signedOffsetDistance distance to offset
|
|
244323
|
+
* @param offsetOptions angle options. The default options are recommended.
|
|
244324
|
+
* @returns shifted mesh.
|
|
244325
|
+
*/
|
|
244326
|
+
static cloneOffset(source, signedOffsetDistance, offsetOptions = OffsetMeshOptions.create()) {
|
|
244327
|
+
const strokeOptions = _curve_StrokeOptions__WEBPACK_IMPORTED_MODULE_23__.StrokeOptions.createForFacets();
|
|
244328
|
+
const offsetBuilder = _PolyfaceBuilder__WEBPACK_IMPORTED_MODULE_16__.PolyfaceBuilder.create(strokeOptions);
|
|
244329
|
+
_multiclip_OffsetMeshContext__WEBPACK_IMPORTED_MODULE_31__.OffsetMeshContext.buildOffsetMeshWithEdgeChamfers(source, offsetBuilder, signedOffsetDistance, offsetOptions);
|
|
244330
|
+
return offsetBuilder.claimPolyface();
|
|
244108
244331
|
}
|
|
244109
244332
|
}
|
|
244110
244333
|
// amount of computation to do per step of async methods.
|
|
@@ -245016,6 +245239,1064 @@ class LinearSearchRange2dArray {
|
|
|
245016
245239
|
}
|
|
245017
245240
|
|
|
245018
245241
|
|
|
245242
|
+
/***/ }),
|
|
245243
|
+
|
|
245244
|
+
/***/ "../../core/geometry/lib/esm/polyface/multiclip/OffsetMeshContext.js":
|
|
245245
|
+
/*!***************************************************************************!*\
|
|
245246
|
+
!*** ../../core/geometry/lib/esm/polyface/multiclip/OffsetMeshContext.js ***!
|
|
245247
|
+
\***************************************************************************/
|
|
245248
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
245249
|
+
|
|
245250
|
+
"use strict";
|
|
245251
|
+
__webpack_require__.r(__webpack_exports__);
|
|
245252
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
245253
|
+
/* harmony export */ "FacetOffsetProperties": () => (/* binding */ FacetOffsetProperties),
|
|
245254
|
+
/* harmony export */ "OffsetMeshContext": () => (/* binding */ OffsetMeshContext),
|
|
245255
|
+
/* harmony export */ "SectorOffsetProperties": () => (/* binding */ SectorOffsetProperties)
|
|
245256
|
+
/* harmony export */ });
|
|
245257
|
+
/* harmony import */ var _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../numerics/Polynomials */ "../../core/geometry/lib/esm/numerics/Polynomials.js");
|
|
245258
|
+
/* harmony import */ var _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../geometry3d/GrowableXYZArray */ "../../core/geometry/lib/esm/geometry3d/GrowableXYZArray.js");
|
|
245259
|
+
/* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
|
|
245260
|
+
/* harmony import */ var _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../geometry3d/PolygonOps */ "../../core/geometry/lib/esm/geometry3d/PolygonOps.js");
|
|
245261
|
+
/* harmony import */ var _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../geometry3d/Ray3d */ "../../core/geometry/lib/esm/geometry3d/Ray3d.js");
|
|
245262
|
+
/* harmony import */ var _topology_Graph__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../topology/Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
|
|
245263
|
+
/* harmony import */ var _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../topology/HalfEdgeGraphFromIndexedLoopsContext */ "../../core/geometry/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js");
|
|
245264
|
+
/* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
|
|
245265
|
+
/* harmony import */ var _geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../geometry3d/PolylineCompressionByEdgeOffset */ "../../core/geometry/lib/esm/geometry3d/PolylineCompressionByEdgeOffset.js");
|
|
245266
|
+
/* harmony import */ var _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../geometry3d/Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
|
|
245267
|
+
/*---------------------------------------------------------------------------------------------
|
|
245268
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
245269
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
245270
|
+
*--------------------------------------------------------------------------------------------*/
|
|
245271
|
+
/** @packageDocumentation
|
|
245272
|
+
* @module Polyface
|
|
245273
|
+
*/
|
|
245274
|
+
|
|
245275
|
+
|
|
245276
|
+
|
|
245277
|
+
|
|
245278
|
+
|
|
245279
|
+
|
|
245280
|
+
|
|
245281
|
+
|
|
245282
|
+
|
|
245283
|
+
|
|
245284
|
+
function isDefinedAndTrue(value) {
|
|
245285
|
+
if (value === undefined)
|
|
245286
|
+
return false;
|
|
245287
|
+
return value;
|
|
245288
|
+
}
|
|
245289
|
+
class AverageNormalData {
|
|
245290
|
+
constructor() {
|
|
245291
|
+
this.numActiveSectors = 0;
|
|
245292
|
+
this.numInactiveSectors = 0; // exterior and sling.
|
|
245293
|
+
this.averageNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create();
|
|
245294
|
+
this.radiansSum = 0.0;
|
|
245295
|
+
this.maxDeviationRadiansFromAverage = 0.0;
|
|
245296
|
+
}
|
|
245297
|
+
clear() {
|
|
245298
|
+
this.numActiveSectors = 0;
|
|
245299
|
+
this.numInactiveSectors = 0; // exterior and sling.
|
|
245300
|
+
this.averageNormal.setZero();
|
|
245301
|
+
this.radiansSum = 0.0;
|
|
245302
|
+
this.maxDeviationRadiansFromAverage = 0.0;
|
|
245303
|
+
}
|
|
245304
|
+
/** Add a normal to the evolving sum, scaled by radians in the corner */
|
|
245305
|
+
accumulateNormal(node, normal, inactiveMask) {
|
|
245306
|
+
if (node.isMaskSet(inactiveMask)) {
|
|
245307
|
+
this.numInactiveSectors++;
|
|
245308
|
+
}
|
|
245309
|
+
else {
|
|
245310
|
+
const sectorSweepRadians = _topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.sectorSweepRadiansXYZ(node, normal);
|
|
245311
|
+
this.averageNormal.addScaledInPlace(normal, sectorSweepRadians);
|
|
245312
|
+
this.radiansSum += sectorSweepRadians;
|
|
245313
|
+
this.numActiveSectors++;
|
|
245314
|
+
}
|
|
245315
|
+
}
|
|
245316
|
+
/** normalize the accumulated normals. */
|
|
245317
|
+
finishNormalAveraging() {
|
|
245318
|
+
if (this.numActiveSectors > 0 && this.averageNormal.normalizeInPlace()) {
|
|
245319
|
+
return true;
|
|
245320
|
+
}
|
|
245321
|
+
return false;
|
|
245322
|
+
}
|
|
245323
|
+
/** Compute the deviation from average. update max deviation member */
|
|
245324
|
+
recordDeviation(normal, isActive) {
|
|
245325
|
+
if (isActive) {
|
|
245326
|
+
const radians = this.averageNormal.radiansTo(normal);
|
|
245327
|
+
this.maxDeviationRadiansFromAverage = Math.max(Math.abs(this.maxDeviationRadiansFromAverage), radians);
|
|
245328
|
+
}
|
|
245329
|
+
else {
|
|
245330
|
+
}
|
|
245331
|
+
}
|
|
245332
|
+
/** Return the max deviation as computed on prior calls to recordDeviation */
|
|
245333
|
+
get maxDeviationRadians() { return this.maxDeviationRadiansFromAverage; }
|
|
245334
|
+
}
|
|
245335
|
+
function emitSector(sector) {
|
|
245336
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined) {
|
|
245337
|
+
OffsetMeshContext.stringDebugFunction(` Sector xyz ${sector.xyz.x},${sector.xyz.y},${sector.xyz.z} `);
|
|
245338
|
+
OffsetMeshContext.stringDebugFunction(` normal ${sector.normal.x},${sector.normal.y},${sector.normal.z} `);
|
|
245339
|
+
}
|
|
245340
|
+
}
|
|
245341
|
+
// facet properties used during offset.
|
|
245342
|
+
//
|
|
245343
|
+
class FacetOffsetProperties {
|
|
245344
|
+
constructor(facetIndex, normal) {
|
|
245345
|
+
this.facetIndex = facetIndex;
|
|
245346
|
+
this.facetNormal = normal;
|
|
245347
|
+
}
|
|
245348
|
+
}
|
|
245349
|
+
/**
|
|
245350
|
+
* Sector properties during offset.
|
|
245351
|
+
* * this.normal may be initially assigned as the facet normal but can mutate by
|
|
245352
|
+
* averaging with neighbors.
|
|
245353
|
+
* * this.xyz is initially the base mesh xyz but is expected to move along the normal.
|
|
245354
|
+
* * this.count is used locally in computations.
|
|
245355
|
+
*/
|
|
245356
|
+
class SectorOffsetProperties {
|
|
245357
|
+
constructor(normal, xyz) {
|
|
245358
|
+
this.xyz = xyz;
|
|
245359
|
+
this.normal = normal;
|
|
245360
|
+
this.count = 0;
|
|
245361
|
+
}
|
|
245362
|
+
/**
|
|
245363
|
+
* Compute the angle between plane normals on opposite sides of the edge.
|
|
245364
|
+
* * parallel normals have zero angle.
|
|
245365
|
+
* * if the edge cuts inward to the volume behind the faces, the angle is negative.
|
|
245366
|
+
* * if the edge is outward (a convex edge) the the volume, the angle is positive.
|
|
245367
|
+
* @param edgeNodeA node on one side of the edge
|
|
245368
|
+
* @param edgeVector pre-allocated vector to receive vector along edge.
|
|
245369
|
+
* @param averageNormal pre-allocated vector to receive the average normal for a chamfer of the offset edge.
|
|
245370
|
+
* @param offsetDistance distance of offset being constructed. The sign of this resolves angle ambiguity.
|
|
245371
|
+
* @param radiansTolerance tolerance for large angle between normals.
|
|
245372
|
+
* @returns true if this edge has SectorOffsetProperties on both sides and the angle between normals angle exceeds radiansTolerance.
|
|
245373
|
+
*/
|
|
245374
|
+
static edgeHasLargeExteriorAngleBetweenNormals(edgeNodeA, edgeVector, averageNormal, offsetDistance, radiansTolerance = Math.PI * 0.5) {
|
|
245375
|
+
const propsA = edgeNodeA.edgeTag;
|
|
245376
|
+
const edgeNodeB = edgeNodeA.edgeMate;
|
|
245377
|
+
const propsB = edgeNodeB.edgeTag;
|
|
245378
|
+
if (propsA !== undefined && propsB !== undefined) {
|
|
245379
|
+
edgeNodeA.vectorToFaceSuccessor(edgeVector);
|
|
245380
|
+
const radians = propsA.normal.signedRadiansTo(propsB.normal, edgeVector);
|
|
245381
|
+
if (_Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.split3WaySign(offsetDistance, -1, 1, 1) * radians >= radiansTolerance) {
|
|
245382
|
+
_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.createAdd2Scaled(propsA.normal, 1.0, propsB.normal, 1.0, averageNormal);
|
|
245383
|
+
if (averageNormal.normalizeInPlace())
|
|
245384
|
+
return true;
|
|
245385
|
+
}
|
|
245386
|
+
}
|
|
245387
|
+
return false;
|
|
245388
|
+
}
|
|
245389
|
+
static almostEqualNormals(sectorA, sectorB, radiansTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallAngleRadians) {
|
|
245390
|
+
return sectorA.normal.radiansTo(sectorB.normal) <= radiansTolerance;
|
|
245391
|
+
}
|
|
245392
|
+
static radiansBetweenNormals(sectorA, sectorB) {
|
|
245393
|
+
return sectorA.normal.radiansTo(sectorB.normal);
|
|
245394
|
+
}
|
|
245395
|
+
// Set the offset point this.xyz as sum of the nodeXyz + distance * this.normal
|
|
245396
|
+
setOffsetPointAtDistanceAtHalfEdge(halfEdge, distance) {
|
|
245397
|
+
halfEdge.getPoint3d(this.xyz);
|
|
245398
|
+
this.xyz.addScaledInPlace(this.normal, distance);
|
|
245399
|
+
}
|
|
245400
|
+
// Copy xyz from parameter into (preexisting object) xyz
|
|
245401
|
+
static setXYZAtHalfEdge(halfEdge, xyz) {
|
|
245402
|
+
const props = halfEdge.edgeTag;
|
|
245403
|
+
if (props !== undefined && xyz !== undefined)
|
|
245404
|
+
props.xyz.set(xyz.x, xyz.y, xyz.z);
|
|
245405
|
+
}
|
|
245406
|
+
// Set the offset point this.xyz directly
|
|
245407
|
+
setXYAndZ(xyz) {
|
|
245408
|
+
this.xyz.set(xyz.x, xyz.y, xyz.z);
|
|
245409
|
+
}
|
|
245410
|
+
// Look through the half edge to its properties. Set the normal there. Optionally set xyz from node xyz and offset distance
|
|
245411
|
+
static setNormalAtHalfEdge(halfEdge, uvw, distance) {
|
|
245412
|
+
const props = halfEdge.edgeTag;
|
|
245413
|
+
if (props !== undefined) {
|
|
245414
|
+
props.normal.set(uvw.x, uvw.y, uvw.z);
|
|
245415
|
+
if (distance !== undefined)
|
|
245416
|
+
props.setOffsetPointAtDistanceAtHalfEdge(halfEdge, distance);
|
|
245417
|
+
}
|
|
245418
|
+
}
|
|
245419
|
+
// Look through the half edge and its vertex successor to properties. Get the two normals. Return the angle sweeping from one to the next
|
|
245420
|
+
static sweepRadiansAroundNormal(nodeA, upVector) {
|
|
245421
|
+
const propsA = nodeA.edgeTag;
|
|
245422
|
+
const propsB = nodeA.vertexSuccessor.edgeTag;
|
|
245423
|
+
if (propsA !== undefined && propsB !== undefined) {
|
|
245424
|
+
return propsA.normal.planarRadiansTo(propsB.normal, upVector);
|
|
245425
|
+
}
|
|
245426
|
+
return undefined;
|
|
245427
|
+
}
|
|
245428
|
+
// Look through the half edge to its properties. return (if possible) the coordinates
|
|
245429
|
+
static getSectorPointAtHalfEdge(halfEdge, xyz, xyzArray) {
|
|
245430
|
+
const props = halfEdge.edgeTag;
|
|
245431
|
+
if (props !== undefined) {
|
|
245432
|
+
if (xyz !== undefined)
|
|
245433
|
+
xyz.setFromPoint3d(props.xyz);
|
|
245434
|
+
if (xyzArray !== undefined)
|
|
245435
|
+
xyzArray.push(props.xyz);
|
|
245436
|
+
return true;
|
|
245437
|
+
}
|
|
245438
|
+
return false;
|
|
245439
|
+
}
|
|
245440
|
+
// access the XYZ and push to the array (which makes copies, not reference)
|
|
245441
|
+
// return pointer to the SectorOffsetProperties
|
|
245442
|
+
static pushXYZ(xyzArray, halfEdge) {
|
|
245443
|
+
const sector = halfEdge.edgeTag;
|
|
245444
|
+
if (sector !== undefined)
|
|
245445
|
+
xyzArray.push(sector.xyz);
|
|
245446
|
+
return sector;
|
|
245447
|
+
}
|
|
245448
|
+
// Dereference to execute: accumulatingVector += halfEdge.edgeTag.normal * scale
|
|
245449
|
+
static accumulateScaledNormalAtHalfEdge(halfEdge, scale, accumulatingVector) {
|
|
245450
|
+
const sector = halfEdge.edgeTag;
|
|
245451
|
+
if (sector !== undefined)
|
|
245452
|
+
accumulatingVector.addScaledInPlace(sector.normal, scale);
|
|
245453
|
+
}
|
|
245454
|
+
}
|
|
245455
|
+
/*
|
|
245456
|
+
About Chamfer Edges ..... as constructed in addChamferTopologyToAllEdges
|
|
245457
|
+
|
|
245458
|
+
When edge vertex X to vertex Y has a sharp angle between normals, a "chamfer face" must be created to "fatten" it.
|
|
245459
|
+
|
|
245460
|
+
The original half edges (nodes) for the edge are AX and AY. These are "mates" in the halfEdge mental model. As always,
|
|
245461
|
+
AX is (as needed)
|
|
245462
|
+
(i) the preferred half edge for the left side of the edge moving from X to Y. (i.e. above the edge)
|
|
245463
|
+
(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
|
|
245464
|
+
(iii) a part of the vertex loop around X
|
|
245465
|
+
Likewise, AY is (as needed)
|
|
245466
|
+
(i) the preferred half edge for the left side of the edge moving from Y to X (i.e. below the edge)
|
|
245467
|
+
(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.
|
|
245468
|
+
(iii) a part of the vertex loop around Y
|
|
245469
|
+
|
|
245470
|
+
AX------>
|
|
245471
|
+
X______________________________________________________________________Y
|
|
245472
|
+
<---AY
|
|
245473
|
+
|
|
245474
|
+
When the chamfer face is created, it needs to have a sliver face "inside the edge" -- something in the space here
|
|
245475
|
+
|
|
245476
|
+
AX------>
|
|
245477
|
+
_____________________________________________________________________
|
|
245478
|
+
/ \
|
|
245479
|
+
X Y
|
|
245480
|
+
\_____________________________________________________________________/
|
|
245481
|
+
<---AY
|
|
245482
|
+
|
|
245483
|
+
The chamfer face will have a plane normal is the average of the two faces' plane normals.
|
|
245484
|
+
|
|
245485
|
+
The creation sequence for the chamfer face puts a slit "inside the edge" as above HalfEdges AX and AY remain as parts
|
|
245486
|
+
of their respective face loops. In addition, at each end a singleton edge "sling" face is inserted at each
|
|
245487
|
+
end of the sliver face.
|
|
245488
|
+
|
|
245489
|
+
The sequence is:
|
|
245490
|
+
|
|
245491
|
+
STEP 1: splitEdgeCreateSliver creates the sliver face with 2 half edges DX and DY
|
|
245492
|
+
STEP 2: splitEdge (with undefined as the "prior" edge) creates a sling with HalfEdge CX "inside" and BX "outside".
|
|
245493
|
+
(The sling face is not yet attached to X -- briefly floating in space)
|
|
245494
|
+
STEP 3: pinch of HalfEdges BX and DX inserts the sling face "inside" the slit face at the X end.
|
|
245495
|
+
|
|
245496
|
+
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.
|
|
245497
|
+
|
|
245498
|
+
AX------>
|
|
245499
|
+
_______________________________________________________________
|
|
245500
|
+
/ <---DY \
|
|
245501
|
+
/ \
|
|
245502
|
+
/ BX---> \
|
|
245503
|
+
/ _______________ _______________ \
|
|
245504
|
+
| / \ / <----CY \ |
|
|
245505
|
+
|/ \ / \|
|
|
245506
|
+
X | | Y
|
|
245507
|
+
|\ CX---> / \ /|
|
|
245508
|
+
| \_______________/ \_______________/ |
|
|
245509
|
+
\ <---BY /
|
|
245510
|
+
\ /
|
|
245511
|
+
\ DX---> /
|
|
245512
|
+
\ ______________________________________________________________/
|
|
245513
|
+
<---AY
|
|
245514
|
+
|
|
245515
|
+
During the construction, the letters ABCD are used as above, but with prefixes emphasizing their role
|
|
245516
|
+
outsideAX, outsideAY
|
|
245517
|
+
slingB, slingC, sliverD
|
|
245518
|
+
|
|
245519
|
+
The "inside" sling faces (CX and CY) each have their own FacetOffsetProperties and SectorOffsetProperties.
|
|
245520
|
+
The sliver face has its own FacetOffsetProperties which are referenced by DX, BY, DY, BX.
|
|
245521
|
+
Each of those 4 has its own SectorOffSetProperties.
|
|
245522
|
+
|
|
245523
|
+
Important properties during offset construction:
|
|
245524
|
+
1) the original graph always has original topology and coordinates
|
|
245525
|
+
2) Each face of the original graph has a FacetOffsetProperties with a representative point and a normal. These are unchanged during the computation.
|
|
245526
|
+
3) Each node has its own SectorOffsetProperties with a coordinate and normal independent of the parent node.
|
|
245527
|
+
3.1 The first offset coordinates in each node are directly offset by face normal.
|
|
245528
|
+
3.2 This creates mismatch across edges and around vertices.
|
|
245529
|
+
3.3 Various sweeps "around each vertex" try to do intersections among appropriate offset planes to find
|
|
245530
|
+
common coordinates in place of the initial mismatches.
|
|
245531
|
+
4) The independence of all the sectors allows the offset construction to fix things up in any order it chooses.
|
|
245532
|
+
5) During the construction, the xyz in SectorOffsetProperties around a single vertex do NOT have to match.
|
|
245533
|
+
6) At output time, there are three sweeps:
|
|
245534
|
+
6.1: By face: Go around the face and output a facet with the coordinates in the various sectors.
|
|
245535
|
+
6.2: By edge: For each edge, if the sector xyz match across both ends output nothing. If not, output a triangle or quad
|
|
245536
|
+
6.3: By vertex: At each vertex, if all vertex coordinates match output nothing. Otherwise output a facet with all the coordinates.
|
|
245537
|
+
*/
|
|
245538
|
+
class OffsetMeshContext {
|
|
245539
|
+
constructor(basePolyface, baseGraph, options) {
|
|
245540
|
+
this._basePolyface = basePolyface;
|
|
245541
|
+
this._baseGraph = baseGraph;
|
|
245542
|
+
this._breakMaskA = baseGraph.grabMask();
|
|
245543
|
+
this._breakMaskB = baseGraph.grabMask();
|
|
245544
|
+
this._insideOfChamferFace = baseGraph.grabMask();
|
|
245545
|
+
this._outsideOfChamferFace = baseGraph.grabMask();
|
|
245546
|
+
this._insideChamferSling = baseGraph.grabMask();
|
|
245547
|
+
this._outsideEndOfChamferFace = baseGraph.grabMask();
|
|
245548
|
+
this._exteriorMask = _topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdgeMask.EXTERIOR;
|
|
245549
|
+
this._offsetCoordinatesReassigned = baseGraph.grabMask();
|
|
245550
|
+
this._smoothRadiansBetweenNormals = options.smoothSingleAngleBetweenNormals.radians;
|
|
245551
|
+
this._chamferTurnRadians = options.chamferAngleBetweenNormals.radians;
|
|
245552
|
+
this._smoothAccumulatedRadiansBetweenNormals = options.smoothAccumulatedAngleBetweenNormals.radians;
|
|
245553
|
+
}
|
|
245554
|
+
/** "Exterior" side of a bare edge of the mesh */
|
|
245555
|
+
get exteriorMask() { return this._exteriorMask; }
|
|
245556
|
+
/** "First" sector of a smooth sequence. */
|
|
245557
|
+
get breakMaskA() { return this._breakMaskA; }
|
|
245558
|
+
/** "Last" sector of a smooth sequence. */
|
|
245559
|
+
get breakMaskB() { return this._breakMaskB; }
|
|
245560
|
+
/** This edge is on a chamfered face, and along the original edge */
|
|
245561
|
+
get insideOfChamferFace() { return this._insideOfChamferFace; }
|
|
245562
|
+
/** This is the original edge of a chamfer face */
|
|
245563
|
+
get outsideOfChamferFace() { return this._outsideOfChamferFace; }
|
|
245564
|
+
/** This edge is on a chamfered face, and at the end -- other side may be a sling */
|
|
245565
|
+
get insideChamferSling() { return this._insideChamferSling; }
|
|
245566
|
+
/** This is the outside of the end of a chamfer face -- i.e. the inside of a new face-at-vertex */
|
|
245567
|
+
get outsideEndOfChamferFace() { return this._outsideEndOfChamferFace; }
|
|
245568
|
+
// At each node . .
|
|
245569
|
+
// * Find the sector data
|
|
245570
|
+
// * recompute the sector point using node XYZ and sectorData normal.
|
|
245571
|
+
applyFaceNormalOffsetsToSectorData(distance) {
|
|
245572
|
+
this._baseGraph.announceNodes((_graph, node) => {
|
|
245573
|
+
const sectorData = node.edgeTag;
|
|
245574
|
+
if (sectorData !== undefined) {
|
|
245575
|
+
sectorData.setOffsetPointAtDistanceAtHalfEdge(node, distance);
|
|
245576
|
+
}
|
|
245577
|
+
return true;
|
|
245578
|
+
});
|
|
245579
|
+
}
|
|
245580
|
+
/**
|
|
245581
|
+
* * build a mesh offset by given distance.
|
|
245582
|
+
* * output the mesh to the given builder.
|
|
245583
|
+
* @param basePolyface original mesh
|
|
245584
|
+
* @param builder polyface builder to receive the new mesh.
|
|
245585
|
+
* @param distance signed offset distance.
|
|
245586
|
+
*/
|
|
245587
|
+
static buildOffsetMeshWithEdgeChamfers(basePolyface, builder, distance, options) {
|
|
245588
|
+
const baseGraph = this.buildBaseGraph(basePolyface);
|
|
245589
|
+
if (baseGraph !== undefined) {
|
|
245590
|
+
const offsetBuilder = new OffsetMeshContext(basePolyface, baseGraph, options);
|
|
245591
|
+
offsetBuilder.applyFaceNormalOffsetsToSectorData(distance);
|
|
245592
|
+
if (OffsetMeshContext.graphDebugFunction !== undefined)
|
|
245593
|
+
OffsetMeshContext.graphDebugFunction("BaseGraph", baseGraph, offsetBuilder._breakMaskA, offsetBuilder._breakMaskB);
|
|
245594
|
+
const outputSelector = options.outputSelector ? options.outputSelector : {
|
|
245595
|
+
outputOffsetsFromFaces: true,
|
|
245596
|
+
outputOffsetsFromEdges: true,
|
|
245597
|
+
outputOffsetsFromVertices: true,
|
|
245598
|
+
};
|
|
245599
|
+
if (isDefinedAndTrue(outputSelector.outputOffsetsFromFacesBeforeChamfers))
|
|
245600
|
+
offsetBuilder.announceFacetsWithSectorCoordinatesAroundFaces(builder);
|
|
245601
|
+
offsetBuilder.addChamferTopologyToAllEdges(options, distance);
|
|
245602
|
+
offsetBuilder.computeOffsetFacetIntersections(distance);
|
|
245603
|
+
if (OffsetMeshContext.graphDebugFunction !== undefined)
|
|
245604
|
+
OffsetMeshContext.graphDebugFunction("after computeEdgeChamfers", baseGraph, offsetBuilder._breakMaskA, offsetBuilder._breakMaskB);
|
|
245605
|
+
if (isDefinedAndTrue(outputSelector.outputOffsetsFromFaces))
|
|
245606
|
+
offsetBuilder.announceFacetsWithSectorCoordinatesAroundFaces(builder);
|
|
245607
|
+
if (isDefinedAndTrue(outputSelector.outputOffsetsFromEdges))
|
|
245608
|
+
offsetBuilder.announceFacetsWithSectorCoordinatesAroundEdges(builder);
|
|
245609
|
+
if (isDefinedAndTrue(outputSelector.outputOffsetsFromVertices))
|
|
245610
|
+
offsetBuilder.announceFacetsWithSectorCoordinatesAroundVertices(builder);
|
|
245611
|
+
}
|
|
245612
|
+
}
|
|
245613
|
+
/**
|
|
245614
|
+
* For each face of the graph, shift vertices by offsetDistance and emit to the builder as a facet
|
|
245615
|
+
* @param polyfaceBuilder
|
|
245616
|
+
*/
|
|
245617
|
+
announceSimpleOffsetFromFaces(polyfaceBuilder, offsetDistance) {
|
|
245618
|
+
const xyzLoop = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__.GrowableXYZArray();
|
|
245619
|
+
const xyz = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create(); // reused at each point around each facet.
|
|
245620
|
+
const uvw = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create(); // reused once per facet
|
|
245621
|
+
const announceNodeAroundFace = (node) => {
|
|
245622
|
+
node.getPoint3d(xyz);
|
|
245623
|
+
xyz.addInPlace(uvw);
|
|
245624
|
+
xyzLoop.push(xyz);
|
|
245625
|
+
return 0;
|
|
245626
|
+
};
|
|
245627
|
+
this._baseGraph.announceFaceLoops((_graph, seed) => {
|
|
245628
|
+
if (!seed.isMaskSet(_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdgeMask.EXTERIOR)) {
|
|
245629
|
+
const facetProperties = seed.faceTag;
|
|
245630
|
+
uvw.setFromVector3d(facetProperties.facetNormal.direction);
|
|
245631
|
+
uvw.scaleInPlace(offsetDistance);
|
|
245632
|
+
xyzLoop.length = 0;
|
|
245633
|
+
seed.sumAroundFace(announceNodeAroundFace);
|
|
245634
|
+
polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);
|
|
245635
|
+
}
|
|
245636
|
+
return true;
|
|
245637
|
+
});
|
|
245638
|
+
}
|
|
245639
|
+
/**
|
|
245640
|
+
* For each face of the graph, output the xyz of the sector data
|
|
245641
|
+
* @param polyfaceBuilder
|
|
245642
|
+
*/
|
|
245643
|
+
announceFacetsWithSectorCoordinatesAroundFaces(polyfaceBuilder) {
|
|
245644
|
+
const xyzLoop = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__.GrowableXYZArray();
|
|
245645
|
+
// For face loop visits .. get the point from the sector data.
|
|
245646
|
+
const announceNodeAroundFace = (node) => {
|
|
245647
|
+
const sectorData = node.edgeTag;
|
|
245648
|
+
if (sectorData !== undefined) {
|
|
245649
|
+
xyzLoop.push(sectorData.xyz);
|
|
245650
|
+
}
|
|
245651
|
+
return 0;
|
|
245652
|
+
};
|
|
245653
|
+
this._baseGraph.announceFaceLoops((_graph, seed) => {
|
|
245654
|
+
if (!seed.isMaskSet(_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdgeMask.EXTERIOR)) {
|
|
245655
|
+
xyzLoop.length = 0;
|
|
245656
|
+
seed.sumAroundFace(announceNodeAroundFace);
|
|
245657
|
+
if (xyzLoop.length > 2)
|
|
245658
|
+
polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);
|
|
245659
|
+
}
|
|
245660
|
+
return true;
|
|
245661
|
+
});
|
|
245662
|
+
}
|
|
245663
|
+
countBits(mask) {
|
|
245664
|
+
let n = 0;
|
|
245665
|
+
let mask1 = mask;
|
|
245666
|
+
while (mask1 !== 0) {
|
|
245667
|
+
if (mask1 & 0x01)
|
|
245668
|
+
n++;
|
|
245669
|
+
mask1 = mask1 >> 1;
|
|
245670
|
+
}
|
|
245671
|
+
return n;
|
|
245672
|
+
}
|
|
245673
|
+
/**
|
|
245674
|
+
* For each edge of the graph . .
|
|
245675
|
+
* * Collect coordinates in 4 sectors going around the edge
|
|
245676
|
+
* * Compress with tight tolerance so adjacent sectors with clean point match reduce to a single point.
|
|
245677
|
+
* * Emit as a facet.
|
|
245678
|
+
* @param polyfaceBuilder
|
|
245679
|
+
*/
|
|
245680
|
+
announceFacetsWithSectorCoordinatesAroundEdges(polyfaceBuilder) {
|
|
245681
|
+
const xyzLoop = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__.GrowableXYZArray();
|
|
245682
|
+
const primaryCompressionTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallMetricDistance;
|
|
245683
|
+
const allMasksForEdgesToIgnore = this._exteriorMask
|
|
245684
|
+
| this._outsideEndOfChamferFace
|
|
245685
|
+
| this._outsideOfChamferFace
|
|
245686
|
+
| this._insideOfChamferFace
|
|
245687
|
+
| this._insideChamferSling;
|
|
245688
|
+
this._baseGraph.announceEdges((_graph, nodeA) => {
|
|
245689
|
+
// This starts by looking for EXTERIOR on both sides ...
|
|
245690
|
+
if (nodeA.findMaskAroundEdge(this._exteriorMask) !== undefined) {
|
|
245691
|
+
return true;
|
|
245692
|
+
}
|
|
245693
|
+
else if (!nodeA.isMaskSet(allMasksForEdgesToIgnore)) { // By design, we believe that these two test for allMasksForEdgesToIgnore condition would catch the EXTERIOR case above
|
|
245694
|
+
const nodeB = nodeA.faceSuccessor;
|
|
245695
|
+
const nodeC = nodeA.edgeMate;
|
|
245696
|
+
if (!nodeC.isMaskSet(allMasksForEdgesToIgnore)) {
|
|
245697
|
+
const nodeD = nodeC.faceSuccessor;
|
|
245698
|
+
xyzLoop.clear();
|
|
245699
|
+
SectorOffsetProperties.getSectorPointAtHalfEdge(nodeA, undefined, xyzLoop);
|
|
245700
|
+
SectorOffsetProperties.getSectorPointAtHalfEdge(nodeB, undefined, xyzLoop);
|
|
245701
|
+
SectorOffsetProperties.getSectorPointAtHalfEdge(nodeC, undefined, xyzLoop);
|
|
245702
|
+
SectorOffsetProperties.getSectorPointAtHalfEdge(nodeD, undefined, xyzLoop);
|
|
245703
|
+
_geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_4__.PolylineCompressionContext.compressInPlaceByShortEdgeLength(xyzLoop, primaryCompressionTolerance);
|
|
245704
|
+
if (xyzLoop.length > 2) {
|
|
245705
|
+
polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);
|
|
245706
|
+
}
|
|
245707
|
+
}
|
|
245708
|
+
}
|
|
245709
|
+
else {
|
|
245710
|
+
return true;
|
|
245711
|
+
}
|
|
245712
|
+
return true;
|
|
245713
|
+
});
|
|
245714
|
+
}
|
|
245715
|
+
getCoordinateString(node, showXYZ = true, showFaceSuccessorXYZ = false) {
|
|
245716
|
+
if (showXYZ) {
|
|
245717
|
+
if (showFaceSuccessorXYZ) {
|
|
245718
|
+
return `${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(node)} ==> ${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(node.faceSuccessor)}`;
|
|
245719
|
+
}
|
|
245720
|
+
else {
|
|
245721
|
+
return `${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(node)}`;
|
|
245722
|
+
}
|
|
245723
|
+
}
|
|
245724
|
+
else {
|
|
245725
|
+
if (showFaceSuccessorXYZ) {
|
|
245726
|
+
return `==> ${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(node.faceSuccessor)}`;
|
|
245727
|
+
}
|
|
245728
|
+
else {
|
|
245729
|
+
return "";
|
|
245730
|
+
}
|
|
245731
|
+
}
|
|
245732
|
+
}
|
|
245733
|
+
inspectMasks(node, showXYZ = true, showFaceSuccessorXYZ = false) {
|
|
245734
|
+
const s = "[";
|
|
245735
|
+
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), "]");
|
|
245736
|
+
return v;
|
|
245737
|
+
}
|
|
245738
|
+
/**
|
|
245739
|
+
* For each face of the graph, output the xyz of the sector data
|
|
245740
|
+
* @param polyfaceBuilder
|
|
245741
|
+
*/
|
|
245742
|
+
announceFacetsWithSectorCoordinatesAroundVertices(polyfaceBuilder) {
|
|
245743
|
+
const xyzLoop = new _geometry3d_GrowableXYZArray__WEBPACK_IMPORTED_MODULE_3__.GrowableXYZArray();
|
|
245744
|
+
const primaryCompressionTolerance = _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallMetricDistance;
|
|
245745
|
+
this._baseGraph.announceVertexLoops((_graph, seed) => {
|
|
245746
|
+
if (!seed.findMaskAroundVertex(this._exteriorMask)) {
|
|
245747
|
+
xyzLoop.length = 0;
|
|
245748
|
+
seed.sumAroundVertex((node) => {
|
|
245749
|
+
if (!node.isMaskSet(this._insideChamferSling))
|
|
245750
|
+
SectorOffsetProperties.getSectorPointAtHalfEdge(node, undefined, xyzLoop);
|
|
245751
|
+
return 0.0;
|
|
245752
|
+
});
|
|
245753
|
+
_geometry3d_PolylineCompressionByEdgeOffset__WEBPACK_IMPORTED_MODULE_4__.PolylineCompressionContext.compressInPlaceByShortEdgeLength(xyzLoop, primaryCompressionTolerance);
|
|
245754
|
+
if (xyzLoop.length > 2) {
|
|
245755
|
+
polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);
|
|
245756
|
+
}
|
|
245757
|
+
}
|
|
245758
|
+
return true;
|
|
245759
|
+
});
|
|
245760
|
+
}
|
|
245761
|
+
/**
|
|
245762
|
+
* * Exterior half edges have HalfEdgeMask.EXTERIOR
|
|
245763
|
+
* * All interior half edge around a facet have facetTag pointing to a facetProperties object for that facet.
|
|
245764
|
+
* * the facetOffsetProperties object has the simple facet normal.
|
|
245765
|
+
* * Each half edge has edgeTag pointing to to a sectorOffsetProperties object
|
|
245766
|
+
* * the sectorOffsetProperties has a copy of the facet normal.
|
|
245767
|
+
* @param polyface
|
|
245768
|
+
* @returns graph
|
|
245769
|
+
*/
|
|
245770
|
+
static buildBaseGraph(polyface) {
|
|
245771
|
+
const graphBuilder = new _topology_HalfEdgeGraphFromIndexedLoopsContext__WEBPACK_IMPORTED_MODULE_5__.HalfEdgeGraphFromIndexedLoopsContext();
|
|
245772
|
+
const visitor = polyface.createVisitor();
|
|
245773
|
+
const xyzA = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
|
|
245774
|
+
const xyzB = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
|
|
245775
|
+
for (visitor.reset(); visitor.moveToNextFacet();) {
|
|
245776
|
+
const normal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_6__.PolygonOps.centroidAreaNormal(visitor.point);
|
|
245777
|
+
if (normal !== undefined) {
|
|
245778
|
+
const edgeA = graphBuilder.insertLoop(visitor.pointIndex, (insideHalfEdge) => {
|
|
245779
|
+
const mate = insideHalfEdge.edgeMate;
|
|
245780
|
+
polyface.data.getPoint(insideHalfEdge.i, xyzA);
|
|
245781
|
+
insideHalfEdge.setXYZ(xyzA);
|
|
245782
|
+
polyface.data.getPoint(mate.i, xyzB);
|
|
245783
|
+
mate.setXYZ(xyzB);
|
|
245784
|
+
});
|
|
245785
|
+
const facetProperties = new FacetOffsetProperties(visitor.currentReadIndex(), normal);
|
|
245786
|
+
if (edgeA !== undefined) {
|
|
245787
|
+
edgeA.sumAroundFace((edgeB) => {
|
|
245788
|
+
edgeB.faceTag = facetProperties;
|
|
245789
|
+
edgeB.edgeTag = new SectorOffsetProperties(normal.direction.clone(), edgeB.getPoint3d());
|
|
245790
|
+
return 0;
|
|
245791
|
+
});
|
|
245792
|
+
}
|
|
245793
|
+
}
|
|
245794
|
+
}
|
|
245795
|
+
return graphBuilder.graph;
|
|
245796
|
+
}
|
|
245797
|
+
setOffsetAtDistanceAroundVertex(vertexSeed, distance, ignoreChamfers = false) {
|
|
245798
|
+
vertexSeed.sumAroundVertex((nodeAroundVertex) => {
|
|
245799
|
+
const props = nodeAroundVertex.edgeTag;
|
|
245800
|
+
if (props !== undefined) {
|
|
245801
|
+
if (ignoreChamfers && this.isInsideChamferOrSling(vertexSeed)) {
|
|
245802
|
+
// SKIP !!
|
|
245803
|
+
}
|
|
245804
|
+
else {
|
|
245805
|
+
props.setOffsetPointAtDistanceAtHalfEdge(nodeAroundVertex, distance);
|
|
245806
|
+
}
|
|
245807
|
+
}
|
|
245808
|
+
return 0.0;
|
|
245809
|
+
});
|
|
245810
|
+
}
|
|
245811
|
+
setOffsetXYAndZAroundVertex(vertexSeed, xyz) {
|
|
245812
|
+
vertexSeed.sumAroundVertex((nodeAroundVertex) => {
|
|
245813
|
+
const props = nodeAroundVertex.edgeTag;
|
|
245814
|
+
if (props !== undefined) {
|
|
245815
|
+
props.setXYAndZ(xyz);
|
|
245816
|
+
nodeAroundVertex.setMask(this._offsetCoordinatesReassigned);
|
|
245817
|
+
}
|
|
245818
|
+
return 0.0;
|
|
245819
|
+
});
|
|
245820
|
+
}
|
|
245821
|
+
/**
|
|
245822
|
+
* * start at vertexSeed.
|
|
245823
|
+
* * set the offset point at up to (and including) one with (a) this._breakMaskB or (b) this._exteriorMask
|
|
245824
|
+
* *
|
|
245825
|
+
* @param vertexSeed first node to mark.
|
|
245826
|
+
* @param f function to call to announce each node and its sector properties.
|
|
245827
|
+
* @returns number of nodes marked.
|
|
245828
|
+
*/
|
|
245829
|
+
announceNodeAndSectorPropertiesInSmoothSector(vertexSeed, f) {
|
|
245830
|
+
let n = 0;
|
|
245831
|
+
for (let currentNode = vertexSeed;; currentNode = currentNode.vertexSuccessor) {
|
|
245832
|
+
const props = currentNode.edgeTag;
|
|
245833
|
+
if (props !== undefined) {
|
|
245834
|
+
f(currentNode, props);
|
|
245835
|
+
n++;
|
|
245836
|
+
}
|
|
245837
|
+
if (currentNode.isMaskSet(this._breakMaskB))
|
|
245838
|
+
return n;
|
|
245839
|
+
// REMARK: these additional exit conditions should not happen if (a) the graph is properly marked and (b) the start node is not exterior.
|
|
245840
|
+
if (currentNode.isMaskSet(this._exteriorMask))
|
|
245841
|
+
return n;
|
|
245842
|
+
if (currentNode === vertexSeed && n === 0)
|
|
245843
|
+
return n;
|
|
245844
|
+
}
|
|
245845
|
+
}
|
|
245846
|
+
computeAverageNormalAndMaxDeviationAroundVertex(vertexSeed, data) {
|
|
245847
|
+
data.clear();
|
|
245848
|
+
const inactiveNodeMask = this._exteriorMask | this._insideChamferSling;
|
|
245849
|
+
vertexSeed.sumAroundVertex((node) => {
|
|
245850
|
+
const sectorData = node.edgeTag;
|
|
245851
|
+
if (sectorData)
|
|
245852
|
+
data.accumulateNormal(node, sectorData.normal, inactiveNodeMask);
|
|
245853
|
+
return 0.0;
|
|
245854
|
+
});
|
|
245855
|
+
if (!data.finishNormalAveraging()) {
|
|
245856
|
+
return undefined;
|
|
245857
|
+
}
|
|
245858
|
+
vertexSeed.sumAroundVertex((node) => {
|
|
245859
|
+
const sectorData = node.edgeTag;
|
|
245860
|
+
if (sectorData)
|
|
245861
|
+
data.recordDeviation(sectorData.normal, !node.isMaskSet(inactiveNodeMask));
|
|
245862
|
+
return 0.0;
|
|
245863
|
+
});
|
|
245864
|
+
return data.maxDeviationRadians;
|
|
245865
|
+
}
|
|
245866
|
+
assignOffsetByAverageNormalAroundVertex(vertexSeed, maxAllowedDeviationRadians, data, distance) {
|
|
245867
|
+
const maxDeviationRadians = this.computeAverageNormalAndMaxDeviationAroundVertex(vertexSeed, data);
|
|
245868
|
+
if (OffsetMeshContext.stringDebugFunction) {
|
|
245869
|
+
OffsetMeshContext.stringDebugFunction(`XYZ ${_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.nodeToIdXYZString(vertexSeed)} Average Normal ${data.averageNormal.toJSON()}`);
|
|
245870
|
+
OffsetMeshContext.stringDebugFunction(` angle ratio ${data.radiansSum / (2 * Math.PI)} maxDeviation ${data.maxDeviationRadiansFromAverage}`);
|
|
245871
|
+
}
|
|
245872
|
+
if (maxDeviationRadians !== undefined && maxDeviationRadians <= maxAllowedDeviationRadians) {
|
|
245873
|
+
vertexSeed.sumAroundVertex((node) => {
|
|
245874
|
+
SectorOffsetProperties.setNormalAtHalfEdge(node, data.averageNormal, distance);
|
|
245875
|
+
return 0;
|
|
245876
|
+
});
|
|
245877
|
+
return true;
|
|
245878
|
+
}
|
|
245879
|
+
return false;
|
|
245880
|
+
}
|
|
245881
|
+
/** Search around a vertex for a sector which has a different normal from its vertexPredecessor.
|
|
245882
|
+
* * The seed will be the first candidate considered
|
|
245883
|
+
*/
|
|
245884
|
+
markBreakEdgesAndSaveAverageNormalsAroundVertex(vertexSeed) {
|
|
245885
|
+
vertexSeed.clearMaskAroundVertex(this._breakMaskA);
|
|
245886
|
+
vertexSeed.clearMaskAroundVertex(this._breakMaskB);
|
|
245887
|
+
const smoothSingleSmoothRadiansBetweenNormals = this._smoothRadiansBetweenNormals;
|
|
245888
|
+
const accumulatedRadiansBetweenNormals = this._smoothAccumulatedRadiansBetweenNormals;
|
|
245889
|
+
// Step 1: Examine the edge between nodeA and the sector on its vertex predecessor side. This (alone) determines single angle breaks.
|
|
245890
|
+
let numBreaks = 0;
|
|
245891
|
+
let nodeP = vertexSeed;
|
|
245892
|
+
let _numSmooth = 0;
|
|
245893
|
+
do {
|
|
245894
|
+
const nodeQ = nodeP.edgeMate;
|
|
245895
|
+
const nodeR = nodeQ.faceSuccessor; // same as nodeA.vertexPredecessor
|
|
245896
|
+
if (nodeP.isMaskSet(this._exteriorMask)) {
|
|
245897
|
+
if (!nodeQ.isMaskSet(this._exteriorMask)) {
|
|
245898
|
+
nodeR.setMask(this._breakMaskB);
|
|
245899
|
+
numBreaks++;
|
|
245900
|
+
}
|
|
245901
|
+
}
|
|
245902
|
+
else {
|
|
245903
|
+
if (nodeP.isMaskSet(this._outsideOfChamferFace)) {
|
|
245904
|
+
nodeP.setMask(this._breakMaskA);
|
|
245905
|
+
}
|
|
245906
|
+
else if (nodeP.isMaskSet(this._outsideEndOfChamferFace)) {
|
|
245907
|
+
nodeP.setMask(this._breakMaskA);
|
|
245908
|
+
nodeP.setMask(this._breakMaskB);
|
|
245909
|
+
}
|
|
245910
|
+
else if (nodeP.isMaskSet(this._insideChamferSling)) {
|
|
245911
|
+
// This is the sling. It's normal is along edge -- not really a break.
|
|
245912
|
+
}
|
|
245913
|
+
else if (nodeP.isMaskSet(this._insideOfChamferFace)) {
|
|
245914
|
+
nodeP.setMask(this._breakMaskA);
|
|
245915
|
+
nodeP.setMask(this._breakMaskB);
|
|
245916
|
+
nodeR.setMask(this._breakMaskB);
|
|
245917
|
+
}
|
|
245918
|
+
else if (nodeQ.isMaskSet(this._exteriorMask)) {
|
|
245919
|
+
numBreaks++;
|
|
245920
|
+
nodeP.setMask(this._breakMaskA);
|
|
245921
|
+
}
|
|
245922
|
+
else if (!SectorOffsetProperties.almostEqualNormals(nodeP.edgeTag, nodeR.edgeTag, smoothSingleSmoothRadiansBetweenNormals)) {
|
|
245923
|
+
nodeP.setMask(this._breakMaskA);
|
|
245924
|
+
numBreaks++;
|
|
245925
|
+
nodeR.setMask(this._breakMaskB);
|
|
245926
|
+
}
|
|
245927
|
+
else {
|
|
245928
|
+
_numSmooth++;
|
|
245929
|
+
}
|
|
245930
|
+
}
|
|
245931
|
+
nodeP = nodeP.vertexSuccessor;
|
|
245932
|
+
} while (nodeP !== vertexSeed);
|
|
245933
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined)
|
|
245934
|
+
OffsetMeshContext.stringDebugFunction(` numSkip ${_numSmooth} `);
|
|
245935
|
+
if (numBreaks === 0) {
|
|
245936
|
+
// make the first vertex a break so subsequent searches have a place to start
|
|
245937
|
+
vertexSeed.setMask(this._breakMaskA);
|
|
245938
|
+
vertexSeed.vertexPredecessor.setMask(this._breakMaskB);
|
|
245939
|
+
numBreaks = 1;
|
|
245940
|
+
}
|
|
245941
|
+
// Step 2: At each single break, sweep forward to its closing breakB. Insert breaks at accumulated angles.
|
|
245942
|
+
// (minor TODO: for the insertion case, try to split more equally.)
|
|
245943
|
+
const nodeAStart = nodeP.findMaskAroundVertex(this._breakMaskA);
|
|
245944
|
+
if (nodeAStart !== undefined) {
|
|
245945
|
+
nodeP = nodeAStart;
|
|
245946
|
+
do {
|
|
245947
|
+
if (nodeP.isMaskSet(this._breakMaskA) && !nodeP.isMaskSet(this._breakMaskB)) {
|
|
245948
|
+
let accumulatedRadians = 0.0;
|
|
245949
|
+
do {
|
|
245950
|
+
const nodeB = nodeP.vertexSuccessor;
|
|
245951
|
+
accumulatedRadians += SectorOffsetProperties.radiansBetweenNormals(nodeP.edgeTag, nodeB.edgeTag);
|
|
245952
|
+
if (accumulatedRadians > accumulatedRadiansBetweenNormals) {
|
|
245953
|
+
nodeP.setMask(this._breakMaskB);
|
|
245954
|
+
nodeB.setMask(this._breakMaskA);
|
|
245955
|
+
numBreaks++;
|
|
245956
|
+
accumulatedRadians = 0.0;
|
|
245957
|
+
}
|
|
245958
|
+
nodeP = nodeB;
|
|
245959
|
+
} while (!nodeP.isMaskSet(this._breakMaskB));
|
|
245960
|
+
}
|
|
245961
|
+
else {
|
|
245962
|
+
nodeP = nodeP.vertexSuccessor;
|
|
245963
|
+
}
|
|
245964
|
+
} while (nodeP !== nodeAStart);
|
|
245965
|
+
}
|
|
245966
|
+
if (numBreaks > 0 && nodeAStart !== undefined) {
|
|
245967
|
+
// In each compound sector, accumulate and install average normal.
|
|
245968
|
+
nodeP = nodeAStart;
|
|
245969
|
+
const averageNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create();
|
|
245970
|
+
const edgeVectorU = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create();
|
|
245971
|
+
const edgeVectorV = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create();
|
|
245972
|
+
averageNormal.setZero();
|
|
245973
|
+
do {
|
|
245974
|
+
if (nodeP.isMaskSet(this._breakMaskA) && !nodeP.isMaskSet(this._breakMaskB)) {
|
|
245975
|
+
let nodeQ = nodeP;
|
|
245976
|
+
averageNormal.setZero();
|
|
245977
|
+
for (;;) {
|
|
245978
|
+
nodeQ.vectorToFaceSuccessor(edgeVectorU);
|
|
245979
|
+
nodeQ.vectorToFacePredecessor(edgeVectorV);
|
|
245980
|
+
let singleSectorRadians = edgeVectorU.signedRadiansTo(edgeVectorV, nodeQ.faceTag.facetNormal.direction);
|
|
245981
|
+
if (singleSectorRadians < 0.0)
|
|
245982
|
+
singleSectorRadians += Math.PI * 2;
|
|
245983
|
+
SectorOffsetProperties.accumulateScaledNormalAtHalfEdge(nodeQ, singleSectorRadians, averageNormal);
|
|
245984
|
+
if (nodeQ.isMaskSet(this._breakMaskB))
|
|
245985
|
+
break;
|
|
245986
|
+
nodeQ = nodeQ.vertexSuccessor;
|
|
245987
|
+
}
|
|
245988
|
+
if (averageNormal.normalizeInPlace()) {
|
|
245989
|
+
nodeQ = nodeP;
|
|
245990
|
+
for (;;) {
|
|
245991
|
+
SectorOffsetProperties.setNormalAtHalfEdge(nodeQ, averageNormal);
|
|
245992
|
+
if (nodeQ.isMaskSet(this._breakMaskB))
|
|
245993
|
+
break;
|
|
245994
|
+
nodeQ = nodeQ.vertexSuccessor;
|
|
245995
|
+
}
|
|
245996
|
+
}
|
|
245997
|
+
}
|
|
245998
|
+
nodeP = nodeP.vertexSuccessor;
|
|
245999
|
+
} while (nodeP !== nodeAStart);
|
|
246000
|
+
}
|
|
246001
|
+
}
|
|
246002
|
+
/** Compute the point of intersection of the planes in the sectors of 3 half edges */
|
|
246003
|
+
compute3SectorIntersection(nodeA, nodeB, nodeC, result) {
|
|
246004
|
+
const sectorA = nodeA.edgeTag;
|
|
246005
|
+
const sectorB = nodeB.edgeTag;
|
|
246006
|
+
const sectorC = nodeC.edgeTag;
|
|
246007
|
+
const vector = _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_7__.SmallSystem.intersect3Planes(sectorA.xyz, sectorA.normal, sectorB.xyz, sectorB.normal, sectorC.xyz, sectorC.normal, result);
|
|
246008
|
+
return vector;
|
|
246009
|
+
}
|
|
246010
|
+
/** Compute the point of intersection of the planes in the sectors of 3 half edges */
|
|
246011
|
+
compute3SectorIntersectionDebug(nodeA, nodeB, nodeC, result) {
|
|
246012
|
+
const sectorA = nodeA.edgeTag;
|
|
246013
|
+
const sectorB = nodeB.edgeTag;
|
|
246014
|
+
const sectorC = nodeC.edgeTag;
|
|
246015
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined) {
|
|
246016
|
+
OffsetMeshContext.stringDebugFunction(`compute3${this.inspectMasks(nodeA)}${this.inspectMasks(nodeB)}${this.inspectMasks(nodeC)} `);
|
|
246017
|
+
for (const sector of [sectorA, sectorB, sectorC])
|
|
246018
|
+
emitSector(sector);
|
|
246019
|
+
}
|
|
246020
|
+
const vector = _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_7__.SmallSystem.intersect3Planes(sectorA.xyz, sectorA.normal, sectorB.xyz, sectorB.normal, sectorC.xyz, sectorC.normal, result);
|
|
246021
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined) {
|
|
246022
|
+
if (vector === undefined)
|
|
246023
|
+
OffsetMeshContext.stringDebugFunction(" NO INTERSECTION");
|
|
246024
|
+
else
|
|
246025
|
+
OffsetMeshContext.stringDebugFunction(` ComputedVector ${vector.x},${vector.y},${vector.z} `);
|
|
246026
|
+
}
|
|
246027
|
+
return vector;
|
|
246028
|
+
}
|
|
246029
|
+
/** Compute the point of intersection of the planes in the sectors of 2 half edges, using cross product of their normals to resolve */
|
|
246030
|
+
compute2SectorIntersection(nodeA, nodeB, result) {
|
|
246031
|
+
const sectorA = nodeA.edgeTag;
|
|
246032
|
+
const sectorB = nodeB.edgeTag;
|
|
246033
|
+
const normalC = sectorA.normal.crossProduct(sectorB.normal);
|
|
246034
|
+
return _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_7__.SmallSystem.intersect3Planes(sectorA.xyz, sectorA.normal, sectorB.xyz, sectorB.normal, sectorB.xyz, normalC, result);
|
|
246035
|
+
}
|
|
246036
|
+
/**
|
|
246037
|
+
* * at input, graph has all original faces and edges
|
|
246038
|
+
* * each sector points to a faceProperties with original facet normal
|
|
246039
|
+
* * at exit:
|
|
246040
|
+
* * new "chamfer faces" are added outside of edges with angle between normal sin excess of options.chamferTurnAngleBetweenNormals
|
|
246041
|
+
* * the original edge is split along its length to create space
|
|
246042
|
+
* * one edge "along" each direction inside the slit.
|
|
246043
|
+
* * a sling edge at each end of the slit.
|
|
246044
|
+
* * outside of the sling is part of the slit face loop.
|
|
246045
|
+
* * inside is a single-node face
|
|
246046
|
+
* * thus the slit itself has 4 nodes.
|
|
246047
|
+
* * the two nodes at each end can thus contain the two distinct points at that end of the chamfer.
|
|
246048
|
+
* * all 4 nodes of the slit face point to a new FacetOffsetProperties with the average normal.
|
|
246049
|
+
* * the inside of each sling face has
|
|
246050
|
+
* * original vertex coordinates in the node
|
|
246051
|
+
* * face properties with a normal pointing outward from that end of the original edge -- hence define a plane that can clip the chamfer
|
|
246052
|
+
* * the two points at each end of the chamfer are computed as the intersection of
|
|
246053
|
+
* * chamfer plane
|
|
246054
|
+
* * sling plane
|
|
246055
|
+
* * adjacent plane of the face on the other side of the edge being chamfered.
|
|
246056
|
+
* @param distance distance to offset. The sign of this is important in the chamfer construction.
|
|
246057
|
+
*/
|
|
246058
|
+
addChamferTopologyToAllEdges(options, distance) {
|
|
246059
|
+
const edgesToChamfer = [];
|
|
246060
|
+
const chamferRadians = options.chamferAngleBetweenNormals.radians;
|
|
246061
|
+
const vertexXYZ = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create(); // reuse
|
|
246062
|
+
const edgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create(); // reuse
|
|
246063
|
+
const outwardEdgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create(); // reuse
|
|
246064
|
+
const averageNormal = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Vector3d.create(); // reuse
|
|
246065
|
+
// collect all the edges with sharp turn angle.
|
|
246066
|
+
this._baseGraph.announceEdges((_graph, edgeNode) => {
|
|
246067
|
+
if (SectorOffsetProperties.edgeHasLargeExteriorAngleBetweenNormals(edgeNode, edgeVector, averageNormal, distance, chamferRadians)) {
|
|
246068
|
+
edgesToChamfer.push(edgeNode);
|
|
246069
|
+
return true;
|
|
246070
|
+
}
|
|
246071
|
+
return true;
|
|
246072
|
+
});
|
|
246073
|
+
// Create sliver faces.
|
|
246074
|
+
// Sliver face gets an average normal from its neighbors.
|
|
246075
|
+
// outsideA is the HalfEdge labeled A in the diagram.
|
|
246076
|
+
// sliverDX and sliverDY are the edges "inside the sliver" at the respective X and Y ends.
|
|
246077
|
+
for (const outsideA of edgesToChamfer) {
|
|
246078
|
+
// remark: this recomputes as in collection round.
|
|
246079
|
+
if (SectorOffsetProperties.edgeHasLargeExteriorAngleBetweenNormals(outsideA, edgeVector, averageNormal, chamferRadians)) {
|
|
246080
|
+
// This copies coordinates and vertex id .... sectorOffsetProperties are delayed until late in the 2-pass loop below.
|
|
246081
|
+
// The returned HalfEdge is labeled D in the diagram
|
|
246082
|
+
const sliverDX = this._baseGraph.splitEdgeCreateSliverFace(outsideA);
|
|
246083
|
+
const sliverDY = sliverDX.facePredecessor;
|
|
246084
|
+
const offsetPoint = sliverDX.getPoint3d();
|
|
246085
|
+
offsetPoint.addScaledInPlace(averageNormal, distance);
|
|
246086
|
+
const ray = _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_8__.Ray3d.createCapture(offsetPoint, averageNormal.clone());
|
|
246087
|
+
const facetProperties = new FacetOffsetProperties(-1, ray);
|
|
246088
|
+
// for each side (hence end) of the sliver face, set mask and install a sling loop for the anticipated end of the chamfer face
|
|
246089
|
+
// new node names in the loop omit X or Y suffix because that is implied by which pass is running.
|
|
246090
|
+
let s = -1.0;
|
|
246091
|
+
for (const sliverD of [sliverDX, sliverDY]) {
|
|
246092
|
+
edgeVector.scale(s, outwardEdgeVector);
|
|
246093
|
+
sliverD.getPoint3d(vertexXYZ);
|
|
246094
|
+
sliverD.setMask(this._insideOfChamferFace);
|
|
246095
|
+
sliverD.edgeMate.setMask(this._outsideOfChamferFace);
|
|
246096
|
+
// mark and reference the chamfer face.
|
|
246097
|
+
sliverD.faceTag = facetProperties;
|
|
246098
|
+
// sling at this end
|
|
246099
|
+
const slingB = this._baseGraph.splitEdge(undefined, vertexXYZ.x, vertexXYZ.y, vertexXYZ.z, sliverD.i);
|
|
246100
|
+
const slingC = slingB.edgeMate;
|
|
246101
|
+
slingB.setMask(this._outsideEndOfChamferFace);
|
|
246102
|
+
slingB.faceTag = facetProperties;
|
|
246103
|
+
slingC.setMask(this._insideChamferSling);
|
|
246104
|
+
_topology_Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdge.pinch(sliverD, slingB);
|
|
246105
|
+
const endNormal = _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_8__.Ray3d.create(vertexXYZ, outwardEdgeVector); // clones the inputs
|
|
246106
|
+
const slingFaceProperties = new FacetOffsetProperties(-1, endNormal);
|
|
246107
|
+
slingC.faceTag = slingFaceProperties;
|
|
246108
|
+
// initialize sectors with existing vertex point.
|
|
246109
|
+
sliverD.edgeTag = new SectorOffsetProperties(averageNormal.clone(), offsetPoint.clone());
|
|
246110
|
+
slingB.edgeTag = new SectorOffsetProperties(averageNormal.clone(), offsetPoint.clone());
|
|
246111
|
+
slingC.edgeTag = new SectorOffsetProperties(outwardEdgeVector.clone(), vertexXYZ.clone());
|
|
246112
|
+
// OffsetMeshContext.stringDebugFunction("Chamfer Setup");
|
|
246113
|
+
const chamferPointE = this.compute3SectorIntersection(sliverD, sliverD.edgeMate, slingC);
|
|
246114
|
+
const chamferPointF = this.compute3SectorIntersection(slingB, slingB.vertexSuccessor, slingC);
|
|
246115
|
+
// sliverD.edgeTag = new SectorOffsetProperties(averageNormal.clone(), vertexXYZ.clone());
|
|
246116
|
+
SectorOffsetProperties.setXYZAtHalfEdge(sliverD, chamferPointE);
|
|
246117
|
+
SectorOffsetProperties.setXYZAtHalfEdge(slingB, chamferPointF);
|
|
246118
|
+
s *= -1.0;
|
|
246119
|
+
}
|
|
246120
|
+
}
|
|
246121
|
+
}
|
|
246122
|
+
}
|
|
246123
|
+
/**
|
|
246124
|
+
* * at input:
|
|
246125
|
+
* * Each node points to sectorOffsetProperties with previously computed XYZ (presumably mismatched)
|
|
246126
|
+
* * at exit:
|
|
246127
|
+
* * Each sectorOffsetProperties has an offset point computed with consideration of offset planes in the neighborhood.
|
|
246128
|
+
* @param distance distance to offset.
|
|
246129
|
+
*/
|
|
246130
|
+
computeOffsetFacetIntersections(distance) {
|
|
246131
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined)
|
|
246132
|
+
OffsetMeshContext.stringDebugFunction("***** recompute intersections");
|
|
246133
|
+
const breakEdges = [];
|
|
246134
|
+
const vertexXYZ = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
|
|
246135
|
+
const chamferXYZ = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_0__.Point3d.create();
|
|
246136
|
+
const maxVertexMove = 2.0 * distance;
|
|
246137
|
+
const averageNormalData = new AverageNormalData();
|
|
246138
|
+
const maxAllowedNormalDeviationRadians = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_9__.Angle.degreesToRadians(25.0);
|
|
246139
|
+
//
|
|
246140
|
+
// FOR EACH VERTEX
|
|
246141
|
+
//
|
|
246142
|
+
this._baseGraph.announceVertexLoops((_graph, vertexSeedA) => {
|
|
246143
|
+
// reposition to an important vertex.
|
|
246144
|
+
// first choice: a chamfer face.
|
|
246145
|
+
let vertexSeed = vertexSeedA.findMaskAroundVertex(this._outsideEndOfChamferFace);
|
|
246146
|
+
if (vertexSeed === undefined)
|
|
246147
|
+
vertexSeed = vertexSeedA.findMaskAroundVertex(this._breakMaskA);
|
|
246148
|
+
if (vertexSeed === undefined)
|
|
246149
|
+
vertexSeed = vertexSeedA;
|
|
246150
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined) {
|
|
246151
|
+
OffsetMeshContext.stringDebugFunction("");
|
|
246152
|
+
OffsetMeshContext.stringDebugFunction(` VERTEX LOOP ${vertexSeed.getPoint3d().toJSON()} `);
|
|
246153
|
+
vertexSeed.sumAroundVertex((node) => { OffsetMeshContext.stringDebugFunction(this.inspectMasks(node, false, true)); return 0; });
|
|
246154
|
+
}
|
|
246155
|
+
// Take care of the easiest vertices directly . . . note that this returns from the lambda, not computeOffsetFacetIntersections
|
|
246156
|
+
if (this.assignOffsetByAverageNormalAroundVertex(vertexSeed, maxAllowedNormalDeviationRadians, averageNormalData, distance))
|
|
246157
|
+
return true;
|
|
246158
|
+
this.markBreakEdgesAndSaveAverageNormalsAroundVertex(vertexSeed);
|
|
246159
|
+
this.setOffsetAtDistanceAroundVertex(vertexSeed, distance, true);
|
|
246160
|
+
vertexSeed.collectMaskedEdgesAroundVertex(this._breakMaskA, true, breakEdges);
|
|
246161
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined) {
|
|
246162
|
+
OffsetMeshContext.stringDebugFunction(` BREAK EDGES from ${this.inspectMasks(vertexSeed, true, false)}`);
|
|
246163
|
+
for (const node of breakEdges) {
|
|
246164
|
+
OffsetMeshContext.stringDebugFunction(this.inspectMasks(node, false, true));
|
|
246165
|
+
}
|
|
246166
|
+
}
|
|
246167
|
+
if (breakEdges.length <= 1) {
|
|
246168
|
+
// just one smooth sequence.
|
|
246169
|
+
// everything is set already.
|
|
246170
|
+
}
|
|
246171
|
+
else if (breakEdges.length === 2) {
|
|
246172
|
+
// exterior vertex with two incident smooth
|
|
246173
|
+
const vectorFromOrigin = this.compute2SectorIntersection(breakEdges[0], breakEdges[1]);
|
|
246174
|
+
if (vectorFromOrigin !== undefined) {
|
|
246175
|
+
this.setOffsetXYAndZAroundVertex(vertexSeed, vectorFromOrigin);
|
|
246176
|
+
}
|
|
246177
|
+
}
|
|
246178
|
+
else if (breakEdges.length === 3) {
|
|
246179
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined)
|
|
246180
|
+
OffsetMeshContext.stringDebugFunction(` Vertex Update just ${breakEdges.length} `);
|
|
246181
|
+
const vectorFromOrigin = this.compute3SectorIntersection(breakEdges[0], breakEdges[1], breakEdges[2]);
|
|
246182
|
+
if (vectorFromOrigin !== undefined) {
|
|
246183
|
+
this.setOffsetXYAndZAroundVertex(vertexSeed, vectorFromOrigin);
|
|
246184
|
+
}
|
|
246185
|
+
// simple 3-face corner . . .
|
|
246186
|
+
}
|
|
246187
|
+
else {
|
|
246188
|
+
// Lots and Lots of edges
|
|
246189
|
+
// each set of 3 sectors independently generates an offset for its central sector.
|
|
246190
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined)
|
|
246191
|
+
OffsetMeshContext.stringDebugFunction(` Vertex Update breakEdges ${breakEdges.length} `);
|
|
246192
|
+
vertexSeed.getPoint3d(vertexXYZ);
|
|
246193
|
+
// Pass 1 -- look for intersection among multiple chamfers
|
|
246194
|
+
for (let i = 0; i < breakEdges.length; i++) {
|
|
246195
|
+
const i0 = i;
|
|
246196
|
+
const i1 = (i0 + 1) % breakEdges.length;
|
|
246197
|
+
const i2 = (i1 + 1) % breakEdges.length;
|
|
246198
|
+
if (breakEdges[i0].isMaskSet(this._outsideEndOfChamferFace)
|
|
246199
|
+
&& breakEdges[i1].isMaskSet(this._outsideOfChamferFace)
|
|
246200
|
+
&& breakEdges[i2].isMaskSet(this._insideOfChamferFace)) {
|
|
246201
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined)
|
|
246202
|
+
OffsetMeshContext.stringDebugFunction(` ChamferChamfer Fixup ${this.inspectMasks(breakEdges[i0])} ${this.inspectMasks(breakEdges[i1])} ${this.inspectMasks(breakEdges[i2])} `);
|
|
246203
|
+
const vectorFromOrigin = this.compute3SectorIntersection(breakEdges[i0], breakEdges[i1], breakEdges[i2]);
|
|
246204
|
+
if (vectorFromOrigin !== undefined) {
|
|
246205
|
+
// Treat all 3 spots as possibly compound sequences
|
|
246206
|
+
for (const iOutput of [i0, i1, i2]) {
|
|
246207
|
+
this.announceNodeAndSectorPropertiesInSmoothSector(breakEdges[iOutput], (node, properties) => {
|
|
246208
|
+
properties.setXYAndZ(vectorFromOrigin);
|
|
246209
|
+
node.setMask(this._offsetCoordinatesReassigned);
|
|
246210
|
+
});
|
|
246211
|
+
}
|
|
246212
|
+
// Since all three were reset, skip past. This is done on the acyclic integer that controls the loop.
|
|
246213
|
+
i += 2;
|
|
246214
|
+
}
|
|
246215
|
+
}
|
|
246216
|
+
}
|
|
246217
|
+
// Pass 2 -- look for unassigned nodes just before or after a chamfer.
|
|
246218
|
+
// The chamfer wins
|
|
246219
|
+
for (let i = 0; i < breakEdges.length; i++) {
|
|
246220
|
+
const i0 = i;
|
|
246221
|
+
const i1 = (i0 + 1) % breakEdges.length;
|
|
246222
|
+
if (this.isInsideSling(breakEdges[i0], breakEdges[i1]))
|
|
246223
|
+
continue;
|
|
246224
|
+
if (!this.isOffsetAssigned(breakEdges[i0])
|
|
246225
|
+
&& breakEdges[i1].isMaskSet(this.insideOfChamferFace)) {
|
|
246226
|
+
this.transferXYZFromNodeToSmoothSector(breakEdges[i1], breakEdges[i0], "push left from chamfer", chamferXYZ);
|
|
246227
|
+
}
|
|
246228
|
+
else if (!this.isOffsetAssigned(breakEdges[i1])
|
|
246229
|
+
&& breakEdges[i0].isMaskSet(this.outsideEndOfChamferFace)) {
|
|
246230
|
+
this.transferXYZFromNodeToSmoothSector(breakEdges[i0], breakEdges[i1], "push right from chamfer", chamferXYZ);
|
|
246231
|
+
}
|
|
246232
|
+
}
|
|
246233
|
+
// Pass 3 -- look for unassigned nodes as middle of 3-face intersections
|
|
246234
|
+
for (let i = 0; i < breakEdges.length; i++) {
|
|
246235
|
+
const i0 = i;
|
|
246236
|
+
const i1 = (i0 + 1) % breakEdges.length;
|
|
246237
|
+
const i2 = (i1 + 1) % breakEdges.length;
|
|
246238
|
+
if (this.isInsideSling(breakEdges[i0], breakEdges[i1], breakEdges[i2]))
|
|
246239
|
+
continue;
|
|
246240
|
+
if (this.isOffsetAssigned(breakEdges[i1]))
|
|
246241
|
+
continue;
|
|
246242
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined)
|
|
246243
|
+
OffsetMeshContext.stringDebugFunction(` Intersection Fixup ${this.inspectMasks(breakEdges[i0])} ${this.inspectMasks(breakEdges[i1])} ${this.inspectMasks(breakEdges[i2])} `);
|
|
246244
|
+
const vectorFromOrigin = this.compute3SectorIntersection(breakEdges[i0], breakEdges[i1], breakEdges[i2]);
|
|
246245
|
+
if (vectorFromOrigin !== undefined) {
|
|
246246
|
+
if (vertexXYZ.distance(vectorFromOrigin) < maxVertexMove) {
|
|
246247
|
+
this.announceNodeAndSectorPropertiesInSmoothSector(breakEdges[i1], (node, properties) => {
|
|
246248
|
+
properties.setXYAndZ(vectorFromOrigin);
|
|
246249
|
+
node.setMask(this._offsetCoordinatesReassigned);
|
|
246250
|
+
});
|
|
246251
|
+
}
|
|
246252
|
+
}
|
|
246253
|
+
}
|
|
246254
|
+
}
|
|
246255
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined) {
|
|
246256
|
+
const n0 = vertexSeed.countMaskAroundVertex(this._offsetCoordinatesReassigned, false);
|
|
246257
|
+
const n1 = vertexSeed.countMaskAroundVertex(this._offsetCoordinatesReassigned, true);
|
|
246258
|
+
const message = ` **** Vertex offset mask counts(TRUE ${n1})(FALSE ${n0})`;
|
|
246259
|
+
OffsetMeshContext.stringDebugFunction(message);
|
|
246260
|
+
}
|
|
246261
|
+
return true;
|
|
246262
|
+
});
|
|
246263
|
+
}
|
|
246264
|
+
// return true if any of these nodes is "inside" the sling at the end of a chamfer.
|
|
246265
|
+
isInsideSling(node0, node1, node2) {
|
|
246266
|
+
return node0.isMaskSet(this._insideChamferSling)
|
|
246267
|
+
|| (node1 !== undefined && node1.isMaskSet(this._insideChamferSling))
|
|
246268
|
+
|| (node2 !== undefined && node2.isMaskSet(this._insideChamferSling));
|
|
246269
|
+
}
|
|
246270
|
+
// return true if any of these nodes is "inside" the sling at the end of a chamfer.
|
|
246271
|
+
isInsideChamferOrSling(node0) {
|
|
246272
|
+
return node0.isMaskSet(this._insideChamferSling)
|
|
246273
|
+
|| node0.isMaskSet(this._insideOfChamferFace)
|
|
246274
|
+
|| node0.isMaskSet(this._outsideEndOfChamferFace);
|
|
246275
|
+
}
|
|
246276
|
+
isOffsetAssigned(node0, node1, node2) {
|
|
246277
|
+
return node0.isMaskSet(this._offsetCoordinatesReassigned)
|
|
246278
|
+
|| (node1 !== undefined && node1.isMaskSet(this._offsetCoordinatesReassigned))
|
|
246279
|
+
|| (node2 !== undefined && node2.isMaskSet(this._offsetCoordinatesReassigned));
|
|
246280
|
+
}
|
|
246281
|
+
/**
|
|
246282
|
+
*
|
|
246283
|
+
* @param sourceNode node with good xyz
|
|
246284
|
+
* @param destinationStartNode first of a sequence of nodes to set (delimited by masks)
|
|
246285
|
+
* @param description string for debug
|
|
246286
|
+
* @param workPoint point to use for coordinate transfer.
|
|
246287
|
+
*/
|
|
246288
|
+
transferXYZFromNodeToSmoothSector(sourceNode, destinationStartNode, description, workPoint) {
|
|
246289
|
+
if (OffsetMeshContext.stringDebugFunction !== undefined)
|
|
246290
|
+
OffsetMeshContext.stringDebugFunction(` ${description} ${this.inspectMasks(sourceNode)} to ${this.inspectMasks(destinationStartNode)}} `);
|
|
246291
|
+
SectorOffsetProperties.getSectorPointAtHalfEdge(sourceNode, workPoint, undefined);
|
|
246292
|
+
this.announceNodeAndSectorPropertiesInSmoothSector(destinationStartNode, (node, properties) => {
|
|
246293
|
+
properties.setXYAndZ(workPoint);
|
|
246294
|
+
node.setMask(this._offsetCoordinatesReassigned);
|
|
246295
|
+
});
|
|
246296
|
+
}
|
|
246297
|
+
}
|
|
246298
|
+
|
|
246299
|
+
|
|
245019
246300
|
/***/ }),
|
|
245020
246301
|
|
|
245021
246302
|
/***/ "../../core/geometry/lib/esm/polyface/multiclip/RangeSearch.js":
|
|
@@ -254224,16 +255505,16 @@ class Sample {
|
|
|
254224
255505
|
_curve_Arc3d__WEBPACK_IMPORTED_MODULE_20__.Arc3d.createXY(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(5, 0), 5, _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_0__.AngleSweep.createStartEndDegrees(180, 0)), _curve_Arc3d__WEBPACK_IMPORTED_MODULE_20__.Arc3d.createXY(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(15, 0), 5, _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_0__.AngleSweep.createStartEndDegrees(180, 360)), _curve_Arc3d__WEBPACK_IMPORTED_MODULE_20__.Arc3d.createXY(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(25, 0), 5, _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_0__.AngleSweep.createStartEndDegrees(180, 0)))));
|
|
254225
255506
|
result.push(_curve_CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_44__.CurveChainWithDistanceIndex.createCapture(_curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(// 2-pt Interpolation Curve
|
|
254226
255507
|
_bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3d.createCapture(_bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3dOptions.create({
|
|
254227
|
-
fitPoints: [pointsA[0], pointsA[1]]
|
|
255508
|
+
fitPoints: [pointsA[0], pointsA[1]],
|
|
254228
255509
|
})))));
|
|
254229
255510
|
result.push(_curve_CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_44__.CurveChainWithDistanceIndex.createCapture(_curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(// 3-pt Interpolation Curve
|
|
254230
255511
|
_bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3d.createCapture(_bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3dOptions.create({
|
|
254231
|
-
fitPoints: [pointsA[0], pointsA[1], pointsA[2]]
|
|
255512
|
+
fitPoints: [pointsA[0], pointsA[1], pointsA[2]],
|
|
254232
255513
|
})))));
|
|
254233
255514
|
result.push(_curve_CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_44__.CurveChainWithDistanceIndex.createCapture(_curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(_bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3d.createCapture(_bspline_InterpolationCurve3d__WEBPACK_IMPORTED_MODULE_45__.InterpolationCurve3dOptions.create({
|
|
254234
255515
|
fitPoints: pointsA,
|
|
254235
255516
|
startTangent: _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(1, -1),
|
|
254236
|
-
endTangent: _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(-1, -1)
|
|
255517
|
+
endTangent: _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(-1, -1),
|
|
254237
255518
|
})))));
|
|
254238
255519
|
result.push(_curve_CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_44__.CurveChainWithDistanceIndex.createCapture(_curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(_curve_spiral_IntegratedSpiral3d__WEBPACK_IMPORTED_MODULE_39__.IntegratedSpiral3d.createRadiusRadiusBearingBearing(_geometry3d_Segment1d__WEBPACK_IMPORTED_MODULE_40__.Segment1d.create(0, 100), _geometry3d_AngleSweep__WEBPACK_IMPORTED_MODULE_0__.AngleSweep.createStartEndDegrees(10, 75), _geometry3d_Segment1d__WEBPACK_IMPORTED_MODULE_40__.Segment1d.create(0, 1), _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_16__.Transform.createOriginAndMatrix(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.createZero(), _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_12__.Matrix3d.createRotationAroundAxisIndex(2, _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__.Angle.createDegrees(30))), "bloss"))));
|
|
254239
255520
|
result.push(_curve_CurveChainWithDistanceIndex__WEBPACK_IMPORTED_MODULE_44__.CurveChainWithDistanceIndex.createCapture(_curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(_curve_spiral_DirectSpiral3d__WEBPACK_IMPORTED_MODULE_41__.DirectSpiral3d.createDirectHalfCosine(_geometry3d_Transform__WEBPACK_IMPORTED_MODULE_16__.Transform.createOriginAndMatrix(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.createZero(), _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_12__.Matrix3d.createRotationAroundAxisIndex(2, _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__.Angle.createDegrees(110))), 50, 350, _geometry3d_Segment1d__WEBPACK_IMPORTED_MODULE_40__.Segment1d.create(0, 1)))));
|
|
@@ -254347,8 +255628,11 @@ class Sample {
|
|
|
254347
255628
|
/** Create swept "solids" that can be capped.
|
|
254348
255629
|
* * At least one of each solid type.
|
|
254349
255630
|
* * each is within 10 of the origin all directions.
|
|
255631
|
+
* @param capped true to include caps
|
|
255632
|
+
* @param rotationAngle angle of rotation for the angular sweep. The default is 90 degrees.
|
|
255633
|
+
* Beware that the rotation sweep created with the default or any positive angle produces a mesh with inward normals.
|
|
254350
255634
|
*/
|
|
254351
|
-
static createClosedSolidSampler(capped) {
|
|
255635
|
+
static createClosedSolidSampler(capped, rotationAngle = _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__.Angle.createDegrees(90)) {
|
|
254352
255636
|
const result = [];
|
|
254353
255637
|
result.push(_solid_Box__WEBPACK_IMPORTED_MODULE_35__.Box.createRange(_geometry3d_Range__WEBPACK_IMPORTED_MODULE_4__.Range3d.createXYZXYZ(0, 0, 0, 3, 2, 5), capped));
|
|
254354
255638
|
result.push(_solid_Cone__WEBPACK_IMPORTED_MODULE_33__.Cone.createAxisPoints(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(0, 0, 0), _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(0, 0, 5), 1.0, 1.0, capped));
|
|
@@ -254360,18 +255644,23 @@ class Sample {
|
|
|
254360
255644
|
const pointQ2 = arcA.fractionAndDistanceToPointOnTangent(1.0, 0.5);
|
|
254361
255645
|
const pointR1 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(point0.x, pointQ1.y);
|
|
254362
255646
|
const pointR2 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(point0.x, pointQ1.y);
|
|
255647
|
+
const pointR3 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(pointQ1.x - 1, pointQ1.y);
|
|
255648
|
+
const pointR4 = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(pointQ1.x - 3, pointQ1.y);
|
|
254363
255649
|
const linestringQ1 = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_15__.LineString3d.create(arcA.fractionToPoint(1.0), pointQ1, pointR1, point0);
|
|
254364
255650
|
const linestringQ2 = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_15__.LineString3d.create(arcA.fractionToPoint(1.0), pointQ2, pointR2, point0);
|
|
255651
|
+
const linestringQ3 = _curve_LineString3d__WEBPACK_IMPORTED_MODULE_15__.LineString3d.create(arcA.fractionToPoint(1.0), pointQ2, pointR3, pointR4, point0);
|
|
254365
255652
|
const contourZ = _curve_Path__WEBPACK_IMPORTED_MODULE_21__.Path.create(linestringQ1.clone());
|
|
254366
255653
|
const contourA = _curve_Loop__WEBPACK_IMPORTED_MODULE_23__.Loop.create(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_19__.LineSegment3d.create(point0, arcA.fractionToPoint(0)), arcA.clone(), linestringQ1.clone());
|
|
254367
255654
|
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());
|
|
255655
|
+
const contourC1 = _curve_Loop__WEBPACK_IMPORTED_MODULE_23__.Loop.create(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_19__.LineSegment3d.create(point0, arcA.fractionToPoint(0)), arcA.clone(), linestringQ3.clone());
|
|
254368
255656
|
contourB.tryTransformInPlace(_geometry3d_Transform__WEBPACK_IMPORTED_MODULE_16__.Transform.createTranslationXYZ(1, 1, 3));
|
|
254369
255657
|
// const contourC = contourB.cloneTransformed(Transform.createTranslationXYZ(2, 1, 4))!;
|
|
254370
255658
|
result.push(_solid_LinearSweep__WEBPACK_IMPORTED_MODULE_30__.LinearSweep.create(contourA, _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(0, 0, 5), capped));
|
|
255659
|
+
result.push(_solid_LinearSweep__WEBPACK_IMPORTED_MODULE_30__.LinearSweep.create(contourC1, _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(0, 0, 5), capped));
|
|
254371
255660
|
const axis = _geometry3d_Ray3d__WEBPACK_IMPORTED_MODULE_14__.Ray3d.createXYZUVW(0, 8, 0, 1, 0, 0);
|
|
254372
|
-
result.push(_solid_RotationalSweep__WEBPACK_IMPORTED_MODULE_31__.RotationalSweep.create(contourA.clone(), axis.clone(),
|
|
255661
|
+
result.push(_solid_RotationalSweep__WEBPACK_IMPORTED_MODULE_31__.RotationalSweep.create(contourA.clone(), axis.clone(), rotationAngle, capped));
|
|
254373
255662
|
if (!capped)
|
|
254374
|
-
result.push(_solid_RotationalSweep__WEBPACK_IMPORTED_MODULE_31__.RotationalSweep.create(contourZ.clone(), axis.clone(),
|
|
255663
|
+
result.push(_solid_RotationalSweep__WEBPACK_IMPORTED_MODULE_31__.RotationalSweep.create(contourZ.clone(), axis.clone(), rotationAngle, false));
|
|
254375
255664
|
result.push(_solid_RuledSweep__WEBPACK_IMPORTED_MODULE_36__.RuledSweep.create([contourA.clone(), contourB.clone()], capped));
|
|
254376
255665
|
const transformC = _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_16__.Transform.createScaleAboutPoint(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(0, 0, 8), 0.5);
|
|
254377
255666
|
const contourC = contourB.cloneTransformed(transformC);
|
|
@@ -258796,12 +260085,13 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
258796
260085
|
/* harmony export */ "HalfEdgeGraph": () => (/* binding */ HalfEdgeGraph),
|
|
258797
260086
|
/* harmony export */ "HalfEdgeMask": () => (/* binding */ HalfEdgeMask)
|
|
258798
260087
|
/* harmony export */ });
|
|
258799
|
-
/* harmony import */ var
|
|
260088
|
+
/* harmony import */ var _curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../curve/LineSegment3d */ "../../core/geometry/lib/esm/curve/LineSegment3d.js");
|
|
258800
260089
|
/* harmony import */ var _Geometry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Geometry */ "../../core/geometry/lib/esm/Geometry.js");
|
|
260090
|
+
/* harmony import */ var _geometry3d_Angle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../geometry3d/Angle */ "../../core/geometry/lib/esm/geometry3d/Angle.js");
|
|
258801
260091
|
/* harmony import */ var _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../geometry3d/Point2dVector2d */ "../../core/geometry/lib/esm/geometry3d/Point2dVector2d.js");
|
|
258802
260092
|
/* harmony import */ var _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../geometry3d/Point3dVector3d */ "../../core/geometry/lib/esm/geometry3d/Point3dVector3d.js");
|
|
258803
|
-
/* harmony import */ var
|
|
258804
|
-
/* harmony import */ var
|
|
260093
|
+
/* harmony import */ var _numerics_Polynomials__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../numerics/Polynomials */ "../../core/geometry/lib/esm/numerics/Polynomials.js");
|
|
260094
|
+
/* harmony import */ var _MaskManager__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./MaskManager */ "../../core/geometry/lib/esm/topology/MaskManager.js");
|
|
258805
260095
|
/*---------------------------------------------------------------------------------------------
|
|
258806
260096
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
258807
260097
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
@@ -258815,6 +260105,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
258815
260105
|
|
|
258816
260106
|
|
|
258817
260107
|
|
|
260108
|
+
|
|
258818
260109
|
// import { GraphChecker } from "../test/topology/Graph.test";
|
|
258819
260110
|
/* eslint-disable @typescript-eslint/no-this-alias */
|
|
258820
260111
|
// cspell:word CONSTU
|
|
@@ -258902,6 +260193,7 @@ class HalfEdge {
|
|
|
258902
260193
|
this.sortAngle = undefined;
|
|
258903
260194
|
this.sortData = undefined;
|
|
258904
260195
|
this.edgeTag = undefined;
|
|
260196
|
+
this.faceTag = undefined;
|
|
258905
260197
|
// Always created in pairs, init here to make TS compiler and JS runtime happy
|
|
258906
260198
|
this._facePredecessor = this;
|
|
258907
260199
|
this._faceSuccessor = this;
|
|
@@ -259022,6 +260314,36 @@ class HalfEdge {
|
|
|
259022
260314
|
}
|
|
259023
260315
|
return newA;
|
|
259024
260316
|
}
|
|
260317
|
+
/**
|
|
260318
|
+
* * Create a new sliver face "inside" an existing edge.
|
|
260319
|
+
* * Insert it "within" the base edge.
|
|
260320
|
+
* * This requires two new half edges.
|
|
260321
|
+
* * if the base is undefined, create a single-edge loop.
|
|
260322
|
+
* * This (unlike pinch) breaks the edgeMate pairing of the base edge.
|
|
260323
|
+
* * This preserves xyz and i properties at all existing vertices.
|
|
260324
|
+
* * The two new half edges are a sliver face (via their predecessor and successor)
|
|
260325
|
+
* * Each new edge mates to one existing edge.
|
|
260326
|
+
* @returns Returns the reference to the half edge created.
|
|
260327
|
+
*/
|
|
260328
|
+
static splitEdgeCreateSliverFace(baseA, heArray) {
|
|
260329
|
+
// raw edges ...
|
|
260330
|
+
const newA = new HalfEdge();
|
|
260331
|
+
const newB = new HalfEdge();
|
|
260332
|
+
const baseB = baseA.edgeMate;
|
|
260333
|
+
if (heArray) {
|
|
260334
|
+
heArray.push(newA);
|
|
260335
|
+
heArray.push(newB);
|
|
260336
|
+
}
|
|
260337
|
+
newA._faceSuccessor = newA._facePredecessor = newB;
|
|
260338
|
+
newB._faceSuccessor = newB._facePredecessor = newA;
|
|
260339
|
+
// newA is in vertex loop with baseA etc.
|
|
260340
|
+
// newA mates to baseB
|
|
260341
|
+
HalfEdge.setEdgeMates(newA, baseB);
|
|
260342
|
+
HalfEdge.setEdgeMates(newB, baseA);
|
|
260343
|
+
newA.copyDataFrom(baseA, true, true, false, false);
|
|
260344
|
+
newB.copyDataFrom(baseB, true, true, false, false);
|
|
260345
|
+
return newA;
|
|
260346
|
+
}
|
|
259025
260347
|
/**
|
|
259026
260348
|
* Copy "edge based" content of fromNode to toNode
|
|
259027
260349
|
* * edgeTag
|
|
@@ -259232,6 +260554,35 @@ class HalfEdge {
|
|
|
259232
260554
|
}
|
|
259233
260555
|
return count;
|
|
259234
260556
|
}
|
|
260557
|
+
/** Returns the first node with given mask value around this vertex loop. */
|
|
260558
|
+
findMaskAroundVertex(mask, value = true) {
|
|
260559
|
+
let node = this;
|
|
260560
|
+
do {
|
|
260561
|
+
if (node.isMaskSet(mask) === value)
|
|
260562
|
+
return node;
|
|
260563
|
+
node = node.vertexSuccessor;
|
|
260564
|
+
} while (node !== this);
|
|
260565
|
+
return undefined;
|
|
260566
|
+
}
|
|
260567
|
+
/** Returns the first node with given mask value around this face loop. */
|
|
260568
|
+
findMaskAroundFace(mask, value = true) {
|
|
260569
|
+
let node = this;
|
|
260570
|
+
do {
|
|
260571
|
+
if (node.isMaskSet(mask) === value)
|
|
260572
|
+
return node;
|
|
260573
|
+
node = node.faceSuccessor;
|
|
260574
|
+
} while (node !== this);
|
|
260575
|
+
return undefined;
|
|
260576
|
+
}
|
|
260577
|
+
/** Returns the first node with given mask value on this edge (i.e. examining this and this.mate) */
|
|
260578
|
+
findMaskAroundEdge(mask, value = true) {
|
|
260579
|
+
if (this.isMaskSet(mask) === value)
|
|
260580
|
+
return this;
|
|
260581
|
+
const mate = this.edgeMate;
|
|
260582
|
+
if (mate.isMaskSet(mask) === value)
|
|
260583
|
+
return mate;
|
|
260584
|
+
return undefined;
|
|
260585
|
+
}
|
|
259235
260586
|
/** Set a mask, and return prior value.
|
|
259236
260587
|
* @param mask mask to apply
|
|
259237
260588
|
*/
|
|
@@ -259249,6 +260600,15 @@ class HalfEdge {
|
|
|
259249
260600
|
this.y = node.y;
|
|
259250
260601
|
this.z = node.z;
|
|
259251
260602
|
}
|
|
260603
|
+
/**
|
|
260604
|
+
* Set (copy) the this.x, this.y, this.z from xyz.x, xyz.y, xyz.z
|
|
260605
|
+
* @param node source with x,y,z properties
|
|
260606
|
+
*/
|
|
260607
|
+
setXYZ(xyz) {
|
|
260608
|
+
this.x = xyz.x;
|
|
260609
|
+
this.y = xyz.y;
|
|
260610
|
+
this.z = xyz.z;
|
|
260611
|
+
}
|
|
259252
260612
|
/**
|
|
259253
260613
|
* Test if mask bits are set in the node's bitMask.
|
|
259254
260614
|
* @return Return true (as a simple boolean, not a mask) if any bits of the mask parameter match bits of the node's bitMask
|
|
@@ -259338,6 +260698,10 @@ class HalfEdge {
|
|
|
259338
260698
|
const s = `${node.id.toString()}+${HalfEdge.nodeToMaskString(node)}[${node.x},${node.y}]`;
|
|
259339
260699
|
return s;
|
|
259340
260700
|
}
|
|
260701
|
+
/** Return the [id, [x,y],z] of a node. Useful for collector methods. */
|
|
260702
|
+
static nodeToIdXYZString(node) {
|
|
260703
|
+
return `[${node.id.toString()}: ${node.x},${node.y},${node.z}]`;
|
|
260704
|
+
}
|
|
259341
260705
|
/** Create a string representation of the mask
|
|
259342
260706
|
* * Null mask is empty string.
|
|
259343
260707
|
* * Appended characters B,P,X for Boundary, Primary, Exterior mask bits.
|
|
@@ -259362,7 +260726,13 @@ class HalfEdge {
|
|
|
259362
260726
|
}
|
|
259363
260727
|
/** Return Vector3d to face successor */
|
|
259364
260728
|
vectorToFaceSuccessor(result) {
|
|
259365
|
-
|
|
260729
|
+
const other = this.faceSuccessor;
|
|
260730
|
+
return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(other.x - this.x, other.y - this.y, other.z - this.z, result);
|
|
260731
|
+
}
|
|
260732
|
+
/** Return Vector3d to face successor */
|
|
260733
|
+
vectorToFacePredecessor(result) {
|
|
260734
|
+
const other = this.facePredecessor;
|
|
260735
|
+
return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Vector3d.create(other.x - this.x, other.y - this.y, other.z - this.z, result);
|
|
259366
260736
|
}
|
|
259367
260737
|
/** test if spaceNode is in the sector at sectorNode */
|
|
259368
260738
|
static isNodeVisibleInSector(spaceNode, sectorNode) {
|
|
@@ -259486,6 +260856,14 @@ class HalfEdge {
|
|
|
259486
260856
|
static testNodeMaskNotExterior(node) { return !node.isMaskSet(HalfEdgeMask.EXTERIOR); }
|
|
259487
260857
|
/** Returns Returns true if the node does NOT have Mask.EXTERIOR_MASK set. */
|
|
259488
260858
|
static testMateMaskExterior(node) { return node.edgeMate.isMaskSet(HalfEdgeMask.EXTERIOR); }
|
|
260859
|
+
/** Returns radians between this edge and its face predecessor edge, using all three coordinates x,y,z and given normal to resolve sweep direction.
|
|
260860
|
+
* * The returned angle is positive, i.e. may be larger than PI radians.
|
|
260861
|
+
*/
|
|
260862
|
+
static sectorSweepRadiansXYZ(node, normal) {
|
|
260863
|
+
const nodeB = node.faceSuccessor;
|
|
260864
|
+
const nodeC = node.facePredecessor;
|
|
260865
|
+
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);
|
|
260866
|
+
}
|
|
259489
260867
|
/** Returns Returns true if the face has positive area in xy parts. */
|
|
259490
260868
|
static testFacePositiveAreaXY(node) {
|
|
259491
260869
|
return node.countEdgesAroundFace() > 2 && node.signedFaceArea() > 0.0;
|
|
@@ -259517,6 +260895,26 @@ class HalfEdge {
|
|
|
259517
260895
|
} while (node !== this);
|
|
259518
260896
|
return nodes;
|
|
259519
260897
|
}
|
|
260898
|
+
/**
|
|
260899
|
+
* search around a vertex for nodes that have a specified mask setting.
|
|
260900
|
+
* @param vertexSeed first node to search
|
|
260901
|
+
* @param mask target mask
|
|
260902
|
+
* @param value target value for mask on half edges.
|
|
260903
|
+
* @param collectedNodes optional array to be cleared and receive masked nodes
|
|
260904
|
+
*/
|
|
260905
|
+
collectMaskedEdgesAroundVertex(mask, value = true, result) {
|
|
260906
|
+
if (result === undefined)
|
|
260907
|
+
result = [];
|
|
260908
|
+
else
|
|
260909
|
+
result.length = 0;
|
|
260910
|
+
let node = this;
|
|
260911
|
+
do {
|
|
260912
|
+
if (node.isMaskSet(mask) === value)
|
|
260913
|
+
result.push(node);
|
|
260914
|
+
node = node.vertexSuccessor;
|
|
260915
|
+
} while (node !== this);
|
|
260916
|
+
return result;
|
|
260917
|
+
}
|
|
259520
260918
|
/**
|
|
259521
260919
|
*
|
|
259522
260920
|
* * Evaluate f(node) at each outbound node around this node's vertex loop.
|
|
@@ -259700,7 +261098,7 @@ class HalfEdge {
|
|
|
259700
261098
|
const nodeB1 = nodeB0.faceSuccessor;
|
|
259701
261099
|
if (!result)
|
|
259702
261100
|
result = _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_0__.Vector2d.create();
|
|
259703
|
-
if (
|
|
261101
|
+
if (_numerics_Polynomials__WEBPACK_IMPORTED_MODULE_4__.SmallSystem.linearSystem2d(nodeA1.x - nodeA0.x, nodeB0.x - nodeB1.x, nodeA1.y - nodeA0.y, nodeB0.y - nodeB1.y, nodeB0.x - nodeA0.x, nodeB0.y - nodeA0.y, result))
|
|
259704
261102
|
return result;
|
|
259705
261103
|
return undefined;
|
|
259706
261104
|
}
|
|
@@ -259709,8 +261107,7 @@ class HalfEdge {
|
|
|
259709
261107
|
* * If the edge is horizontal with (approximate) identical y, return the node.
|
|
259710
261108
|
* * If the edge is horizontal with different y, return undefined.
|
|
259711
261109
|
* * If the edge is not horizontal, return the fractional position (possibly outside 0..1) of the intersection.
|
|
259712
|
-
* @param
|
|
259713
|
-
* @param result optional preallocated result
|
|
261110
|
+
* @param node0 Base node of edge
|
|
259714
261111
|
*/
|
|
259715
261112
|
static horizontalScanFraction(node0, y) {
|
|
259716
261113
|
const node1 = node0.faceSuccessor;
|
|
@@ -259725,8 +261122,7 @@ class HalfEdge {
|
|
|
259725
261122
|
* * Compute fractional coordinates of the intersection of a horizontal line with an edge.
|
|
259726
261123
|
* * If the edge is horizontal return undefined (no test for horizontal at y!!!)
|
|
259727
261124
|
* * If the edge is not horizontal and y is between its end y's, return the fraction
|
|
259728
|
-
* @param
|
|
259729
|
-
* @param result optional preallocated result
|
|
261125
|
+
* @param node0 Base node of edge
|
|
259730
261126
|
*/
|
|
259731
261127
|
static horizontalScanFraction01(node0, y) {
|
|
259732
261128
|
const node1 = node0.faceSuccessor;
|
|
@@ -259740,6 +261136,31 @@ class HalfEdge {
|
|
|
259740
261136
|
return fraction;
|
|
259741
261137
|
return undefined;
|
|
259742
261138
|
}
|
|
261139
|
+
/**
|
|
261140
|
+
* Copy various data from source to this.
|
|
261141
|
+
* @param source other half edge.
|
|
261142
|
+
* @param XYZ copy simple coordinates
|
|
261143
|
+
* @param copyVertexData true to copy data belonging to the vertex. (i.e. the "i" member)
|
|
261144
|
+
* @param copyVertexData true to copy data belonging to the edge. (i.e. call transferEdgeData)
|
|
261145
|
+
* @param copyFaceData true to copy faceTag
|
|
261146
|
+
*/
|
|
261147
|
+
copyDataFrom(source, copyXYZ, copyVertexData, copyEdgeData, copyFaceData) {
|
|
261148
|
+
if (copyXYZ) {
|
|
261149
|
+
this.x = source.x;
|
|
261150
|
+
this.y = source.y;
|
|
261151
|
+
this.z = source.z;
|
|
261152
|
+
}
|
|
261153
|
+
if (copyVertexData) {
|
|
261154
|
+
this.i = source.i;
|
|
261155
|
+
}
|
|
261156
|
+
if (copyEdgeData) {
|
|
261157
|
+
HalfEdge.transferEdgeProperties(source, this);
|
|
261158
|
+
this.edgeTag = source.edgeTag;
|
|
261159
|
+
}
|
|
261160
|
+
if (copyFaceData) {
|
|
261161
|
+
this.faceTag = source.faceTag;
|
|
261162
|
+
}
|
|
261163
|
+
}
|
|
259743
261164
|
}
|
|
259744
261165
|
HalfEdge._edgePropertyMasks = [HalfEdgeMask.BOUNDARY_EDGE, HalfEdgeMask.EXTERIOR, HalfEdgeMask.PRIMARY_EDGE, HalfEdgeMask.NULL_FACE];
|
|
259745
261166
|
HalfEdge._totalNodesCreated = 0;
|
|
@@ -259753,7 +261174,7 @@ class HalfEdgeGraph {
|
|
|
259753
261174
|
constructor() {
|
|
259754
261175
|
this._numNodesCreated = 0;
|
|
259755
261176
|
this.allHalfEdges = [];
|
|
259756
|
-
this._maskManager =
|
|
261177
|
+
this._maskManager = _MaskManager__WEBPACK_IMPORTED_MODULE_5__.MaskManager.create(HalfEdgeMask.ALL_GRAB_DROP_MASKS);
|
|
259757
261178
|
}
|
|
259758
261179
|
/** Ask for a mask (from the graph's free pool.) for caller's use.
|
|
259759
261180
|
* * Optionally clear the mask throughout the graph.
|
|
@@ -259780,6 +261201,19 @@ class HalfEdgeGraph {
|
|
|
259780
261201
|
const a = HalfEdge.createHalfEdgePairWithCoordinates(xA, yA, zA, iA, xB, yB, zB, iB, this.allHalfEdges);
|
|
259781
261202
|
return a;
|
|
259782
261203
|
}
|
|
261204
|
+
/**
|
|
261205
|
+
* * Create 2 half edges forming 2 vertices, 1 edge, and 1 face
|
|
261206
|
+
* * The two edges are joined as edgeMate pair.
|
|
261207
|
+
* * The two edges are a 2-half-edge face loop in both the faceSuccessor and facePredecessor directions.
|
|
261208
|
+
* * The two edges are added to the graph's HalfEdge set
|
|
261209
|
+
* * Coordinates are set to zero.
|
|
261210
|
+
* * ids are installed in the two half edges.
|
|
261211
|
+
* @returns Return pointer to the first half edge created. (This has idA as its id.)
|
|
261212
|
+
*/
|
|
261213
|
+
createEdgeIdId(iA = 0, iB = 0) {
|
|
261214
|
+
const a = HalfEdge.createHalfEdgePairWithCoordinates(0.0, 0.0, 0.0, iA, 0.0, 0.0, 0.0, iB, this.allHalfEdges);
|
|
261215
|
+
return a;
|
|
261216
|
+
}
|
|
259783
261217
|
/**
|
|
259784
261218
|
* * create an edge from coordinates x,y,z to (the tail of) an existing half edge.
|
|
259785
261219
|
* @returns Return pointer to the half edge with tail at x,y,z
|
|
@@ -259824,6 +261258,20 @@ class HalfEdgeGraph {
|
|
|
259824
261258
|
const he = HalfEdge.splitEdge(base, xA, yA, zA, iA, this.allHalfEdges);
|
|
259825
261259
|
return he;
|
|
259826
261260
|
}
|
|
261261
|
+
/**
|
|
261262
|
+
* * Create a sliver face "within" an edge.
|
|
261263
|
+
* * this creates two half edges.
|
|
261264
|
+
* * The existing edges both stay in their same face loops and retain coordinates and i value.
|
|
261265
|
+
* * Each existing edge's mate is a new edge (rather than original mate)
|
|
261266
|
+
* * Coordinates are copied to the new edges at respective vertices.
|
|
261267
|
+
* * New faceTag and edgeTag undefined.
|
|
261268
|
+
* * i members are copied around their respective vertices.
|
|
261269
|
+
* @returns Returns the reference to the half edge created.
|
|
261270
|
+
*/
|
|
261271
|
+
splitEdgeCreateSliverFace(base) {
|
|
261272
|
+
const he = HalfEdge.splitEdgeCreateSliverFace(base, this.allHalfEdges);
|
|
261273
|
+
return he;
|
|
261274
|
+
}
|
|
259827
261275
|
/**
|
|
259828
261276
|
* * Insert a vertex in the edge beginning at base, with coordinates specified as a fraction along the existing edge.
|
|
259829
261277
|
* * this creates two half edges.
|
|
@@ -259892,7 +261340,7 @@ class HalfEdgeGraph {
|
|
|
259892
261340
|
const segments = [];
|
|
259893
261341
|
for (const node of this.allHalfEdges) {
|
|
259894
261342
|
if (node.id < node.edgeMate.id)
|
|
259895
|
-
segments.push(
|
|
261343
|
+
segments.push(_curve_LineSegment3d__WEBPACK_IMPORTED_MODULE_6__.LineSegment3d.create(_geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(node.x, node.y), _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(node.faceSuccessor.x, node.faceSuccessor.y)));
|
|
259896
261344
|
}
|
|
259897
261345
|
return segments;
|
|
259898
261346
|
}
|
|
@@ -259961,6 +261409,26 @@ class HalfEdgeGraph {
|
|
|
259961
261409
|
break;
|
|
259962
261410
|
}
|
|
259963
261411
|
}
|
|
261412
|
+
/**
|
|
261413
|
+
* * Visit each edge of the graph once.
|
|
261414
|
+
* * Call the announceEdge function.
|
|
261415
|
+
* * the edge mate will NOT appear in an announceEdge call.
|
|
261416
|
+
* * continue search if announceEdge(graph, node) returns true
|
|
261417
|
+
* * terminate search if announceEdge (graph, node) returns false
|
|
261418
|
+
* @param announceEdge function to apply at one node of each edge.
|
|
261419
|
+
*/
|
|
261420
|
+
announceEdges(announceEdge) {
|
|
261421
|
+
this.clearMask(HalfEdgeMask.VISITED);
|
|
261422
|
+
for (const node of this.allHalfEdges) {
|
|
261423
|
+
if (node.getMask(HalfEdgeMask.VISITED))
|
|
261424
|
+
continue;
|
|
261425
|
+
const mate = node.edgeMate;
|
|
261426
|
+
node.setMask(HalfEdgeMask.VISITED);
|
|
261427
|
+
mate.setMask(HalfEdgeMask.VISITED);
|
|
261428
|
+
if (!announceEdge(this, node))
|
|
261429
|
+
break;
|
|
261430
|
+
}
|
|
261431
|
+
}
|
|
259964
261432
|
/**
|
|
259965
261433
|
* * Visit each vertex loop of the graph once.
|
|
259966
261434
|
* * Call the announceVertex function
|
|
@@ -259979,8 +261447,8 @@ class HalfEdgeGraph {
|
|
|
259979
261447
|
}
|
|
259980
261448
|
}
|
|
259981
261449
|
/**
|
|
259982
|
-
* * Visit each
|
|
259983
|
-
* * Call the
|
|
261450
|
+
* * Visit each half edge (node) of the graph once.
|
|
261451
|
+
* * Call the announceNode function
|
|
259984
261452
|
* * continue search if announceNode(graph, node) returns true
|
|
259985
261453
|
* * terminate search if announce face (graph, node) returns false
|
|
259986
261454
|
* @param announceNode function to apply at one node of each face.
|
|
@@ -260039,6 +261507,99 @@ class HalfEdgeGraph {
|
|
|
260039
261507
|
}
|
|
260040
261508
|
|
|
260041
261509
|
|
|
261510
|
+
/***/ }),
|
|
261511
|
+
|
|
261512
|
+
/***/ "../../core/geometry/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js":
|
|
261513
|
+
/*!************************************************************************************!*\
|
|
261514
|
+
!*** ../../core/geometry/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js ***!
|
|
261515
|
+
\************************************************************************************/
|
|
261516
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
261517
|
+
|
|
261518
|
+
"use strict";
|
|
261519
|
+
__webpack_require__.r(__webpack_exports__);
|
|
261520
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
261521
|
+
/* harmony export */ "HalfEdgeGraphFromIndexedLoopsContext": () => (/* binding */ HalfEdgeGraphFromIndexedLoopsContext)
|
|
261522
|
+
/* harmony export */ });
|
|
261523
|
+
/* harmony import */ var _Graph__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
|
|
261524
|
+
/*---------------------------------------------------------------------------------------------
|
|
261525
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
261526
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
261527
|
+
*--------------------------------------------------------------------------------------------*/
|
|
261528
|
+
|
|
261529
|
+
/** @packageDocumentation
|
|
261530
|
+
* @module Topology
|
|
261531
|
+
*/
|
|
261532
|
+
/**
|
|
261533
|
+
* Context for building a half edge graph from loops defined only by indices.
|
|
261534
|
+
* * Direct use case:
|
|
261535
|
+
* * Create the context.
|
|
261536
|
+
* * Repeatedly call insertLoop(indicesAroundLoop) to announce various loops.
|
|
261537
|
+
* * Finish by accessing the graph property.
|
|
261538
|
+
* @internal
|
|
261539
|
+
*/
|
|
261540
|
+
class HalfEdgeGraphFromIndexedLoopsContext {
|
|
261541
|
+
constructor() {
|
|
261542
|
+
this._unmatchedEdges = new Map();
|
|
261543
|
+
this._graph = new _Graph__WEBPACK_IMPORTED_MODULE_0__.HalfEdgeGraph();
|
|
261544
|
+
this._halfEdgesAroundCurrentLoop = [];
|
|
261545
|
+
}
|
|
261546
|
+
get graph() { return this._graph; }
|
|
261547
|
+
indexPairToString(index0, index1) {
|
|
261548
|
+
return `${index0.toString()},${index1.toString()}`;
|
|
261549
|
+
}
|
|
261550
|
+
/** Create a loop with specified indices at its vertices.
|
|
261551
|
+
* * For an edge with index pair [indexA, indexB]:
|
|
261552
|
+
* * if [indexB, indexA] has never appeared, a HalfEdge mated pair is created.
|
|
261553
|
+
* * One of that mated pair becomes a HalfEdge in this loop.
|
|
261554
|
+
* * The other is "unmatched"
|
|
261555
|
+
* * When announceMatedHalfEdges(halfEdge) is called:
|
|
261556
|
+
* * halfEdge and its mate are "new"
|
|
261557
|
+
* * all coordinates are zeros.
|
|
261558
|
+
* * each contains (as its halfEdge.id property) one index of the [indexA,indexB] pair.
|
|
261559
|
+
* * those coordinates and indices will never be referenced again by this construction sequence -- the caller is free to mutate them as needed.
|
|
261560
|
+
* * if [indexB, indexA] appeared previously (and its outer HalfEdge was left "unmatched"),
|
|
261561
|
+
* the "unmatched" HalfEdge is used in the loop being constructed.
|
|
261562
|
+
* @param indices Array of indices around the edge. This is accessed cyclically.
|
|
261563
|
+
* @param announceMatedHalfEdges optional function to be called as mated pairs are created. At the call,
|
|
261564
|
+
* the given HalfEdge and its mate will have a pair of successive indices from the array.
|
|
261565
|
+
*/
|
|
261566
|
+
insertLoop(indices, announceMatedHalfEdges) {
|
|
261567
|
+
const n = indices.length;
|
|
261568
|
+
if (n > 1) {
|
|
261569
|
+
let index0 = indices[indices.length - 1];
|
|
261570
|
+
this._halfEdgesAroundCurrentLoop.length = 0;
|
|
261571
|
+
for (const index1 of indices) {
|
|
261572
|
+
const insideString = this.indexPairToString(index0, index1);
|
|
261573
|
+
const halfEdgePreviouslyConstructedFromOppositeSide = this._unmatchedEdges.get(insideString);
|
|
261574
|
+
if (halfEdgePreviouslyConstructedFromOppositeSide === undefined) {
|
|
261575
|
+
// This is the first appearance of this edge in either direction.
|
|
261576
|
+
const outsideString = this.indexPairToString(index1, index0); // string referencing the "other" side of the new edge.
|
|
261577
|
+
const newHalfEdgeAroundLoop = this._graph.createEdgeIdId(index0, index1);
|
|
261578
|
+
if (announceMatedHalfEdges !== undefined)
|
|
261579
|
+
announceMatedHalfEdges(newHalfEdgeAroundLoop);
|
|
261580
|
+
this._unmatchedEdges.set(outsideString, newHalfEdgeAroundLoop.edgeMate);
|
|
261581
|
+
this._halfEdgesAroundCurrentLoop.push(newHalfEdgeAroundLoop);
|
|
261582
|
+
newHalfEdgeAroundLoop.edgeMate.setMask(_Graph__WEBPACK_IMPORTED_MODULE_0__.HalfEdgeMask.EXTERIOR);
|
|
261583
|
+
}
|
|
261584
|
+
else {
|
|
261585
|
+
this._halfEdgesAroundCurrentLoop.push(halfEdgePreviouslyConstructedFromOppositeSide);
|
|
261586
|
+
halfEdgePreviouslyConstructedFromOppositeSide.clearMask(_Graph__WEBPACK_IMPORTED_MODULE_0__.HalfEdgeMask.EXTERIOR);
|
|
261587
|
+
}
|
|
261588
|
+
index0 = index1;
|
|
261589
|
+
}
|
|
261590
|
+
let halfEdgeA = this._halfEdgesAroundCurrentLoop[this._halfEdgesAroundCurrentLoop.length - 1];
|
|
261591
|
+
for (const halfEdgeB of this._halfEdgesAroundCurrentLoop) {
|
|
261592
|
+
const halfEdgeC = halfEdgeA.faceSuccessor;
|
|
261593
|
+
_Graph__WEBPACK_IMPORTED_MODULE_0__.HalfEdge.pinch(halfEdgeB, halfEdgeC);
|
|
261594
|
+
halfEdgeA = halfEdgeB;
|
|
261595
|
+
}
|
|
261596
|
+
return this._halfEdgesAroundCurrentLoop[0];
|
|
261597
|
+
}
|
|
261598
|
+
return undefined;
|
|
261599
|
+
}
|
|
261600
|
+
}
|
|
261601
|
+
|
|
261602
|
+
|
|
260042
261603
|
/***/ }),
|
|
260043
261604
|
|
|
260044
261605
|
/***/ "../../core/geometry/lib/esm/topology/HalfEdgeGraphSearch.js":
|
|
@@ -285523,7 +287084,7 @@ class TestContext {
|
|
|
285523
287084
|
this.initializeRpcInterfaces({ title: this.settings.Backend.name, version: this.settings.Backend.version });
|
|
285524
287085
|
const iModelClient = new imodels_client_management_1.IModelsClient({ api: { baseUrl: `https://${(_a = process.env.IMJS_URL_PREFIX) !== null && _a !== void 0 ? _a : ""}api.bentley.com/imodels` } });
|
|
285525
287086
|
await core_frontend_1.NoRenderApp.startup({
|
|
285526
|
-
applicationVersion: "4.0.0-dev.
|
|
287087
|
+
applicationVersion: "4.0.0-dev.8",
|
|
285527
287088
|
applicationId: this.settings.gprid,
|
|
285528
287089
|
authorizationClient: new frontend_1.TestFrontendAuthorizationClient(this.adminUserAccessToken),
|
|
285529
287090
|
hubAccess: new imodels_access_frontend_1.FrontendIModelsAccess(iModelClient),
|
|
@@ -304952,7 +306513,7 @@ module.exports = JSON.parse('{"name":"axios","version":"0.21.4","description":"P
|
|
|
304952
306513
|
/***/ ((module) => {
|
|
304953
306514
|
|
|
304954
306515
|
"use strict";
|
|
304955
|
-
module.exports = JSON.parse('{"name":"@itwin/core-frontend","version":"4.0.0-dev.
|
|
306516
|
+
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"}}]}}');
|
|
304956
306517
|
|
|
304957
306518
|
/***/ }),
|
|
304958
306519
|
|