brepjs 18.66.2 → 18.68.0
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/brepjs.cjs +485 -51
- package/dist/brepjs.js +474 -57
- package/dist/implicit/index.d.ts +11 -0
- package/dist/implicit/sdfFns.d.ts +59 -0
- package/dist/index.d.ts +4 -2
- package/dist/voxel/engine.d.ts +94 -0
- package/dist/voxel/fieldFns.d.ts +121 -0
- package/dist/voxel/index.d.ts +2 -0
- package/package.json +1 -1
package/dist/brepjs.js
CHANGED
|
@@ -14,7 +14,7 @@ import { a as meshEdges$1, c as createMeshCache, i as mesh$1, n as exportSTEP, o
|
|
|
14
14
|
import { n as getAtOrThrow, r as lastOrThrow, t as firstOrThrow } from "./arrayAccess-DrUGPADn.js";
|
|
15
15
|
import { _ as makeThreePointArc, d as makeCircle, h as makeLine, l as makeBSplineInterpolation, n as fill, r as makeFace, s as assembleWire } from "./surfaceBuilders-jx81G_YJ.js";
|
|
16
16
|
import { a as fuseAll, c as sectionToFace$1, i as fuse$2, l as slice$1, n as cut$2, o as intersect$2, r as cutAll, s as section$1, t as booleanPipeline, u as split$1 } from "./booleanFns-CaKngiuu.js";
|
|
17
|
-
import { $ as fuseAllBisect, A as fixShape, B as offset$1, C as threePointArc, D as wireLoop, E as wire, F as isValid$1, G as chamferWithEvolution, H as thicken$1, I as solidFromShell, J as fuseWithEvolution, K as cutWithEvolution, L as chamfer$1, M as healFace, N as healSolid, O as autoHeal, P as healWire, Q as cutAllBisect, R as draft$1, S as tangentArc, T as vertex, U as variableFillet, V as shell$1, W as positionOnCurve, X as shellWithEvolution, Y as intersectWithEvolution, Z as checkBoolean, _ as polygon, a as circle, at as sharedEdges, b as sphere, c as cylinder, ct as chamferDistAngle, d as ellipsoid, dt as toLODGeometryData, et as getNurbsCurveData, f as face, ft as toLineGeometryData, g as offsetFace, h as line, i as bsplineApprox, it as facesOfEdge, j as heal$1, k as fixSelfIntersection, l as ellipse, lt as toBufferGeometryData, m as helix, n as bezier, nt as adjacentFaces, o as compound, ot as verticesOfEdge, p as filledFace, q as filletWithEvolution, r as box, rt as edgesOfFace, s as cone, st as wiresOfFace, t as addHoles, tt as getNurbsSurfaceData, u as ellipseArc, ut as toGroupedBufferGeometryData, v as sewShells, w as torus, x as subFace, y as solid, z as fillet$1 } from "./primitiveFns-ecKWNC5k.js";
|
|
17
|
+
import { $ as fuseAllBisect, A as fixShape, B as offset$1, C as threePointArc, D as wireLoop, E as wire, F as isValid$1, G as chamferWithEvolution, H as thicken$1, I as solidFromShell, J as fuseWithEvolution, K as cutWithEvolution, L as chamfer$1, M as healFace, N as healSolid, O as autoHeal, P as healWire, Q as cutAllBisect, R as draft$1, S as tangentArc, T as vertex, U as variableFillet, V as shell$1, W as positionOnCurve, X as shellWithEvolution, Y as intersectWithEvolution, Z as checkBoolean, _ as polygon, a as circle, at as sharedEdges, b as sphere$1, c as cylinder, ct as chamferDistAngle, d as ellipsoid, dt as toLODGeometryData, et as getNurbsCurveData, f as face, ft as toLineGeometryData, g as offsetFace, h as line, i as bsplineApprox, it as facesOfEdge, j as heal$1, k as fixSelfIntersection, l as ellipse, lt as toBufferGeometryData, m as helix, n as bezier, nt as adjacentFaces, o as compound, ot as verticesOfEdge, p as filledFace, q as filletWithEvolution, r as box, rt as edgesOfFace, s as cone, st as wiresOfFace, t as addHoles, tt as getNurbsSurfaceData, u as ellipseArc, ut as toGroupedBufferGeometryData, v as sewShells, w as torus$1, x as subFace, y as solid, z as fillet$1 } from "./primitiveFns-ecKWNC5k.js";
|
|
18
18
|
import { C as walkAssembly, D as exportAssemblySTEP, E as linearPattern, O as createAssembly, S as updateNode, _ as collectShapes, a as findStep, b as findNode, c as registerOperation, d as replayHistory, f as serializeHistory, g as addChild, h as undoLast, i as deserializeHistory, l as registerShape, m as stepsFrom, n as createHistory, o as getShape, p as stepCount, r as createRegistry, s as modifyStep, t as addStep, u as replayFrom, v as countNodes, w as circularPattern, x as removeChild, y as createAssemblyNode } from "./historyFns-CZ9oNL7j.js";
|
|
19
19
|
import { n as BaseSketcher2d, r as organiseBlueprints, t as BlueprintSketcher } from "./blueprintSketcher-0DeTMXwj.js";
|
|
20
20
|
import { a as createTypedFinder, i as wireFinder, n as edgeFinder, r as faceFinder, t as getSingleFace } from "./helpers-BX-0e71G.js";
|
|
@@ -193,7 +193,7 @@ function validateInputs(mesh, queries) {
|
|
|
193
193
|
return null;
|
|
194
194
|
}
|
|
195
195
|
/** Resolve a registered voxel engine, mapping an unregistered id to an error. */
|
|
196
|
-
function resolveEngine(id) {
|
|
196
|
+
function resolveEngine$1(id) {
|
|
197
197
|
try {
|
|
198
198
|
return ok(getVoxel(id));
|
|
199
199
|
} catch (cause) {
|
|
@@ -210,7 +210,7 @@ function resolveEngine(id) {
|
|
|
210
210
|
function windingNumbers(mesh, queries, id) {
|
|
211
211
|
const invalid = validateInputs(mesh, queries);
|
|
212
212
|
if (invalid) return err(invalid);
|
|
213
|
-
const engine = resolveEngine(id);
|
|
213
|
+
const engine = resolveEngine$1(id);
|
|
214
214
|
if (isErr(engine)) return engine;
|
|
215
215
|
return ok(engine.value.winding_numbers(mesh.vertices, mesh.triangles, queries));
|
|
216
216
|
}
|
|
@@ -222,15 +222,15 @@ function windingNumbers(mesh, queries, id) {
|
|
|
222
222
|
function pointsInside(mesh, queries, id) {
|
|
223
223
|
const invalid = validateInputs(mesh, queries);
|
|
224
224
|
if (invalid) return err(invalid);
|
|
225
|
-
const engine = resolveEngine(id);
|
|
225
|
+
const engine = resolveEngine$1(id);
|
|
226
226
|
if (isErr(engine)) return engine;
|
|
227
227
|
const flags = engine.value.points_inside(mesh.vertices, mesh.triangles, queries);
|
|
228
228
|
return ok(Array.from(flags, (flag) => flag === 1));
|
|
229
229
|
}
|
|
230
230
|
//#endregion
|
|
231
231
|
//#region src/voxel/repairFns.ts
|
|
232
|
-
var DEFAULT_RESOLUTION$
|
|
233
|
-
var DEFAULT_PADDING$
|
|
232
|
+
var DEFAULT_RESOLUTION$4 = 48;
|
|
233
|
+
var DEFAULT_PADDING$4 = 2;
|
|
234
234
|
/**
|
|
235
235
|
* Repair a (possibly non-watertight) triangle-soup mesh into a closed surface:
|
|
236
236
|
* voxelize an FWN-signed SDF, then Surface-Nets contour it back to triangles.
|
|
@@ -243,16 +243,16 @@ function repairMesh(mesh, opts, id) {
|
|
|
243
243
|
const invalid = validateMesh(mesh);
|
|
244
244
|
if (invalid) return err(invalid);
|
|
245
245
|
if (mesh.vertices.length === 0 || mesh.triangles.length === 0) return err(validationError("VOXEL_EMPTY_MESH", "repairMesh requires a non-empty triangle mesh."));
|
|
246
|
-
const resolution = opts?.resolution ?? DEFAULT_RESOLUTION$
|
|
247
|
-
const padding = opts?.padding ?? DEFAULT_PADDING$
|
|
246
|
+
const resolution = opts?.resolution ?? DEFAULT_RESOLUTION$4;
|
|
247
|
+
const padding = opts?.padding ?? DEFAULT_PADDING$4;
|
|
248
248
|
if (!Number.isInteger(resolution) || resolution < 1) return err(validationError("VOXEL_INVALID_RESOLUTION", "resolution must be an integer >= 1."));
|
|
249
249
|
if (!Number.isInteger(padding) || padding < 1) return err(validationError("VOXEL_INVALID_PADDING", "padding must be an integer >= 1."));
|
|
250
|
-
const engine = resolveEngine(id);
|
|
250
|
+
const engine = resolveEngine$1(id);
|
|
251
251
|
if (isErr(engine)) return engine;
|
|
252
252
|
try {
|
|
253
253
|
try {
|
|
254
|
-
var _usingCtx$
|
|
255
|
-
const repaired = _usingCtx$
|
|
254
|
+
var _usingCtx$7 = _usingCtx();
|
|
255
|
+
const repaired = _usingCtx$7.u(engine.value.repair_mesh(mesh.vertices, mesh.triangles, resolution, padding));
|
|
256
256
|
const vertexCount = repaired.positions.length / 3;
|
|
257
257
|
return ok({
|
|
258
258
|
vertices: repaired.positions,
|
|
@@ -266,9 +266,9 @@ function repairMesh(mesh, opts, id) {
|
|
|
266
266
|
}]
|
|
267
267
|
});
|
|
268
268
|
} catch (_) {
|
|
269
|
-
_usingCtx$
|
|
269
|
+
_usingCtx$7.e = _;
|
|
270
270
|
} finally {
|
|
271
|
-
_usingCtx$
|
|
271
|
+
_usingCtx$7.d();
|
|
272
272
|
}
|
|
273
273
|
} catch (cause) {
|
|
274
274
|
return err(computationError("VOXEL_REPAIR_FAILED", cause instanceof Error ? cause.message : "voxel repair failed (grid too large?).", cause));
|
|
@@ -297,16 +297,16 @@ function shapeToMeshInput(shape, deflection = DEFAULT_DEFLECTION) {
|
|
|
297
297
|
}
|
|
298
298
|
//#endregion
|
|
299
299
|
//#region src/voxel/meshOpsFns.ts
|
|
300
|
-
var DEFAULT_RESOLUTION$
|
|
301
|
-
var DEFAULT_PADDING$
|
|
302
|
-
var BOOLEAN_OP_CODES = {
|
|
300
|
+
var DEFAULT_RESOLUTION$3 = 48;
|
|
301
|
+
var DEFAULT_PADDING$3 = 2;
|
|
302
|
+
var BOOLEAN_OP_CODES$1 = {
|
|
303
303
|
union: 0,
|
|
304
304
|
intersection: 1,
|
|
305
305
|
difference: 2
|
|
306
306
|
};
|
|
307
|
-
function resolveGridParams(opts) {
|
|
308
|
-
const resolution = opts?.resolution ?? DEFAULT_RESOLUTION$
|
|
309
|
-
const padding = opts?.padding ?? DEFAULT_PADDING$
|
|
307
|
+
function resolveGridParams$2(opts) {
|
|
308
|
+
const resolution = opts?.resolution ?? DEFAULT_RESOLUTION$3;
|
|
309
|
+
const padding = opts?.padding ?? DEFAULT_PADDING$3;
|
|
310
310
|
if (!Number.isInteger(resolution) || resolution < 1) return err(validationError("VOXEL_INVALID_RESOLUTION", "resolution must be an integer >= 1."));
|
|
311
311
|
if (!Number.isInteger(padding) || padding < 1) return err(validationError("VOXEL_INVALID_PADDING", "padding must be an integer >= 1."));
|
|
312
312
|
return ok({
|
|
@@ -341,18 +341,18 @@ function offsetMesh(mesh, distance, opts, id) {
|
|
|
341
341
|
if (invalid) return err(invalid);
|
|
342
342
|
if (mesh.vertices.length === 0 || mesh.triangles.length === 0) return err(validationError("VOXEL_EMPTY_MESH", "offsetMesh requires a non-empty triangle mesh."));
|
|
343
343
|
if (!Number.isFinite(distance)) return err(validationError("VOXEL_INVALID_DISTANCE", "distance must be a finite number."));
|
|
344
|
-
const params = resolveGridParams(opts);
|
|
344
|
+
const params = resolveGridParams$2(opts);
|
|
345
345
|
if (isErr(params)) return params;
|
|
346
|
-
const engine = resolveEngine(id);
|
|
346
|
+
const engine = resolveEngine$1(id);
|
|
347
347
|
if (isErr(engine)) return engine;
|
|
348
348
|
try {
|
|
349
349
|
try {
|
|
350
|
-
var _usingCtx$
|
|
351
|
-
return meshFromResult(_usingCtx$
|
|
350
|
+
var _usingCtx$6 = _usingCtx();
|
|
351
|
+
return meshFromResult(_usingCtx$6.u(engine.value.offset_mesh(mesh.vertices, mesh.triangles, distance, params.value.resolution, params.value.padding)));
|
|
352
352
|
} catch (_) {
|
|
353
|
-
_usingCtx$
|
|
353
|
+
_usingCtx$6.e = _;
|
|
354
354
|
} finally {
|
|
355
|
-
_usingCtx$
|
|
355
|
+
_usingCtx$6.d();
|
|
356
356
|
}
|
|
357
357
|
} catch (cause) {
|
|
358
358
|
return err(computationError("VOXEL_OFFSET_FAILED", cause instanceof Error ? cause.message : "voxel offset failed (grid too large?).", cause));
|
|
@@ -370,9 +370,9 @@ function shellMesh(mesh, thickness, opts, id) {
|
|
|
370
370
|
if (invalid) return err(invalid);
|
|
371
371
|
if (mesh.vertices.length === 0 || mesh.triangles.length === 0) return err(validationError("VOXEL_EMPTY_MESH", "shellMesh requires a non-empty triangle mesh."));
|
|
372
372
|
if (!Number.isFinite(thickness) || thickness <= 0) return err(validationError("VOXEL_INVALID_THICKNESS", "thickness must be a finite number > 0."));
|
|
373
|
-
const params = resolveGridParams(opts);
|
|
373
|
+
const params = resolveGridParams$2(opts);
|
|
374
374
|
if (isErr(params)) return params;
|
|
375
|
-
const engine = resolveEngine(id);
|
|
375
|
+
const engine = resolveEngine$1(id);
|
|
376
376
|
if (isErr(engine)) return engine;
|
|
377
377
|
try {
|
|
378
378
|
try {
|
|
@@ -401,10 +401,10 @@ function voxelBoolean(a, b, op, opts, id) {
|
|
|
401
401
|
if (invalidB) return err(invalidB);
|
|
402
402
|
if (a.vertices.length === 0 || a.triangles.length === 0) return err(validationError("VOXEL_EMPTY_MESH", "voxelBoolean requires a non-empty mesh for operand A."));
|
|
403
403
|
if (b.vertices.length === 0 || b.triangles.length === 0) return err(validationError("VOXEL_EMPTY_MESH", "voxelBoolean requires a non-empty mesh for operand B."));
|
|
404
|
-
const opCode = BOOLEAN_OP_CODES[op];
|
|
405
|
-
const params = resolveGridParams(opts);
|
|
404
|
+
const opCode = BOOLEAN_OP_CODES$1[op];
|
|
405
|
+
const params = resolveGridParams$2(opts);
|
|
406
406
|
if (isErr(params)) return params;
|
|
407
|
-
const engine = resolveEngine(id);
|
|
407
|
+
const engine = resolveEngine$1(id);
|
|
408
408
|
if (isErr(engine)) return engine;
|
|
409
409
|
try {
|
|
410
410
|
try {
|
|
@@ -452,6 +452,423 @@ function voxelBooleanShapes(a, b, op, opts, id) {
|
|
|
452
452
|
return voxelBoolean(meshA.value, meshB.value, op, opts, id);
|
|
453
453
|
}
|
|
454
454
|
//#endregion
|
|
455
|
+
//#region src/voxel/fieldFns.ts
|
|
456
|
+
var DEFAULT_RESOLUTION$2 = 48;
|
|
457
|
+
var DEFAULT_PADDING$2 = 2;
|
|
458
|
+
var BOOLEAN_OP_CODES = {
|
|
459
|
+
union: 0,
|
|
460
|
+
intersection: 1,
|
|
461
|
+
difference: 2
|
|
462
|
+
};
|
|
463
|
+
function resolveGridParams$1(opts) {
|
|
464
|
+
const resolution = opts?.resolution ?? DEFAULT_RESOLUTION$2;
|
|
465
|
+
const padding = opts?.padding ?? DEFAULT_PADDING$2;
|
|
466
|
+
if (!Number.isInteger(resolution) || resolution < 1) return err(validationError("VOXEL_INVALID_RESOLUTION", "resolution must be an integer >= 1."));
|
|
467
|
+
if (!Number.isInteger(padding) || padding < 1) return err(validationError("VOXEL_INVALID_PADDING", "padding must be an integer >= 1."));
|
|
468
|
+
return ok({
|
|
469
|
+
resolution,
|
|
470
|
+
padding
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Copy the buffers out of a WASM {@link VoxelRepairResult} into a plain
|
|
475
|
+
* {@link KernelMeshResult}, freeing the WASM result via `using` (the getters
|
|
476
|
+
* copy, so the mesh survives the free). An empty contour surfaces as an error.
|
|
477
|
+
*/
|
|
478
|
+
function meshFromField(field) {
|
|
479
|
+
try {
|
|
480
|
+
var _usingCtx$5 = _usingCtx();
|
|
481
|
+
const rawResult = field.contour();
|
|
482
|
+
const { positions, normals, indices } = _usingCtx$5.u({
|
|
483
|
+
value: rawResult,
|
|
484
|
+
[Symbol.dispose]() {
|
|
485
|
+
rawResult.free();
|
|
486
|
+
}
|
|
487
|
+
}).value;
|
|
488
|
+
if (positions.length === 0 || indices.length === 0) return err(computationError("VOXEL_DEGENERATE_RESULT", "the voxel field contoured to an empty mesh (over-shrunk offset or disjoint operands?)."));
|
|
489
|
+
const vertexCount = positions.length / 3;
|
|
490
|
+
return ok({
|
|
491
|
+
vertices: positions,
|
|
492
|
+
normals,
|
|
493
|
+
triangles: indices,
|
|
494
|
+
uvs: new Float32Array(vertexCount * 2),
|
|
495
|
+
faceGroups: [{
|
|
496
|
+
start: 0,
|
|
497
|
+
count: indices.length / 3,
|
|
498
|
+
faceHash: 0
|
|
499
|
+
}]
|
|
500
|
+
});
|
|
501
|
+
} catch (_) {
|
|
502
|
+
_usingCtx$5.e = _;
|
|
503
|
+
} finally {
|
|
504
|
+
_usingCtx$5.d();
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
function fieldDeletable(raw) {
|
|
508
|
+
return {
|
|
509
|
+
raw,
|
|
510
|
+
delete() {
|
|
511
|
+
raw.free();
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
function makeFieldHandle(raw) {
|
|
516
|
+
return makeHandle(raw);
|
|
517
|
+
}
|
|
518
|
+
function makeHandle(raw) {
|
|
519
|
+
const inner = createKernelHandle(fieldDeletable(raw));
|
|
520
|
+
const handle = {
|
|
521
|
+
get value() {
|
|
522
|
+
return inner.value.raw;
|
|
523
|
+
},
|
|
524
|
+
get disposed() {
|
|
525
|
+
return inner.disposed;
|
|
526
|
+
},
|
|
527
|
+
[Symbol.dispose]() {
|
|
528
|
+
inner[Symbol.dispose]();
|
|
529
|
+
},
|
|
530
|
+
boolean(other, op) {
|
|
531
|
+
this.value.boolean(other.value, BOOLEAN_OP_CODES[op]);
|
|
532
|
+
return handle;
|
|
533
|
+
},
|
|
534
|
+
offset(distance) {
|
|
535
|
+
this.value.offset(distance);
|
|
536
|
+
return handle;
|
|
537
|
+
},
|
|
538
|
+
shell(thickness) {
|
|
539
|
+
this.value.shell(thickness);
|
|
540
|
+
return handle;
|
|
541
|
+
},
|
|
542
|
+
reinit() {
|
|
543
|
+
this.value.reinit();
|
|
544
|
+
return handle;
|
|
545
|
+
},
|
|
546
|
+
contour() {
|
|
547
|
+
const mesh = meshFromField(this.value);
|
|
548
|
+
if (isErr(mesh)) throw new Error(mesh.error.message);
|
|
549
|
+
return mesh.value;
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
return handle;
|
|
553
|
+
}
|
|
554
|
+
/** Live-handle guard (the `VoxelFieldHandle` analogue of disposal's `isLive`). */
|
|
555
|
+
function isLive$1(handle) {
|
|
556
|
+
return !handle.disposed;
|
|
557
|
+
}
|
|
558
|
+
function disposedErr() {
|
|
559
|
+
return err(validationError("VOXEL_FIELD_DISPOSED", "the voxel field handle has been disposed."));
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Voxelize a mesh into a persistent dense {@link VoxelFieldHandle}: one grid you
|
|
563
|
+
* can boolean / offset / shell / reinit in place, then contour once. The handle
|
|
564
|
+
* is disposable — free the WASM grid with `using` (or `[Symbol.dispose]()`).
|
|
565
|
+
*
|
|
566
|
+
* `resolution` sizes the longest bbox axis; `padding` is the air-margin ring.
|
|
567
|
+
* Errors on an empty/invalid mesh, or if the grid would exceed the dense budget
|
|
568
|
+
* (the persistent path is dense-only) or the voxel cap.
|
|
569
|
+
*/
|
|
570
|
+
function voxelField(mesh, opts, id) {
|
|
571
|
+
const invalid = validateMesh(mesh);
|
|
572
|
+
if (invalid) return err(invalid);
|
|
573
|
+
if (mesh.vertices.length === 0 || mesh.triangles.length === 0) return err(validationError("VOXEL_EMPTY_MESH", "voxelField requires a non-empty triangle mesh."));
|
|
574
|
+
const params = resolveGridParams$1(opts);
|
|
575
|
+
if (isErr(params)) return params;
|
|
576
|
+
const engine = resolveEngine$1(id);
|
|
577
|
+
if (isErr(engine)) return engine;
|
|
578
|
+
try {
|
|
579
|
+
return ok(makeHandle(new engine.value.VoxelField(mesh.vertices, mesh.triangles, params.value.resolution, params.value.padding)));
|
|
580
|
+
} catch (cause) {
|
|
581
|
+
return err(computationError("VOXEL_FIELD_VOXELIZE_FAILED", cause instanceof Error ? cause.message : "voxel field voxelization failed (grid too large or non-dense?).", cause));
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Boolean two meshes into ONE co-registered, chainable {@link VoxelFieldHandle}:
|
|
586
|
+
* voxelize both onto a single shared grid sized to their union bbox, combine by
|
|
587
|
+
* `op`, and keep the field. This is THE correct way to "boolean then chain
|
|
588
|
+
* offset/shell" two independently-described meshes — unlike {@link fieldBoolean},
|
|
589
|
+
* which requires the operands to already share grid geometry. The result is
|
|
590
|
+
* dirty (the blend drifts the gradient), so a subsequent offset/shell
|
|
591
|
+
* auto-reinitializes. The handle is disposable — free it with `using`.
|
|
592
|
+
*
|
|
593
|
+
* `op` is `'difference'` = A − B. Errors on an empty/invalid mesh, or if the
|
|
594
|
+
* shared grid would exceed the dense budget (the persistent path is dense-only).
|
|
595
|
+
*/
|
|
596
|
+
function voxelBooleanField(a, b, op, opts, id) {
|
|
597
|
+
const invalidA = validateMesh(a);
|
|
598
|
+
if (invalidA) return err(invalidA);
|
|
599
|
+
const invalidB = validateMesh(b);
|
|
600
|
+
if (invalidB) return err(invalidB);
|
|
601
|
+
if (a.vertices.length === 0 || a.triangles.length === 0) return err(validationError("VOXEL_EMPTY_MESH", "voxelBooleanField requires a non-empty mesh for operand A."));
|
|
602
|
+
if (b.vertices.length === 0 || b.triangles.length === 0) return err(validationError("VOXEL_EMPTY_MESH", "voxelBooleanField requires a non-empty mesh for operand B."));
|
|
603
|
+
const params = resolveGridParams$1(opts);
|
|
604
|
+
if (isErr(params)) return params;
|
|
605
|
+
const engine = resolveEngine$1(id);
|
|
606
|
+
if (isErr(engine)) return engine;
|
|
607
|
+
try {
|
|
608
|
+
return ok(makeHandle(engine.value.VoxelField.boolean_of(a.vertices, a.triangles, b.vertices, b.triangles, BOOLEAN_OP_CODES[op], params.value.resolution, params.value.padding)));
|
|
609
|
+
} catch (cause) {
|
|
610
|
+
return err(computationError("VOXEL_FIELD_BOOLEAN_FAILED", cause instanceof Error ? cause.message : "voxel field boolean failed (grid too large or non-dense?).", cause));
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* CSG-combine two fields IN PLACE, returning the SAME `handle` for chaining. The
|
|
615
|
+
* min/max blend keeps the zero set exact but drifts the gradient near the join,
|
|
616
|
+
* so a subsequent {@link fieldOffset}/{@link fieldShell} auto-reinitializes.
|
|
617
|
+
*
|
|
618
|
+
* PRECONDITION: both operands must be CO-REGISTERED — same origin, spacing, AND
|
|
619
|
+
* dims. Two fields built by {@link voxelField} from DIFFERENT meshes generally do
|
|
620
|
+
* NOT share geometry (each sizes its grid to its own bbox), and the WASM guard
|
|
621
|
+
* rejects that mismatch as an `err(...)` rather than silently blending mismatched
|
|
622
|
+
* coordinate frames. For the easy co-registered path, build the field directly
|
|
623
|
+
* from both meshes with {@link voxelBooleanField}.
|
|
624
|
+
*/
|
|
625
|
+
function fieldBoolean(handle, other, op) {
|
|
626
|
+
if (!isLive$1(handle) || !isLive$1(other)) return disposedErr();
|
|
627
|
+
try {
|
|
628
|
+
handle.value.boolean(other.value, BOOLEAN_OP_CODES[op]);
|
|
629
|
+
return ok(handle);
|
|
630
|
+
} catch (cause) {
|
|
631
|
+
return err(computationError("VOXEL_FIELD_BOOLEAN_FAILED", cause instanceof Error ? cause.message : "voxel field boolean failed (dim mismatch?).", cause));
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Offset the field's surface IN PLACE (>0 outward, <0 inward), returning the
|
|
636
|
+
* SAME `handle`. Auto-reinitializes first if the field is dirty (post-boolean),
|
|
637
|
+
* so the iso-shift always rides a true SDF.
|
|
638
|
+
*/
|
|
639
|
+
function fieldOffset(handle, distance) {
|
|
640
|
+
if (!isLive$1(handle)) return disposedErr();
|
|
641
|
+
if (!Number.isFinite(distance)) return err(validationError("VOXEL_INVALID_DISTANCE", "distance must be a finite number."));
|
|
642
|
+
try {
|
|
643
|
+
handle.value.offset(distance);
|
|
644
|
+
return ok(handle);
|
|
645
|
+
} catch (cause) {
|
|
646
|
+
return err(computationError("VOXEL_FIELD_OFFSET_FAILED", cause instanceof Error ? cause.message : "voxel field offset failed.", cause));
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* Hollow the field into an inward shell of `thickness` IN PLACE, returning the
|
|
651
|
+
* SAME `handle`. Auto-reinitializes first if dirty; the result is dirty again
|
|
652
|
+
* (the shell re-introduces a kink).
|
|
653
|
+
*/
|
|
654
|
+
function fieldShell(handle, thickness) {
|
|
655
|
+
if (!isLive$1(handle)) return disposedErr();
|
|
656
|
+
if (!Number.isFinite(thickness) || thickness <= 0) return err(validationError("VOXEL_INVALID_THICKNESS", "thickness must be a finite number > 0."));
|
|
657
|
+
try {
|
|
658
|
+
handle.value.shell(thickness);
|
|
659
|
+
return ok(handle);
|
|
660
|
+
} catch (cause) {
|
|
661
|
+
return err(computationError("VOXEL_FIELD_SHELL_FAILED", cause instanceof Error ? cause.message : "voxel field shell failed.", cause));
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Explicitly reinitialize φ to a true SDF (|∇φ|=1) while preserving the zero
|
|
666
|
+
* set, returning the SAME `handle`. Idempotent on a clean field. Offset/shell
|
|
667
|
+
* already auto-reinitialize, so this is for advanced control only.
|
|
668
|
+
*/
|
|
669
|
+
function fieldReinit(handle) {
|
|
670
|
+
if (!isLive$1(handle)) return disposedErr();
|
|
671
|
+
try {
|
|
672
|
+
handle.value.reinit();
|
|
673
|
+
return ok(handle);
|
|
674
|
+
} catch (cause) {
|
|
675
|
+
return err(computationError("VOXEL_FIELD_REINIT_FAILED", cause instanceof Error ? cause.message : "voxel field reinit failed.", cause));
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* Surface-Nets contour the current field to a {@link KernelMeshResult}. The
|
|
680
|
+
* field stays alive and chainable afterwards (contour borrows it). An empty
|
|
681
|
+
* contour surfaces as `VOXEL_DEGENERATE_RESULT`.
|
|
682
|
+
*/
|
|
683
|
+
function fieldContour(handle) {
|
|
684
|
+
if (!isLive$1(handle)) return disposedErr();
|
|
685
|
+
try {
|
|
686
|
+
return meshFromField(handle.value);
|
|
687
|
+
} catch (cause) {
|
|
688
|
+
return err(computationError("VOXEL_FIELD_CONTOUR_FAILED", cause instanceof Error ? cause.message : "voxel field contour failed.", cause));
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* Voxelize a B-rep shape into a persistent {@link VoxelFieldHandle}: tessellate
|
|
693
|
+
* it, then run {@link voxelField}. Threads a meshing failure back as an
|
|
694
|
+
* `err(...)`. The handle is disposable — free it with `using`.
|
|
695
|
+
*/
|
|
696
|
+
function voxelFieldFromShape(shape, opts, id) {
|
|
697
|
+
const meshInput = shapeToMeshInput(shape);
|
|
698
|
+
if (isErr(meshInput)) return meshInput;
|
|
699
|
+
return voxelField(meshInput.value, opts, id);
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Boolean two B-rep shapes into one co-registered, chainable
|
|
703
|
+
* {@link VoxelFieldHandle}: tessellate both, then run {@link voxelBooleanField}.
|
|
704
|
+
* `op` is `'difference'` = A − B. Threads either meshing failure back as an
|
|
705
|
+
* `err(...)`. The handle is disposable — free it with `using`.
|
|
706
|
+
*/
|
|
707
|
+
function voxelBooleanFieldShapes(a, b, op, opts, id) {
|
|
708
|
+
const meshA = shapeToMeshInput(a);
|
|
709
|
+
if (isErr(meshA)) return meshA;
|
|
710
|
+
const meshB = shapeToMeshInput(b);
|
|
711
|
+
if (isErr(meshB)) return meshB;
|
|
712
|
+
return voxelBooleanField(meshA.value, meshB.value, op, opts, id);
|
|
713
|
+
}
|
|
714
|
+
//#endregion
|
|
715
|
+
//#region src/implicit/sdfFns.ts
|
|
716
|
+
var DEFAULT_RESOLUTION$1 = 48;
|
|
717
|
+
var DEFAULT_PADDING$1 = 2;
|
|
718
|
+
function resolveEngine(id) {
|
|
719
|
+
try {
|
|
720
|
+
return ok(getVoxel(id));
|
|
721
|
+
} catch (cause) {
|
|
722
|
+
return err(moduleInitError("VOXEL_NOT_INITIALIZED", cause instanceof Error ? cause.message : "voxel engine not initialized", cause));
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
function resolveGridParams(opts) {
|
|
726
|
+
const resolution = opts?.resolution ?? DEFAULT_RESOLUTION$1;
|
|
727
|
+
const padding = opts?.padding ?? DEFAULT_PADDING$1;
|
|
728
|
+
if (!Number.isInteger(resolution) || resolution < 1) return err(validationError("SDF_INVALID_RESOLUTION", "resolution must be an integer >= 1."));
|
|
729
|
+
if (!Number.isInteger(padding) || padding < 1) return err(validationError("SDF_INVALID_PADDING", "padding must be an integer >= 1."));
|
|
730
|
+
return ok({
|
|
731
|
+
resolution,
|
|
732
|
+
padding
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
function sdfDeletable(raw) {
|
|
736
|
+
return {
|
|
737
|
+
raw,
|
|
738
|
+
delete() {
|
|
739
|
+
raw.free();
|
|
740
|
+
}
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
function makeSdfHandle(raw) {
|
|
744
|
+
const inner = createKernelHandle(sdfDeletable(raw));
|
|
745
|
+
return {
|
|
746
|
+
get value() {
|
|
747
|
+
return inner.value.raw;
|
|
748
|
+
},
|
|
749
|
+
get disposed() {
|
|
750
|
+
return inner.disposed;
|
|
751
|
+
},
|
|
752
|
+
[Symbol.dispose]() {
|
|
753
|
+
inner[Symbol.dispose]();
|
|
754
|
+
},
|
|
755
|
+
union(other) {
|
|
756
|
+
return makeSdfHandle(this.value.union(other.value));
|
|
757
|
+
},
|
|
758
|
+
intersection(other) {
|
|
759
|
+
return makeSdfHandle(this.value.intersection(other.value));
|
|
760
|
+
},
|
|
761
|
+
difference(other) {
|
|
762
|
+
return makeSdfHandle(this.value.difference(other.value));
|
|
763
|
+
},
|
|
764
|
+
smoothUnion(other, k) {
|
|
765
|
+
return makeSdfHandle(this.value.smooth_union(other.value, k));
|
|
766
|
+
},
|
|
767
|
+
smoothIntersection(other, k) {
|
|
768
|
+
return makeSdfHandle(this.value.smooth_intersection(other.value, k));
|
|
769
|
+
},
|
|
770
|
+
smoothDifference(other, k) {
|
|
771
|
+
return makeSdfHandle(this.value.smooth_difference(other.value, k));
|
|
772
|
+
},
|
|
773
|
+
offset(distance) {
|
|
774
|
+
return makeSdfHandle(this.value.offset(distance));
|
|
775
|
+
},
|
|
776
|
+
round(radius) {
|
|
777
|
+
return makeSdfHandle(this.value.round(radius));
|
|
778
|
+
},
|
|
779
|
+
shell(thickness) {
|
|
780
|
+
return makeSdfHandle(this.value.shell(thickness));
|
|
781
|
+
},
|
|
782
|
+
onion(thickness) {
|
|
783
|
+
return makeSdfHandle(this.value.onion(thickness));
|
|
784
|
+
},
|
|
785
|
+
translate(x, y, z) {
|
|
786
|
+
return makeSdfHandle(this.value.translate(x, y, z));
|
|
787
|
+
},
|
|
788
|
+
rotate(ax, ay, az, angle) {
|
|
789
|
+
return makeSdfHandle(this.value.rotate(ax, ay, az, angle));
|
|
790
|
+
},
|
|
791
|
+
scale(s) {
|
|
792
|
+
return makeSdfHandle(this.value.scale(s));
|
|
793
|
+
},
|
|
794
|
+
rasterize(opts) {
|
|
795
|
+
return rasterizeField(this.value, opts);
|
|
796
|
+
},
|
|
797
|
+
rasterizeIn(bounds, opts) {
|
|
798
|
+
return rasterizeFieldIn(this.value, bounds, opts);
|
|
799
|
+
}
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
function rasterizeField(sdf, opts) {
|
|
803
|
+
const params = resolveGridParams(opts);
|
|
804
|
+
if (isErr(params)) return params;
|
|
805
|
+
try {
|
|
806
|
+
return ok(makeFieldHandle(sdf.rasterize(params.value.resolution, params.value.padding)));
|
|
807
|
+
} catch (cause) {
|
|
808
|
+
return rasterizeError(cause);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
function rasterizeFieldIn(sdf, bounds, opts) {
|
|
812
|
+
const params = resolveGridParams(opts);
|
|
813
|
+
if (isErr(params)) return params;
|
|
814
|
+
const invalid = validateBounds(bounds);
|
|
815
|
+
if (invalid) return err(invalid);
|
|
816
|
+
try {
|
|
817
|
+
return ok(makeFieldHandle(sdf.rasterize_in(bounds.min[0], bounds.min[1], bounds.min[2], bounds.max[0], bounds.max[1], bounds.max[2], params.value.resolution, params.value.padding)));
|
|
818
|
+
} catch (cause) {
|
|
819
|
+
return rasterizeError(cause);
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
function rasterizeError(cause) {
|
|
823
|
+
return err(computationError("SDF_RASTERIZE_FAILED", cause instanceof Error ? cause.message : "SDF rasterization failed (grid too large?).", cause));
|
|
824
|
+
}
|
|
825
|
+
function validateBounds(bounds) {
|
|
826
|
+
if (![...bounds.min, ...bounds.max].every((v) => Number.isFinite(v))) return validationError("SDF_INVALID_BOUNDS", "bounds must be finite numbers.");
|
|
827
|
+
for (let axis = 0; axis < 3; axis++) if (bounds.max[axis] <= bounds.min[axis]) return validationError("SDF_INVALID_BOUNDS", "bounds max must exceed min on every axis.");
|
|
828
|
+
return null;
|
|
829
|
+
}
|
|
830
|
+
function build(make, id) {
|
|
831
|
+
const engine = resolveEngine(id);
|
|
832
|
+
if (isErr(engine)) return engine;
|
|
833
|
+
try {
|
|
834
|
+
return ok(makeSdfHandle(make(engine.value)));
|
|
835
|
+
} catch (cause) {
|
|
836
|
+
return err(computationError("SDF_BUILD_FAILED", cause instanceof Error ? cause.message : "SDF primitive construction failed.", cause));
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
/** A sphere of radius `r`, centered at the origin. */
|
|
840
|
+
function sphere(r, id) {
|
|
841
|
+
return build((e) => e.Sdf.sphere(r), id);
|
|
842
|
+
}
|
|
843
|
+
/** An axis-aligned box of half-extents `(hx, hy, hz)`, centered at the origin. */
|
|
844
|
+
function box$1(hx, hy, hz, id) {
|
|
845
|
+
return build((e) => e.Sdf.box_(hx, hy, hz), id);
|
|
846
|
+
}
|
|
847
|
+
/** A box with rounded edges of radius `r`. */
|
|
848
|
+
function roundedBox(hx, hy, hz, r, id) {
|
|
849
|
+
return build((e) => e.Sdf.rounded_box(hx, hy, hz, r), id);
|
|
850
|
+
}
|
|
851
|
+
/** A capped cylinder, axis +Z, radius `r`, total height `h`, centered at origin. */
|
|
852
|
+
function cylinder$1(r, h, id) {
|
|
853
|
+
return build((e) => e.Sdf.cylinder(r, h), id);
|
|
854
|
+
}
|
|
855
|
+
/** A capped cone centered at the origin: base radius `r` at z = −h/2 tapering to an apex at z = +h/2. */
|
|
856
|
+
function cone$1(r, h, id) {
|
|
857
|
+
return build((e) => e.Sdf.cone(r, h), id);
|
|
858
|
+
}
|
|
859
|
+
/** A capsule: a line segment `a`→`b` of radius `r`. */
|
|
860
|
+
function capsule(a, b, r, id) {
|
|
861
|
+
return build((e) => e.Sdf.capsule(a[0], a[1], a[2], b[0], b[1], b[2], r), id);
|
|
862
|
+
}
|
|
863
|
+
/** A torus in the XY plane (axis +Z): a `minor`-radius tube on a `major` circle. */
|
|
864
|
+
function torus(major, minor, id) {
|
|
865
|
+
return build((e) => e.Sdf.torus(major, minor), id);
|
|
866
|
+
}
|
|
867
|
+
/** A half-space: the plane through `h·n` with outward normal `n` (normalized). */
|
|
868
|
+
function plane(n, h, id) {
|
|
869
|
+
return build((e) => e.Sdf.plane(n[0], n[1], n[2], h), id);
|
|
870
|
+
}
|
|
871
|
+
//#endregion
|
|
455
872
|
//#region src/lattice/latticeFns.ts
|
|
456
873
|
var LATTICE_TAGS = {
|
|
457
874
|
gyroid: 0,
|
|
@@ -505,7 +922,7 @@ function latticeInfill(mesh, opts, id) {
|
|
|
505
922
|
if (mesh.vertices.length === 0 || mesh.triangles.length === 0) return err(validationError("LATTICE_EMPTY_MESH", "latticeInfill requires a non-empty triangle mesh."));
|
|
506
923
|
const resolved = validateOptions(opts);
|
|
507
924
|
if (isErr(resolved)) return resolved;
|
|
508
|
-
const engine = resolveEngine(id);
|
|
925
|
+
const engine = resolveEngine$1(id);
|
|
509
926
|
if (isErr(engine)) return engine;
|
|
510
927
|
const { tag, period, thickness, resolution, padding } = resolved.value;
|
|
511
928
|
try {
|
|
@@ -546,7 +963,7 @@ function tpmsLattice(bounds, opts, id) {
|
|
|
546
963
|
}
|
|
547
964
|
const resolved = validateOptions(opts);
|
|
548
965
|
if (isErr(resolved)) return resolved;
|
|
549
|
-
const engine = resolveEngine(id);
|
|
966
|
+
const engine = resolveEngine$1(id);
|
|
550
967
|
if (isErr(engine)) return engine;
|
|
551
968
|
const { tag, period, thickness, resolution, padding } = resolved.value;
|
|
552
969
|
const [minX, minY, minZ] = bounds.min;
|
|
@@ -3775,11 +4192,11 @@ var primitives_exports = /* @__PURE__ */ __exportAll({
|
|
|
3775
4192
|
polyhedron: () => polyhedron,
|
|
3776
4193
|
sewShells: () => sewShells,
|
|
3777
4194
|
solid: () => solid,
|
|
3778
|
-
sphere: () => sphere,
|
|
4195
|
+
sphere: () => sphere$1,
|
|
3779
4196
|
subFace: () => subFace,
|
|
3780
4197
|
tangentArc: () => tangentArc,
|
|
3781
4198
|
threePointArc: () => threePointArc,
|
|
3782
|
-
torus: () => torus,
|
|
4199
|
+
torus: () => torus$1,
|
|
3783
4200
|
vertex: () => vertex,
|
|
3784
4201
|
wire: () => wire,
|
|
3785
4202
|
wireLoop: () => wireLoop
|
|
@@ -4207,7 +4624,7 @@ function depsOf(...sources) {
|
|
|
4207
4624
|
}
|
|
4208
4625
|
return acc.size === 0 ? EMPTY_DEPS : acc;
|
|
4209
4626
|
}
|
|
4210
|
-
function box$
|
|
4627
|
+
function box$2(x, y, z) {
|
|
4211
4628
|
const xe = asScalarExpr(x);
|
|
4212
4629
|
const ye = asScalarExpr(y);
|
|
4213
4630
|
const ze = asScalarExpr(z);
|
|
@@ -4222,7 +4639,7 @@ function box$1(x, y, z) {
|
|
|
4222
4639
|
freeParams: depsOf(xe, ye, ze)
|
|
4223
4640
|
};
|
|
4224
4641
|
}
|
|
4225
|
-
function sphere$
|
|
4642
|
+
function sphere$2(radius) {
|
|
4226
4643
|
const re = asScalarExpr(radius);
|
|
4227
4644
|
return {
|
|
4228
4645
|
kind: "Sphere",
|
|
@@ -4231,7 +4648,7 @@ function sphere$1(radius) {
|
|
|
4231
4648
|
freeParams: re.freeParams
|
|
4232
4649
|
};
|
|
4233
4650
|
}
|
|
4234
|
-
function cylinder$
|
|
4651
|
+
function cylinder$2(radius, height) {
|
|
4235
4652
|
const re = asScalarExpr(radius);
|
|
4236
4653
|
const he = asScalarExpr(height);
|
|
4237
4654
|
return {
|
|
@@ -4242,7 +4659,7 @@ function cylinder$1(radius, height) {
|
|
|
4242
4659
|
freeParams: depsOf(re, he)
|
|
4243
4660
|
};
|
|
4244
4661
|
}
|
|
4245
|
-
function cone$
|
|
4662
|
+
function cone$2(radius1, radius2, height) {
|
|
4246
4663
|
const r1 = asScalarExpr(radius1);
|
|
4247
4664
|
const r2 = asScalarExpr(radius2);
|
|
4248
4665
|
const he = asScalarExpr(height);
|
|
@@ -4257,7 +4674,7 @@ function cone$1(radius1, radius2, height) {
|
|
|
4257
4674
|
freeParams: depsOf(r1, r2, he)
|
|
4258
4675
|
};
|
|
4259
4676
|
}
|
|
4260
|
-
function torus$
|
|
4677
|
+
function torus$2(majorRadius, minorRadius) {
|
|
4261
4678
|
const ma = asScalarExpr(majorRadius);
|
|
4262
4679
|
const mi = asScalarExpr(minorRadius);
|
|
4263
4680
|
return {
|
|
@@ -4493,7 +4910,7 @@ function evalBox(node, ctx) {
|
|
|
4493
4910
|
function evalSphere(node, ctx) {
|
|
4494
4911
|
const r = evalScalar(node.radius, ctx.env, "Sphere.radius");
|
|
4495
4912
|
if (!r.ok) return r;
|
|
4496
|
-
return ok(sphere(r.value));
|
|
4913
|
+
return ok(sphere$1(r.value));
|
|
4497
4914
|
}
|
|
4498
4915
|
function evalCylinder(node, ctx) {
|
|
4499
4916
|
const r = evalScalar(node.radius, ctx.env, "Cylinder.radius");
|
|
@@ -4516,7 +4933,7 @@ function evalTorus(node, ctx) {
|
|
|
4516
4933
|
if (!ma.ok) return ma;
|
|
4517
4934
|
const mi = evalScalar(node.minorRadius, ctx.env, "Torus.minorRadius");
|
|
4518
4935
|
if (!mi.ok) return mi;
|
|
4519
|
-
return ok(torus(ma.value, mi.value));
|
|
4936
|
+
return ok(torus$1(ma.value, mi.value));
|
|
4520
4937
|
}
|
|
4521
4938
|
function evalPolygon(node, ctx) {
|
|
4522
4939
|
const pts = [];
|
|
@@ -5162,7 +5579,7 @@ function readSingleExpr(j, key, build) {
|
|
|
5162
5579
|
function readPrimitive(kind, j) {
|
|
5163
5580
|
switch (kind) {
|
|
5164
5581
|
case "Box": return readBox(j);
|
|
5165
|
-
case "Sphere": return readSingleExpr(j, "radius", sphere$
|
|
5582
|
+
case "Sphere": return readSingleExpr(j, "radius", sphere$2);
|
|
5166
5583
|
case "Cylinder": return readCylinder(j);
|
|
5167
5584
|
case "Cone": return readCone(j);
|
|
5168
5585
|
case "Torus": return readTorus(j);
|
|
@@ -5181,14 +5598,14 @@ function readBox(j) {
|
|
|
5181
5598
|
if (!y.ok) return y;
|
|
5182
5599
|
const z = readExpr(j["z"]);
|
|
5183
5600
|
if (!z.ok) return z;
|
|
5184
|
-
return ok(box$
|
|
5601
|
+
return ok(box$2(x.value, y.value, z.value));
|
|
5185
5602
|
}
|
|
5186
5603
|
function readCylinder(j) {
|
|
5187
5604
|
const r = readExpr(j["radius"]);
|
|
5188
5605
|
if (!r.ok) return r;
|
|
5189
5606
|
const h = readExpr(j["height"]);
|
|
5190
5607
|
if (!h.ok) return h;
|
|
5191
|
-
return ok(cylinder$
|
|
5608
|
+
return ok(cylinder$2(r.value, h.value));
|
|
5192
5609
|
}
|
|
5193
5610
|
function readCone(j) {
|
|
5194
5611
|
const r1 = readExpr(j["radius1"]);
|
|
@@ -5197,14 +5614,14 @@ function readCone(j) {
|
|
|
5197
5614
|
if (!r2.ok) return r2;
|
|
5198
5615
|
const h = readExpr(j["height"]);
|
|
5199
5616
|
if (!h.ok) return h;
|
|
5200
|
-
return ok(cone$
|
|
5617
|
+
return ok(cone$2(r1.value, r2.value, h.value));
|
|
5201
5618
|
}
|
|
5202
5619
|
function readTorus(j) {
|
|
5203
5620
|
const ma = readExpr(j["majorRadius"]);
|
|
5204
5621
|
if (!ma.ok) return ma;
|
|
5205
5622
|
const mi = readExpr(j["minorRadius"]);
|
|
5206
5623
|
if (!mi.ok) return mi;
|
|
5207
|
-
return ok(torus$
|
|
5624
|
+
return ok(torus$2(ma.value, mi.value));
|
|
5208
5625
|
}
|
|
5209
5626
|
function readPolygon(j) {
|
|
5210
5627
|
const pts = j["points"];
|
|
@@ -5380,11 +5797,11 @@ function foldBuildVec(dim, comps) {
|
|
|
5380
5797
|
}
|
|
5381
5798
|
function optimizeNode(n) {
|
|
5382
5799
|
switch (n.kind) {
|
|
5383
|
-
case "Box": return box$
|
|
5384
|
-
case "Sphere": return sphere$
|
|
5385
|
-
case "Cylinder": return cylinder$
|
|
5386
|
-
case "Cone": return cone$
|
|
5387
|
-
case "Torus": return torus$
|
|
5800
|
+
case "Box": return box$2(foldExpr(n.x), foldExpr(n.y), foldExpr(n.z));
|
|
5801
|
+
case "Sphere": return sphere$2(foldExpr(n.radius));
|
|
5802
|
+
case "Cylinder": return cylinder$2(foldExpr(n.radius), foldExpr(n.height));
|
|
5803
|
+
case "Cone": return cone$2(foldExpr(n.radius1), foldExpr(n.radius2), foldExpr(n.height));
|
|
5804
|
+
case "Torus": return torus$2(foldExpr(n.majorRadius), foldExpr(n.minorRadius));
|
|
5388
5805
|
case "Polygon": return polygon$1(n.points.map(foldExpr));
|
|
5389
5806
|
case "Circle": return circle$1(foldExpr(n.radius));
|
|
5390
5807
|
case "Line": return line$1(foldExpr(n.from), foldExpr(n.to));
|
|
@@ -5542,15 +5959,15 @@ var csg_exports = /* @__PURE__ */ __exportAll({
|
|
|
5542
5959
|
asVec2Expr: () => asVec2Expr,
|
|
5543
5960
|
asVec3Expr: () => asVec3Expr,
|
|
5544
5961
|
binOp: () => binOp,
|
|
5545
|
-
box: () => box$
|
|
5962
|
+
box: () => box$2,
|
|
5546
5963
|
buildVec: () => buildVec,
|
|
5547
5964
|
circle: () => circle$1,
|
|
5548
5965
|
component: () => component,
|
|
5549
5966
|
compound: () => compound$1,
|
|
5550
|
-
cone: () => cone$
|
|
5967
|
+
cone: () => cone$2,
|
|
5551
5968
|
cut: () => cut$1,
|
|
5552
5969
|
cutAll: () => cutAll$1,
|
|
5553
|
-
cylinder: () => cylinder$
|
|
5970
|
+
cylinder: () => cylinder$2,
|
|
5554
5971
|
emptyFace: () => emptyFace,
|
|
5555
5972
|
emptySolid: () => emptySolid,
|
|
5556
5973
|
emptyWire: () => emptyWire,
|
|
@@ -5572,9 +5989,9 @@ var csg_exports = /* @__PURE__ */ __exportAll({
|
|
|
5572
5989
|
replaceNode: () => replaceNode,
|
|
5573
5990
|
rotate: () => rotate$1,
|
|
5574
5991
|
scale: () => scale$1,
|
|
5575
|
-
sphere: () => sphere$
|
|
5992
|
+
sphere: () => sphere$2,
|
|
5576
5993
|
toJSON: () => toJSON,
|
|
5577
|
-
torus: () => torus$
|
|
5994
|
+
torus: () => torus$2,
|
|
5578
5995
|
translate: () => translate$1,
|
|
5579
5996
|
unaryOp: () => unaryOp,
|
|
5580
5997
|
vec2Lit: () => vec2Lit,
|
|
@@ -5583,4 +6000,4 @@ var csg_exports = /* @__PURE__ */ __exportAll({
|
|
|
5583
6000
|
withEvaluator: () => withEvaluator
|
|
5584
6001
|
});
|
|
5585
6002
|
//#endregion
|
|
5586
|
-
export { BaseSketcher2d, BlueprintSketcher, BrepBugError, BrepErrorCode, BrepWrapperError, BrepkitAdapter, CompoundSketch, DEFAULT_CAPABILITIES, DEG2RAD, DisposalScope, EXACT_BREP_CAPABILITIES, FaceSketcher, HASH_CODE_MAX, OK, OcctWasmAdapter, RAD2DEG, Sketch, Sketcher, Sketches, addChild, addHoles, addMate, addStep, adjacentFaces, all, andThen, applyGlue, applyMatrix, approximateCurve, as2D, as3D, asTopo, assignRoles, autoHeal, bezier, blueprintToDXF, booleanPipeline, booleans_exports as booleans, boss, box, bsplineApprox, bug, cameraFromPlane, cameraLookAt, captureHint, cast, castShape, castShape3D, chamfer, chamferDistAngle as chamferDistAngleShape, chamferWithEvolution, checkAllInterferences, checkBoolean, checkInterference, circle, circularPattern, classifyPointOnFace, clearMeshCache, clone, closedWire, collect, collectShapes, colorFaces, colorShape, complexExtrude, composeTransforms, compound, compoundSketchExtrude, compoundSketchFace, compoundSketchLoft, compoundSketchRevolve, computationError, computeStraightSkeleton, cone, construction_exports as construction, convexHull, cornerFinder, countNodes, createAssembly, createAssemblyNode, createBlueprint, createCamera, createCompound, createCompoundBlueprint, createDistanceQuery, createEdge, createFace, createHandle, createHistory, createKernelHandle, createMeshCache, createNamedPlane, createOperationRegistry, createPlane, createRef, createRegistry, createShell, createSolid, createTaskQueue, createVertex, createWire, createWorkerClient, createWorkerHandler, csg_exports as csg, currentQuality, curve2dBoundingBox, curve2dDistanceFrom, curve2dFirstPoint, curve2dIsOnCurve, curve2dLastPoint, curve2dParameter, curve2dSplitAt, curve2dTangentAt, curveEndPoint, curveIsClosed, curveIsPeriodic, curveLength, curvePeriod, curvePointAt, curveStartPoint, curveTangentAt, cut, cut2D, cutAll, cutAllBisect, cutBlueprints, cutWithEvolution, cylinder, defaultScorer, dequeueTask, describe, deserializeDrawing, deserializeHistory, fromBREP as deserializeShape, downcast, draft, draw, drawCircle, drawEllipse, drawFaceOutline, drawParametricFunction, drawPointsInterpolation, drawPolysides, drawProjection, drawRectangle, drawRoundedRectangle, drawSingleCircle, drawSingleEllipse, drawText, drawingChamfer, drawingCut, drawingFillet, drawingFuse, drawingIntersect, drawingToSketchOnPlane, drill, edgeFinder, edgesOfFace, ellipse, ellipseArc, ellipsoid, enqueueTask, err, exportAssemblySTEP, exportDXF, exportGlb, exportGltf, exportIGES, exportOBJ, exportSTEP, exportSTEPConfigured, exportSTL, exportThreeMF, extrude, extrudeAll, face, faceCenter, faceFinder, faceGeomType, faceOrientation, facesOfEdge, fill, filledFace, fillet, filletWithEvolution, findFacesByTag, findNode, findStep, fixSelfIntersection, fixShape, flatMap, flatten, flipFaceOrientation, flipOrientation, fontMetrics, fromBREP$1 as fromBREP, fromKernelDir, fromKernelPnt, fromKernelVec, fromNullable, fuse, fuse2D, fuseAll, fuseAllBisect, fuseBlueprints, fuseWithEvolution, gearGeometry, getActiveVoxelId, getBounds, getBounds2D, getCompSolids, getCurveType, getDisposalStats, getEdges, getFaceColor, getFaceOrigins, getFaceTags, getFaces, getFont, getHashCode, getShape as getHistoryShape, getKernel, getKernelCapabilities, getKernelTier, getNurbsCurveData, getNurbsSurfaceData, getOrientation, getOrientation2D, getPerformanceStats, getShapeColor, getShapeKind, getShells, getSingleFace, getSolids, getSurfaceType, getTagMetadata, getVertices, getVoxel, getWires, guidedSweep, heal, healFace, healSolid, healWire, helix, hull, importDXF, importGLB, importIGES, importOBJ, importSTEP, importSTL, importSVG, importSVGPathD, importThreeMF, init, initFromManifold, initFromOC, initVoxel, innerWires, interpolateCurve, intersect, intersect2D, intersectBlueprints, intersectWithEvolution, invalidateShapeCache, ioNs_exports as io, ioError, is2D, is3D, isChamferRadius, isClosedWire, isCompSolid, isCompound, isDisposeRequest, isEdge, isEmpty, isEqualShape, isErr, isErrorResponse, isFace, isFilletRadius, isInitRequest, isInside2D, isLive, isManifoldShell, isNumber, isOk, isOperationRequest, isOrientedFace, isPlanarFace, isPlanarWire, isProjectionPlane, isEmpty$1 as isQueueEmpty, isSameShape, isShape1D, isShape3D, isShell, isSolid, isSuccessResponse, isValid, isValidSolid, isVertex, isWire, iterCompSolids, iterEdges, iterFaces, iterShells, iterSolids, iterTopo, iterVertices, iterWires, kernelCall, kernelCallRaw, kernelCallScoped, kernelError, latticeInfill, latticeInfillShape, line, linearPattern, loadFont, loft, loftAll, makeBaseBox, makeExternalGear, makeInternalGear, makePlane, makePlanetaryGear, makeProjectedEdges, manifoldShell, map, mapBoth, mapErr, match, measureArea, measureCurvatureAt, measureCurvatureAtMid, measureDistance, measureDistanceProps, measureLength, measureLinearProps, measureSurfaceProps, measureVolume, measureVolumeProps, measurement_exports as measurement, mesh, meshEdges, meshMultiLOD, minkowski, mirror, mirror2D, mirrorDrawing, mirrorJoin, modifiers_exports as modifiers, modifyStep, moduleInitError, multiSectionSweep, normalAt, offset, offsetFace, offsetMesh, offsetShape, offsetWire2D, ok, or, orElse, organiseBlueprints, orientedFace, outerWire, patterns_exports as patterns, pendingCount, pipeline, pivotPlane, planarFace, planarWire, planetPlacements, pocket, pointOnSurface, pointsInside, polygon, polyhedron, polysideInnerRadius, polysidesBlueprint, positionOnCurve, prewarm, primitives_exports as primitives, projectEdges, projectPointOnFace, query_exports as query, queryError, rectangularPattern, registerHandler, registerKernel, registerKernelTier, registerOperation, registerShape, registerVoxel, rejectAll, removeChild, removeHolesFromFace, repairMesh, replayFrom, replayHistory, resetDisposalStats, resetPerformanceStats, resize, resolve, resolve3D, resolveDirection, resolvePlane, resolveRef, reverseCurve, revolve, roof, rotate, rotate2D, rotateDrawing, roundedRectangleBlueprint, scale, scale2D, scaleDrawing, section, sectionToFace, serializeHistory, setShapeOrigin, setTagMetadata, sewShells, shape, shapeToMeshInput, shapeType, sharedEdges, shell, shellMesh, shellShape, shellWithEvolution, simplify, sketchCircle, sketchEllipse, sketchExtrude, sketchFace, sketchFaceOffset, sketchHelix, sketchLoft, sketchOnFace2D, sketchOnPlane2D, sketchParametricFunction, sketchPolysides, sketchRectangle, sketchRevolve, sketchRoundedRectangle, sketchSweep, sketchText, sketchWires, sketcherStateError, slice, solid, solidFromShell, solveAssembly, sphere, split, stepCount, stepsFrom, stretch2D, subFace, supportExtrude, supportsConstraintSketch, supportsProjection, surfaceFromGrid, surfaceFromImage, sweep, tagFaces, tangentArc, tap, tapErr, textBlueprints, textMetrics, thicken, threePointArc, toBREP, toBufferGeometryData, toGroupedBufferGeometryData, toKernelVec, toLODGeometryData, toLineGeometryData, toSVGPathD, toVec2, toVec3, torus, tpmsLattice, transformCopy, transforms_exports as transforms, translate, translate2D, translateDrawing, translatePlane, tryCatch, tryCatchAsync, twistExtrude, typeCastError, undoLast, unsupportedError, unwrap, unwrapErr, unwrapOr, unwrapOrElse, updateNode, updateRoles, uvBounds, uvCoordinates, validSolid, validatePlanetary, validationError, variableFillet, vecAdd, vecAngle, vecCross, vecDistance, vecDot, vecEquals, vecIsZero, vecLength, vecLengthSq, vecNegate, vecNormalize, vecProjectToPlane, vecRepr, vecRotate, vecScale, vecSub, vertex, vertexFinder, vertexPosition, verticesOfEdge, voxelBoolean, voxelBooleanShapes, walkAssembly, windingNumbers, wire, wireFinder, wireLoop, wiresOfFace, withKernel, withKernelDir, withKernelPnt, withKernelVec, withQuality, withScope, withScopeResult, withScopeResultAsync, withTier, zip as zipResults };
|
|
6003
|
+
export { BaseSketcher2d, BlueprintSketcher, BrepBugError, BrepErrorCode, BrepWrapperError, BrepkitAdapter, CompoundSketch, DEFAULT_CAPABILITIES, DEG2RAD, DisposalScope, EXACT_BREP_CAPABILITIES, FaceSketcher, HASH_CODE_MAX, OK, OcctWasmAdapter, RAD2DEG, Sketch, Sketcher, Sketches, addChild, addHoles, addMate, addStep, adjacentFaces, all, andThen, applyGlue, applyMatrix, approximateCurve, as2D, as3D, asTopo, assignRoles, autoHeal, bezier, blueprintToDXF, booleanPipeline, booleans_exports as booleans, boss, box, bsplineApprox, bug, cameraFromPlane, cameraLookAt, captureHint, cast, castShape, castShape3D, chamfer, chamferDistAngle as chamferDistAngleShape, chamferWithEvolution, checkAllInterferences, checkBoolean, checkInterference, circle, circularPattern, classifyPointOnFace, clearMeshCache, clone, closedWire, collect, collectShapes, colorFaces, colorShape, complexExtrude, composeTransforms, compound, compoundSketchExtrude, compoundSketchFace, compoundSketchLoft, compoundSketchRevolve, computationError, computeStraightSkeleton, cone, construction_exports as construction, convexHull, cornerFinder, countNodes, createAssembly, createAssemblyNode, createBlueprint, createCamera, createCompound, createCompoundBlueprint, createDistanceQuery, createEdge, createFace, createHandle, createHistory, createKernelHandle, createMeshCache, createNamedPlane, createOperationRegistry, createPlane, createRef, createRegistry, createShell, createSolid, createTaskQueue, createVertex, createWire, createWorkerClient, createWorkerHandler, csg_exports as csg, currentQuality, curve2dBoundingBox, curve2dDistanceFrom, curve2dFirstPoint, curve2dIsOnCurve, curve2dLastPoint, curve2dParameter, curve2dSplitAt, curve2dTangentAt, curveEndPoint, curveIsClosed, curveIsPeriodic, curveLength, curvePeriod, curvePointAt, curveStartPoint, curveTangentAt, cut, cut2D, cutAll, cutAllBisect, cutBlueprints, cutWithEvolution, cylinder, defaultScorer, dequeueTask, describe, deserializeDrawing, deserializeHistory, fromBREP as deserializeShape, downcast, draft, draw, drawCircle, drawEllipse, drawFaceOutline, drawParametricFunction, drawPointsInterpolation, drawPolysides, drawProjection, drawRectangle, drawRoundedRectangle, drawSingleCircle, drawSingleEllipse, drawText, drawingChamfer, drawingCut, drawingFillet, drawingFuse, drawingIntersect, drawingToSketchOnPlane, drill, edgeFinder, edgesOfFace, ellipse, ellipseArc, ellipsoid, enqueueTask, err, exportAssemblySTEP, exportDXF, exportGlb, exportGltf, exportIGES, exportOBJ, exportSTEP, exportSTEPConfigured, exportSTL, exportThreeMF, extrude, extrudeAll, face, faceCenter, faceFinder, faceGeomType, faceOrientation, facesOfEdge, fieldBoolean, fieldContour, fieldOffset, fieldReinit, fieldShell, fill, filledFace, fillet, filletWithEvolution, findFacesByTag, findNode, findStep, fixSelfIntersection, fixShape, flatMap, flatten, flipFaceOrientation, flipOrientation, fontMetrics, fromBREP$1 as fromBREP, fromKernelDir, fromKernelPnt, fromKernelVec, fromNullable, fuse, fuse2D, fuseAll, fuseAllBisect, fuseBlueprints, fuseWithEvolution, gearGeometry, getActiveVoxelId, getBounds, getBounds2D, getCompSolids, getCurveType, getDisposalStats, getEdges, getFaceColor, getFaceOrigins, getFaceTags, getFaces, getFont, getHashCode, getShape as getHistoryShape, getKernel, getKernelCapabilities, getKernelTier, getNurbsCurveData, getNurbsSurfaceData, getOrientation, getOrientation2D, getPerformanceStats, getShapeColor, getShapeKind, getShells, getSingleFace, getSolids, getSurfaceType, getTagMetadata, getVertices, getVoxel, getWires, guidedSweep, heal, healFace, healSolid, healWire, helix, hull, importDXF, importGLB, importIGES, importOBJ, importSTEP, importSTL, importSVG, importSVGPathD, importThreeMF, init, initFromManifold, initFromOC, initVoxel, innerWires, interpolateCurve, intersect, intersect2D, intersectBlueprints, intersectWithEvolution, invalidateShapeCache, ioNs_exports as io, ioError, is2D, is3D, isChamferRadius, isClosedWire, isCompSolid, isCompound, isDisposeRequest, isEdge, isEmpty, isEqualShape, isErr, isErrorResponse, isFace, isFilletRadius, isInitRequest, isInside2D, isLive, isManifoldShell, isNumber, isOk, isOperationRequest, isOrientedFace, isPlanarFace, isPlanarWire, isProjectionPlane, isEmpty$1 as isQueueEmpty, isSameShape, isShape1D, isShape3D, isShell, isSolid, isSuccessResponse, isValid, isValidSolid, isVertex, isWire, iterCompSolids, iterEdges, iterFaces, iterShells, iterSolids, iterTopo, iterVertices, iterWires, kernelCall, kernelCallRaw, kernelCallScoped, kernelError, latticeInfill, latticeInfillShape, line, linearPattern, loadFont, loft, loftAll, makeBaseBox, makeExternalGear, makeInternalGear, makePlane, makePlanetaryGear, makeProjectedEdges, manifoldShell, map, mapBoth, mapErr, match, measureArea, measureCurvatureAt, measureCurvatureAtMid, measureDistance, measureDistanceProps, measureLength, measureLinearProps, measureSurfaceProps, measureVolume, measureVolumeProps, measurement_exports as measurement, mesh, meshEdges, meshMultiLOD, minkowski, mirror, mirror2D, mirrorDrawing, mirrorJoin, modifiers_exports as modifiers, modifyStep, moduleInitError, multiSectionSweep, normalAt, offset, offsetFace, offsetMesh, offsetShape, offsetWire2D, ok, or, orElse, organiseBlueprints, orientedFace, outerWire, patterns_exports as patterns, pendingCount, pipeline, pivotPlane, planarFace, planarWire, planetPlacements, pocket, pointOnSurface, pointsInside, polygon, polyhedron, polysideInnerRadius, polysidesBlueprint, positionOnCurve, prewarm, primitives_exports as primitives, projectEdges, projectPointOnFace, query_exports as query, queryError, rectangularPattern, registerHandler, registerKernel, registerKernelTier, registerOperation, registerShape, registerVoxel, rejectAll, removeChild, removeHolesFromFace, repairMesh, replayFrom, replayHistory, resetDisposalStats, resetPerformanceStats, resize, resolve, resolve3D, resolveDirection, resolvePlane, resolveRef, reverseCurve, revolve, roof, rotate, rotate2D, rotateDrawing, roundedRectangleBlueprint, scale, scale2D, scaleDrawing, box$1 as sdfBox, capsule as sdfCapsule, cone$1 as sdfCone, cylinder$1 as sdfCylinder, plane as sdfPlane, roundedBox as sdfRoundedBox, sphere as sdfSphere, torus as sdfTorus, section, sectionToFace, serializeHistory, setShapeOrigin, setTagMetadata, sewShells, shape, shapeToMeshInput, shapeType, sharedEdges, shell, shellMesh, shellShape, shellWithEvolution, simplify, sketchCircle, sketchEllipse, sketchExtrude, sketchFace, sketchFaceOffset, sketchHelix, sketchLoft, sketchOnFace2D, sketchOnPlane2D, sketchParametricFunction, sketchPolysides, sketchRectangle, sketchRevolve, sketchRoundedRectangle, sketchSweep, sketchText, sketchWires, sketcherStateError, slice, solid, solidFromShell, solveAssembly, sphere$1 as sphere, split, stepCount, stepsFrom, stretch2D, subFace, supportExtrude, supportsConstraintSketch, supportsProjection, surfaceFromGrid, surfaceFromImage, sweep, tagFaces, tangentArc, tap, tapErr, textBlueprints, textMetrics, thicken, threePointArc, toBREP, toBufferGeometryData, toGroupedBufferGeometryData, toKernelVec, toLODGeometryData, toLineGeometryData, toSVGPathD, toVec2, toVec3, torus$1 as torus, tpmsLattice, transformCopy, transforms_exports as transforms, translate, translate2D, translateDrawing, translatePlane, tryCatch, tryCatchAsync, twistExtrude, typeCastError, undoLast, unsupportedError, unwrap, unwrapErr, unwrapOr, unwrapOrElse, updateNode, updateRoles, uvBounds, uvCoordinates, validSolid, validatePlanetary, validationError, variableFillet, vecAdd, vecAngle, vecCross, vecDistance, vecDot, vecEquals, vecIsZero, vecLength, vecLengthSq, vecNegate, vecNormalize, vecProjectToPlane, vecRepr, vecRotate, vecScale, vecSub, vertex, vertexFinder, vertexPosition, verticesOfEdge, voxelBoolean, voxelBooleanField, voxelBooleanFieldShapes, voxelBooleanShapes, voxelField, voxelFieldFromShape, walkAssembly, windingNumbers, wire, wireFinder, wireLoop, wiresOfFace, withKernel, withKernelDir, withKernelPnt, withKernelVec, withQuality, withScope, withScopeResult, withScopeResultAsync, withTier, zip as zipResults };
|