brepjs 18.17.0 → 18.19.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/README.md +24 -14
- package/dist/2d.cjs +7 -7
- package/dist/2d.js +7 -7
- package/dist/{blueprint-Dn16jzZs.cjs → blueprint-Bl0YQjkk.cjs} +7 -7
- package/dist/{blueprint-C-ngUkOG.js → blueprint-Cy5veXS3.js} +7 -7
- package/dist/{blueprintFns-B7OF-Tv3.js → blueprintFns-CSB51aXT.js} +3 -3
- package/dist/{blueprintFns-j2YskNJl.cjs → blueprintFns-Dkccxo6d.cjs} +3 -3
- package/dist/{blueprintSketcher-D2awQyoi.cjs → blueprintSketcher-Cr9A-R8I.cjs} +4 -4
- package/dist/{blueprintSketcher-DlJ7yDBD.js → blueprintSketcher-DeEogKbs.js} +4 -4
- package/dist/{boolean2D-BlazC0Yu.cjs → boolean2D-BZ1UjpjX.cjs} +5 -5
- package/dist/{boolean2D-C3x4nSLt.js → boolean2D-lE2uy4Mm.js} +5 -5
- package/dist/{booleanFns-COUVhZlF.cjs → booleanFns-CD25YZGm.cjs} +6 -6
- package/dist/{booleanFns-CwskNGMz.js → booleanFns-CtvYfQZq.js} +6 -6
- package/dist/brepjs.cjs +1721 -34
- package/dist/brepjs.js +1735 -54
- package/dist/{cameraFns-leKP1O1t.cjs → cameraFns-CR2inEBU.cjs} +3 -3
- package/dist/{cameraFns-Bix9SLAm.js → cameraFns-Dg1lQP0S.js} +3 -3
- package/dist/core/errors.d.ts +1 -0
- package/dist/core.cjs +3 -3
- package/dist/core.js +3 -3
- package/dist/{cornerFinder-Cm58LsyX.cjs → cornerFinder-CXN1IxPg.cjs} +1 -1
- package/dist/{cornerFinder-GBVBku2c.js → cornerFinder-tfWhcA2M.js} +1 -1
- package/dist/csg/builders.d.ts +36 -0
- package/dist/csg/edit.d.ts +5 -0
- package/dist/csg/evaluate.d.ts +52 -0
- package/dist/csg/evaluators/booleans.d.ts +11 -0
- package/dist/csg/evaluators/compound.d.ts +8 -0
- package/dist/csg/evaluators/context.d.ts +9 -0
- package/dist/csg/evaluators/primitives.d.ts +15 -0
- package/dist/csg/evaluators/transforms.d.ts +10 -0
- package/dist/csg/expressions.d.ts +72 -0
- package/dist/csg/hash.d.ts +9 -0
- package/dist/csg/index.d.ts +15 -0
- package/dist/csg/optimize.d.ts +4 -0
- package/dist/csg/serialize.d.ts +9 -0
- package/dist/csg/types.d.ts +128 -0
- package/dist/{curveFns-DVHUVmuO.js → curveFns-BEF8t7XY.js} +2 -2
- package/dist/{curveFns-Ds0e7i2y.cjs → curveFns-CcheHkr4.cjs} +2 -2
- package/dist/{drawFns-CaWzI_lX.js → drawFns-CEjshioX.js} +14 -14
- package/dist/{drawFns-BvqZW_fK.cjs → drawFns-CuzUHFyD.cjs} +14 -14
- package/dist/{errors-0fYW_YnO.js → errors-8GZS3vy9.js} +1 -0
- package/dist/{errors-Dv6pfNct.cjs → errors-BiY8-q1s.cjs} +1 -0
- package/dist/{extrudeFns-BZAIPeYY.cjs → extrudeFns-BwU4ng1V.cjs} +2 -2
- package/dist/{extrudeFns-vl1_n-yk.js → extrudeFns-gcWJSK9T.js} +2 -2
- package/dist/{faceFns-m0GePUMn.js → faceFns-BNhFoEII.js} +3 -3
- package/dist/{faceFns-CbpUuSSF.cjs → faceFns-BbESdudy.cjs} +3 -3
- package/dist/{helpers-CrH0p3GU.cjs → helpers-BU3ANziG.cjs} +7 -7
- package/dist/{helpers-C7wU_L9l.js → helpers-D1J5VHbk.js} +7 -7
- package/dist/{historyFns-CdhKQcbS.cjs → historyFns-DHOoBh6G.cjs} +5 -5
- package/dist/{historyFns-Cs19Tmq_.js → historyFns-XZp1D_aA.js} +5 -5
- package/dist/{importFns-FvsXxxRS.cjs → importFns-CsRJ9lbm.cjs} +3 -3
- package/dist/{importFns-B1IIPON9.js → importFns-D1oB3yU8.js} +3 -3
- package/dist/index.d.ts +1 -0
- package/dist/io.cjs +2 -2
- package/dist/io.js +2 -2
- package/dist/kernel/brepkit/brepkitWasmTypes.d.ts +10 -7
- package/dist/kernel/index.d.ts +6 -0
- package/dist/{measureFns-DuXAfU3o.cjs → measureFns-BkoPw5JT.cjs} +4 -4
- package/dist/{measureFns-HKGnPqSW.js → measureFns-C3y_WX_E.js} +4 -4
- package/dist/measurement.cjs +1 -1
- package/dist/measurement.js +1 -1
- package/dist/{meshFns-Dr3EAM7B.cjs → meshFns-CFMr9FBb.cjs} +3 -3
- package/dist/{meshFns-BtZ68glt.js → meshFns-k0BdoBGR.js} +3 -3
- package/dist/ns/csg.d.ts +4 -0
- package/dist/operations.cjs +2 -2
- package/dist/operations.js +2 -2
- package/dist/{planeOps-CH4ruLuj.cjs → planeOps-2EyPq0tU.cjs} +1 -1
- package/dist/{planeOps-4i2qEraD.js → planeOps-Bea3T3mc.js} +1 -1
- package/dist/{primitiveFns-DVxhf1Oj.js → primitiveFns-DF5IAVNP.js} +7 -7
- package/dist/{primitiveFns-CvE88XaR.cjs → primitiveFns-YpYBx4Pd.cjs} +7 -7
- 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/result.cjs +1 -1
- package/dist/result.js +1 -1
- package/dist/{shapeFns-D1gHNJJY.cjs → shapeFns-CHTLdb_n.cjs} +3 -3
- package/dist/{shapeFns-CkkChODq.js → shapeFns-x8vqq2fR.js} +3 -3
- package/dist/shapeRef.cjs +1 -1
- package/dist/shapeRef.js +1 -1
- package/dist/{shapeRefFns-BkVipOTE.cjs → shapeRefFns-CDRLEUik.cjs} +4 -4
- package/dist/{shapeRefFns-TUtuCJ85.js → shapeRefFns-CE0yS0EB.js} +4 -4
- package/dist/{shapeTypes-xj3nxBTM.cjs → shapeTypes-BpKhed-9.cjs} +19 -2
- package/dist/{shapeTypes-B_s2jyQ2.js → shapeTypes-DGtDTS9s.js} +14 -3
- package/dist/sketching.cjs +3 -3
- package/dist/sketching.js +3 -3
- package/dist/{solidBuilders-lBO5Fk9Z.cjs → solidBuilders-BlBaFSCS.cjs} +3 -3
- package/dist/{solidBuilders-DLJlAEi9.js → solidBuilders-Cot05qzs.js} +3 -3
- package/dist/{surfaceBuilders-BkgewbNs.cjs → surfaceBuilders-frj7YRrD.cjs} +3 -3
- package/dist/{surfaceBuilders-DRxCelXR.js → surfaceBuilders-zJyikeav.js} +3 -3
- package/dist/text.cjs +2 -2
- package/dist/text.js +2 -2
- package/dist/{textBlueprints-D5zPssgR.js → textBlueprints-Bv6zhEyn.js} +9 -9
- package/dist/{textBlueprints-Dy4xulfR.cjs → textBlueprints-CHh9SChA.cjs} +9 -9
- package/dist/{textMetrics-DcIcFPtV.cjs → textMetrics-CKNdQX02.cjs} +2 -2
- package/dist/{textMetrics-Dkitx1CA.js → textMetrics-vUJTTEFi.js} +2 -2
- package/dist/topology.cjs +7 -7
- package/dist/topology.js +7 -7
- package/dist/{topologyQueryFns-D0v-c2Xk.cjs → topologyQueryFns-CHsPXNbI.cjs} +2 -2
- package/dist/{topologyQueryFns-BcYn7Adz.js → topologyQueryFns-CcWaCxeb.js} +2 -2
- package/dist/vectors.cjs +1 -1
- package/dist/vectors.js +1 -1
- package/package.json +2 -2
package/dist/brepjs.cjs
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_textBlueprints = require("./textBlueprints-
|
|
3
|
-
const require_shapeTypes = require("./shapeTypes-
|
|
2
|
+
const require_textBlueprints = require("./textBlueprints-CHh9SChA.cjs");
|
|
3
|
+
const require_shapeTypes = require("./shapeTypes-BpKhed-9.cjs");
|
|
4
4
|
const require_vec3 = require("./vec3-S4Oh59IX.cjs");
|
|
5
5
|
const require_occtWasmAdapter = require("./occtWasmAdapter-C2VW-uYg.cjs");
|
|
6
|
-
const require_errors = require("./errors-
|
|
7
|
-
const require_topologyQueryFns = require("./topologyQueryFns-
|
|
6
|
+
const require_errors = require("./errors-BiY8-q1s.cjs");
|
|
7
|
+
const require_topologyQueryFns = require("./topologyQueryFns-CHsPXNbI.cjs");
|
|
8
8
|
const require_constants = require("./constants-DTorLmes.cjs");
|
|
9
9
|
const require_types = require("./types-CDkxah-M.cjs");
|
|
10
10
|
const require_vecOps = require("./vecOps-D7xplSx8.cjs");
|
|
11
|
-
const require_planeOps = require("./planeOps-
|
|
12
|
-
const require_faceFns = require("./faceFns-
|
|
13
|
-
const require_shapeFns = require("./shapeFns-
|
|
14
|
-
const require_curveFns = require("./curveFns-
|
|
15
|
-
const require_meshFns = require("./meshFns-
|
|
11
|
+
const require_planeOps = require("./planeOps-2EyPq0tU.cjs");
|
|
12
|
+
const require_faceFns = require("./faceFns-BbESdudy.cjs");
|
|
13
|
+
const require_shapeFns = require("./shapeFns-CHTLdb_n.cjs");
|
|
14
|
+
const require_curveFns = require("./curveFns-CcheHkr4.cjs");
|
|
15
|
+
const require_meshFns = require("./meshFns-CFMr9FBb.cjs");
|
|
16
16
|
const require_arrayAccess = require("./arrayAccess-7pTWqkJu.cjs");
|
|
17
|
-
const require_surfaceBuilders = require("./surfaceBuilders-
|
|
18
|
-
const require_booleanFns = require("./booleanFns-
|
|
19
|
-
const require_primitiveFns = require("./primitiveFns-
|
|
20
|
-
const require_historyFns = require("./historyFns-
|
|
21
|
-
const require_blueprintSketcher = require("./blueprintSketcher-
|
|
22
|
-
const require_helpers = require("./helpers-
|
|
23
|
-
const require_drawFns = require("./drawFns-
|
|
24
|
-
const require_solidBuilders = require("./solidBuilders-
|
|
25
|
-
const require_measureFns = require("./measureFns-
|
|
26
|
-
const require_cornerFinder = require("./cornerFinder-
|
|
27
|
-
const require_boolean2D = require("./boolean2D-
|
|
28
|
-
const require_blueprintFns = require("./blueprintFns-
|
|
29
|
-
const require_importFns = require("./importFns-
|
|
30
|
-
const require_extrudeFns = require("./extrudeFns-
|
|
31
|
-
const require_cameraFns = require("./cameraFns-
|
|
32
|
-
const require_textMetrics = require("./textMetrics-
|
|
33
|
-
const require_shapeRefFns = require("./shapeRefFns-
|
|
17
|
+
const require_surfaceBuilders = require("./surfaceBuilders-frj7YRrD.cjs");
|
|
18
|
+
const require_booleanFns = require("./booleanFns-CD25YZGm.cjs");
|
|
19
|
+
const require_primitiveFns = require("./primitiveFns-YpYBx4Pd.cjs");
|
|
20
|
+
const require_historyFns = require("./historyFns-DHOoBh6G.cjs");
|
|
21
|
+
const require_blueprintSketcher = require("./blueprintSketcher-Cr9A-R8I.cjs");
|
|
22
|
+
const require_helpers = require("./helpers-BU3ANziG.cjs");
|
|
23
|
+
const require_drawFns = require("./drawFns-CuzUHFyD.cjs");
|
|
24
|
+
const require_solidBuilders = require("./solidBuilders-BlBaFSCS.cjs");
|
|
25
|
+
const require_measureFns = require("./measureFns-BkoPw5JT.cjs");
|
|
26
|
+
const require_cornerFinder = require("./cornerFinder-CXN1IxPg.cjs");
|
|
27
|
+
const require_boolean2D = require("./boolean2D-BZ1UjpjX.cjs");
|
|
28
|
+
const require_blueprintFns = require("./blueprintFns-Dkccxo6d.cjs");
|
|
29
|
+
const require_importFns = require("./importFns-CsRJ9lbm.cjs");
|
|
30
|
+
const require_extrudeFns = require("./extrudeFns-BwU4ng1V.cjs");
|
|
31
|
+
const require_cameraFns = require("./cameraFns-CR2inEBU.cjs");
|
|
32
|
+
const require_textMetrics = require("./textMetrics-CKNdQX02.cjs");
|
|
33
|
+
const require_shapeRefFns = require("./shapeRefFns-CDRLEUik.cjs");
|
|
34
34
|
const require_workerHandler = require("./workerHandler-C7seK7H-.cjs");
|
|
35
35
|
//#region src/topology/shapeBooleans.ts
|
|
36
36
|
var BOPAlgo_GlueShift = 1;
|
|
@@ -2879,12 +2879,12 @@ function makeInternalGearProfileWire(params) {
|
|
|
2879
2879
|
}
|
|
2880
2880
|
function makeProfileWire(params, isInternal) {
|
|
2881
2881
|
try {
|
|
2882
|
-
var _usingCtx$
|
|
2882
|
+
var _usingCtx$3 = require_shapeTypes._usingCtx();
|
|
2883
2883
|
const { teeth, moduleSize, pressureAngle, shift, clearance, flankThinning, samples = adaptiveSampleCount(moduleSize) } = params;
|
|
2884
2884
|
if (teeth < 4) return require_errors.err(require_errors.validationError("GEAR_TEETH_TOO_FEW", `gear needs ≥ 4 teeth, got ${teeth}`));
|
|
2885
2885
|
if (moduleSize <= 0) return require_errors.err(require_errors.validationError("GEAR_MODULE_NONPOSITIVE", `module must be > 0, got ${moduleSize}`));
|
|
2886
2886
|
const tm = gearGeometry(teeth, moduleSize, pressureAngle, shift, clearance, flankThinning, isInternal);
|
|
2887
|
-
const scope = _usingCtx$
|
|
2887
|
+
const scope = _usingCtx$3.u(new require_shapeTypes.DisposalScope());
|
|
2888
2888
|
const allEdges = [];
|
|
2889
2889
|
for (let i = 0; i < teeth; i++) {
|
|
2890
2890
|
const periodEdges = buildToothPeriodEdges(tm, i, teeth, samples, scope);
|
|
@@ -2895,9 +2895,9 @@ function makeProfileWire(params, isInternal) {
|
|
|
2895
2895
|
if (require_errors.isErr(wireResult)) return wireResult;
|
|
2896
2896
|
return require_errors.ok(wireResult.value);
|
|
2897
2897
|
} catch (_) {
|
|
2898
|
-
_usingCtx$
|
|
2898
|
+
_usingCtx$3.e = _;
|
|
2899
2899
|
} finally {
|
|
2900
|
-
_usingCtx$
|
|
2900
|
+
_usingCtx$3.d();
|
|
2901
2901
|
}
|
|
2902
2902
|
}
|
|
2903
2903
|
//#endregion
|
|
@@ -3078,8 +3078,8 @@ function resolvePlanetaryParams(params) {
|
|
|
3078
3078
|
}
|
|
3079
3079
|
function makeOuterCircleWire(radius) {
|
|
3080
3080
|
try {
|
|
3081
|
-
var _usingCtx$
|
|
3082
|
-
const wireResult = require_surfaceBuilders.assembleWire([_usingCtx$
|
|
3081
|
+
var _usingCtx$2 = require_shapeTypes._usingCtx();
|
|
3082
|
+
const wireResult = require_surfaceBuilders.assembleWire([_usingCtx$2.u(new require_shapeTypes.DisposalScope()).register(require_surfaceBuilders.makeCircle(radius, [
|
|
3083
3083
|
0,
|
|
3084
3084
|
0,
|
|
3085
3085
|
0
|
|
@@ -3091,9 +3091,9 @@ function makeOuterCircleWire(radius) {
|
|
|
3091
3091
|
if (require_errors.isErr(wireResult)) return wireResult;
|
|
3092
3092
|
return require_errors.ok(wireResult.value);
|
|
3093
3093
|
} catch (_) {
|
|
3094
|
-
_usingCtx$
|
|
3094
|
+
_usingCtx$2.e = _;
|
|
3095
3095
|
} finally {
|
|
3096
|
-
_usingCtx$
|
|
3096
|
+
_usingCtx$2.d();
|
|
3097
3097
|
}
|
|
3098
3098
|
}
|
|
3099
3099
|
function finalizeExternalSolid(wire, thickness, bore, geom, diagnostics) {
|
|
@@ -3412,6 +3412,1687 @@ var patterns_exports = /* @__PURE__ */ require_textBlueprints.__exportAll({
|
|
|
3412
3412
|
linearPattern: () => require_historyFns.linearPattern
|
|
3413
3413
|
});
|
|
3414
3414
|
//#endregion
|
|
3415
|
+
//#region src/csg/hash.ts
|
|
3416
|
+
var FNV_OFFSET = 14695981039346656037n;
|
|
3417
|
+
var FNV_PRIME = 1099511628211n;
|
|
3418
|
+
var MASK_64 = 18446744073709551615n;
|
|
3419
|
+
function fnvInit() {
|
|
3420
|
+
return FNV_OFFSET;
|
|
3421
|
+
}
|
|
3422
|
+
function fnvMixByte(h, byte) {
|
|
3423
|
+
return (h ^ BigInt(byte & 255)) * FNV_PRIME & MASK_64;
|
|
3424
|
+
}
|
|
3425
|
+
function fnvMixBytes(h, bytes) {
|
|
3426
|
+
let r = h;
|
|
3427
|
+
for (let i = 0; i < bytes.length; i++) r = fnvMixByte(r, bytes[i] ?? 0);
|
|
3428
|
+
return r;
|
|
3429
|
+
}
|
|
3430
|
+
var ENCODER = new TextEncoder();
|
|
3431
|
+
function fnvMixString(h, s) {
|
|
3432
|
+
return fnvMixBytes(h, ENCODER.encode(s));
|
|
3433
|
+
}
|
|
3434
|
+
var SCRATCH = /* @__PURE__ */ new ArrayBuffer(8);
|
|
3435
|
+
var SCRATCH_VIEW = new DataView(SCRATCH);
|
|
3436
|
+
var SCRATCH_BYTES = new Uint8Array(SCRATCH);
|
|
3437
|
+
function fnvMixNumber(h, n) {
|
|
3438
|
+
SCRATCH_VIEW.setFloat64(0, Object.is(n, -0) ? 0 : n);
|
|
3439
|
+
return fnvMixBytes(h, SCRATCH_BYTES);
|
|
3440
|
+
}
|
|
3441
|
+
function fnvMixHash(h, child) {
|
|
3442
|
+
let r = h;
|
|
3443
|
+
let v = child & MASK_64;
|
|
3444
|
+
for (let i = 0; i < 8; i++) {
|
|
3445
|
+
r = fnvMixByte(r, Number(v & 255n));
|
|
3446
|
+
v >>= 8n;
|
|
3447
|
+
}
|
|
3448
|
+
return r;
|
|
3449
|
+
}
|
|
3450
|
+
function fnvMixInt32(h, n) {
|
|
3451
|
+
let r = h;
|
|
3452
|
+
let v = n | 0;
|
|
3453
|
+
for (let i = 0; i < 4; i++) {
|
|
3454
|
+
r = fnvMixByte(r, v & 255);
|
|
3455
|
+
v >>>= 8;
|
|
3456
|
+
}
|
|
3457
|
+
return r;
|
|
3458
|
+
}
|
|
3459
|
+
function fnvMixBool(h, b) {
|
|
3460
|
+
return fnvMixByte(h, b ? 1 : 0);
|
|
3461
|
+
}
|
|
3462
|
+
function toHex(h) {
|
|
3463
|
+
return (h & MASK_64).toString(16).padStart(16, "0");
|
|
3464
|
+
}
|
|
3465
|
+
//#endregion
|
|
3466
|
+
//#region src/csg/expressions.ts
|
|
3467
|
+
var EMPTY_DEPS$1 = /* @__PURE__ */ new Set();
|
|
3468
|
+
function startHash$1(tag) {
|
|
3469
|
+
return fnvMixString(fnvInit(), tag);
|
|
3470
|
+
}
|
|
3471
|
+
function numLit(value) {
|
|
3472
|
+
return {
|
|
3473
|
+
kind: "NumLit",
|
|
3474
|
+
value,
|
|
3475
|
+
structuralHash: fnvMixNumber(startHash$1("NumLit"), value),
|
|
3476
|
+
freeParams: EMPTY_DEPS$1
|
|
3477
|
+
};
|
|
3478
|
+
}
|
|
3479
|
+
function vec3Lit(value) {
|
|
3480
|
+
let h = startHash$1("Vec3Lit");
|
|
3481
|
+
for (const n of value) h = fnvMixNumber(h, n);
|
|
3482
|
+
return {
|
|
3483
|
+
kind: "Vec3Lit",
|
|
3484
|
+
value,
|
|
3485
|
+
structuralHash: h,
|
|
3486
|
+
freeParams: EMPTY_DEPS$1
|
|
3487
|
+
};
|
|
3488
|
+
}
|
|
3489
|
+
function vec2Lit(value) {
|
|
3490
|
+
let h = startHash$1("Vec2Lit");
|
|
3491
|
+
for (const n of value) h = fnvMixNumber(h, n);
|
|
3492
|
+
return {
|
|
3493
|
+
kind: "Vec2Lit",
|
|
3494
|
+
value,
|
|
3495
|
+
structuralHash: h,
|
|
3496
|
+
freeParams: EMPTY_DEPS$1
|
|
3497
|
+
};
|
|
3498
|
+
}
|
|
3499
|
+
function param(name) {
|
|
3500
|
+
return {
|
|
3501
|
+
kind: "Param",
|
|
3502
|
+
name,
|
|
3503
|
+
structuralHash: fnvMixString(startHash$1("Param"), name),
|
|
3504
|
+
freeParams: new Set([name])
|
|
3505
|
+
};
|
|
3506
|
+
}
|
|
3507
|
+
function binOp(op, a, b) {
|
|
3508
|
+
let h = fnvMixString(startHash$1("BinOp"), op);
|
|
3509
|
+
h = fnvMixHash(h, a.structuralHash);
|
|
3510
|
+
h = fnvMixHash(h, b.structuralHash);
|
|
3511
|
+
return {
|
|
3512
|
+
kind: "BinOp",
|
|
3513
|
+
op,
|
|
3514
|
+
a,
|
|
3515
|
+
b,
|
|
3516
|
+
structuralHash: h,
|
|
3517
|
+
freeParams: unionParams(a.freeParams, b.freeParams)
|
|
3518
|
+
};
|
|
3519
|
+
}
|
|
3520
|
+
function unaryOp(op, arg) {
|
|
3521
|
+
let h = fnvMixString(startHash$1("UnaryOp"), op);
|
|
3522
|
+
h = fnvMixHash(h, arg.structuralHash);
|
|
3523
|
+
return {
|
|
3524
|
+
kind: "UnaryOp",
|
|
3525
|
+
op,
|
|
3526
|
+
arg,
|
|
3527
|
+
structuralHash: h,
|
|
3528
|
+
freeParams: arg.freeParams
|
|
3529
|
+
};
|
|
3530
|
+
}
|
|
3531
|
+
function component(vec, index) {
|
|
3532
|
+
let h = fnvMixInt32(startHash$1("Component"), index);
|
|
3533
|
+
h = fnvMixHash(h, vec.structuralHash);
|
|
3534
|
+
return {
|
|
3535
|
+
kind: "Component",
|
|
3536
|
+
vec,
|
|
3537
|
+
index,
|
|
3538
|
+
structuralHash: h,
|
|
3539
|
+
freeParams: vec.freeParams
|
|
3540
|
+
};
|
|
3541
|
+
}
|
|
3542
|
+
function buildVec(dim, components) {
|
|
3543
|
+
let h = fnvMixInt32(startHash$1("BuildVec"), dim);
|
|
3544
|
+
const deps = /* @__PURE__ */ new Set();
|
|
3545
|
+
for (const c of components) {
|
|
3546
|
+
h = fnvMixHash(h, c.structuralHash);
|
|
3547
|
+
for (const p of c.freeParams) deps.add(p);
|
|
3548
|
+
}
|
|
3549
|
+
return {
|
|
3550
|
+
kind: "BuildVec",
|
|
3551
|
+
dim,
|
|
3552
|
+
components,
|
|
3553
|
+
structuralHash: h,
|
|
3554
|
+
freeParams: deps
|
|
3555
|
+
};
|
|
3556
|
+
}
|
|
3557
|
+
var add = (a, b) => binOp("+", a, b);
|
|
3558
|
+
var mul = (a, b) => binOp("*", a, b);
|
|
3559
|
+
function asScalarExpr(input) {
|
|
3560
|
+
return typeof input === "number" ? numLit(input) : input;
|
|
3561
|
+
}
|
|
3562
|
+
function asVecExpr(input, dim) {
|
|
3563
|
+
if (!Array.isArray(input)) return input;
|
|
3564
|
+
const arr = input;
|
|
3565
|
+
if (arr.every((v) => typeof v === "number")) return dim === 3 ? vec3Lit([
|
|
3566
|
+
arr[0],
|
|
3567
|
+
arr[1],
|
|
3568
|
+
arr[2]
|
|
3569
|
+
]) : vec2Lit([arr[0], arr[1]]);
|
|
3570
|
+
return buildVec(dim, arr.map(asScalarExpr));
|
|
3571
|
+
}
|
|
3572
|
+
function asVec3Expr(input) {
|
|
3573
|
+
return asVecExpr(input, 3);
|
|
3574
|
+
}
|
|
3575
|
+
function asVec2Expr(input) {
|
|
3576
|
+
return asVecExpr(input, 2);
|
|
3577
|
+
}
|
|
3578
|
+
function unionParams(a, b) {
|
|
3579
|
+
if (a.size === 0) return b;
|
|
3580
|
+
if (b.size === 0) return a;
|
|
3581
|
+
const out = new Set(a);
|
|
3582
|
+
for (const x of b) out.add(x);
|
|
3583
|
+
return out;
|
|
3584
|
+
}
|
|
3585
|
+
function isNumber$2(v) {
|
|
3586
|
+
return typeof v === "number";
|
|
3587
|
+
}
|
|
3588
|
+
function expectNumber(v, where) {
|
|
3589
|
+
if (isNumber$2(v)) return require_errors.ok(v);
|
|
3590
|
+
return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.NULL_SHAPE_INPUT, `${where}: expected number, got ${Array.isArray(v) ? `vector(${v.length})` : typeof v}`));
|
|
3591
|
+
}
|
|
3592
|
+
function expectVecLen(v, len, where) {
|
|
3593
|
+
if (Array.isArray(v) && v.length === len) return require_errors.ok(v);
|
|
3594
|
+
return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.NULL_SHAPE_INPUT, `${where}: expected Vec${len}, got ${isNumber$2(v) ? "number" : `vector(${v.length})`}`));
|
|
3595
|
+
}
|
|
3596
|
+
function evalExpr(expr, env) {
|
|
3597
|
+
switch (expr.kind) {
|
|
3598
|
+
case "NumLit": return require_errors.ok(expr.value);
|
|
3599
|
+
case "Vec3Lit": return require_errors.ok(expr.value);
|
|
3600
|
+
case "Vec2Lit": return require_errors.ok(expr.value);
|
|
3601
|
+
case "Param": {
|
|
3602
|
+
const v = env[expr.name];
|
|
3603
|
+
if (v === void 0) return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.NULL_SHAPE_INPUT, `unbound param: ${expr.name}`));
|
|
3604
|
+
return require_errors.ok(v);
|
|
3605
|
+
}
|
|
3606
|
+
case "BinOp": return evalBinOp(expr, env);
|
|
3607
|
+
case "UnaryOp": return evalUnaryOp(expr, env);
|
|
3608
|
+
case "Component": return evalComponent(expr, env);
|
|
3609
|
+
case "BuildVec": return evalBuildVec(expr, env);
|
|
3610
|
+
}
|
|
3611
|
+
}
|
|
3612
|
+
function evalBinOp(expr, env) {
|
|
3613
|
+
const ar = evalExpr(expr.a, env);
|
|
3614
|
+
if (!ar.ok) return ar;
|
|
3615
|
+
const br = evalExpr(expr.b, env);
|
|
3616
|
+
if (!br.ok) return br;
|
|
3617
|
+
const an = expectNumber(ar.value, `BinOp(${expr.op}).a`);
|
|
3618
|
+
if (!an.ok) return an;
|
|
3619
|
+
const bn = expectNumber(br.value, `BinOp(${expr.op}).b`);
|
|
3620
|
+
if (!bn.ok) return bn;
|
|
3621
|
+
switch (expr.op) {
|
|
3622
|
+
case "+": return require_errors.ok(an.value + bn.value);
|
|
3623
|
+
case "-": return require_errors.ok(an.value - bn.value);
|
|
3624
|
+
case "*": return require_errors.ok(an.value * bn.value);
|
|
3625
|
+
case "/":
|
|
3626
|
+
if (bn.value === 0) return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.NULL_SHAPE_INPUT, `BinOp(/): division by zero`));
|
|
3627
|
+
return require_errors.ok(an.value / bn.value);
|
|
3628
|
+
}
|
|
3629
|
+
}
|
|
3630
|
+
function evalUnaryOp(expr, env) {
|
|
3631
|
+
const ar = evalExpr(expr.arg, env);
|
|
3632
|
+
if (!ar.ok) return ar;
|
|
3633
|
+
const an = expectNumber(ar.value, `UnaryOp(${expr.op})`);
|
|
3634
|
+
if (!an.ok) return an;
|
|
3635
|
+
const n = an.value;
|
|
3636
|
+
switch (expr.op) {
|
|
3637
|
+
case "neg": return require_errors.ok(-n);
|
|
3638
|
+
case "sin": return require_errors.ok(Math.sin(n));
|
|
3639
|
+
case "cos": return require_errors.ok(Math.cos(n));
|
|
3640
|
+
case "sqrt": return require_errors.ok(Math.sqrt(n));
|
|
3641
|
+
case "abs": return require_errors.ok(Math.abs(n));
|
|
3642
|
+
}
|
|
3643
|
+
}
|
|
3644
|
+
function evalComponent(expr, env) {
|
|
3645
|
+
const vr = evalExpr(expr.vec, env);
|
|
3646
|
+
if (!vr.ok) return vr;
|
|
3647
|
+
if (isNumber$2(vr.value)) return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.NULL_SHAPE_INPUT, `Component: cannot index a scalar`));
|
|
3648
|
+
const v = vr.value;
|
|
3649
|
+
const c = v[expr.index];
|
|
3650
|
+
if (c === void 0) return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.NULL_SHAPE_INPUT, `Component: index ${expr.index} out of range for Vec${v.length}`));
|
|
3651
|
+
return require_errors.ok(c);
|
|
3652
|
+
}
|
|
3653
|
+
function evalBuildVec(expr, env) {
|
|
3654
|
+
if (expr.components.length !== expr.dim) return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.NULL_SHAPE_INPUT, `BuildVec(${expr.dim}): expected ${expr.dim} components, got ${expr.components.length}`));
|
|
3655
|
+
const out = [];
|
|
3656
|
+
for (const c of expr.components) {
|
|
3657
|
+
const r = evalExpr(c, env);
|
|
3658
|
+
if (!r.ok) return r;
|
|
3659
|
+
const n = expectNumber(r.value, "BuildVec.component");
|
|
3660
|
+
if (!n.ok) return n;
|
|
3661
|
+
out.push(n.value);
|
|
3662
|
+
}
|
|
3663
|
+
return require_errors.ok(expr.dim === 2 ? [out[0], out[1]] : [
|
|
3664
|
+
out[0],
|
|
3665
|
+
out[1],
|
|
3666
|
+
out[2]
|
|
3667
|
+
]);
|
|
3668
|
+
}
|
|
3669
|
+
function evalScalar(expr, env, where) {
|
|
3670
|
+
const r = evalExpr(expr, env);
|
|
3671
|
+
if (!r.ok) return r;
|
|
3672
|
+
return expectNumber(r.value, where);
|
|
3673
|
+
}
|
|
3674
|
+
function evalVec3(expr, env, where) {
|
|
3675
|
+
const r = evalExpr(expr, env);
|
|
3676
|
+
if (!r.ok) return r;
|
|
3677
|
+
const v = expectVecLen(r.value, 3, where);
|
|
3678
|
+
if (!v.ok) return v;
|
|
3679
|
+
const [a, b, c] = v.value;
|
|
3680
|
+
return require_errors.ok([
|
|
3681
|
+
a,
|
|
3682
|
+
b,
|
|
3683
|
+
c
|
|
3684
|
+
]);
|
|
3685
|
+
}
|
|
3686
|
+
function projectEnv(env, deps) {
|
|
3687
|
+
if (deps.size === 0) return Object.freeze({});
|
|
3688
|
+
const out = {};
|
|
3689
|
+
for (const k of deps) {
|
|
3690
|
+
const v = env[k];
|
|
3691
|
+
if (v !== void 0) out[k] = v;
|
|
3692
|
+
}
|
|
3693
|
+
return Object.freeze(out);
|
|
3694
|
+
}
|
|
3695
|
+
//#endregion
|
|
3696
|
+
//#region src/csg/builders.ts
|
|
3697
|
+
var EMPTY_DEPS = /* @__PURE__ */ new Set();
|
|
3698
|
+
function startHash(tag) {
|
|
3699
|
+
return fnvMixString(fnvInit(), tag);
|
|
3700
|
+
}
|
|
3701
|
+
function mix(h, x) {
|
|
3702
|
+
return fnvMixHash(h, x.structuralHash);
|
|
3703
|
+
}
|
|
3704
|
+
function mixOptExpr(h, e) {
|
|
3705
|
+
if (e === void 0) return fnvMixBool(h, false);
|
|
3706
|
+
return mix(fnvMixBool(h, true), e);
|
|
3707
|
+
}
|
|
3708
|
+
function mixOptNumber(h, n) {
|
|
3709
|
+
if (n === void 0) return fnvMixBool(h, false);
|
|
3710
|
+
return fnvMixNumber(fnvMixBool(h, true), n);
|
|
3711
|
+
}
|
|
3712
|
+
function depsOf(...sources) {
|
|
3713
|
+
const acc = /* @__PURE__ */ new Set();
|
|
3714
|
+
for (const s of sources) {
|
|
3715
|
+
if (!s) continue;
|
|
3716
|
+
for (const p of s.freeParams) acc.add(p);
|
|
3717
|
+
}
|
|
3718
|
+
return acc.size === 0 ? EMPTY_DEPS : acc;
|
|
3719
|
+
}
|
|
3720
|
+
function box$1(x, y, z) {
|
|
3721
|
+
const xe = asScalarExpr(x);
|
|
3722
|
+
const ye = asScalarExpr(y);
|
|
3723
|
+
const ze = asScalarExpr(z);
|
|
3724
|
+
let h = startHash("Box");
|
|
3725
|
+
h = mix(mix(mix(h, xe), ye), ze);
|
|
3726
|
+
return {
|
|
3727
|
+
kind: "Box",
|
|
3728
|
+
x: xe,
|
|
3729
|
+
y: ye,
|
|
3730
|
+
z: ze,
|
|
3731
|
+
structuralHash: h,
|
|
3732
|
+
freeParams: depsOf(xe, ye, ze)
|
|
3733
|
+
};
|
|
3734
|
+
}
|
|
3735
|
+
function sphere$1(radius) {
|
|
3736
|
+
const re = asScalarExpr(radius);
|
|
3737
|
+
return {
|
|
3738
|
+
kind: "Sphere",
|
|
3739
|
+
radius: re,
|
|
3740
|
+
structuralHash: mix(startHash("Sphere"), re),
|
|
3741
|
+
freeParams: re.freeParams
|
|
3742
|
+
};
|
|
3743
|
+
}
|
|
3744
|
+
function cylinder$1(radius, height) {
|
|
3745
|
+
const re = asScalarExpr(radius);
|
|
3746
|
+
const he = asScalarExpr(height);
|
|
3747
|
+
return {
|
|
3748
|
+
kind: "Cylinder",
|
|
3749
|
+
radius: re,
|
|
3750
|
+
height: he,
|
|
3751
|
+
structuralHash: mix(mix(startHash("Cylinder"), re), he),
|
|
3752
|
+
freeParams: depsOf(re, he)
|
|
3753
|
+
};
|
|
3754
|
+
}
|
|
3755
|
+
function cone$1(radius1, radius2, height) {
|
|
3756
|
+
const r1 = asScalarExpr(radius1);
|
|
3757
|
+
const r2 = asScalarExpr(radius2);
|
|
3758
|
+
const he = asScalarExpr(height);
|
|
3759
|
+
let h = startHash("Cone");
|
|
3760
|
+
h = mix(mix(mix(h, r1), r2), he);
|
|
3761
|
+
return {
|
|
3762
|
+
kind: "Cone",
|
|
3763
|
+
radius1: r1,
|
|
3764
|
+
radius2: r2,
|
|
3765
|
+
height: he,
|
|
3766
|
+
structuralHash: h,
|
|
3767
|
+
freeParams: depsOf(r1, r2, he)
|
|
3768
|
+
};
|
|
3769
|
+
}
|
|
3770
|
+
function torus$1(majorRadius, minorRadius) {
|
|
3771
|
+
const ma = asScalarExpr(majorRadius);
|
|
3772
|
+
const mi = asScalarExpr(minorRadius);
|
|
3773
|
+
return {
|
|
3774
|
+
kind: "Torus",
|
|
3775
|
+
majorRadius: ma,
|
|
3776
|
+
minorRadius: mi,
|
|
3777
|
+
structuralHash: mix(mix(startHash("Torus"), ma), mi),
|
|
3778
|
+
freeParams: depsOf(ma, mi)
|
|
3779
|
+
};
|
|
3780
|
+
}
|
|
3781
|
+
function polygon$1(points) {
|
|
3782
|
+
const pts = points.map(asVec3Expr);
|
|
3783
|
+
let h = fnvMixInt32(startHash("Polygon"), pts.length);
|
|
3784
|
+
for (const p of pts) h = mix(h, p);
|
|
3785
|
+
return {
|
|
3786
|
+
kind: "Polygon",
|
|
3787
|
+
points: pts,
|
|
3788
|
+
structuralHash: h,
|
|
3789
|
+
freeParams: depsOf(...pts)
|
|
3790
|
+
};
|
|
3791
|
+
}
|
|
3792
|
+
function circle$1(radius) {
|
|
3793
|
+
const re = asScalarExpr(radius);
|
|
3794
|
+
return {
|
|
3795
|
+
kind: "Circle",
|
|
3796
|
+
radius: re,
|
|
3797
|
+
structuralHash: mix(startHash("Circle"), re),
|
|
3798
|
+
freeParams: re.freeParams
|
|
3799
|
+
};
|
|
3800
|
+
}
|
|
3801
|
+
function line$1(from, to) {
|
|
3802
|
+
const fe = asVec3Expr(from);
|
|
3803
|
+
const te = asVec3Expr(to);
|
|
3804
|
+
return {
|
|
3805
|
+
kind: "Line",
|
|
3806
|
+
from: fe,
|
|
3807
|
+
to: te,
|
|
3808
|
+
structuralHash: mix(mix(startHash("Line"), fe), te),
|
|
3809
|
+
freeParams: depsOf(fe, te)
|
|
3810
|
+
};
|
|
3811
|
+
}
|
|
3812
|
+
function vertex$1(point) {
|
|
3813
|
+
const pe = asVec3Expr(point);
|
|
3814
|
+
return {
|
|
3815
|
+
kind: "Vertex",
|
|
3816
|
+
point: pe,
|
|
3817
|
+
structuralHash: mix(startHash("Vertex"), pe),
|
|
3818
|
+
freeParams: pe.freeParams
|
|
3819
|
+
};
|
|
3820
|
+
}
|
|
3821
|
+
function emptyOf(output) {
|
|
3822
|
+
return {
|
|
3823
|
+
kind: "Empty",
|
|
3824
|
+
output,
|
|
3825
|
+
structuralHash: fnvMixString(startHash("Empty"), output),
|
|
3826
|
+
freeParams: EMPTY_DEPS
|
|
3827
|
+
};
|
|
3828
|
+
}
|
|
3829
|
+
function emptySolid() {
|
|
3830
|
+
return emptyOf("Solid");
|
|
3831
|
+
}
|
|
3832
|
+
function emptyFace() {
|
|
3833
|
+
return emptyOf("Face");
|
|
3834
|
+
}
|
|
3835
|
+
function emptyWire() {
|
|
3836
|
+
return emptyOf("Wire");
|
|
3837
|
+
}
|
|
3838
|
+
function binaryBoolHash(tag, a, b, tol) {
|
|
3839
|
+
return mixOptNumber(mix(mix(startHash(tag), a), b), tol);
|
|
3840
|
+
}
|
|
3841
|
+
function fuse$1(a, b, tolerance) {
|
|
3842
|
+
return {
|
|
3843
|
+
kind: "Fuse",
|
|
3844
|
+
a,
|
|
3845
|
+
b,
|
|
3846
|
+
tolerance,
|
|
3847
|
+
structuralHash: binaryBoolHash("Fuse", a, b, tolerance),
|
|
3848
|
+
freeParams: depsOf(a, b)
|
|
3849
|
+
};
|
|
3850
|
+
}
|
|
3851
|
+
function cut$1(a, b, tolerance) {
|
|
3852
|
+
return {
|
|
3853
|
+
kind: "Cut",
|
|
3854
|
+
a,
|
|
3855
|
+
b,
|
|
3856
|
+
tolerance,
|
|
3857
|
+
structuralHash: binaryBoolHash("Cut", a, b, tolerance),
|
|
3858
|
+
freeParams: depsOf(a, b)
|
|
3859
|
+
};
|
|
3860
|
+
}
|
|
3861
|
+
function intersect$1(a, b, tolerance) {
|
|
3862
|
+
return {
|
|
3863
|
+
kind: "Intersect",
|
|
3864
|
+
a,
|
|
3865
|
+
b,
|
|
3866
|
+
tolerance,
|
|
3867
|
+
structuralHash: binaryBoolHash("Intersect", a, b, tolerance),
|
|
3868
|
+
freeParams: depsOf(a, b)
|
|
3869
|
+
};
|
|
3870
|
+
}
|
|
3871
|
+
function fuseAll$1(shapes, tolerance) {
|
|
3872
|
+
let h = fnvMixInt32(startHash("FuseAll"), shapes.length);
|
|
3873
|
+
for (const s of shapes) h = mix(h, s);
|
|
3874
|
+
h = mixOptNumber(h, tolerance);
|
|
3875
|
+
return {
|
|
3876
|
+
kind: "FuseAll",
|
|
3877
|
+
shapes,
|
|
3878
|
+
tolerance,
|
|
3879
|
+
structuralHash: h,
|
|
3880
|
+
freeParams: depsOf(...shapes)
|
|
3881
|
+
};
|
|
3882
|
+
}
|
|
3883
|
+
function cutAll$1(base, tools, tolerance) {
|
|
3884
|
+
let h = mix(startHash("CutAll"), base);
|
|
3885
|
+
h = fnvMixInt32(h, tools.length);
|
|
3886
|
+
for (const t of tools) h = mix(h, t);
|
|
3887
|
+
h = mixOptNumber(h, tolerance);
|
|
3888
|
+
return {
|
|
3889
|
+
kind: "CutAll",
|
|
3890
|
+
base,
|
|
3891
|
+
tools,
|
|
3892
|
+
tolerance,
|
|
3893
|
+
structuralHash: h,
|
|
3894
|
+
freeParams: depsOf(base, ...tools)
|
|
3895
|
+
};
|
|
3896
|
+
}
|
|
3897
|
+
function optVec3$1(v) {
|
|
3898
|
+
return v !== void 0 ? asVec3Expr(v) : void 0;
|
|
3899
|
+
}
|
|
3900
|
+
function translate$1(target, vector) {
|
|
3901
|
+
const ve = asVec3Expr(vector);
|
|
3902
|
+
return {
|
|
3903
|
+
kind: "Translate",
|
|
3904
|
+
target,
|
|
3905
|
+
vector: ve,
|
|
3906
|
+
structuralHash: mix(mix(startHash("Translate"), target), ve),
|
|
3907
|
+
freeParams: depsOf(target, ve)
|
|
3908
|
+
};
|
|
3909
|
+
}
|
|
3910
|
+
function rotate$1(target, angle, options) {
|
|
3911
|
+
const ae = asScalarExpr(angle);
|
|
3912
|
+
const axisE = optVec3$1(options?.axis);
|
|
3913
|
+
const atE = optVec3$1(options?.at);
|
|
3914
|
+
let h = mix(mix(startHash("Rotate"), target), ae);
|
|
3915
|
+
h = mixOptExpr(h, axisE);
|
|
3916
|
+
h = mixOptExpr(h, atE);
|
|
3917
|
+
return {
|
|
3918
|
+
kind: "Rotate",
|
|
3919
|
+
target,
|
|
3920
|
+
angle: ae,
|
|
3921
|
+
axis: axisE,
|
|
3922
|
+
at: atE,
|
|
3923
|
+
structuralHash: h,
|
|
3924
|
+
freeParams: depsOf(target, ae, axisE, atE)
|
|
3925
|
+
};
|
|
3926
|
+
}
|
|
3927
|
+
function scale$1(target, factor, options) {
|
|
3928
|
+
const fe = asScalarExpr(factor);
|
|
3929
|
+
const cE = optVec3$1(options?.center);
|
|
3930
|
+
let h = mix(mix(startHash("Scale"), target), fe);
|
|
3931
|
+
h = mixOptExpr(h, cE);
|
|
3932
|
+
return {
|
|
3933
|
+
kind: "Scale",
|
|
3934
|
+
target,
|
|
3935
|
+
factor: fe,
|
|
3936
|
+
center: cE,
|
|
3937
|
+
structuralHash: h,
|
|
3938
|
+
freeParams: depsOf(target, fe, cE)
|
|
3939
|
+
};
|
|
3940
|
+
}
|
|
3941
|
+
function mirror$1(target, options) {
|
|
3942
|
+
const nE = optVec3$1(options?.normal);
|
|
3943
|
+
const atE = optVec3$1(options?.at);
|
|
3944
|
+
let h = mix(startHash("Mirror"), target);
|
|
3945
|
+
h = mixOptExpr(h, nE);
|
|
3946
|
+
h = mixOptExpr(h, atE);
|
|
3947
|
+
return {
|
|
3948
|
+
kind: "Mirror",
|
|
3949
|
+
target,
|
|
3950
|
+
normal: nE,
|
|
3951
|
+
at: atE,
|
|
3952
|
+
structuralHash: h,
|
|
3953
|
+
freeParams: depsOf(target, nE, atE)
|
|
3954
|
+
};
|
|
3955
|
+
}
|
|
3956
|
+
function compound$1(children) {
|
|
3957
|
+
let h = fnvMixInt32(startHash("Compound"), children.length);
|
|
3958
|
+
for (const c of children) h = mix(h, c);
|
|
3959
|
+
return {
|
|
3960
|
+
kind: "Compound",
|
|
3961
|
+
children,
|
|
3962
|
+
structuralHash: h,
|
|
3963
|
+
freeParams: depsOf(...children)
|
|
3964
|
+
};
|
|
3965
|
+
}
|
|
3966
|
+
//#endregion
|
|
3967
|
+
//#region src/csg/types.ts
|
|
3968
|
+
function outputKindOf(node) {
|
|
3969
|
+
switch (node.kind) {
|
|
3970
|
+
case "Box":
|
|
3971
|
+
case "Sphere":
|
|
3972
|
+
case "Cylinder":
|
|
3973
|
+
case "Cone":
|
|
3974
|
+
case "Torus": return "Solid";
|
|
3975
|
+
case "Polygon": return "Face";
|
|
3976
|
+
case "Circle":
|
|
3977
|
+
case "Line": return "Edge";
|
|
3978
|
+
case "Vertex": return "Vertex";
|
|
3979
|
+
case "Empty": return node.output;
|
|
3980
|
+
case "Fuse":
|
|
3981
|
+
case "Cut":
|
|
3982
|
+
case "Intersect": return outputKindOf(node.a);
|
|
3983
|
+
case "FuseAll": return node.shapes[0] ? outputKindOf(node.shapes[0]) : "Solid";
|
|
3984
|
+
case "CutAll": return outputKindOf(node.base);
|
|
3985
|
+
case "Translate":
|
|
3986
|
+
case "Rotate":
|
|
3987
|
+
case "Scale":
|
|
3988
|
+
case "Mirror": return outputKindOf(node.target);
|
|
3989
|
+
case "Compound": return "Compound";
|
|
3990
|
+
}
|
|
3991
|
+
}
|
|
3992
|
+
//#endregion
|
|
3993
|
+
//#region src/csg/evaluators/primitives.ts
|
|
3994
|
+
function evalBox(node, ctx) {
|
|
3995
|
+
const x = evalScalar(node.x, ctx.env, "Box.x");
|
|
3996
|
+
if (!x.ok) return x;
|
|
3997
|
+
const y = evalScalar(node.y, ctx.env, "Box.y");
|
|
3998
|
+
if (!y.ok) return y;
|
|
3999
|
+
const z = evalScalar(node.z, ctx.env, "Box.z");
|
|
4000
|
+
if (!z.ok) return z;
|
|
4001
|
+
return require_errors.ok(require_primitiveFns.box(x.value, y.value, z.value));
|
|
4002
|
+
}
|
|
4003
|
+
function evalSphere(node, ctx) {
|
|
4004
|
+
const r = evalScalar(node.radius, ctx.env, "Sphere.radius");
|
|
4005
|
+
if (!r.ok) return r;
|
|
4006
|
+
return require_errors.ok(require_primitiveFns.sphere(r.value));
|
|
4007
|
+
}
|
|
4008
|
+
function evalCylinder(node, ctx) {
|
|
4009
|
+
const r = evalScalar(node.radius, ctx.env, "Cylinder.radius");
|
|
4010
|
+
if (!r.ok) return r;
|
|
4011
|
+
const h = evalScalar(node.height, ctx.env, "Cylinder.height");
|
|
4012
|
+
if (!h.ok) return h;
|
|
4013
|
+
return require_errors.ok(require_primitiveFns.cylinder(r.value, h.value));
|
|
4014
|
+
}
|
|
4015
|
+
function evalCone(node, ctx) {
|
|
4016
|
+
const r1 = evalScalar(node.radius1, ctx.env, "Cone.radius1");
|
|
4017
|
+
if (!r1.ok) return r1;
|
|
4018
|
+
const r2 = evalScalar(node.radius2, ctx.env, "Cone.radius2");
|
|
4019
|
+
if (!r2.ok) return r2;
|
|
4020
|
+
const h = evalScalar(node.height, ctx.env, "Cone.height");
|
|
4021
|
+
if (!h.ok) return h;
|
|
4022
|
+
return require_errors.ok(require_primitiveFns.cone(r1.value, r2.value, h.value));
|
|
4023
|
+
}
|
|
4024
|
+
function evalTorus(node, ctx) {
|
|
4025
|
+
const ma = evalScalar(node.majorRadius, ctx.env, "Torus.majorRadius");
|
|
4026
|
+
if (!ma.ok) return ma;
|
|
4027
|
+
const mi = evalScalar(node.minorRadius, ctx.env, "Torus.minorRadius");
|
|
4028
|
+
if (!mi.ok) return mi;
|
|
4029
|
+
return require_errors.ok(require_primitiveFns.torus(ma.value, mi.value));
|
|
4030
|
+
}
|
|
4031
|
+
function evalPolygon(node, ctx) {
|
|
4032
|
+
const pts = [];
|
|
4033
|
+
for (const p of node.points) {
|
|
4034
|
+
const r = evalVec3(p, ctx.env, "Polygon.point");
|
|
4035
|
+
if (!r.ok) return r;
|
|
4036
|
+
pts.push(r.value);
|
|
4037
|
+
}
|
|
4038
|
+
return require_primitiveFns.polygon(pts);
|
|
4039
|
+
}
|
|
4040
|
+
function evalCircle(node, ctx) {
|
|
4041
|
+
const r = evalScalar(node.radius, ctx.env, "Circle.radius");
|
|
4042
|
+
if (!r.ok) return r;
|
|
4043
|
+
return require_errors.ok(require_primitiveFns.circle(r.value));
|
|
4044
|
+
}
|
|
4045
|
+
function evalLine(node, ctx) {
|
|
4046
|
+
const f = evalVec3(node.from, ctx.env, "Line.from");
|
|
4047
|
+
if (!f.ok) return f;
|
|
4048
|
+
const t = evalVec3(node.to, ctx.env, "Line.to");
|
|
4049
|
+
if (!t.ok) return t;
|
|
4050
|
+
return require_errors.ok(require_primitiveFns.line(f.value, t.value));
|
|
4051
|
+
}
|
|
4052
|
+
function evalVertex(node, ctx) {
|
|
4053
|
+
const p = evalVec3(node.point, ctx.env, "Vertex.point");
|
|
4054
|
+
if (!p.ok) return p;
|
|
4055
|
+
return require_errors.ok(require_primitiveFns.vertex(p.value));
|
|
4056
|
+
}
|
|
4057
|
+
//#endregion
|
|
4058
|
+
//#region src/csg/evaluators/booleans.ts
|
|
4059
|
+
/**
|
|
4060
|
+
* Evaluators for CSG boolean nodes.
|
|
4061
|
+
*
|
|
4062
|
+
* Identity short-circuits are correctness invariants, not optimisations:
|
|
4063
|
+
* Fuse with an Empty operand: short-circuits to the other operand
|
|
4064
|
+
* Cut with an Empty tool: short-circuits to the base
|
|
4065
|
+
* Intersect with any Empty: errors (no empty-solid representation)
|
|
4066
|
+
*
|
|
4067
|
+
* The optimizer pass handles broader rewrites; these inline checks just
|
|
4068
|
+
* keep the evaluator from feeding null operands to the kernel.
|
|
4069
|
+
*/
|
|
4070
|
+
function emptyResult$1(kind) {
|
|
4071
|
+
return require_errors.err(require_errors.computationError(require_errors.BrepErrorCode.NULL_SHAPE_INPUT, `${kind}: empty result has no kernel representation`));
|
|
4072
|
+
}
|
|
4073
|
+
function resolveOperand(ctx, node, where) {
|
|
4074
|
+
const r = ctx.evalNode(node);
|
|
4075
|
+
if (!r.ok) return r;
|
|
4076
|
+
if (!require_shapeTypes.isShape3D(r.value)) return require_errors.err(require_errors.typeCastError(require_errors.BrepErrorCode.CSG_NOT_3D, `${where}: operand did not produce a 3D shape`));
|
|
4077
|
+
return require_errors.ok(r.value);
|
|
4078
|
+
}
|
|
4079
|
+
function boolOptions(node, ctx) {
|
|
4080
|
+
return {
|
|
4081
|
+
unsafe: true,
|
|
4082
|
+
fuzzyValue: node.tolerance ?? ctx.tolerance
|
|
4083
|
+
};
|
|
4084
|
+
}
|
|
4085
|
+
function evalFuse(node, ctx) {
|
|
4086
|
+
if (node.a.kind === "Empty") return ctx.evalNode(node.b);
|
|
4087
|
+
if (node.b.kind === "Empty") return ctx.evalNode(node.a);
|
|
4088
|
+
const a = resolveOperand(ctx, node.a, "Fuse.a");
|
|
4089
|
+
if (!a.ok) return a;
|
|
4090
|
+
const b = resolveOperand(ctx, node.b, "Fuse.b");
|
|
4091
|
+
if (!b.ok) return b;
|
|
4092
|
+
return require_booleanFns.fuse(a.value, b.value, boolOptions(node, ctx));
|
|
4093
|
+
}
|
|
4094
|
+
function evalCut(node, ctx) {
|
|
4095
|
+
if (node.a.kind === "Empty") return emptyResult$1("Cut");
|
|
4096
|
+
if (node.b.kind === "Empty") return ctx.evalNode(node.a);
|
|
4097
|
+
const a = resolveOperand(ctx, node.a, "Cut.a");
|
|
4098
|
+
if (!a.ok) return a;
|
|
4099
|
+
const b = resolveOperand(ctx, node.b, "Cut.b");
|
|
4100
|
+
if (!b.ok) return b;
|
|
4101
|
+
return require_booleanFns.cut(a.value, b.value, boolOptions(node, ctx));
|
|
4102
|
+
}
|
|
4103
|
+
function evalIntersect(node, ctx) {
|
|
4104
|
+
if (node.a.kind === "Empty" || node.b.kind === "Empty") return emptyResult$1("Intersect");
|
|
4105
|
+
const a = resolveOperand(ctx, node.a, "Intersect.a");
|
|
4106
|
+
if (!a.ok) return a;
|
|
4107
|
+
const b = resolveOperand(ctx, node.b, "Intersect.b");
|
|
4108
|
+
if (!b.ok) return b;
|
|
4109
|
+
return require_booleanFns.intersect(a.value, b.value, boolOptions(node, ctx));
|
|
4110
|
+
}
|
|
4111
|
+
function resolveAll(ctx, nodes, where) {
|
|
4112
|
+
const out = [];
|
|
4113
|
+
for (const n of nodes) {
|
|
4114
|
+
const r = resolveOperand(ctx, n, where);
|
|
4115
|
+
if (!r.ok) return r;
|
|
4116
|
+
out.push(r.value);
|
|
4117
|
+
}
|
|
4118
|
+
return require_errors.ok(out);
|
|
4119
|
+
}
|
|
4120
|
+
function evalFuseAll(node, ctx) {
|
|
4121
|
+
const non = node.shapes.filter((s) => s.kind !== "Empty");
|
|
4122
|
+
if (non.length === 0) return emptyResult$1("FuseAll");
|
|
4123
|
+
if (non.length === 1 && non[0]) return ctx.evalNode(non[0]);
|
|
4124
|
+
const resolved = resolveAll(ctx, non, "FuseAll.operand");
|
|
4125
|
+
if (!resolved.ok) return resolved;
|
|
4126
|
+
return require_booleanFns.fuseAll(resolved.value, boolOptions(node, ctx));
|
|
4127
|
+
}
|
|
4128
|
+
function evalCutAll(node, ctx) {
|
|
4129
|
+
if (node.base.kind === "Empty") return emptyResult$1("CutAll");
|
|
4130
|
+
const tools = node.tools.filter((s) => s.kind !== "Empty");
|
|
4131
|
+
if (tools.length === 0) return ctx.evalNode(node.base);
|
|
4132
|
+
const base = resolveOperand(ctx, node.base, "CutAll.base");
|
|
4133
|
+
if (!base.ok) return base;
|
|
4134
|
+
const resolved = resolveAll(ctx, tools, "CutAll.tool");
|
|
4135
|
+
if (!resolved.ok) return resolved;
|
|
4136
|
+
return require_booleanFns.cutAll(base.value, resolved.value, boolOptions(node, ctx));
|
|
4137
|
+
}
|
|
4138
|
+
//#endregion
|
|
4139
|
+
//#region src/csg/evaluators/transforms.ts
|
|
4140
|
+
function emptyResult(kind) {
|
|
4141
|
+
return require_errors.err(require_errors.computationError(require_errors.BrepErrorCode.NULL_SHAPE_INPUT, `${kind}: cannot transform an Empty node`));
|
|
4142
|
+
}
|
|
4143
|
+
function optVec3(expr, env, where, fallback) {
|
|
4144
|
+
return expr ? evalVec3(expr, env, where) : require_errors.ok(fallback);
|
|
4145
|
+
}
|
|
4146
|
+
function evalTranslate(node, ctx) {
|
|
4147
|
+
if (node.target.kind === "Empty") return emptyResult("Translate");
|
|
4148
|
+
const v = evalVec3(node.vector, ctx.env, "Translate.vector");
|
|
4149
|
+
if (!v.ok) return v;
|
|
4150
|
+
const r = ctx.evalNode(node.target);
|
|
4151
|
+
if (!r.ok) return r;
|
|
4152
|
+
return require_errors.ok(require_shapeFns.translate(r.value, v.value));
|
|
4153
|
+
}
|
|
4154
|
+
function evalRotate(node, ctx) {
|
|
4155
|
+
if (node.target.kind === "Empty") return emptyResult("Rotate");
|
|
4156
|
+
const a = evalScalar(node.angle, ctx.env, "Rotate.angle");
|
|
4157
|
+
if (!a.ok) return a;
|
|
4158
|
+
const axis = optVec3(node.axis, ctx.env, "Rotate.axis", [
|
|
4159
|
+
0,
|
|
4160
|
+
0,
|
|
4161
|
+
1
|
|
4162
|
+
]);
|
|
4163
|
+
if (!axis.ok) return axis;
|
|
4164
|
+
const at = optVec3(node.at, ctx.env, "Rotate.at", [
|
|
4165
|
+
0,
|
|
4166
|
+
0,
|
|
4167
|
+
0
|
|
4168
|
+
]);
|
|
4169
|
+
if (!at.ok) return at;
|
|
4170
|
+
const r = ctx.evalNode(node.target);
|
|
4171
|
+
if (!r.ok) return r;
|
|
4172
|
+
return require_errors.ok(require_shapeFns.rotate(r.value, a.value, at.value, axis.value));
|
|
4173
|
+
}
|
|
4174
|
+
function evalScale(node, ctx) {
|
|
4175
|
+
if (node.target.kind === "Empty") return emptyResult("Scale");
|
|
4176
|
+
const f = evalScalar(node.factor, ctx.env, "Scale.factor");
|
|
4177
|
+
if (!f.ok) return f;
|
|
4178
|
+
const center = optVec3(node.center, ctx.env, "Scale.center", [
|
|
4179
|
+
0,
|
|
4180
|
+
0,
|
|
4181
|
+
0
|
|
4182
|
+
]);
|
|
4183
|
+
if (!center.ok) return center;
|
|
4184
|
+
const r = ctx.evalNode(node.target);
|
|
4185
|
+
if (!r.ok) return r;
|
|
4186
|
+
return require_errors.ok(require_shapeFns.scale(r.value, f.value, center.value));
|
|
4187
|
+
}
|
|
4188
|
+
function evalMirror(node, ctx) {
|
|
4189
|
+
if (node.target.kind === "Empty") return emptyResult("Mirror");
|
|
4190
|
+
const normal = optVec3(node.normal, ctx.env, "Mirror.normal", [
|
|
4191
|
+
1,
|
|
4192
|
+
0,
|
|
4193
|
+
0
|
|
4194
|
+
]);
|
|
4195
|
+
if (!normal.ok) return normal;
|
|
4196
|
+
const at = optVec3(node.at, ctx.env, "Mirror.at", [
|
|
4197
|
+
0,
|
|
4198
|
+
0,
|
|
4199
|
+
0
|
|
4200
|
+
]);
|
|
4201
|
+
if (!at.ok) return at;
|
|
4202
|
+
const r = ctx.evalNode(node.target);
|
|
4203
|
+
if (!r.ok) return r;
|
|
4204
|
+
return require_errors.ok(require_shapeFns.mirror(r.value, normal.value, at.value));
|
|
4205
|
+
}
|
|
4206
|
+
//#endregion
|
|
4207
|
+
//#region src/csg/evaluators/compound.ts
|
|
4208
|
+
function evalCompound(node, ctx) {
|
|
4209
|
+
const non = node.children.filter((c) => c.kind !== "Empty");
|
|
4210
|
+
if (non.length === 0) return require_errors.err(require_errors.computationError(require_errors.BrepErrorCode.NULL_SHAPE_INPUT, "Compound: cannot materialize a compound with zero non-empty children"));
|
|
4211
|
+
const shapes = [];
|
|
4212
|
+
for (const c of non) {
|
|
4213
|
+
const r = ctx.evalNode(c);
|
|
4214
|
+
if (!r.ok) return r;
|
|
4215
|
+
shapes.push(r.value);
|
|
4216
|
+
}
|
|
4217
|
+
return require_errors.ok(require_primitiveFns.compound(shapes));
|
|
4218
|
+
}
|
|
4219
|
+
function evalEmpty() {
|
|
4220
|
+
return require_errors.err(require_errors.computationError(require_errors.BrepErrorCode.NULL_SHAPE_INPUT, "Empty: cannot materialize an Empty node directly — only valid as boolean/transform operand"));
|
|
4221
|
+
}
|
|
4222
|
+
//#endregion
|
|
4223
|
+
//#region src/csg/evaluate.ts
|
|
4224
|
+
function dispatch(node, ctx) {
|
|
4225
|
+
switch (node.kind) {
|
|
4226
|
+
case "Box": return evalBox(node, ctx);
|
|
4227
|
+
case "Sphere": return evalSphere(node, ctx);
|
|
4228
|
+
case "Cylinder": return evalCylinder(node, ctx);
|
|
4229
|
+
case "Cone": return evalCone(node, ctx);
|
|
4230
|
+
case "Torus": return evalTorus(node, ctx);
|
|
4231
|
+
case "Polygon": return evalPolygon(node, ctx);
|
|
4232
|
+
case "Circle": return evalCircle(node, ctx);
|
|
4233
|
+
case "Line": return evalLine(node, ctx);
|
|
4234
|
+
case "Vertex": return evalVertex(node, ctx);
|
|
4235
|
+
case "Empty": return evalEmpty();
|
|
4236
|
+
case "Fuse": return evalFuse(node, ctx);
|
|
4237
|
+
case "Cut": return evalCut(node, ctx);
|
|
4238
|
+
case "Intersect": return evalIntersect(node, ctx);
|
|
4239
|
+
case "FuseAll": return evalFuseAll(node, ctx);
|
|
4240
|
+
case "CutAll": return evalCutAll(node, ctx);
|
|
4241
|
+
case "Translate": return evalTranslate(node, ctx);
|
|
4242
|
+
case "Rotate": return evalRotate(node, ctx);
|
|
4243
|
+
case "Scale": return evalScale(node, ctx);
|
|
4244
|
+
case "Mirror": return evalMirror(node, ctx);
|
|
4245
|
+
case "Compound": return evalCompound(node, ctx);
|
|
4246
|
+
}
|
|
4247
|
+
}
|
|
4248
|
+
function hashExprValue(h, v) {
|
|
4249
|
+
if (typeof v === "number") return fnvMixNumber(fnvMixBool(h, false), v);
|
|
4250
|
+
let r = fnvMixBool(h, true);
|
|
4251
|
+
r = fnvMixInt32(r, v.length);
|
|
4252
|
+
for (const n of v) r = fnvMixNumber(r, n);
|
|
4253
|
+
return r;
|
|
4254
|
+
}
|
|
4255
|
+
function projectedEnvHash(env, deps) {
|
|
4256
|
+
if (deps.size === 0) return fnvInit();
|
|
4257
|
+
const projected = projectEnv(env, deps);
|
|
4258
|
+
const keys = Object.keys(projected).sort();
|
|
4259
|
+
let h = fnvInit();
|
|
4260
|
+
for (const k of keys) {
|
|
4261
|
+
h = fnvMixString(h, k);
|
|
4262
|
+
const v = projected[k];
|
|
4263
|
+
if (v !== void 0) h = hashExprValue(h, v);
|
|
4264
|
+
}
|
|
4265
|
+
return h;
|
|
4266
|
+
}
|
|
4267
|
+
function cacheKey(node, env, kernelId, tolerance) {
|
|
4268
|
+
const projHash = projectedEnvHash(env, node.freeParams);
|
|
4269
|
+
const tolHash = tolerance === void 0 ? "d" : fnvMixNumber(fnvInit(), tolerance).toString(16);
|
|
4270
|
+
return `${toHex(node.structuralHash)}:${kernelId}:${toHex(projHash)}:${tolHash}`;
|
|
4271
|
+
}
|
|
4272
|
+
var Evaluator = class {
|
|
4273
|
+
scope = new require_shapeTypes.DisposalScope();
|
|
4274
|
+
cache = /* @__PURE__ */ new Map();
|
|
4275
|
+
registered = /* @__PURE__ */ new WeakSet();
|
|
4276
|
+
kernelId;
|
|
4277
|
+
defaultTolerance;
|
|
4278
|
+
onStep;
|
|
4279
|
+
hits = 0;
|
|
4280
|
+
misses = 0;
|
|
4281
|
+
constructor(options = {}) {
|
|
4282
|
+
this.kernelId = options.kernel ?? require_shapeTypes.getActiveKernelId() ?? "unregistered";
|
|
4283
|
+
this.defaultTolerance = options.tolerance;
|
|
4284
|
+
if (options.onStep) this.onStep = options.onStep;
|
|
4285
|
+
}
|
|
4286
|
+
/**
|
|
4287
|
+
* Materialize a CSG IR tree against the given parameter environment.
|
|
4288
|
+
* The returned shape is borrowed — valid for as long as this Evaluator is
|
|
4289
|
+
* not disposed. Callers must NOT call `.delete()` / `[Symbol.dispose]()`
|
|
4290
|
+
* on the returned shape; that would invalidate the cache entry for every
|
|
4291
|
+
* future call returning the same handle.
|
|
4292
|
+
*/
|
|
4293
|
+
evaluate(node, env = {}) {
|
|
4294
|
+
return require_shapeTypes.withKernel(this.kernelId, () => this.evaluateInner(node, env));
|
|
4295
|
+
}
|
|
4296
|
+
evaluateInner(node, env) {
|
|
4297
|
+
const key = cacheKey(node, env, this.kernelId, this.defaultTolerance);
|
|
4298
|
+
const cached = this.cache.get(key);
|
|
4299
|
+
if (cached !== void 0) {
|
|
4300
|
+
this.hits++;
|
|
4301
|
+
this.onStep?.({
|
|
4302
|
+
node,
|
|
4303
|
+
cacheKey: key,
|
|
4304
|
+
cacheHit: true
|
|
4305
|
+
});
|
|
4306
|
+
return require_errors.ok(cached);
|
|
4307
|
+
}
|
|
4308
|
+
this.misses++;
|
|
4309
|
+
const result = dispatch(node, {
|
|
4310
|
+
env,
|
|
4311
|
+
tolerance: this.defaultTolerance,
|
|
4312
|
+
evalNode: (child) => this.evaluateInner(child, env)
|
|
4313
|
+
});
|
|
4314
|
+
if (!result.ok) return result;
|
|
4315
|
+
if (!this.registered.has(result.value)) {
|
|
4316
|
+
this.scope.register(result.value);
|
|
4317
|
+
this.registered.add(result.value);
|
|
4318
|
+
}
|
|
4319
|
+
this.cache.set(key, result.value);
|
|
4320
|
+
this.onStep?.({
|
|
4321
|
+
node,
|
|
4322
|
+
cacheKey: key,
|
|
4323
|
+
cacheHit: false
|
|
4324
|
+
});
|
|
4325
|
+
return result;
|
|
4326
|
+
}
|
|
4327
|
+
cacheStats() {
|
|
4328
|
+
return {
|
|
4329
|
+
hits: this.hits,
|
|
4330
|
+
misses: this.misses,
|
|
4331
|
+
entries: this.cache.size
|
|
4332
|
+
};
|
|
4333
|
+
}
|
|
4334
|
+
resetStats() {
|
|
4335
|
+
this.hits = 0;
|
|
4336
|
+
this.misses = 0;
|
|
4337
|
+
}
|
|
4338
|
+
[Symbol.dispose]() {
|
|
4339
|
+
this.scope[Symbol.dispose]();
|
|
4340
|
+
this.cache.clear();
|
|
4341
|
+
}
|
|
4342
|
+
};
|
|
4343
|
+
/**
|
|
4344
|
+
* Run a callback with a fresh Evaluator that is disposed when the callback
|
|
4345
|
+
* returns. Sync-only: an async callback would resolve after disposal,
|
|
4346
|
+
* leaving borrowed shapes pointing at freed WASM memory. Mirrors the
|
|
4347
|
+
* Promise-guard pattern in `withKernel`.
|
|
4348
|
+
*/
|
|
4349
|
+
function withEvaluator(options, fn) {
|
|
4350
|
+
try {
|
|
4351
|
+
var _usingCtx$1 = require_shapeTypes._usingCtx();
|
|
4352
|
+
const result = fn(_usingCtx$1.u(new Evaluator(options)));
|
|
4353
|
+
if (result instanceof Promise) throw new Error("withEvaluator() callback returned a Promise. Async code must construct an Evaluator directly and dispose it manually — borrowed shapes would otherwise be freed before the Promise resolves.");
|
|
4354
|
+
return result;
|
|
4355
|
+
} catch (_) {
|
|
4356
|
+
_usingCtx$1.e = _;
|
|
4357
|
+
} finally {
|
|
4358
|
+
_usingCtx$1.d();
|
|
4359
|
+
}
|
|
4360
|
+
}
|
|
4361
|
+
function toJSON(node) {
|
|
4362
|
+
return {
|
|
4363
|
+
csgVersion: 1,
|
|
4364
|
+
root: nodeToJson(node)
|
|
4365
|
+
};
|
|
4366
|
+
}
|
|
4367
|
+
function exprToJson(e) {
|
|
4368
|
+
switch (e.kind) {
|
|
4369
|
+
case "NumLit": return {
|
|
4370
|
+
kind: "NumLit",
|
|
4371
|
+
value: e.value
|
|
4372
|
+
};
|
|
4373
|
+
case "Vec3Lit": return {
|
|
4374
|
+
kind: "Vec3Lit",
|
|
4375
|
+
value: [
|
|
4376
|
+
e.value[0],
|
|
4377
|
+
e.value[1],
|
|
4378
|
+
e.value[2]
|
|
4379
|
+
]
|
|
4380
|
+
};
|
|
4381
|
+
case "Vec2Lit": return {
|
|
4382
|
+
kind: "Vec2Lit",
|
|
4383
|
+
value: [e.value[0], e.value[1]]
|
|
4384
|
+
};
|
|
4385
|
+
case "Param": return {
|
|
4386
|
+
kind: "Param",
|
|
4387
|
+
name: e.name
|
|
4388
|
+
};
|
|
4389
|
+
case "BinOp": return {
|
|
4390
|
+
kind: "BinOp",
|
|
4391
|
+
op: e.op,
|
|
4392
|
+
a: exprToJson(e.a),
|
|
4393
|
+
b: exprToJson(e.b)
|
|
4394
|
+
};
|
|
4395
|
+
case "UnaryOp": return {
|
|
4396
|
+
kind: "UnaryOp",
|
|
4397
|
+
op: e.op,
|
|
4398
|
+
arg: exprToJson(e.arg)
|
|
4399
|
+
};
|
|
4400
|
+
case "Component": return {
|
|
4401
|
+
kind: "Component",
|
|
4402
|
+
vec: exprToJson(e.vec),
|
|
4403
|
+
index: e.index
|
|
4404
|
+
};
|
|
4405
|
+
case "BuildVec": return {
|
|
4406
|
+
kind: "BuildVec",
|
|
4407
|
+
dim: e.dim,
|
|
4408
|
+
components: e.components.map(exprToJson)
|
|
4409
|
+
};
|
|
4410
|
+
}
|
|
4411
|
+
}
|
|
4412
|
+
function primitiveToJson(n) {
|
|
4413
|
+
switch (n.kind) {
|
|
4414
|
+
case "Box": return {
|
|
4415
|
+
kind: "Box",
|
|
4416
|
+
x: exprToJson(n.x),
|
|
4417
|
+
y: exprToJson(n.y),
|
|
4418
|
+
z: exprToJson(n.z)
|
|
4419
|
+
};
|
|
4420
|
+
case "Sphere": return {
|
|
4421
|
+
kind: "Sphere",
|
|
4422
|
+
radius: exprToJson(n.radius)
|
|
4423
|
+
};
|
|
4424
|
+
case "Cylinder": return {
|
|
4425
|
+
kind: "Cylinder",
|
|
4426
|
+
radius: exprToJson(n.radius),
|
|
4427
|
+
height: exprToJson(n.height)
|
|
4428
|
+
};
|
|
4429
|
+
case "Cone": return {
|
|
4430
|
+
kind: "Cone",
|
|
4431
|
+
radius1: exprToJson(n.radius1),
|
|
4432
|
+
radius2: exprToJson(n.radius2),
|
|
4433
|
+
height: exprToJson(n.height)
|
|
4434
|
+
};
|
|
4435
|
+
case "Torus": return {
|
|
4436
|
+
kind: "Torus",
|
|
4437
|
+
majorRadius: exprToJson(n.majorRadius),
|
|
4438
|
+
minorRadius: exprToJson(n.minorRadius)
|
|
4439
|
+
};
|
|
4440
|
+
case "Polygon": return {
|
|
4441
|
+
kind: "Polygon",
|
|
4442
|
+
points: n.points.map(exprToJson)
|
|
4443
|
+
};
|
|
4444
|
+
case "Circle": return {
|
|
4445
|
+
kind: "Circle",
|
|
4446
|
+
radius: exprToJson(n.radius)
|
|
4447
|
+
};
|
|
4448
|
+
case "Line": return {
|
|
4449
|
+
kind: "Line",
|
|
4450
|
+
from: exprToJson(n.from),
|
|
4451
|
+
to: exprToJson(n.to)
|
|
4452
|
+
};
|
|
4453
|
+
case "Vertex": return {
|
|
4454
|
+
kind: "Vertex",
|
|
4455
|
+
point: exprToJson(n.point)
|
|
4456
|
+
};
|
|
4457
|
+
case "Empty": return {
|
|
4458
|
+
kind: "Empty",
|
|
4459
|
+
output: n.output
|
|
4460
|
+
};
|
|
4461
|
+
default: return;
|
|
4462
|
+
}
|
|
4463
|
+
}
|
|
4464
|
+
function booleanToJson(n) {
|
|
4465
|
+
switch (n.kind) {
|
|
4466
|
+
case "Fuse":
|
|
4467
|
+
case "Cut":
|
|
4468
|
+
case "Intersect": return {
|
|
4469
|
+
kind: n.kind,
|
|
4470
|
+
a: nodeToJson(n.a),
|
|
4471
|
+
b: nodeToJson(n.b),
|
|
4472
|
+
tolerance: n.tolerance
|
|
4473
|
+
};
|
|
4474
|
+
case "FuseAll": return {
|
|
4475
|
+
kind: "FuseAll",
|
|
4476
|
+
shapes: n.shapes.map(nodeToJson),
|
|
4477
|
+
tolerance: n.tolerance
|
|
4478
|
+
};
|
|
4479
|
+
case "CutAll": return {
|
|
4480
|
+
kind: "CutAll",
|
|
4481
|
+
base: nodeToJson(n.base),
|
|
4482
|
+
tools: n.tools.map(nodeToJson),
|
|
4483
|
+
tolerance: n.tolerance
|
|
4484
|
+
};
|
|
4485
|
+
default: return;
|
|
4486
|
+
}
|
|
4487
|
+
}
|
|
4488
|
+
function optExprToJson(e) {
|
|
4489
|
+
return e ? exprToJson(e) : void 0;
|
|
4490
|
+
}
|
|
4491
|
+
function transformToJson(n) {
|
|
4492
|
+
switch (n.kind) {
|
|
4493
|
+
case "Translate": return {
|
|
4494
|
+
kind: "Translate",
|
|
4495
|
+
target: nodeToJson(n.target),
|
|
4496
|
+
vector: exprToJson(n.vector)
|
|
4497
|
+
};
|
|
4498
|
+
case "Rotate": return {
|
|
4499
|
+
kind: "Rotate",
|
|
4500
|
+
target: nodeToJson(n.target),
|
|
4501
|
+
angle: exprToJson(n.angle),
|
|
4502
|
+
axis: optExprToJson(n.axis),
|
|
4503
|
+
at: optExprToJson(n.at)
|
|
4504
|
+
};
|
|
4505
|
+
case "Scale": return {
|
|
4506
|
+
kind: "Scale",
|
|
4507
|
+
target: nodeToJson(n.target),
|
|
4508
|
+
factor: exprToJson(n.factor),
|
|
4509
|
+
center: optExprToJson(n.center)
|
|
4510
|
+
};
|
|
4511
|
+
case "Mirror": return {
|
|
4512
|
+
kind: "Mirror",
|
|
4513
|
+
target: nodeToJson(n.target),
|
|
4514
|
+
normal: optExprToJson(n.normal),
|
|
4515
|
+
at: optExprToJson(n.at)
|
|
4516
|
+
};
|
|
4517
|
+
default: return;
|
|
4518
|
+
}
|
|
4519
|
+
}
|
|
4520
|
+
function nodeToJson(n) {
|
|
4521
|
+
if (n.kind === "Compound") return {
|
|
4522
|
+
kind: "Compound",
|
|
4523
|
+
children: n.children.map(nodeToJson)
|
|
4524
|
+
};
|
|
4525
|
+
return primitiveToJson(n) ?? booleanToJson(n) ?? transformToJson(n);
|
|
4526
|
+
}
|
|
4527
|
+
function bad(msg) {
|
|
4528
|
+
return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.NULL_SHAPE_INPUT, `csg.fromJSON: ${msg}`));
|
|
4529
|
+
}
|
|
4530
|
+
function isObj(v) {
|
|
4531
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
4532
|
+
}
|
|
4533
|
+
function isNumber$1(v) {
|
|
4534
|
+
return typeof v === "number" && Number.isFinite(v);
|
|
4535
|
+
}
|
|
4536
|
+
function isString(v) {
|
|
4537
|
+
return typeof v === "string";
|
|
4538
|
+
}
|
|
4539
|
+
function readVec3(v, where) {
|
|
4540
|
+
if (!Array.isArray(v) || v.length !== 3) return bad(`${where}: expected Vec3 array`);
|
|
4541
|
+
const [a, b, c] = v;
|
|
4542
|
+
if (!isNumber$1(a) || !isNumber$1(b) || !isNumber$1(c)) return bad(`${where}: Vec3 contains non-number`);
|
|
4543
|
+
return require_errors.ok([
|
|
4544
|
+
a,
|
|
4545
|
+
b,
|
|
4546
|
+
c
|
|
4547
|
+
]);
|
|
4548
|
+
}
|
|
4549
|
+
function readVec2(v, where) {
|
|
4550
|
+
if (!Array.isArray(v) || v.length !== 2) return bad(`${where}: expected Vec2 array`);
|
|
4551
|
+
const [a, b] = v;
|
|
4552
|
+
if (!isNumber$1(a) || !isNumber$1(b)) return bad(`${where}: Vec2 contains non-number`);
|
|
4553
|
+
return require_errors.ok([a, b]);
|
|
4554
|
+
}
|
|
4555
|
+
function fromJSON(envelope) {
|
|
4556
|
+
if (!isObj(envelope)) return bad("input is not an object");
|
|
4557
|
+
const v = envelope["csgVersion"];
|
|
4558
|
+
if (v !== 1) return bad(`unsupported csgVersion ${String(v)} (expected 1)`);
|
|
4559
|
+
const root = envelope["root"];
|
|
4560
|
+
return readNode(root);
|
|
4561
|
+
}
|
|
4562
|
+
function readExpr(j) {
|
|
4563
|
+
if (!isObj(j)) return bad("expression: not an object");
|
|
4564
|
+
const kind = j["kind"];
|
|
4565
|
+
switch (kind) {
|
|
4566
|
+
case "NumLit": return isNumber$1(j["value"]) ? require_errors.ok(numLit(j["value"])) : bad("NumLit.value");
|
|
4567
|
+
case "Vec3Lit": {
|
|
4568
|
+
const v = readVec3(j["value"], "Vec3Lit.value");
|
|
4569
|
+
return v.ok ? require_errors.ok(vec3Lit(v.value)) : v;
|
|
4570
|
+
}
|
|
4571
|
+
case "Vec2Lit": {
|
|
4572
|
+
const v = readVec2(j["value"], "Vec2Lit.value");
|
|
4573
|
+
return v.ok ? require_errors.ok(vec2Lit(v.value)) : v;
|
|
4574
|
+
}
|
|
4575
|
+
case "Param": return isString(j["name"]) ? require_errors.ok(param(j["name"])) : bad("Param.name");
|
|
4576
|
+
case "BinOp": return readBinOp(j);
|
|
4577
|
+
case "UnaryOp": return readUnaryOp(j);
|
|
4578
|
+
case "Component": return readComponent(j);
|
|
4579
|
+
case "BuildVec": return readBuildVec(j);
|
|
4580
|
+
default: return bad(`unknown expression kind: ${String(kind)}`);
|
|
4581
|
+
}
|
|
4582
|
+
}
|
|
4583
|
+
function readBinOp(j) {
|
|
4584
|
+
const op = j["op"];
|
|
4585
|
+
if (op !== "+" && op !== "-" && op !== "*" && op !== "/") return bad(`BinOp.op: ${String(op)}`);
|
|
4586
|
+
const a = readExpr(j["a"]);
|
|
4587
|
+
if (!a.ok) return a;
|
|
4588
|
+
const b = readExpr(j["b"]);
|
|
4589
|
+
if (!b.ok) return b;
|
|
4590
|
+
return require_errors.ok(binOp(op, a.value, b.value));
|
|
4591
|
+
}
|
|
4592
|
+
function readUnaryOp(j) {
|
|
4593
|
+
const op = j["op"];
|
|
4594
|
+
if (!isString(op) || ![
|
|
4595
|
+
"neg",
|
|
4596
|
+
"sin",
|
|
4597
|
+
"cos",
|
|
4598
|
+
"sqrt",
|
|
4599
|
+
"abs"
|
|
4600
|
+
].includes(op)) return bad(`UnaryOp.op: ${String(op)}`);
|
|
4601
|
+
const arg = readExpr(j["arg"]);
|
|
4602
|
+
if (!arg.ok) return arg;
|
|
4603
|
+
return require_errors.ok(unaryOp(op, arg.value));
|
|
4604
|
+
}
|
|
4605
|
+
function readComponent(j) {
|
|
4606
|
+
const index = j["index"];
|
|
4607
|
+
if (index !== 0 && index !== 1 && index !== 2) return bad(`Component.index: ${String(index)}`);
|
|
4608
|
+
const vec = readExpr(j["vec"]);
|
|
4609
|
+
if (!vec.ok) return vec;
|
|
4610
|
+
return require_errors.ok(component(vec.value, index));
|
|
4611
|
+
}
|
|
4612
|
+
function readBuildVec(j) {
|
|
4613
|
+
const dim = j["dim"];
|
|
4614
|
+
if (dim !== 2 && dim !== 3) return bad(`BuildVec.dim: ${String(dim)}`);
|
|
4615
|
+
const comps = j["components"];
|
|
4616
|
+
if (!Array.isArray(comps)) return bad("BuildVec.components: not array");
|
|
4617
|
+
if (comps.length !== dim) return bad(`BuildVec.components: expected ${dim} components, got ${comps.length}`);
|
|
4618
|
+
const out = [];
|
|
4619
|
+
for (const c of comps) {
|
|
4620
|
+
const r = readExpr(c);
|
|
4621
|
+
if (!r.ok) return r;
|
|
4622
|
+
out.push(r.value);
|
|
4623
|
+
}
|
|
4624
|
+
return require_errors.ok(buildVec(dim, out));
|
|
4625
|
+
}
|
|
4626
|
+
function readNodeArray(j, where) {
|
|
4627
|
+
if (!Array.isArray(j)) return bad(`${where}: not array`);
|
|
4628
|
+
const out = [];
|
|
4629
|
+
for (const c of j) {
|
|
4630
|
+
const r = readNode(c);
|
|
4631
|
+
if (!r.ok) return r;
|
|
4632
|
+
out.push(r.value);
|
|
4633
|
+
}
|
|
4634
|
+
return require_errors.ok(out);
|
|
4635
|
+
}
|
|
4636
|
+
function readOptTolerance(j) {
|
|
4637
|
+
const t = j["tolerance"];
|
|
4638
|
+
if (t === void 0 || t === null) return require_errors.ok(void 0);
|
|
4639
|
+
return isNumber$1(t) ? require_errors.ok(t) : bad("tolerance: not a finite number");
|
|
4640
|
+
}
|
|
4641
|
+
function readNode(j) {
|
|
4642
|
+
if (!isObj(j)) return bad("node: not an object");
|
|
4643
|
+
const kind = j["kind"];
|
|
4644
|
+
switch (kind) {
|
|
4645
|
+
case "Box":
|
|
4646
|
+
case "Sphere":
|
|
4647
|
+
case "Cylinder":
|
|
4648
|
+
case "Cone":
|
|
4649
|
+
case "Torus":
|
|
4650
|
+
case "Polygon":
|
|
4651
|
+
case "Circle":
|
|
4652
|
+
case "Line":
|
|
4653
|
+
case "Vertex":
|
|
4654
|
+
case "Empty": return readPrimitive(kind, j);
|
|
4655
|
+
case "Fuse":
|
|
4656
|
+
case "Cut":
|
|
4657
|
+
case "Intersect": return readBinaryBool(kind, j);
|
|
4658
|
+
case "FuseAll":
|
|
4659
|
+
case "CutAll": return readNaryBool(kind, j);
|
|
4660
|
+
case "Translate":
|
|
4661
|
+
case "Rotate":
|
|
4662
|
+
case "Scale":
|
|
4663
|
+
case "Mirror": return readTransform(kind, j);
|
|
4664
|
+
case "Compound": return readCompound(j);
|
|
4665
|
+
default: return bad(`unknown node kind: ${String(kind)}`);
|
|
4666
|
+
}
|
|
4667
|
+
}
|
|
4668
|
+
function readSingleExpr(j, key, build) {
|
|
4669
|
+
const r = readExpr(j[key]);
|
|
4670
|
+
return r.ok ? require_errors.ok(build(r.value)) : r;
|
|
4671
|
+
}
|
|
4672
|
+
function readPrimitive(kind, j) {
|
|
4673
|
+
switch (kind) {
|
|
4674
|
+
case "Box": return readBox(j);
|
|
4675
|
+
case "Sphere": return readSingleExpr(j, "radius", sphere$1);
|
|
4676
|
+
case "Cylinder": return readCylinder(j);
|
|
4677
|
+
case "Cone": return readCone(j);
|
|
4678
|
+
case "Torus": return readTorus(j);
|
|
4679
|
+
case "Polygon": return readPolygon(j);
|
|
4680
|
+
case "Circle": return readSingleExpr(j, "radius", circle$1);
|
|
4681
|
+
case "Line": return readLine(j);
|
|
4682
|
+
case "Vertex": return readSingleExpr(j, "point", vertex$1);
|
|
4683
|
+
case "Empty": return readEmpty(j);
|
|
4684
|
+
}
|
|
4685
|
+
return bad(`unhandled primitive: ${kind}`);
|
|
4686
|
+
}
|
|
4687
|
+
function readBox(j) {
|
|
4688
|
+
const x = readExpr(j["x"]);
|
|
4689
|
+
if (!x.ok) return x;
|
|
4690
|
+
const y = readExpr(j["y"]);
|
|
4691
|
+
if (!y.ok) return y;
|
|
4692
|
+
const z = readExpr(j["z"]);
|
|
4693
|
+
if (!z.ok) return z;
|
|
4694
|
+
return require_errors.ok(box$1(x.value, y.value, z.value));
|
|
4695
|
+
}
|
|
4696
|
+
function readCylinder(j) {
|
|
4697
|
+
const r = readExpr(j["radius"]);
|
|
4698
|
+
if (!r.ok) return r;
|
|
4699
|
+
const h = readExpr(j["height"]);
|
|
4700
|
+
if (!h.ok) return h;
|
|
4701
|
+
return require_errors.ok(cylinder$1(r.value, h.value));
|
|
4702
|
+
}
|
|
4703
|
+
function readCone(j) {
|
|
4704
|
+
const r1 = readExpr(j["radius1"]);
|
|
4705
|
+
if (!r1.ok) return r1;
|
|
4706
|
+
const r2 = readExpr(j["radius2"]);
|
|
4707
|
+
if (!r2.ok) return r2;
|
|
4708
|
+
const h = readExpr(j["height"]);
|
|
4709
|
+
if (!h.ok) return h;
|
|
4710
|
+
return require_errors.ok(cone$1(r1.value, r2.value, h.value));
|
|
4711
|
+
}
|
|
4712
|
+
function readTorus(j) {
|
|
4713
|
+
const ma = readExpr(j["majorRadius"]);
|
|
4714
|
+
if (!ma.ok) return ma;
|
|
4715
|
+
const mi = readExpr(j["minorRadius"]);
|
|
4716
|
+
if (!mi.ok) return mi;
|
|
4717
|
+
return require_errors.ok(torus$1(ma.value, mi.value));
|
|
4718
|
+
}
|
|
4719
|
+
function readPolygon(j) {
|
|
4720
|
+
const pts = j["points"];
|
|
4721
|
+
if (!Array.isArray(pts)) return bad("Polygon.points: not array");
|
|
4722
|
+
const out = [];
|
|
4723
|
+
for (const p of pts) {
|
|
4724
|
+
const r = readExpr(p);
|
|
4725
|
+
if (!r.ok) return r;
|
|
4726
|
+
out.push(r.value);
|
|
4727
|
+
}
|
|
4728
|
+
return require_errors.ok(polygon$1(out));
|
|
4729
|
+
}
|
|
4730
|
+
function readLine(j) {
|
|
4731
|
+
const f = readExpr(j["from"]);
|
|
4732
|
+
if (!f.ok) return f;
|
|
4733
|
+
const t = readExpr(j["to"]);
|
|
4734
|
+
if (!t.ok) return t;
|
|
4735
|
+
return require_errors.ok(line$1(f.value, t.value));
|
|
4736
|
+
}
|
|
4737
|
+
function readEmpty(j) {
|
|
4738
|
+
const out = j["output"];
|
|
4739
|
+
switch (out) {
|
|
4740
|
+
case "Solid": return require_errors.ok(emptySolid());
|
|
4741
|
+
case "Face": return require_errors.ok(emptyFace());
|
|
4742
|
+
case "Wire": return require_errors.ok(emptyWire());
|
|
4743
|
+
default: return bad(`Empty.output: ${String(out)}`);
|
|
4744
|
+
}
|
|
4745
|
+
}
|
|
4746
|
+
function readBinaryBool(kind, j) {
|
|
4747
|
+
const a = readNode(j["a"]);
|
|
4748
|
+
if (!a.ok) return a;
|
|
4749
|
+
const b = readNode(j["b"]);
|
|
4750
|
+
if (!b.ok) return b;
|
|
4751
|
+
const t = readOptTolerance(j);
|
|
4752
|
+
if (!t.ok) return t;
|
|
4753
|
+
switch (kind) {
|
|
4754
|
+
case "Fuse": return require_errors.ok(fuse$1(a.value, b.value, t.value));
|
|
4755
|
+
case "Cut": return require_errors.ok(cut$1(a.value, b.value, t.value));
|
|
4756
|
+
case "Intersect": return require_errors.ok(intersect$1(a.value, b.value, t.value));
|
|
4757
|
+
}
|
|
4758
|
+
}
|
|
4759
|
+
function readNaryBool(kind, j) {
|
|
4760
|
+
const t = readOptTolerance(j);
|
|
4761
|
+
if (!t.ok) return t;
|
|
4762
|
+
if (kind === "FuseAll") {
|
|
4763
|
+
const shapes = readNodeArray(j["shapes"], "FuseAll.shapes");
|
|
4764
|
+
return shapes.ok ? require_errors.ok(fuseAll$1(shapes.value, t.value)) : shapes;
|
|
4765
|
+
}
|
|
4766
|
+
const base = readNode(j["base"]);
|
|
4767
|
+
if (!base.ok) return base;
|
|
4768
|
+
const tools = readNodeArray(j["tools"], "CutAll.tools");
|
|
4769
|
+
return tools.ok ? require_errors.ok(cutAll$1(base.value, tools.value, t.value)) : tools;
|
|
4770
|
+
}
|
|
4771
|
+
function readTransform(kind, j) {
|
|
4772
|
+
const tgt = readNode(j["target"]);
|
|
4773
|
+
if (!tgt.ok) return tgt;
|
|
4774
|
+
switch (kind) {
|
|
4775
|
+
case "Translate": return readTranslate(j, tgt.value);
|
|
4776
|
+
case "Rotate": return readRotate(j, tgt.value);
|
|
4777
|
+
case "Scale": return readScale(j, tgt.value);
|
|
4778
|
+
case "Mirror": return readMirror(j, tgt.value);
|
|
4779
|
+
}
|
|
4780
|
+
}
|
|
4781
|
+
function readTranslate(j, target) {
|
|
4782
|
+
const v = readExpr(j["vector"]);
|
|
4783
|
+
return v.ok ? require_errors.ok(translate$1(target, v.value)) : v;
|
|
4784
|
+
}
|
|
4785
|
+
function readOptExpr(j, key) {
|
|
4786
|
+
if (j[key] === void 0) return require_errors.ok(void 0);
|
|
4787
|
+
const r = readExpr(j[key]);
|
|
4788
|
+
return r.ok ? require_errors.ok(r.value) : r;
|
|
4789
|
+
}
|
|
4790
|
+
function readRotate(j, target) {
|
|
4791
|
+
const ang = readExpr(j["angle"]);
|
|
4792
|
+
if (!ang.ok) return ang;
|
|
4793
|
+
const axis = readOptExpr(j, "axis");
|
|
4794
|
+
if (!axis.ok) return axis;
|
|
4795
|
+
const at = readOptExpr(j, "at");
|
|
4796
|
+
if (!at.ok) return at;
|
|
4797
|
+
return require_errors.ok(rotate$1(target, ang.value, {
|
|
4798
|
+
axis: axis.value,
|
|
4799
|
+
at: at.value
|
|
4800
|
+
}));
|
|
4801
|
+
}
|
|
4802
|
+
function readScale(j, target) {
|
|
4803
|
+
const f = readExpr(j["factor"]);
|
|
4804
|
+
if (!f.ok) return f;
|
|
4805
|
+
const center = readOptExpr(j, "center");
|
|
4806
|
+
if (!center.ok) return center;
|
|
4807
|
+
return require_errors.ok(scale$1(target, f.value, { center: center.value }));
|
|
4808
|
+
}
|
|
4809
|
+
function readMirror(j, target) {
|
|
4810
|
+
const normal = readOptExpr(j, "normal");
|
|
4811
|
+
if (!normal.ok) return normal;
|
|
4812
|
+
const at = readOptExpr(j, "at");
|
|
4813
|
+
if (!at.ok) return at;
|
|
4814
|
+
return require_errors.ok(mirror$1(target, {
|
|
4815
|
+
normal: normal.value,
|
|
4816
|
+
at: at.value
|
|
4817
|
+
}));
|
|
4818
|
+
}
|
|
4819
|
+
function readCompound(j) {
|
|
4820
|
+
const children = readNodeArray(j["children"], "Compound.children");
|
|
4821
|
+
return children.ok ? require_errors.ok(compound$1(children.value)) : children;
|
|
4822
|
+
}
|
|
4823
|
+
//#endregion
|
|
4824
|
+
//#region src/csg/optimize.ts
|
|
4825
|
+
function optimize(node) {
|
|
4826
|
+
return optimizeNode(node);
|
|
4827
|
+
}
|
|
4828
|
+
function foldExpr(e) {
|
|
4829
|
+
switch (e.kind) {
|
|
4830
|
+
case "NumLit":
|
|
4831
|
+
case "Vec3Lit":
|
|
4832
|
+
case "Vec2Lit":
|
|
4833
|
+
case "Param": return e;
|
|
4834
|
+
case "BinOp": {
|
|
4835
|
+
const a = foldExpr(e.a);
|
|
4836
|
+
const b = foldExpr(e.b);
|
|
4837
|
+
if (a.kind === "NumLit" && b.kind === "NumLit") switch (e.op) {
|
|
4838
|
+
case "+": return numLit(a.value + b.value);
|
|
4839
|
+
case "-": return numLit(a.value - b.value);
|
|
4840
|
+
case "*": return numLit(a.value * b.value);
|
|
4841
|
+
case "/": return numLit(a.value / b.value);
|
|
4842
|
+
}
|
|
4843
|
+
if (a !== e.a || b !== e.b) return binOp(e.op, a, b);
|
|
4844
|
+
return e;
|
|
4845
|
+
}
|
|
4846
|
+
case "UnaryOp": {
|
|
4847
|
+
const arg = foldExpr(e.arg);
|
|
4848
|
+
if (arg.kind === "NumLit") {
|
|
4849
|
+
const n = arg.value;
|
|
4850
|
+
switch (e.op) {
|
|
4851
|
+
case "neg": return numLit(-n);
|
|
4852
|
+
case "sin": return numLit(Math.sin(n));
|
|
4853
|
+
case "cos": return numLit(Math.cos(n));
|
|
4854
|
+
case "sqrt": return numLit(Math.sqrt(n));
|
|
4855
|
+
case "abs": return numLit(Math.abs(n));
|
|
4856
|
+
}
|
|
4857
|
+
}
|
|
4858
|
+
if (arg !== e.arg) return unaryOp(e.op, arg);
|
|
4859
|
+
return e;
|
|
4860
|
+
}
|
|
4861
|
+
case "Component": {
|
|
4862
|
+
const v = foldExpr(e.vec);
|
|
4863
|
+
if (v.kind === "Vec3Lit") return numLit(v.value[e.index]);
|
|
4864
|
+
if (v.kind === "Vec2Lit" && (e.index === 0 || e.index === 1)) return numLit(v.value[e.index]);
|
|
4865
|
+
if (v !== e.vec) return component(v, e.index);
|
|
4866
|
+
return e;
|
|
4867
|
+
}
|
|
4868
|
+
case "BuildVec": {
|
|
4869
|
+
const folded = e.components.map(foldExpr);
|
|
4870
|
+
const collapsed = foldBuildVec(e.dim, folded);
|
|
4871
|
+
if (collapsed) return collapsed;
|
|
4872
|
+
if (folded.some((c, i) => c !== e.components[i])) return buildVec(e.dim, folded);
|
|
4873
|
+
return e;
|
|
4874
|
+
}
|
|
4875
|
+
}
|
|
4876
|
+
}
|
|
4877
|
+
function foldBuildVec(dim, comps) {
|
|
4878
|
+
if (comps.length !== dim) return void 0;
|
|
4879
|
+
const nums = [];
|
|
4880
|
+
for (const c of comps) {
|
|
4881
|
+
if (c.kind !== "NumLit") return void 0;
|
|
4882
|
+
nums.push(c.value);
|
|
4883
|
+
}
|
|
4884
|
+
if (dim === 2) return vec2Lit([nums[0], nums[1]]);
|
|
4885
|
+
return vec3Lit([
|
|
4886
|
+
nums[0],
|
|
4887
|
+
nums[1],
|
|
4888
|
+
nums[2]
|
|
4889
|
+
]);
|
|
4890
|
+
}
|
|
4891
|
+
function optimizeNode(n) {
|
|
4892
|
+
switch (n.kind) {
|
|
4893
|
+
case "Box": return box$1(foldExpr(n.x), foldExpr(n.y), foldExpr(n.z));
|
|
4894
|
+
case "Sphere": return sphere$1(foldExpr(n.radius));
|
|
4895
|
+
case "Cylinder": return cylinder$1(foldExpr(n.radius), foldExpr(n.height));
|
|
4896
|
+
case "Cone": return cone$1(foldExpr(n.radius1), foldExpr(n.radius2), foldExpr(n.height));
|
|
4897
|
+
case "Torus": return torus$1(foldExpr(n.majorRadius), foldExpr(n.minorRadius));
|
|
4898
|
+
case "Polygon": return polygon$1(n.points.map(foldExpr));
|
|
4899
|
+
case "Circle": return circle$1(foldExpr(n.radius));
|
|
4900
|
+
case "Line": return line$1(foldExpr(n.from), foldExpr(n.to));
|
|
4901
|
+
case "Vertex": return vertex$1(foldExpr(n.point));
|
|
4902
|
+
case "Empty": return n;
|
|
4903
|
+
case "Fuse": return optimizeFuse(n.a, n.b, n.tolerance);
|
|
4904
|
+
case "Cut": return optimizeCut(n.a, n.b, n.tolerance);
|
|
4905
|
+
case "Intersect": return optimizeIntersect(n.a, n.b, n.tolerance);
|
|
4906
|
+
case "FuseAll": return optimizeFuseAll(n.shapes, n.tolerance);
|
|
4907
|
+
case "CutAll": return optimizeCutAll(n.base, n.tools, n.tolerance);
|
|
4908
|
+
case "Translate": return optimizeTranslate(n.target, n.vector);
|
|
4909
|
+
case "Rotate": return rotate$1(optimizeNode(n.target), foldExpr(n.angle), {
|
|
4910
|
+
axis: n.axis ? foldExpr(n.axis) : void 0,
|
|
4911
|
+
at: n.at ? foldExpr(n.at) : void 0
|
|
4912
|
+
});
|
|
4913
|
+
case "Scale": return scale$1(optimizeNode(n.target), foldExpr(n.factor), { center: n.center ? foldExpr(n.center) : void 0 });
|
|
4914
|
+
case "Mirror": return mirror$1(optimizeNode(n.target), {
|
|
4915
|
+
normal: n.normal ? foldExpr(n.normal) : void 0,
|
|
4916
|
+
at: n.at ? foldExpr(n.at) : void 0
|
|
4917
|
+
});
|
|
4918
|
+
case "Compound": return compound$1(n.children.map(optimizeNode).filter((c) => c.kind !== "Empty"));
|
|
4919
|
+
}
|
|
4920
|
+
}
|
|
4921
|
+
function optimizeFuse(a, b, tol) {
|
|
4922
|
+
const oa = optimizeNode(a);
|
|
4923
|
+
const ob = optimizeNode(b);
|
|
4924
|
+
if (oa.kind === "Empty") return ob;
|
|
4925
|
+
if (ob.kind === "Empty") return oa;
|
|
4926
|
+
return fuse$1(oa, ob, tol);
|
|
4927
|
+
}
|
|
4928
|
+
function optimizeCut(a, b, tol) {
|
|
4929
|
+
const oa = optimizeNode(a);
|
|
4930
|
+
const ob = optimizeNode(b);
|
|
4931
|
+
if (ob.kind === "Empty") return oa;
|
|
4932
|
+
if (oa.kind === "Empty") return oa;
|
|
4933
|
+
return cut$1(oa, ob, tol);
|
|
4934
|
+
}
|
|
4935
|
+
function optimizeIntersect(a, b, tol) {
|
|
4936
|
+
const oa = optimizeNode(a);
|
|
4937
|
+
const ob = optimizeNode(b);
|
|
4938
|
+
if (oa.kind === "Empty") return oa;
|
|
4939
|
+
if (ob.kind === "Empty") return ob;
|
|
4940
|
+
return intersect$1(oa, ob, tol);
|
|
4941
|
+
}
|
|
4942
|
+
function optimizeFuseAll(shapes, tol) {
|
|
4943
|
+
const opt = shapes.map(optimizeNode).filter((s) => s.kind !== "Empty");
|
|
4944
|
+
if (opt.length === 0) return emptySolid();
|
|
4945
|
+
if (opt.length === 1) return opt[0];
|
|
4946
|
+
return fuseAll$1(opt, tol);
|
|
4947
|
+
}
|
|
4948
|
+
function optimizeCutAll(base, tools, tol) {
|
|
4949
|
+
const ob = optimizeNode(base);
|
|
4950
|
+
if (ob.kind === "Empty") return ob;
|
|
4951
|
+
const ot = tools.map(optimizeNode).filter((s) => s.kind !== "Empty");
|
|
4952
|
+
if (ot.length === 0) return ob;
|
|
4953
|
+
return cutAll$1(ob, ot, tol);
|
|
4954
|
+
}
|
|
4955
|
+
function optimizeTranslate(target, vector) {
|
|
4956
|
+
const ot = optimizeNode(target);
|
|
4957
|
+
const ov = foldExpr(vector);
|
|
4958
|
+
if (ov.kind !== "Vec3Lit") return translate$1(ot, ov);
|
|
4959
|
+
const [x, y, z] = ov.value;
|
|
4960
|
+
if (x === 0 && y === 0 && z === 0) return ot;
|
|
4961
|
+
if (ot.kind === "Translate") {
|
|
4962
|
+
const inner = foldExpr(ot.vector);
|
|
4963
|
+
if (inner.kind === "Vec3Lit") return translate$1(ot.target, [
|
|
4964
|
+
inner.value[0] + x,
|
|
4965
|
+
inner.value[1] + y,
|
|
4966
|
+
inner.value[2] + z
|
|
4967
|
+
]);
|
|
4968
|
+
}
|
|
4969
|
+
return translate$1(ot, ov);
|
|
4970
|
+
}
|
|
4971
|
+
//#endregion
|
|
4972
|
+
//#region src/csg/edit.ts
|
|
4973
|
+
function replaceNode(root, pred, replacement) {
|
|
4974
|
+
return walk(root, pred, replacement);
|
|
4975
|
+
}
|
|
4976
|
+
function walk(node, pred, repl) {
|
|
4977
|
+
if (pred(node)) return repl;
|
|
4978
|
+
return rebuildChildren(node, pred, repl);
|
|
4979
|
+
}
|
|
4980
|
+
function rebuildChildren(n, pred, repl) {
|
|
4981
|
+
switch (n.kind) {
|
|
4982
|
+
case "Box":
|
|
4983
|
+
case "Sphere":
|
|
4984
|
+
case "Cylinder":
|
|
4985
|
+
case "Cone":
|
|
4986
|
+
case "Torus":
|
|
4987
|
+
case "Polygon":
|
|
4988
|
+
case "Circle":
|
|
4989
|
+
case "Line":
|
|
4990
|
+
case "Vertex":
|
|
4991
|
+
case "Empty": return n;
|
|
4992
|
+
case "Fuse": return fuse$1(walk(n.a, pred, repl), walk(n.b, pred, repl), n.tolerance);
|
|
4993
|
+
case "Cut": return cut$1(walk(n.a, pred, repl), walk(n.b, pred, repl), n.tolerance);
|
|
4994
|
+
case "Intersect": return intersect$1(walk(n.a, pred, repl), walk(n.b, pred, repl), n.tolerance);
|
|
4995
|
+
case "FuseAll": return fuseAll$1(n.shapes.map((c) => walk(c, pred, repl)), n.tolerance);
|
|
4996
|
+
case "CutAll": return cutAll$1(walk(n.base, pred, repl), n.tools.map((c) => walk(c, pred, repl)), n.tolerance);
|
|
4997
|
+
case "Translate": return translate$1(walk(n.target, pred, repl), n.vector);
|
|
4998
|
+
case "Rotate": return rotate$1(walk(n.target, pred, repl), n.angle, {
|
|
4999
|
+
axis: n.axis,
|
|
5000
|
+
at: n.at
|
|
5001
|
+
});
|
|
5002
|
+
case "Scale": return scale$1(walk(n.target, pred, repl), n.factor, { center: n.center });
|
|
5003
|
+
case "Mirror": return mirror$1(walk(n.target, pred, repl), {
|
|
5004
|
+
normal: n.normal,
|
|
5005
|
+
at: n.at
|
|
5006
|
+
});
|
|
5007
|
+
case "Compound": return compound$1(n.children.map((c) => walk(c, pred, repl)));
|
|
5008
|
+
}
|
|
5009
|
+
}
|
|
5010
|
+
function forEachNode(root, fn) {
|
|
5011
|
+
fn(root);
|
|
5012
|
+
for (const child of childrenOf(root)) forEachNode(child, fn);
|
|
5013
|
+
}
|
|
5014
|
+
function childrenOf(n) {
|
|
5015
|
+
switch (n.kind) {
|
|
5016
|
+
case "Box":
|
|
5017
|
+
case "Sphere":
|
|
5018
|
+
case "Cylinder":
|
|
5019
|
+
case "Cone":
|
|
5020
|
+
case "Torus":
|
|
5021
|
+
case "Polygon":
|
|
5022
|
+
case "Circle":
|
|
5023
|
+
case "Line":
|
|
5024
|
+
case "Vertex":
|
|
5025
|
+
case "Empty": return [];
|
|
5026
|
+
case "Fuse":
|
|
5027
|
+
case "Cut":
|
|
5028
|
+
case "Intersect": return [n.a, n.b];
|
|
5029
|
+
case "FuseAll": return n.shapes;
|
|
5030
|
+
case "CutAll": return [n.base, ...n.tools];
|
|
5031
|
+
case "Translate":
|
|
5032
|
+
case "Rotate":
|
|
5033
|
+
case "Scale":
|
|
5034
|
+
case "Mirror": return [n.target];
|
|
5035
|
+
case "Compound": return n.children;
|
|
5036
|
+
}
|
|
5037
|
+
}
|
|
5038
|
+
function nodeCount(root) {
|
|
5039
|
+
let n = 0;
|
|
5040
|
+
forEachNode(root, () => {
|
|
5041
|
+
n++;
|
|
5042
|
+
});
|
|
5043
|
+
return n;
|
|
5044
|
+
}
|
|
5045
|
+
//#endregion
|
|
5046
|
+
//#region src/ns/csg.ts
|
|
5047
|
+
var csg_exports = /* @__PURE__ */ require_textBlueprints.__exportAll({
|
|
5048
|
+
CSG_VERSION: () => 1,
|
|
5049
|
+
Evaluator: () => Evaluator,
|
|
5050
|
+
add: () => add,
|
|
5051
|
+
asScalarExpr: () => asScalarExpr,
|
|
5052
|
+
asVec2Expr: () => asVec2Expr,
|
|
5053
|
+
asVec3Expr: () => asVec3Expr,
|
|
5054
|
+
binOp: () => binOp,
|
|
5055
|
+
box: () => box$1,
|
|
5056
|
+
buildVec: () => buildVec,
|
|
5057
|
+
circle: () => circle$1,
|
|
5058
|
+
component: () => component,
|
|
5059
|
+
compound: () => compound$1,
|
|
5060
|
+
cone: () => cone$1,
|
|
5061
|
+
cut: () => cut$1,
|
|
5062
|
+
cutAll: () => cutAll$1,
|
|
5063
|
+
cylinder: () => cylinder$1,
|
|
5064
|
+
emptyFace: () => emptyFace,
|
|
5065
|
+
emptySolid: () => emptySolid,
|
|
5066
|
+
emptyWire: () => emptyWire,
|
|
5067
|
+
foldExpr: () => foldExpr,
|
|
5068
|
+
forEachNode: () => forEachNode,
|
|
5069
|
+
fromJSON: () => fromJSON,
|
|
5070
|
+
fuse: () => fuse$1,
|
|
5071
|
+
fuseAll: () => fuseAll$1,
|
|
5072
|
+
intersect: () => intersect$1,
|
|
5073
|
+
line: () => line$1,
|
|
5074
|
+
mirror: () => mirror$1,
|
|
5075
|
+
mul: () => mul,
|
|
5076
|
+
nodeCount: () => nodeCount,
|
|
5077
|
+
numLit: () => numLit,
|
|
5078
|
+
optimize: () => optimize,
|
|
5079
|
+
outputKindOf: () => outputKindOf,
|
|
5080
|
+
param: () => param,
|
|
5081
|
+
polygon: () => polygon$1,
|
|
5082
|
+
replaceNode: () => replaceNode,
|
|
5083
|
+
rotate: () => rotate$1,
|
|
5084
|
+
scale: () => scale$1,
|
|
5085
|
+
sphere: () => sphere$1,
|
|
5086
|
+
toJSON: () => toJSON,
|
|
5087
|
+
torus: () => torus$1,
|
|
5088
|
+
translate: () => translate$1,
|
|
5089
|
+
unaryOp: () => unaryOp,
|
|
5090
|
+
vec2Lit: () => vec2Lit,
|
|
5091
|
+
vec3Lit: () => vec3Lit,
|
|
5092
|
+
vertex: () => vertex$1,
|
|
5093
|
+
withEvaluator: () => withEvaluator
|
|
5094
|
+
});
|
|
5095
|
+
//#endregion
|
|
3415
5096
|
exports.BaseSketcher2d = require_blueprintSketcher.BaseSketcher2d;
|
|
3416
5097
|
exports.BlueprintSketcher = require_blueprintSketcher.BlueprintSketcher;
|
|
3417
5098
|
exports.BrepBugError = require_errors.BrepBugError;
|
|
@@ -3523,6 +5204,12 @@ exports.createVertex = require_shapeTypes.createVertex;
|
|
|
3523
5204
|
exports.createWire = require_shapeTypes.createWire;
|
|
3524
5205
|
exports.createWorkerClient = require_workerHandler.createWorkerClient;
|
|
3525
5206
|
exports.createWorkerHandler = require_workerHandler.createWorkerHandler;
|
|
5207
|
+
Object.defineProperty(exports, "csg", {
|
|
5208
|
+
enumerable: true,
|
|
5209
|
+
get: function() {
|
|
5210
|
+
return csg_exports;
|
|
5211
|
+
}
|
|
5212
|
+
});
|
|
3526
5213
|
exports.curve2dBoundingBox = require_blueprintFns.curve2dBoundingBox;
|
|
3527
5214
|
exports.curve2dDistanceFrom = require_blueprintFns.curve2dDistanceFrom;
|
|
3528
5215
|
exports.curve2dFirstPoint = require_blueprintFns.curve2dFirstPoint;
|