brepjs 18.119.2 → 18.119.4
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/dist/2d/blueprints/blueprints.d.ts +3 -0
- package/dist/2d/blueprints/compoundBlueprint.d.ts +3 -0
- package/dist/2d/blueprints/lib.d.ts +6 -0
- package/dist/2d/lib/curve2D.d.ts +6 -1
- package/dist/2d/lib/curve2dFns.d.ts +6 -1
- package/dist/2d.cjs +7 -7
- package/dist/2d.js +7 -7
- package/dist/{adjacencyFns-BdM5p58J.js → adjacencyFns-DLityMyV.js} +2 -2
- package/dist/{adjacencyFns-Brrc7jlS.cjs → adjacencyFns-DSxuQYnb.cjs} +2 -2
- package/dist/{blueprint-DJJo8WkI.js → blueprint-DEMSX-hc.js} +37 -10
- package/dist/{blueprint-DTNT4qYJ.cjs → blueprint-DUnNPwQL.cjs} +43 -10
- package/dist/{blueprintFns-CcpboZ80.js → blueprintFns-DSj4RTjU.js} +9 -4
- package/dist/{blueprintFns-2XDZfCxX.cjs → blueprintFns-Dg8V99O9.cjs} +9 -4
- package/dist/{blueprintSketcher-DDPyypmC.js → blueprintSketcher-gMuUUPb-.js} +185 -54
- package/dist/{blueprintSketcher-C0EXFVb2.cjs → blueprintSketcher-gXVPrPlj.cjs} +192 -61
- package/dist/{boolean2D-Ddfo_dd0.cjs → boolean2D-BpmxQ1AH.cjs} +5 -5
- package/dist/{boolean2D-C_PVz8xT.js → boolean2D-DKT0BgZs.js} +5 -5
- package/dist/brepjs.cjs +105 -92
- package/dist/brepjs.js +39 -27
- package/dist/{cameraFns-Czr5vABD.cjs → cameraFns-2-haLzLi.cjs} +4 -4
- package/dist/{cameraFns-D9tdBYLM.js → cameraFns-CG_J66Hl.js} +4 -4
- package/dist/core.cjs +12 -11
- package/dist/core.js +4 -3
- package/dist/{cornerFinder-Cqg-Dz74.js → cornerFinder-CPFM7bA0.js} +1 -1
- package/dist/{cornerFinder-DETRDOMz.cjs → cornerFinder-mfsUMi5g.cjs} +1 -1
- package/dist/{curveFns-RENXKp64.js → curveFns-DX13KRh2.js} +2 -2
- package/dist/{curveFns-D7utcbnf.cjs → curveFns-GmFnqNo3.cjs} +2 -2
- package/dist/{drawFns-D9Rf4foW.cjs → drawFns-CI6CpqO8.cjs} +35 -16
- package/dist/{drawFns-B9HbtAoc.js → drawFns-CrfBz_wj.js} +35 -16
- package/dist/{errors-B3CDG537.js → errors-MHLiNE-C.js} +1 -92
- package/dist/{errors-CJU8CHng.cjs → errors-RHkKO5bZ.cjs} +0 -103
- package/dist/{faceFns-CPswi9Cm.cjs → faceFns-BK4r7Dxk.cjs} +3 -3
- package/dist/{faceFns-CB6uzvOg.js → faceFns-DJj9Nb6T.js} +3 -3
- package/dist/{healingFns-BFTYLiAm.js → healingFns-DxcRyVCG.js} +5 -6
- package/dist/{healingFns-bhMxTTqw.cjs → healingFns-Hx4oTlq8.cjs} +27 -28
- package/dist/{helpers-Cu4ag5bh.cjs → helpers-BfkBvokP.cjs} +8 -24
- package/dist/{helpers-BiN4qQZP.js → helpers-Du_OdHuy.js} +9 -25
- package/dist/{importFns-X8vBhZI2.js → importFns-DqxAZFb-.js} +3 -3
- package/dist/{importFns-DS4J1xLv.cjs → importFns-pr-r5qiV.cjs} +3 -3
- package/dist/io.cjs +2 -2
- package/dist/io.js +2 -2
- package/dist/{loftFns-ChHjzUK-.cjs → loftFns-BdpZ8FMN.cjs} +2 -125
- package/dist/{loftFns-BF5X7ltI.js → loftFns-BeGJ6dxx.js} +4 -109
- package/dist/{measureFns-B5Zzg1qM.cjs → measureFns-CJGrmhHT.cjs} +4 -4
- package/dist/{measureFns-CC7HhAH3.js → measureFns-CMnbcUZC.js} +4 -4
- package/dist/measurement.cjs +1 -1
- package/dist/measurement.js +1 -1
- package/dist/{meshFns-D57Fyqyf.js → meshFns-Cs5EBsf7.js} +4 -4
- package/dist/{meshFns-CaXmWmhe.cjs → meshFns-Dqf5QBhQ.cjs} +5 -5
- package/dist/operations.cjs +2 -2
- package/dist/operations.js +2 -2
- package/dist/originTrackingFns-DZmdiQ-O.js +203 -0
- package/dist/originTrackingFns-fpEgTIwV.cjs +226 -0
- package/dist/{planeOps-Cp6GQ23-.js → planeOps-CQahLrCx.js} +1 -1
- package/dist/{planeOps-Cr25KWWA.cjs → planeOps-VlFxtvzY.cjs} +1 -1
- package/dist/primitiveFns-B_rflH83.cjs +773 -0
- package/dist/primitiveFns-Cxo3xDKY.js +558 -0
- package/dist/projection.cjs +1 -1
- package/dist/projection.js +1 -1
- package/dist/query.cjs +2 -2
- package/dist/query.js +2 -2
- package/dist/{refResolveFns-3bw9-U-e.js → refResolveFns-BbRLD8LA.js} +6 -6
- package/dist/{refResolveFns-BxmgIhQM.cjs → refResolveFns-CVDLwh12.cjs} +6 -6
- package/dist/result.cjs +1 -1
- package/dist/result.js +1 -1
- package/dist/rolldown-runtime-DakpK96I.cjs +43 -0
- package/dist/shapeFns-BTFx-os7.js +43 -0
- package/dist/shapeFns-D_5TgiUi.cjs +84 -0
- package/dist/shapeRef.cjs +1 -1
- package/dist/shapeRef.js +1 -1
- package/dist/{shapeTypes-Bpsu5KJO.cjs → shapeTypes-CkcIL7zv.cjs} +1 -222
- package/dist/{shapeTypes-CnKFSfDT.js → shapeTypes-t49f64Dx.js} +2 -139
- package/dist/sketching/drawing.d.ts +9 -1
- package/dist/sketching.cjs +3 -3
- package/dist/sketching.js +3 -3
- package/dist/{solidBuilders-I8_V8qqU.js → solidBuilders-DTgqQC3W.js} +310 -8
- package/dist/{solidBuilders-Bp7lQW62.cjs → solidBuilders-IiIzjKAr.cjs} +401 -15
- package/dist/{surfaceBuilders-D8_08oOR.cjs → surfaceBuilders-Biqx51el.cjs} +6 -5
- package/dist/{surfaceBuilders-BNR7yMQO.js → surfaceBuilders-BryY-i0F.js} +4 -3
- package/dist/text.cjs +2 -2
- package/dist/text.js +2 -2
- package/dist/{textBlueprints-B5zcLGvJ.cjs → textBlueprints-BY0FEg59.cjs} +138 -51
- package/dist/{textBlueprints-igbNvKcd.js → textBlueprints-ZzYg3XTS.js} +116 -11
- package/dist/{textMetrics-CJvtpbc3.js → textMetrics-Diakbtem.js} +2 -2
- package/dist/{textMetrics-08fF0QNf.cjs → textMetrics-f5yXR4OG.cjs} +2 -2
- package/dist/{threadFns-CqSMNyTZ.js → threadFns-BOtXTHZ9.js} +8 -8
- package/dist/{threadFns-Co6vWEWx.cjs → threadFns-DRrk9Qod.cjs} +8 -8
- package/dist/topology.cjs +9 -9
- package/dist/topology.js +9 -9
- package/dist/{topologyQueryFns-C3fhJndG.cjs → topologyQueryFns-Bia7o8l_.cjs} +97 -6
- package/dist/{topologyQueryFns-DNqT88yx.js → topologyQueryFns-BkQ6Q7gN.js} +93 -2
- package/dist/validityTypes-DiTgeCD9.js +129 -0
- package/dist/validityTypes-ZGMVlv7b.cjs +200 -0
- package/dist/vectors.cjs +1 -1
- package/dist/vectors.js +1 -1
- package/package.json +8 -8
- package/dist/primitiveFns-CRy_CUVg.cjs +0 -492
- package/dist/primitiveFns-DCIH-SBm.js +0 -331
- package/dist/shapeFns-BrHFNLMA.js +0 -771
- package/dist/shapeFns-qm9VRo4i.cjs +0 -962
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const require_shapeTypes = require("./shapeTypes-
|
|
2
|
-
const require_errors = require("./errors-
|
|
1
|
+
const require_shapeTypes = require("./shapeTypes-CkcIL7zv.cjs");
|
|
2
|
+
const require_errors = require("./errors-RHkKO5bZ.cjs");
|
|
3
3
|
const require_types = require("./types-KjA8tY4Y.cjs");
|
|
4
4
|
const require_vecOps = require("./vecOps-CCnJt-yH.cjs");
|
|
5
5
|
//#region src/operations/extrudeUtils.ts
|
|
@@ -337,111 +337,6 @@ function guidedSweep(profile, spine, guides, options = {}) {
|
|
|
337
337
|
}
|
|
338
338
|
}
|
|
339
339
|
//#endregion
|
|
340
|
-
//#region src/operations/extrudeFns.ts
|
|
341
|
-
/**
|
|
342
|
-
* Basic extrusion operations — extrude and revolve.
|
|
343
|
-
*
|
|
344
|
-
* Sweep-based operations (sweep, supportExtrude, complexExtrude, twistExtrude)
|
|
345
|
-
* have moved to `./sweepFns.js`.
|
|
346
|
-
*/
|
|
347
|
-
/**
|
|
348
|
-
* Extrude a face along a vector to produce a solid.
|
|
349
|
-
*
|
|
350
|
-
* @param face - The planar face to extrude.
|
|
351
|
-
* @param extrusionVec - Direction and magnitude of the extrusion as `[x, y, z]`.
|
|
352
|
-
* @returns `Result` containing the extruded solid, or an error if validation or operation fails.
|
|
353
|
-
*/
|
|
354
|
-
function extrude(face, extrusionVec) {
|
|
355
|
-
if (require_shapeTypes.getKernel().isNull(face.wrapped)) return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.NULL_SHAPE_INPUT, "extrude: face is a null shape"));
|
|
356
|
-
if (require_vecOps.vecLength(extrusionVec) < 1e-10) return require_errors.err(require_errors.validationError("EXTRUDE_ZERO_VECTOR", "extrude: extrusion vector has zero length"));
|
|
357
|
-
try {
|
|
358
|
-
const kernel = require_shapeTypes.getKernel();
|
|
359
|
-
const len = require_vecOps.vecLength(extrusionVec);
|
|
360
|
-
const dir = require_vecOps.vecNormalize(extrusionVec);
|
|
361
|
-
const shape = kernel.extrude(face.wrapped, [...dir], len);
|
|
362
|
-
const solid = require_shapeTypes.createSolid(kernel.downcast(shape, "solid"));
|
|
363
|
-
require_shapeTypes.disposeDowncastSource(shape, solid);
|
|
364
|
-
return require_errors.ok(solid);
|
|
365
|
-
} catch (e) {
|
|
366
|
-
return require_errors.err(require_errors.kernelError("EXTRUDE_FAILED", "Extrusion operation failed", e, {
|
|
367
|
-
operation: "extrude",
|
|
368
|
-
vectorLength: require_vecOps.vecLength(extrusionVec)
|
|
369
|
-
}));
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
/**
|
|
373
|
-
* Revolve a face around an axis to create a solid of revolution.
|
|
374
|
-
*
|
|
375
|
-
* @param face - The face to revolve.
|
|
376
|
-
* @param center - A point on the rotation axis. Defaults to the origin.
|
|
377
|
-
* @param direction - Direction vector of the rotation axis. Defaults to Z-up.
|
|
378
|
-
* @param angle - Rotation angle in **radians**. Defaults to 2π (a full revolution).
|
|
379
|
-
* @returns `Result` containing the revolved 3D shape, or an error if the result is not 3D.
|
|
380
|
-
*/
|
|
381
|
-
function revolve(face, center = [
|
|
382
|
-
0,
|
|
383
|
-
0,
|
|
384
|
-
0
|
|
385
|
-
], direction = [
|
|
386
|
-
0,
|
|
387
|
-
0,
|
|
388
|
-
1
|
|
389
|
-
], angle = 2 * Math.PI) {
|
|
390
|
-
if (require_shapeTypes.getKernel().isNull(face.wrapped)) return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.NULL_SHAPE_INPUT, "revolve: face is a null shape"));
|
|
391
|
-
try {
|
|
392
|
-
const result = require_shapeTypes.castResultShape(require_shapeTypes.getKernel().revolveVec(face.wrapped, [...center], [...direction], angle));
|
|
393
|
-
if (!require_shapeTypes.isShape3D(result)) {
|
|
394
|
-
require_shapeTypes.disposeResultShape(result);
|
|
395
|
-
return require_errors.err(require_errors.typeCastError("REVOLUTION_NOT_3D", "Revolution did not produce a 3D shape"));
|
|
396
|
-
}
|
|
397
|
-
return require_errors.ok(result);
|
|
398
|
-
} catch (e) {
|
|
399
|
-
return require_errors.err(require_errors.kernelError("REVOLVE_FAILED", "Revolution operation failed", e, {
|
|
400
|
-
operation: "revolve",
|
|
401
|
-
angle
|
|
402
|
-
}));
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
/**
|
|
406
|
-
* Batch extrude: build N independent extrusions in a single kernel call.
|
|
407
|
-
*
|
|
408
|
-
* Uses the C++ ExtrudeBatch extractor when available (single WASM call),
|
|
409
|
-
* falling back to N individual extrude operations otherwise.
|
|
410
|
-
*
|
|
411
|
-
* @returns Array of valid solids, one per entry.
|
|
412
|
-
*/
|
|
413
|
-
function extrudeAll(entries) {
|
|
414
|
-
if (entries.length === 0) return require_errors.ok([]);
|
|
415
|
-
const kernel = require_shapeTypes.getKernel();
|
|
416
|
-
const kernelEntries = [];
|
|
417
|
-
for (let i = 0; i < entries.length; i++) {
|
|
418
|
-
const e = entries[i];
|
|
419
|
-
if (!e) continue;
|
|
420
|
-
const vec = typeof e.height === "number" ? [
|
|
421
|
-
0,
|
|
422
|
-
0,
|
|
423
|
-
e.height
|
|
424
|
-
] : e.height;
|
|
425
|
-
const len = require_vecOps.vecLength(vec);
|
|
426
|
-
if (len < 1e-10) return require_errors.err(require_errors.validationError("EXTRUDE_ALL_ZERO_VECTOR", `extrudeAll: entry ${i} has zero-length extrusion vector`));
|
|
427
|
-
const direction = [...require_vecOps.vecNormalize(vec)];
|
|
428
|
-
kernelEntries.push({
|
|
429
|
-
face: e.face.wrapped,
|
|
430
|
-
direction,
|
|
431
|
-
length: len
|
|
432
|
-
});
|
|
433
|
-
}
|
|
434
|
-
try {
|
|
435
|
-
return require_errors.ok((kernel.extrudeBatch?.(kernelEntries) ?? kernelEntries.map((e) => kernel.extrude(e.face, e.direction, e.length))).map((shape) => {
|
|
436
|
-
const solid = require_shapeTypes.createSolid(kernel.downcast(shape, "solid"));
|
|
437
|
-
require_shapeTypes.disposeDowncastSource(shape, solid);
|
|
438
|
-
return solid;
|
|
439
|
-
}));
|
|
440
|
-
} catch (e) {
|
|
441
|
-
return require_errors.err(require_errors.kernelError("EXTRUDE_ALL_FAILED", "Batch extrusion operation failed", e));
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
//#endregion
|
|
445
340
|
//#region src/operations/loftFns.ts
|
|
446
341
|
/**
|
|
447
342
|
* Functional loft operation using branded shape types.
|
|
@@ -544,18 +439,6 @@ Object.defineProperty(exports, "complexExtrude", {
|
|
|
544
439
|
return complexExtrude;
|
|
545
440
|
}
|
|
546
441
|
});
|
|
547
|
-
Object.defineProperty(exports, "extrude", {
|
|
548
|
-
enumerable: true,
|
|
549
|
-
get: function() {
|
|
550
|
-
return extrude;
|
|
551
|
-
}
|
|
552
|
-
});
|
|
553
|
-
Object.defineProperty(exports, "extrudeAll", {
|
|
554
|
-
enumerable: true,
|
|
555
|
-
get: function() {
|
|
556
|
-
return extrudeAll;
|
|
557
|
-
}
|
|
558
|
-
});
|
|
559
442
|
Object.defineProperty(exports, "guidedSweep", {
|
|
560
443
|
enumerable: true,
|
|
561
444
|
get: function() {
|
|
@@ -580,12 +463,6 @@ Object.defineProperty(exports, "multiSectionSweep", {
|
|
|
580
463
|
return multiSectionSweep;
|
|
581
464
|
}
|
|
582
465
|
});
|
|
583
|
-
Object.defineProperty(exports, "revolve", {
|
|
584
|
-
enumerable: true,
|
|
585
|
-
get: function() {
|
|
586
|
-
return revolve;
|
|
587
|
-
}
|
|
588
|
-
});
|
|
589
466
|
Object.defineProperty(exports, "supportExtrude", {
|
|
590
467
|
enumerable: true,
|
|
591
468
|
get: function() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { K as getKernel, T as isWire, W as _usingCtx, h as disposeResultShape, n as castResultShape, x as isShape3D } from "./shapeTypes-t49f64Dx.js";
|
|
2
|
+
import { E as ok, b as isErr, d as validationError, g as err, i as kernelError, l as typeCastError, t as BrepErrorCode } from "./errors-MHLiNE-C.js";
|
|
3
3
|
import { r as toVec3 } from "./types-D24Y27N0.js";
|
|
4
|
-
import { c as vecLength,
|
|
4
|
+
import { c as vecLength, t as vecAdd } from "./vecOps-SKPRvPH-.js";
|
|
5
5
|
//#region src/operations/extrudeUtils.ts
|
|
6
6
|
/**
|
|
7
7
|
* Shared utilities for extrusion operations.
|
|
@@ -337,111 +337,6 @@ function guidedSweep(profile, spine, guides, options = {}) {
|
|
|
337
337
|
}
|
|
338
338
|
}
|
|
339
339
|
//#endregion
|
|
340
|
-
//#region src/operations/extrudeFns.ts
|
|
341
|
-
/**
|
|
342
|
-
* Basic extrusion operations — extrude and revolve.
|
|
343
|
-
*
|
|
344
|
-
* Sweep-based operations (sweep, supportExtrude, complexExtrude, twistExtrude)
|
|
345
|
-
* have moved to `./sweepFns.js`.
|
|
346
|
-
*/
|
|
347
|
-
/**
|
|
348
|
-
* Extrude a face along a vector to produce a solid.
|
|
349
|
-
*
|
|
350
|
-
* @param face - The planar face to extrude.
|
|
351
|
-
* @param extrusionVec - Direction and magnitude of the extrusion as `[x, y, z]`.
|
|
352
|
-
* @returns `Result` containing the extruded solid, or an error if validation or operation fails.
|
|
353
|
-
*/
|
|
354
|
-
function extrude(face, extrusionVec) {
|
|
355
|
-
if (getKernel().isNull(face.wrapped)) return err(validationError(BrepErrorCode.NULL_SHAPE_INPUT, "extrude: face is a null shape"));
|
|
356
|
-
if (vecLength(extrusionVec) < 1e-10) return err(validationError("EXTRUDE_ZERO_VECTOR", "extrude: extrusion vector has zero length"));
|
|
357
|
-
try {
|
|
358
|
-
const kernel = getKernel();
|
|
359
|
-
const len = vecLength(extrusionVec);
|
|
360
|
-
const dir = vecNormalize(extrusionVec);
|
|
361
|
-
const shape = kernel.extrude(face.wrapped, [...dir], len);
|
|
362
|
-
const solid = createSolid(kernel.downcast(shape, "solid"));
|
|
363
|
-
disposeDowncastSource(shape, solid);
|
|
364
|
-
return ok(solid);
|
|
365
|
-
} catch (e) {
|
|
366
|
-
return err(kernelError("EXTRUDE_FAILED", "Extrusion operation failed", e, {
|
|
367
|
-
operation: "extrude",
|
|
368
|
-
vectorLength: vecLength(extrusionVec)
|
|
369
|
-
}));
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
/**
|
|
373
|
-
* Revolve a face around an axis to create a solid of revolution.
|
|
374
|
-
*
|
|
375
|
-
* @param face - The face to revolve.
|
|
376
|
-
* @param center - A point on the rotation axis. Defaults to the origin.
|
|
377
|
-
* @param direction - Direction vector of the rotation axis. Defaults to Z-up.
|
|
378
|
-
* @param angle - Rotation angle in **radians**. Defaults to 2π (a full revolution).
|
|
379
|
-
* @returns `Result` containing the revolved 3D shape, or an error if the result is not 3D.
|
|
380
|
-
*/
|
|
381
|
-
function revolve(face, center = [
|
|
382
|
-
0,
|
|
383
|
-
0,
|
|
384
|
-
0
|
|
385
|
-
], direction = [
|
|
386
|
-
0,
|
|
387
|
-
0,
|
|
388
|
-
1
|
|
389
|
-
], angle = 2 * Math.PI) {
|
|
390
|
-
if (getKernel().isNull(face.wrapped)) return err(validationError(BrepErrorCode.NULL_SHAPE_INPUT, "revolve: face is a null shape"));
|
|
391
|
-
try {
|
|
392
|
-
const result = castResultShape(getKernel().revolveVec(face.wrapped, [...center], [...direction], angle));
|
|
393
|
-
if (!isShape3D(result)) {
|
|
394
|
-
disposeResultShape(result);
|
|
395
|
-
return err(typeCastError("REVOLUTION_NOT_3D", "Revolution did not produce a 3D shape"));
|
|
396
|
-
}
|
|
397
|
-
return ok(result);
|
|
398
|
-
} catch (e) {
|
|
399
|
-
return err(kernelError("REVOLVE_FAILED", "Revolution operation failed", e, {
|
|
400
|
-
operation: "revolve",
|
|
401
|
-
angle
|
|
402
|
-
}));
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
/**
|
|
406
|
-
* Batch extrude: build N independent extrusions in a single kernel call.
|
|
407
|
-
*
|
|
408
|
-
* Uses the C++ ExtrudeBatch extractor when available (single WASM call),
|
|
409
|
-
* falling back to N individual extrude operations otherwise.
|
|
410
|
-
*
|
|
411
|
-
* @returns Array of valid solids, one per entry.
|
|
412
|
-
*/
|
|
413
|
-
function extrudeAll(entries) {
|
|
414
|
-
if (entries.length === 0) return ok([]);
|
|
415
|
-
const kernel = getKernel();
|
|
416
|
-
const kernelEntries = [];
|
|
417
|
-
for (let i = 0; i < entries.length; i++) {
|
|
418
|
-
const e = entries[i];
|
|
419
|
-
if (!e) continue;
|
|
420
|
-
const vec = typeof e.height === "number" ? [
|
|
421
|
-
0,
|
|
422
|
-
0,
|
|
423
|
-
e.height
|
|
424
|
-
] : e.height;
|
|
425
|
-
const len = vecLength(vec);
|
|
426
|
-
if (len < 1e-10) return err(validationError("EXTRUDE_ALL_ZERO_VECTOR", `extrudeAll: entry ${i} has zero-length extrusion vector`));
|
|
427
|
-
const direction = [...vecNormalize(vec)];
|
|
428
|
-
kernelEntries.push({
|
|
429
|
-
face: e.face.wrapped,
|
|
430
|
-
direction,
|
|
431
|
-
length: len
|
|
432
|
-
});
|
|
433
|
-
}
|
|
434
|
-
try {
|
|
435
|
-
return ok((kernel.extrudeBatch?.(kernelEntries) ?? kernelEntries.map((e) => kernel.extrude(e.face, e.direction, e.length))).map((shape) => {
|
|
436
|
-
const solid = createSolid(kernel.downcast(shape, "solid"));
|
|
437
|
-
disposeDowncastSource(shape, solid);
|
|
438
|
-
return solid;
|
|
439
|
-
}));
|
|
440
|
-
} catch (e) {
|
|
441
|
-
return err(kernelError("EXTRUDE_ALL_FAILED", "Batch extrusion operation failed", e));
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
//#endregion
|
|
445
340
|
//#region src/operations/loftFns.ts
|
|
446
341
|
/**
|
|
447
342
|
* Functional loft operation using branded shape types.
|
|
@@ -538,4 +433,4 @@ function loftAll(entries) {
|
|
|
538
433
|
}
|
|
539
434
|
}
|
|
540
435
|
//#endregion
|
|
541
|
-
export {
|
|
436
|
+
export { multiSectionSweep as a, twistExtrude as c, guidedSweep as i, loftAll as n, supportExtrude as o, complexExtrude as r, sweep as s, loft as t };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const require_shapeTypes = require("./shapeTypes-
|
|
2
|
-
const require_errors = require("./errors-
|
|
3
|
-
const require_topologyQueryFns = require("./topologyQueryFns-
|
|
4
|
-
const require_faceFns = require("./faceFns-
|
|
1
|
+
const require_shapeTypes = require("./shapeTypes-CkcIL7zv.cjs");
|
|
2
|
+
const require_errors = require("./errors-RHkKO5bZ.cjs");
|
|
3
|
+
const require_topologyQueryFns = require("./topologyQueryFns-Bia7o8l_.cjs");
|
|
4
|
+
const require_faceFns = require("./faceFns-BK4r7Dxk.cjs");
|
|
5
5
|
//#region src/measurement/measureCache.ts
|
|
6
6
|
var cache = /* @__PURE__ */ new WeakMap();
|
|
7
7
|
function getCachedMeasurement(shape, key) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { T as kernelCallRaw } from "./topologyQueryFns-
|
|
4
|
-
import { m as uvBounds } from "./faceFns-
|
|
1
|
+
import { K as getKernel } from "./shapeTypes-t49f64Dx.js";
|
|
2
|
+
import { E as ok, d as validationError, g as err, t as BrepErrorCode } from "./errors-MHLiNE-C.js";
|
|
3
|
+
import { T as kernelCallRaw } from "./topologyQueryFns-BkQ6Q7gN.js";
|
|
4
|
+
import { m as uvBounds } from "./faceFns-DJj9Nb6T.js";
|
|
5
5
|
//#region src/measurement/measureCache.ts
|
|
6
6
|
var cache = /* @__PURE__ */ new WeakMap();
|
|
7
7
|
function getCachedMeasurement(shape, key) {
|
package/dist/measurement.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_measureFns = require("./measureFns-
|
|
2
|
+
const require_measureFns = require("./measureFns-CJGrmhHT.cjs");
|
|
3
3
|
exports.createDistanceQuery = require_measureFns.createDistanceQuery;
|
|
4
4
|
exports.measureArea = require_measureFns.measureArea;
|
|
5
5
|
exports.measureDistance = require_measureFns.measureDistance;
|
package/dist/measurement.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as measureDistance, c as measureLinearProps, d as measureVolumeProps, l as measureSurfaceProps, n as measureArea, o as measureDistanceProps, s as measureLength, t as createDistanceQuery, u as measureVolume } from "./measureFns-
|
|
1
|
+
import { a as measureDistance, c as measureLinearProps, d as measureVolumeProps, l as measureSurfaceProps, n as measureArea, o as measureDistanceProps, s as measureLength, t as createDistanceQuery, u as measureVolume } from "./measureFns-CMnbcUZC.js";
|
|
2
2
|
export { createDistanceQuery, measureArea, measureDistance, measureDistanceProps, measureLength, measureLinearProps, measureSurfaceProps, measureVolume, measureVolumeProps };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { d as getSolids, n as getBounds } from "./topologyQueryFns-
|
|
4
|
-
import {
|
|
1
|
+
import { K as getKernel, lt as qualityDeflection } from "./shapeTypes-t49f64Dx.js";
|
|
2
|
+
import { E as ok, g as err, r as ioError } from "./errors-MHLiNE-C.js";
|
|
3
|
+
import { d as getSolids, n as getBounds } from "./topologyQueryFns-BkQ6Q7gN.js";
|
|
4
|
+
import { t as getFaceOrigins } from "./originTrackingFns-DZmdiQ-O.js";
|
|
5
5
|
//#region src/topology/meshCache.ts
|
|
6
6
|
/**
|
|
7
7
|
* Build a parameter key for the inner cache map (excludes shape identity).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const require_shapeTypes = require("./shapeTypes-
|
|
2
|
-
const require_errors = require("./errors-
|
|
3
|
-
const require_topologyQueryFns = require("./topologyQueryFns-
|
|
4
|
-
const
|
|
1
|
+
const require_shapeTypes = require("./shapeTypes-CkcIL7zv.cjs");
|
|
2
|
+
const require_errors = require("./errors-RHkKO5bZ.cjs");
|
|
3
|
+
const require_topologyQueryFns = require("./topologyQueryFns-Bia7o8l_.cjs");
|
|
4
|
+
const require_originTrackingFns = require("./originTrackingFns-fpEgTIwV.cjs");
|
|
5
5
|
//#region src/topology/meshCache.ts
|
|
6
6
|
/**
|
|
7
7
|
* Build a parameter key for the inner cache map (excludes shape identity).
|
|
@@ -137,7 +137,7 @@ function mesh(shape, opts = {}) {
|
|
|
137
137
|
includeUVs,
|
|
138
138
|
...signal ? { signal } : {}
|
|
139
139
|
});
|
|
140
|
-
const origins =
|
|
140
|
+
const origins = require_originTrackingFns.getFaceOrigins(shape);
|
|
141
141
|
const mesh = {
|
|
142
142
|
vertices: result.vertices,
|
|
143
143
|
normals: result.normals,
|
package/dist/operations.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_threadFns = require("./threadFns-
|
|
3
|
-
const require_loftFns = require("./loftFns-
|
|
2
|
+
const require_threadFns = require("./threadFns-DRrk9Qod.cjs");
|
|
3
|
+
const require_loftFns = require("./loftFns-BdpZ8FMN.cjs");
|
|
4
4
|
exports.addChild = require_threadFns.addChild;
|
|
5
5
|
exports.addJoint = require_threadFns.addJoint;
|
|
6
6
|
exports.addStep = require_threadFns.addStep;
|
package/dist/operations.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { A as setJointValue, B as createAssemblyNode, C as cylindricalJoint, D as planarJoint, E as mechanismDOF, G as circularPattern, H as removeChild, J as exportAssemblySTEP, K as gridPattern, L as addChild, M as sphericalJoint, O as prismaticJoint, R as collectShapes, S as addJoint, T as jointTransform, U as updateNode, V as findNode, W as walkAssembly, Y as createAssembly, _ as exportURDF, b as inverseKinematics, c as modifyStep, d as replayFrom, f as replayHistory, g as undoLast, h as stepsFrom, i as createRegistry, j as setJointValues, k as revoluteJoint, l as registerOperation, m as stepCount, n as addStep, o as findStep, q as linearPattern, r as createHistory, s as getShape, t as thread, u as registerShape, v as importURDF, w as forwardKinematics, x as jointTrajectory, y as jointsFromDH, z as countNodes } from "./threadFns-
|
|
2
|
-
import {
|
|
1
|
+
import { A as setJointValue, B as createAssemblyNode, C as cylindricalJoint, D as planarJoint, E as mechanismDOF, G as circularPattern, H as removeChild, J as exportAssemblySTEP, K as gridPattern, L as addChild, M as sphericalJoint, O as prismaticJoint, R as collectShapes, S as addJoint, T as jointTransform, U as updateNode, V as findNode, W as walkAssembly, Y as createAssembly, _ as exportURDF, b as inverseKinematics, c as modifyStep, d as replayFrom, f as replayHistory, g as undoLast, h as stepsFrom, i as createRegistry, j as setJointValues, k as revoluteJoint, l as registerOperation, m as stepCount, n as addStep, o as findStep, q as linearPattern, r as createHistory, s as getShape, t as thread, u as registerShape, v as importURDF, w as forwardKinematics, x as jointTrajectory, y as jointsFromDH, z as countNodes } from "./threadFns-BOtXTHZ9.js";
|
|
2
|
+
import { c as twistExtrude, o as supportExtrude, r as complexExtrude, s as sweep } from "./loftFns-BeGJ6dxx.js";
|
|
3
3
|
export { addChild, addJoint, addStep, circularPattern, collectShapes, complexExtrude, countNodes, createAssembly, createAssemblyNode, createHistory, createRegistry, cylindricalJoint, exportAssemblySTEP, exportURDF, findNode, findStep, forwardKinematics, getShape as getHistoryShape, gridPattern, importURDF, inverseKinematics, jointTrajectory, jointTransform, jointsFromDH, linearPattern, mechanismDOF, modifyStep, planarJoint, prismaticJoint, registerOperation, registerShape, removeChild, replayFrom, replayHistory, revoluteJoint, setJointValue, setJointValues, sphericalJoint, stepCount, stepsFrom, supportExtrude, sweep, thread, twistExtrude, undoLast, updateNode, walkAssembly };
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { K as getKernel } from "./shapeTypes-t49f64Dx.js";
|
|
2
|
+
import { S as subShapeHashes, c as getFaces, l as getOrCreateCache, r as getCacheEntry } from "./topologyQueryFns-BkQ6Q7gN.js";
|
|
3
|
+
import { n as HASH_CODE_MAX } from "./constants-ITRzCnCp.js";
|
|
4
|
+
//#region src/topology/metadata/originTrackingFns.ts
|
|
5
|
+
/**
|
|
6
|
+
* Face origin tracking — tag faces with integer origins and propagate
|
|
7
|
+
* them through kernel operations via ShapeEvolution records.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Tag all faces of a shape with an opaque integer origin.
|
|
11
|
+
* Consumers assign meaning (e.g., source line number).
|
|
12
|
+
*/
|
|
13
|
+
function setShapeOrigin(shape, origin) {
|
|
14
|
+
const cache = getOrCreateCache(shape);
|
|
15
|
+
const map = /* @__PURE__ */ new Map();
|
|
16
|
+
for (const hash of subShapeHashes(shape, "face")) map.set(hash, origin);
|
|
17
|
+
cache.faceOrigins = map;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Get the face origin map for a shape (faceHash → originTag).
|
|
21
|
+
* Returns undefined if no origins have been set or propagated.
|
|
22
|
+
*/
|
|
23
|
+
function getFaceOrigins(shape) {
|
|
24
|
+
return getCacheEntry(shape)?.faceOrigins;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Propagate face origins using a kernel-provided ShapeEvolution record.
|
|
28
|
+
*/
|
|
29
|
+
function propagateOriginsFromEvolution(evolution, inputs, result) {
|
|
30
|
+
const inputOrigins = /* @__PURE__ */ new Map();
|
|
31
|
+
for (const input of inputs) {
|
|
32
|
+
const origins = getFaceOrigins(input);
|
|
33
|
+
if (!origins) continue;
|
|
34
|
+
for (const [hash, origin] of origins) inputOrigins.set(hash, origin);
|
|
35
|
+
}
|
|
36
|
+
if (inputOrigins.size === 0) return;
|
|
37
|
+
const resultMap = /* @__PURE__ */ new Map();
|
|
38
|
+
for (const [hash, origin] of inputOrigins) {
|
|
39
|
+
if (evolution.deleted.has(hash)) continue;
|
|
40
|
+
const modifiedHashes = evolution.modified.get(hash);
|
|
41
|
+
if (modifiedHashes && modifiedHashes.length > 0) for (const modHash of modifiedHashes) resultMap.set(modHash, origin);
|
|
42
|
+
else resultMap.set(hash, origin);
|
|
43
|
+
const generatedHashes = evolution.generated.get(hash);
|
|
44
|
+
if (generatedHashes) {
|
|
45
|
+
for (const genHash of generatedHashes) if (!resultMap.has(genHash)) resultMap.set(genHash, origin);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (resultMap.size > 0) {
|
|
49
|
+
const cache = getOrCreateCache(result);
|
|
50
|
+
cache.faceOrigins = resultMap;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** Max 3D centroid separation (mm²) for a "near" match — the general case. */
|
|
54
|
+
var MAX_MATCH_DIST_SQ = 100;
|
|
55
|
+
/** Min |outNormal·inNormal| for two faces to count as sharing a plane's orientation. */
|
|
56
|
+
var COPLANAR_NORMAL_MIN = .985;
|
|
57
|
+
/**
|
|
58
|
+
* Max squared perpendicular offset (mm²) from an input face's plane for the
|
|
59
|
+
* output face to count as *coplanar* with it — i.e. a piece the boolean sliced
|
|
60
|
+
* off that same planar surface. 0.1mm² tolerates kernel/mesh float noise while
|
|
61
|
+
* still separating floors that sit even a fraction of a mm apart in depth.
|
|
62
|
+
*/
|
|
63
|
+
var COPLANAR_OFFSET_SQ = .1;
|
|
64
|
+
/**
|
|
65
|
+
* Find the best origin match for a result face by comparing normals and centroids
|
|
66
|
+
* against input face signatures. Returns `undefined` if no good match exists.
|
|
67
|
+
*
|
|
68
|
+
* Two passes, near strictly preferred:
|
|
69
|
+
* 1. Near match — same-facing normal (signed dot ≥ 0.707) and centroids within
|
|
70
|
+
* {@link MAX_MATCH_DIST_SQ}. The general case for regenerated seam faces
|
|
71
|
+
* (feature tops, flush walls). Unchanged legacy behavior. If any near match
|
|
72
|
+
* exists it wins outright — the coplanar pass never runs — so a distant
|
|
73
|
+
* coplanar candidate can't outscore a valid near one.
|
|
74
|
+
* 2. Coplanar match (only when no near match, and only between PLANAR faces) —
|
|
75
|
+
* the output face lies on an input face's plane (parallel *or* antiparallel
|
|
76
|
+
* normal, tiny perpendicular offset) regardless of how far its centroid
|
|
77
|
+
* drifted in-plane. Two cases pass 1 misses:
|
|
78
|
+
* • A boolean that splits a large planar face — a wide cutout floor sliced
|
|
79
|
+
* by an overlapping deeper cutout — leaves pieces >10mm from the parent
|
|
80
|
+
* centroid (past pass 1's cutoff).
|
|
81
|
+
* • A cut flips the cavity face's normal versus the tool face it came from,
|
|
82
|
+
* so the floor is antiparallel to its origin's input face.
|
|
83
|
+
* Both left the surface tagless → body color in multi-color consumers
|
|
84
|
+
* (gridfinity GH #2443). The planar gate keeps a curved output face from
|
|
85
|
+
* inheriting an origin off an unrelated face that merely shares a sampled
|
|
86
|
+
* tangent plane; among coplanar candidates the nearest in-plane wins.
|
|
87
|
+
*/
|
|
88
|
+
function findBestOriginMatch(outNormal, outCentroid, outPlanar, inputSigs) {
|
|
89
|
+
let bestNearScore = -Infinity;
|
|
90
|
+
let bestNear;
|
|
91
|
+
for (const inp of inputSigs) {
|
|
92
|
+
const dot = outNormal[0] * inp.normal[0] + outNormal[1] * inp.normal[1] + outNormal[2] * inp.normal[2];
|
|
93
|
+
if (dot < .707) continue;
|
|
94
|
+
const dx = outCentroid[0] - inp.centroid[0];
|
|
95
|
+
const dy = outCentroid[1] - inp.centroid[1];
|
|
96
|
+
const dz = outCentroid[2] - inp.centroid[2];
|
|
97
|
+
const distSq = dx * dx + dy * dy + dz * dz;
|
|
98
|
+
if (distSq > MAX_MATCH_DIST_SQ) continue;
|
|
99
|
+
const score = dot - distSq / MAX_MATCH_DIST_SQ;
|
|
100
|
+
if (score > bestNearScore) {
|
|
101
|
+
bestNearScore = score;
|
|
102
|
+
bestNear = inp.origin;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (bestNear !== void 0) return bestNear;
|
|
106
|
+
if (!outPlanar) return void 0;
|
|
107
|
+
let bestInPlaneSq = Infinity;
|
|
108
|
+
let bestCoplanar;
|
|
109
|
+
for (const inp of inputSigs) {
|
|
110
|
+
if (!inp.planar) continue;
|
|
111
|
+
const dot = outNormal[0] * inp.normal[0] + outNormal[1] * inp.normal[1] + outNormal[2] * inp.normal[2];
|
|
112
|
+
if (Math.abs(dot) < COPLANAR_NORMAL_MIN) continue;
|
|
113
|
+
const dx = outCentroid[0] - inp.centroid[0];
|
|
114
|
+
const dy = outCentroid[1] - inp.centroid[1];
|
|
115
|
+
const dz = outCentroid[2] - inp.centroid[2];
|
|
116
|
+
const perp = dx * inp.normal[0] + dy * inp.normal[1] + dz * inp.normal[2];
|
|
117
|
+
if (perp * perp > COPLANAR_OFFSET_SQ) continue;
|
|
118
|
+
const inPlaneSq = Math.max(0, dx * dx + dy * dy + dz * dz - perp * perp);
|
|
119
|
+
if (inPlaneSq < bestInPlaneSq) {
|
|
120
|
+
bestInPlaneSq = inPlaneSq;
|
|
121
|
+
bestCoplanar = inp.origin;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return bestCoplanar;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Fallback origin propagation when no kernel op object is available
|
|
128
|
+
* (native `fuseAll` / `cutAll`, which expose no ShapeEvolution record).
|
|
129
|
+
*
|
|
130
|
+
* Matches result faces to input faces by hash code first. Faces that pass
|
|
131
|
+
* through the boolean unchanged keep their hash and recover their origin
|
|
132
|
+
* directly. Faces the boolean *regenerates* (split, merged, or re-created at
|
|
133
|
+
* the intersection) get a fresh hash that matches no input — these fall back
|
|
134
|
+
* to geometric matching (normal + centroid) against the input face
|
|
135
|
+
* signatures.
|
|
136
|
+
*
|
|
137
|
+
* The geometric pass runs for every unmatched face, not only when the hash
|
|
138
|
+
* pass found nothing. A partial hash match is the common case for additive
|
|
139
|
+
* features (pass-through side walls match by hash; the surfaces where the
|
|
140
|
+
* tool meets the body — feature tops, flush walls — are regenerated and need
|
|
141
|
+
* the geometric pass). Gating the fallback on "zero hash matches" left those
|
|
142
|
+
* regenerated faces with no origin, so they fell back to 0 (body) at mesh
|
|
143
|
+
* time — the multi-color export bug where a scoop/label/lip top printed in
|
|
144
|
+
* the body color. Matching against the full signature set (body origin 0
|
|
145
|
+
* included) keeps body faces body and feature faces feature.
|
|
146
|
+
*/
|
|
147
|
+
function propagateOriginsByHash(inputs, result) {
|
|
148
|
+
const lookup = /* @__PURE__ */ new Map();
|
|
149
|
+
for (const input of inputs) {
|
|
150
|
+
const origins = getFaceOrigins(input);
|
|
151
|
+
if (!origins) continue;
|
|
152
|
+
for (const [hash, origin] of origins) lookup.set(hash, origin);
|
|
153
|
+
}
|
|
154
|
+
if (lookup.size === 0) return;
|
|
155
|
+
const kernel = getKernel();
|
|
156
|
+
const resultMap = /* @__PURE__ */ new Map();
|
|
157
|
+
const resultFaces = getFaces(result);
|
|
158
|
+
const unmatched = [];
|
|
159
|
+
for (const f of resultFaces) {
|
|
160
|
+
const hash = kernel.hashCode(f.wrapped, HASH_CODE_MAX);
|
|
161
|
+
const origin = lookup.get(hash);
|
|
162
|
+
if (origin !== void 0) resultMap.set(hash, origin);
|
|
163
|
+
else unmatched.push(f);
|
|
164
|
+
}
|
|
165
|
+
if (unmatched.length > 0) {
|
|
166
|
+
const inputSigs = [];
|
|
167
|
+
for (const input of inputs) {
|
|
168
|
+
const origins = getFaceOrigins(input);
|
|
169
|
+
if (!origins) continue;
|
|
170
|
+
for (const f of getFaces(input)) {
|
|
171
|
+
const hash = kernel.hashCode(f.wrapped, HASH_CODE_MAX);
|
|
172
|
+
const origin = origins.get(hash);
|
|
173
|
+
if (origin === void 0) continue;
|
|
174
|
+
try {
|
|
175
|
+
const bounds = kernel.uvBounds(f.wrapped);
|
|
176
|
+
const normal = kernel.surfaceNormal(f.wrapped, .5 * (bounds.uMin + bounds.uMax), .5 * (bounds.vMin + bounds.vMax));
|
|
177
|
+
const centroid = kernel.surfaceCenterOfMass(f.wrapped);
|
|
178
|
+
const planar = kernel.surfaceType(f.wrapped) === "plane";
|
|
179
|
+
inputSigs.push({
|
|
180
|
+
origin,
|
|
181
|
+
normal,
|
|
182
|
+
centroid,
|
|
183
|
+
planar
|
|
184
|
+
});
|
|
185
|
+
} catch {}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (inputSigs.length > 0) for (const f of unmatched) {
|
|
189
|
+
const hash = kernel.hashCode(f.wrapped, HASH_CODE_MAX);
|
|
190
|
+
try {
|
|
191
|
+
const outBounds = kernel.uvBounds(f.wrapped);
|
|
192
|
+
const bestOrigin = findBestOriginMatch(kernel.surfaceNormal(f.wrapped, .5 * (outBounds.uMin + outBounds.uMax), .5 * (outBounds.vMin + outBounds.vMax)), kernel.surfaceCenterOfMass(f.wrapped), kernel.surfaceType(f.wrapped) === "plane", inputSigs);
|
|
193
|
+
if (bestOrigin !== void 0) resultMap.set(hash, bestOrigin);
|
|
194
|
+
} catch {}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (resultMap.size > 0) {
|
|
198
|
+
const cache = getOrCreateCache(result);
|
|
199
|
+
cache.faceOrigins = resultMap;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
//#endregion
|
|
203
|
+
export { setShapeOrigin as i, propagateOriginsByHash as n, propagateOriginsFromEvolution as r, getFaceOrigins as t };
|