brepjs 18.154.0 → 18.156.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 +280 -243
- package/dist/brepjs.js +279 -242
- package/dist/csg/edit.d.ts +1 -0
- package/dist/csg/serialize.d.ts +2 -1
- package/dist/io.cjs +1 -1
- package/dist/io.js +1 -1
- package/dist/{meshFns-FSW58GBR.js → meshFns-BTE7WFpU.js} +18 -4
- package/dist/{meshFns-cMtop3IN.cjs → meshFns-BZNqLhDE.cjs} +23 -3
- package/dist/topology/meshFns.d.ts +4 -1
- package/dist/topology.cjs +1 -1
- package/dist/topology.js +1 -1
- package/package.json +1 -1
package/dist/brepjs.js
CHANGED
|
@@ -14,7 +14,7 @@ import { A as parseColor, D as colorShape, E as colorFaces, F as tagFaces, M as
|
|
|
14
14
|
import { A as locate$1, C as threePointArc, D as wireLoop, E as wire, F as transformCopy$1, I as translate$2, M as resize, N as rotate$2, O as applyMatrix$1, P as scale$3, S as tangentArc, T as vertex, _ as polygon, a as circle, b as sphere$1, c as cylinder, d as ellipsoid, f as face, g as offsetFace, h as line, i as bsplineApprox, j as mirror$2, k as composeTransforms, l as ellipse, m as helix, n as bezier, o as compound, p as filledFace, r as box, s as cone, t as addHoles, u as ellipseArc, v as sewShells, w as torus$1, x as subFace, y as solid } from "./primitiveFns-B0iLpCEN.js";
|
|
15
15
|
import { a as isSameShape, i as isEqualShape, n as getHashCode, o as simplify$1, r as isEmpty$2, s as toBREP$1, t as clone$1 } from "./shapeFns-D0hK1y4m.js";
|
|
16
16
|
import { a as curveIsPeriodic, c as curvePointAt, d as flipOrientation, f as getCurveType, h as offsetWire2D, i as curveIsClosed, l as curveStartPoint, m as interpolateCurve, n as curveAxis, o as curveLength, p as getOrientation, r as curveEndPoint, s as curvePeriod, t as approximateCurve, u as curveTangentAt } from "./curveFns-U6vegvin.js";
|
|
17
|
-
import { a as meshEdges$1, c as meshMultiLOD, d as createMeshCache, i as mesh$1, l as
|
|
17
|
+
import { a as meshEdges$1, c as meshMultiLOD, d as clearMeshCache, f as createMeshCache, i as mesh$1, l as scaleDefaultTolerance, n as exportSTEP, o as meshLODs, r as exportSTL, s as meshLODsProgressive, t as exportIGES, u as buildMeshCacheKey } from "./meshFns-BTE7WFpU.js";
|
|
18
18
|
import { n as getAtOrThrow, r as lastOrThrow, t as firstOrThrow } from "./arrayAccess-DrUGPADn.js";
|
|
19
19
|
import { _ as makeThreePointArc, d as makeCircle, h as makeLine, l as makeBSplineInterpolation, n as fill, p as makeEllipseArc, r as makeFace, s as assembleWire, u as makeBezierCurve } from "./surfaceBuilders-C_oBS19q.js";
|
|
20
20
|
import { A as toBufferGeometryData, C as chamfer$2, D as shell$2, E as offset$1, M as toLODGeometryData, N as toLODGeometryLevels, O as thicken$1, P as toLineGeometryData, S as chamferDistAngle, T as fillet$2, _ as checkBoolean, a as healFace, b as getNurbsCurveData, c as isValid$1, d as chamferWithEvolution, f as cutWithEvolution, g as shellWithEvolution, h as intersectWithEvolution, i as heal$1, j as toGroupedBufferGeometryData, k as variableFillet, l as solidFromShell, m as fuseWithEvolution, n as fixSelfIntersection, o as healSolid, p as filletWithEvolution, r as fixShape, s as healWire, t as autoHeal, u as positionOnCurve, v as cutAllBisect, w as draft$1, x as getNurbsSurfaceData, y as fuseAllBisect } from "./healingFns-CN9ra8Kh.js";
|
|
@@ -3365,20 +3365,6 @@ function relocateFaceGroups(faceGroups, innerHashes, placedHashes) {
|
|
|
3365
3365
|
faceId: remap.get(g.faceId) ?? g.faceId
|
|
3366
3366
|
}));
|
|
3367
3367
|
}
|
|
3368
|
-
var SCALE_INVARIANT_DIAGONAL = 10;
|
|
3369
|
-
function scaleDefaultTolerance(base, shape) {
|
|
3370
|
-
let diagonal;
|
|
3371
|
-
try {
|
|
3372
|
-
const b = getBounds(shape);
|
|
3373
|
-
const dx = b.xMax - b.xMin;
|
|
3374
|
-
const dy = b.yMax - b.yMin;
|
|
3375
|
-
const dz = b.zMax - b.zMin;
|
|
3376
|
-
diagonal = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
3377
|
-
} catch {
|
|
3378
|
-
return base;
|
|
3379
|
-
}
|
|
3380
|
-
return base * Math.max(1, diagonal / SCALE_INVARIANT_DIAGONAL);
|
|
3381
|
-
}
|
|
3382
3368
|
var Evaluator = class {
|
|
3383
3369
|
cache = /* @__PURE__ */ new Map();
|
|
3384
3370
|
refCounts = /* @__PURE__ */ new Map();
|
|
@@ -3616,13 +3602,165 @@ function withEvaluator(options, fn) {
|
|
|
3616
3602
|
_usingCtx$4.d();
|
|
3617
3603
|
}
|
|
3618
3604
|
}
|
|
3605
|
+
//#endregion
|
|
3606
|
+
//#region src/csg/edit.ts
|
|
3607
|
+
function replaceNode(root, pred, replacement) {
|
|
3608
|
+
return walk(root, pred, replacement, /* @__PURE__ */ new Map());
|
|
3609
|
+
}
|
|
3610
|
+
function walk(node, pred, repl, memo) {
|
|
3611
|
+
const cached = memo.get(node);
|
|
3612
|
+
if (cached !== void 0) return cached;
|
|
3613
|
+
const out = pred(node) ? repl : rebuildChildren(node, pred, repl, memo);
|
|
3614
|
+
memo.set(node, out);
|
|
3615
|
+
return out;
|
|
3616
|
+
}
|
|
3617
|
+
function rebuildChildren(n, pred, repl, memo) {
|
|
3618
|
+
switch (n.kind) {
|
|
3619
|
+
case "Box":
|
|
3620
|
+
case "Sphere":
|
|
3621
|
+
case "Cylinder":
|
|
3622
|
+
case "Cone":
|
|
3623
|
+
case "Torus":
|
|
3624
|
+
case "Polygon":
|
|
3625
|
+
case "Circle":
|
|
3626
|
+
case "Line":
|
|
3627
|
+
case "Vertex":
|
|
3628
|
+
case "Empty":
|
|
3629
|
+
case "Path":
|
|
3630
|
+
case "Profile": return n;
|
|
3631
|
+
case "Fuse": return fuse$1(walk(n.a, pred, repl, memo), walk(n.b, pred, repl, memo), n.tolerance);
|
|
3632
|
+
case "Cut": return cut$1(walk(n.a, pred, repl, memo), walk(n.b, pred, repl, memo), n.tolerance);
|
|
3633
|
+
case "Intersect": return intersect$1(walk(n.a, pred, repl, memo), walk(n.b, pred, repl, memo), n.tolerance);
|
|
3634
|
+
case "FuseAll": return fuseAll$1(n.shapes.map((c) => walk(c, pred, repl, memo)), n.tolerance);
|
|
3635
|
+
case "CutAll": return cutAll$1(walk(n.base, pred, repl, memo), n.tools.map((c) => walk(c, pred, repl, memo)), n.tolerance);
|
|
3636
|
+
case "Translate": return translate$1(walk(n.target, pred, repl, memo), n.vector);
|
|
3637
|
+
case "Rotate": return rotate$1(walk(n.target, pred, repl, memo), n.angle, {
|
|
3638
|
+
axis: n.axis,
|
|
3639
|
+
at: n.at
|
|
3640
|
+
});
|
|
3641
|
+
case "Scale": return scale$2(walk(n.target, pred, repl, memo), n.factor, { center: n.center });
|
|
3642
|
+
case "Mirror": return mirror$1(walk(n.target, pred, repl, memo), {
|
|
3643
|
+
normal: n.normal,
|
|
3644
|
+
at: n.at
|
|
3645
|
+
});
|
|
3646
|
+
case "Compound": return compound$1(n.children.map((c) => walk(c, pred, repl, memo)));
|
|
3647
|
+
case "Instance": return instance$1(walk(n.source, pred, repl, memo), n.placements, n.fuse);
|
|
3648
|
+
case "Extrude":
|
|
3649
|
+
case "Revolve":
|
|
3650
|
+
case "Loft":
|
|
3651
|
+
case "Sweep":
|
|
3652
|
+
case "Color":
|
|
3653
|
+
case "Fillet":
|
|
3654
|
+
case "Chamfer":
|
|
3655
|
+
case "Shell": return rebuildFeature(n, pred, repl, memo);
|
|
3656
|
+
}
|
|
3657
|
+
}
|
|
3658
|
+
function rebuildFeature(n, pred, repl, memo) {
|
|
3659
|
+
switch (n.kind) {
|
|
3660
|
+
case "Extrude": return extrude$1(walk(n.profile, pred, repl, memo), n.vector);
|
|
3661
|
+
case "Revolve": return revolve$1(walk(n.profile, pred, repl, memo), n.angle, {
|
|
3662
|
+
axis: n.axis,
|
|
3663
|
+
at: n.at
|
|
3664
|
+
});
|
|
3665
|
+
case "Loft": return loft$1(n.sections.map((s) => walk(s, pred, repl, memo)), { ruled: n.ruled });
|
|
3666
|
+
case "Sweep": return sweep$2(walk(n.profile, pred, repl, memo), walk(n.spine, pred, repl, memo), { frenet: n.frenet });
|
|
3667
|
+
case "Color": return color(walk(n.target, pred, repl, memo), [...n.color]);
|
|
3668
|
+
case "Fillet": return fillet$1(walk(n.target, pred, repl, memo), n.ref, n.radius);
|
|
3669
|
+
case "Chamfer": return chamfer$1(walk(n.target, pred, repl, memo), n.ref, n.distance);
|
|
3670
|
+
case "Shell": return shell$1(walk(n.target, pred, repl, memo), n.refs, n.thickness);
|
|
3671
|
+
}
|
|
3672
|
+
}
|
|
3673
|
+
/** Visits each DISTINCT node once (identity-deduplicated), so a shared
|
|
3674
|
+
* subtree is reported once and a self-referencing DAG walks in linear time. */
|
|
3675
|
+
function forEachNode(root, fn) {
|
|
3676
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3677
|
+
const visit = (node) => {
|
|
3678
|
+
if (seen.has(node)) return;
|
|
3679
|
+
seen.add(node);
|
|
3680
|
+
fn(node);
|
|
3681
|
+
for (const child of childrenOf(node)) visit(child);
|
|
3682
|
+
};
|
|
3683
|
+
visit(root);
|
|
3684
|
+
}
|
|
3685
|
+
function childrenOf(n) {
|
|
3686
|
+
switch (n.kind) {
|
|
3687
|
+
case "Box":
|
|
3688
|
+
case "Sphere":
|
|
3689
|
+
case "Cylinder":
|
|
3690
|
+
case "Cone":
|
|
3691
|
+
case "Torus":
|
|
3692
|
+
case "Polygon":
|
|
3693
|
+
case "Circle":
|
|
3694
|
+
case "Line":
|
|
3695
|
+
case "Vertex":
|
|
3696
|
+
case "Empty":
|
|
3697
|
+
case "Path":
|
|
3698
|
+
case "Profile": return [];
|
|
3699
|
+
case "Fuse":
|
|
3700
|
+
case "Cut":
|
|
3701
|
+
case "Intersect": return [n.a, n.b];
|
|
3702
|
+
case "FuseAll": return n.shapes;
|
|
3703
|
+
case "CutAll": return [n.base, ...n.tools];
|
|
3704
|
+
case "Translate":
|
|
3705
|
+
case "Rotate":
|
|
3706
|
+
case "Scale":
|
|
3707
|
+
case "Mirror":
|
|
3708
|
+
case "Color":
|
|
3709
|
+
case "Fillet":
|
|
3710
|
+
case "Chamfer":
|
|
3711
|
+
case "Shell": return [n.target];
|
|
3712
|
+
case "Compound": return n.children;
|
|
3713
|
+
case "Instance": return [n.source];
|
|
3714
|
+
case "Extrude":
|
|
3715
|
+
case "Revolve": return [n.profile];
|
|
3716
|
+
case "Loft": return n.sections;
|
|
3717
|
+
case "Sweep": return [n.profile, n.spine];
|
|
3718
|
+
}
|
|
3719
|
+
}
|
|
3720
|
+
function nodeCount(root) {
|
|
3721
|
+
let n = 0;
|
|
3722
|
+
forEachNode(root, () => {
|
|
3723
|
+
n++;
|
|
3724
|
+
});
|
|
3725
|
+
return n;
|
|
3726
|
+
}
|
|
3619
3727
|
var MIN_CSG_VERSION = 1;
|
|
3620
3728
|
function toJSON(node) {
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3729
|
+
const ctx = {
|
|
3730
|
+
counts: countRefs(node),
|
|
3731
|
+
ids: /* @__PURE__ */ new Map(),
|
|
3732
|
+
defs: []
|
|
3733
|
+
};
|
|
3734
|
+
const root = emitNode(node, ctx);
|
|
3735
|
+
return ctx.defs.length > 0 ? {
|
|
3736
|
+
csgVersion: 8,
|
|
3737
|
+
defs: ctx.defs,
|
|
3738
|
+
root
|
|
3739
|
+
} : {
|
|
3740
|
+
csgVersion: 8,
|
|
3741
|
+
root
|
|
3624
3742
|
};
|
|
3625
3743
|
}
|
|
3744
|
+
function countRefs(root) {
|
|
3745
|
+
const counts = /* @__PURE__ */ new Map();
|
|
3746
|
+
const visit = (n) => {
|
|
3747
|
+
const seen = counts.get(n) ?? 0;
|
|
3748
|
+
counts.set(n, seen + 1);
|
|
3749
|
+
if (seen === 0) for (const child of childrenOf(n)) visit(child);
|
|
3750
|
+
};
|
|
3751
|
+
visit(root);
|
|
3752
|
+
return counts;
|
|
3753
|
+
}
|
|
3754
|
+
function emitNode(n, ctx) {
|
|
3755
|
+
if ((ctx.counts.get(n) ?? 0) < 2) return nodeToJson(n, ctx);
|
|
3756
|
+
const existing = ctx.ids.get(n);
|
|
3757
|
+
if (existing !== void 0) return { $ref: existing };
|
|
3758
|
+
const body = nodeToJson(n, ctx);
|
|
3759
|
+
const id = ctx.defs.length;
|
|
3760
|
+
ctx.defs.push(body);
|
|
3761
|
+
ctx.ids.set(n, id);
|
|
3762
|
+
return { $ref: id };
|
|
3763
|
+
}
|
|
3626
3764
|
function exprToJson(e) {
|
|
3627
3765
|
switch (e.kind) {
|
|
3628
3766
|
case "NumLit": return {
|
|
@@ -3720,25 +3858,25 @@ function primitiveToJson(n) {
|
|
|
3720
3858
|
default: return;
|
|
3721
3859
|
}
|
|
3722
3860
|
}
|
|
3723
|
-
function booleanToJson(n) {
|
|
3861
|
+
function booleanToJson(n, ctx) {
|
|
3724
3862
|
switch (n.kind) {
|
|
3725
3863
|
case "Fuse":
|
|
3726
3864
|
case "Cut":
|
|
3727
3865
|
case "Intersect": return {
|
|
3728
3866
|
kind: n.kind,
|
|
3729
|
-
a:
|
|
3730
|
-
b:
|
|
3867
|
+
a: emitNode(n.a, ctx),
|
|
3868
|
+
b: emitNode(n.b, ctx),
|
|
3731
3869
|
tolerance: n.tolerance
|
|
3732
3870
|
};
|
|
3733
3871
|
case "FuseAll": return {
|
|
3734
3872
|
kind: "FuseAll",
|
|
3735
|
-
shapes: n.shapes.map(
|
|
3873
|
+
shapes: n.shapes.map((s) => emitNode(s, ctx)),
|
|
3736
3874
|
tolerance: n.tolerance
|
|
3737
3875
|
};
|
|
3738
3876
|
case "CutAll": return {
|
|
3739
3877
|
kind: "CutAll",
|
|
3740
|
-
base:
|
|
3741
|
-
tools: n.tools.map(
|
|
3878
|
+
base: emitNode(n.base, ctx),
|
|
3879
|
+
tools: n.tools.map((t) => emitNode(t, ctx)),
|
|
3742
3880
|
tolerance: n.tolerance
|
|
3743
3881
|
};
|
|
3744
3882
|
default: return;
|
|
@@ -3805,103 +3943,108 @@ function contourToJson(c) {
|
|
|
3805
3943
|
segments: c.segments.map(segmentToJson)
|
|
3806
3944
|
};
|
|
3807
3945
|
}
|
|
3808
|
-
function transformToJson(n) {
|
|
3946
|
+
function transformToJson(n, ctx) {
|
|
3809
3947
|
switch (n.kind) {
|
|
3810
3948
|
case "Translate": return {
|
|
3811
3949
|
kind: "Translate",
|
|
3812
|
-
target:
|
|
3950
|
+
target: emitNode(n.target, ctx),
|
|
3813
3951
|
vector: exprToJson(n.vector)
|
|
3814
3952
|
};
|
|
3815
3953
|
case "Rotate": return {
|
|
3816
3954
|
kind: "Rotate",
|
|
3817
|
-
target:
|
|
3955
|
+
target: emitNode(n.target, ctx),
|
|
3818
3956
|
angle: exprToJson(n.angle),
|
|
3819
3957
|
axis: optExprToJson(n.axis),
|
|
3820
3958
|
at: optExprToJson(n.at)
|
|
3821
3959
|
};
|
|
3822
3960
|
case "Scale": return {
|
|
3823
3961
|
kind: "Scale",
|
|
3824
|
-
target:
|
|
3962
|
+
target: emitNode(n.target, ctx),
|
|
3825
3963
|
factor: exprToJson(n.factor),
|
|
3826
3964
|
center: optExprToJson(n.center)
|
|
3827
3965
|
};
|
|
3828
3966
|
case "Mirror": return {
|
|
3829
3967
|
kind: "Mirror",
|
|
3830
|
-
target:
|
|
3968
|
+
target: emitNode(n.target, ctx),
|
|
3831
3969
|
normal: optExprToJson(n.normal),
|
|
3832
3970
|
at: optExprToJson(n.at)
|
|
3833
3971
|
};
|
|
3834
3972
|
default: return;
|
|
3835
3973
|
}
|
|
3836
3974
|
}
|
|
3837
|
-
function
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3975
|
+
function featureToJson(n, ctx) {
|
|
3976
|
+
switch (n.kind) {
|
|
3977
|
+
case "Extrude": return {
|
|
3978
|
+
kind: "Extrude",
|
|
3979
|
+
profile: emitNode(n.profile, ctx),
|
|
3980
|
+
vector: exprToJson(n.vector)
|
|
3981
|
+
};
|
|
3982
|
+
case "Revolve": return {
|
|
3983
|
+
kind: "Revolve",
|
|
3984
|
+
profile: emitNode(n.profile, ctx),
|
|
3985
|
+
angle: exprToJson(n.angle),
|
|
3986
|
+
axis: optExprToJson(n.axis),
|
|
3987
|
+
at: optExprToJson(n.at)
|
|
3988
|
+
};
|
|
3989
|
+
case "Loft": return {
|
|
3990
|
+
kind: "Loft",
|
|
3991
|
+
sections: n.sections.map((s) => emitNode(s, ctx)),
|
|
3992
|
+
ruled: n.ruled
|
|
3993
|
+
};
|
|
3994
|
+
case "Path": return {
|
|
3995
|
+
kind: "Path",
|
|
3996
|
+
start: exprToJson(n.start),
|
|
3997
|
+
segments: n.segments.map(segmentToJson)
|
|
3998
|
+
};
|
|
3999
|
+
case "Sweep": return {
|
|
4000
|
+
kind: "Sweep",
|
|
4001
|
+
profile: emitNode(n.profile, ctx),
|
|
4002
|
+
spine: emitNode(n.spine, ctx),
|
|
4003
|
+
frenet: n.frenet
|
|
4004
|
+
};
|
|
4005
|
+
case "Profile": return {
|
|
4006
|
+
kind: "Profile",
|
|
4007
|
+
outline: contourToJson(n.outline),
|
|
4008
|
+
holes: n.holes.map(contourToJson)
|
|
4009
|
+
};
|
|
4010
|
+
default: return;
|
|
4011
|
+
}
|
|
4012
|
+
}
|
|
4013
|
+
function nodeToJson(n, ctx) {
|
|
3871
4014
|
if (n.kind === "Color") return {
|
|
3872
4015
|
kind: "Color",
|
|
3873
|
-
target:
|
|
4016
|
+
target: emitNode(n.target, ctx),
|
|
3874
4017
|
color: [...n.color]
|
|
3875
4018
|
};
|
|
3876
4019
|
if (n.kind === "Fillet") return {
|
|
3877
4020
|
kind: "Fillet",
|
|
3878
|
-
target:
|
|
4021
|
+
target: emitNode(n.target, ctx),
|
|
3879
4022
|
ref: edgeRefToJson(n.ref),
|
|
3880
4023
|
radius: exprToJson(n.radius)
|
|
3881
4024
|
};
|
|
3882
4025
|
if (n.kind === "Chamfer") return {
|
|
3883
4026
|
kind: "Chamfer",
|
|
3884
|
-
target:
|
|
4027
|
+
target: emitNode(n.target, ctx),
|
|
3885
4028
|
ref: edgeRefToJson(n.ref),
|
|
3886
4029
|
distance: exprToJson(n.distance)
|
|
3887
4030
|
};
|
|
3888
4031
|
if (n.kind === "Shell") return {
|
|
3889
4032
|
kind: "Shell",
|
|
3890
|
-
target:
|
|
4033
|
+
target: emitNode(n.target, ctx),
|
|
3891
4034
|
refs: n.refs.map(shapeRefToJson),
|
|
3892
4035
|
thickness: exprToJson(n.thickness)
|
|
3893
4036
|
};
|
|
3894
4037
|
if (n.kind === "Compound") return {
|
|
3895
4038
|
kind: "Compound",
|
|
3896
|
-
children: n.children.map(
|
|
4039
|
+
children: n.children.map((c) => emitNode(c, ctx))
|
|
3897
4040
|
};
|
|
3898
4041
|
if (n.kind === "Instance") return {
|
|
3899
4042
|
kind: "Instance",
|
|
3900
|
-
source:
|
|
4043
|
+
source: emitNode(n.source, ctx),
|
|
3901
4044
|
placements: n.placements,
|
|
3902
4045
|
fuse: n.fuse
|
|
3903
4046
|
};
|
|
3904
|
-
return primitiveToJson(n) ?? booleanToJson(n) ?? transformToJson(n);
|
|
4047
|
+
return featureToJson(n, ctx) ?? primitiveToJson(n) ?? booleanToJson(n, ctx) ?? transformToJson(n, ctx);
|
|
3905
4048
|
}
|
|
3906
4049
|
function bad(msg) {
|
|
3907
4050
|
return err(validationError(BrepErrorCode.NULL_SHAPE_INPUT, `csg.fromJSON: ${msg}`));
|
|
@@ -3934,9 +4077,18 @@ function readVec2(v, where) {
|
|
|
3934
4077
|
function fromJSON(envelope) {
|
|
3935
4078
|
if (!isObj(envelope)) return bad("input is not an object");
|
|
3936
4079
|
const v = envelope["csgVersion"];
|
|
3937
|
-
if (typeof v !== "number" || !Number.isInteger(v) || v < MIN_CSG_VERSION || v >
|
|
3938
|
-
const
|
|
3939
|
-
|
|
4080
|
+
if (typeof v !== "number" || !Number.isInteger(v) || v < MIN_CSG_VERSION || v > 8) return bad(`unsupported csgVersion ${String(v)} (expected ${MIN_CSG_VERSION}..8)`);
|
|
4081
|
+
const rawDefs = envelope["defs"];
|
|
4082
|
+
const defs = [];
|
|
4083
|
+
if (rawDefs !== void 0) {
|
|
4084
|
+
if (!Array.isArray(rawDefs)) return bad("defs: not an array");
|
|
4085
|
+
for (const raw of rawDefs) {
|
|
4086
|
+
const r = readNode(raw, defs);
|
|
4087
|
+
if (!r.ok) return r;
|
|
4088
|
+
defs.push(r.value);
|
|
4089
|
+
}
|
|
4090
|
+
}
|
|
4091
|
+
return readNode(envelope["root"], defs);
|
|
3940
4092
|
}
|
|
3941
4093
|
function readExpr(j) {
|
|
3942
4094
|
if (!isObj(j)) return bad("expression: not an object");
|
|
@@ -4002,11 +4154,11 @@ function readBuildVec(j) {
|
|
|
4002
4154
|
}
|
|
4003
4155
|
return ok(buildVec(dim, out));
|
|
4004
4156
|
}
|
|
4005
|
-
function readNodeArray(j, where) {
|
|
4157
|
+
function readNodeArray(j, where, defs) {
|
|
4006
4158
|
if (!Array.isArray(j)) return bad(`${where}: not array`);
|
|
4007
4159
|
const out = [];
|
|
4008
4160
|
for (const c of j) {
|
|
4009
|
-
const r = readNode(c);
|
|
4161
|
+
const r = readNode(c, defs);
|
|
4010
4162
|
if (!r.ok) return r;
|
|
4011
4163
|
out.push(r.value);
|
|
4012
4164
|
}
|
|
@@ -4017,8 +4169,15 @@ function readOptTolerance(j) {
|
|
|
4017
4169
|
if (t === void 0 || t === null) return ok(void 0);
|
|
4018
4170
|
return isNumber$1(t) ? ok(t) : bad("tolerance: not a finite number");
|
|
4019
4171
|
}
|
|
4020
|
-
function readNode(j) {
|
|
4172
|
+
function readNode(j, defs) {
|
|
4021
4173
|
if (!isObj(j)) return bad("node: not an object");
|
|
4174
|
+
const ref = j["$ref"];
|
|
4175
|
+
if (ref !== void 0) {
|
|
4176
|
+
if (!isNumber$1(ref) || !Number.isInteger(ref) || ref < 0) return bad("$ref: expected a non-negative integer def index");
|
|
4177
|
+
const node = defs[ref];
|
|
4178
|
+
if (node === void 0) return bad(`$ref: ${ref} is out of range (forward refs are rejected)`);
|
|
4179
|
+
return ok(node);
|
|
4180
|
+
}
|
|
4022
4181
|
const kind = j["kind"];
|
|
4023
4182
|
switch (kind) {
|
|
4024
4183
|
case "Box":
|
|
@@ -4033,25 +4192,25 @@ function readNode(j) {
|
|
|
4033
4192
|
case "Empty": return readPrimitive(kind, j);
|
|
4034
4193
|
case "Fuse":
|
|
4035
4194
|
case "Cut":
|
|
4036
|
-
case "Intersect": return readBinaryBool(kind, j);
|
|
4195
|
+
case "Intersect": return readBinaryBool(kind, j, defs);
|
|
4037
4196
|
case "FuseAll":
|
|
4038
|
-
case "CutAll": return readNaryBool(kind, j);
|
|
4197
|
+
case "CutAll": return readNaryBool(kind, j, defs);
|
|
4039
4198
|
case "Translate":
|
|
4040
4199
|
case "Rotate":
|
|
4041
4200
|
case "Scale":
|
|
4042
|
-
case "Mirror": return readTransform(kind, j);
|
|
4043
|
-
case "Compound": return readCompound(j);
|
|
4044
|
-
case "Instance": return readInstance(j);
|
|
4045
|
-
case "Extrude": return readExtrude(j);
|
|
4046
|
-
case "Revolve": return readRevolve(j);
|
|
4047
|
-
case "Loft": return readLoft(j);
|
|
4201
|
+
case "Mirror": return readTransform(kind, j, defs);
|
|
4202
|
+
case "Compound": return readCompound(j, defs);
|
|
4203
|
+
case "Instance": return readInstance(j, defs);
|
|
4204
|
+
case "Extrude": return readExtrude(j, defs);
|
|
4205
|
+
case "Revolve": return readRevolve(j, defs);
|
|
4206
|
+
case "Loft": return readLoft(j, defs);
|
|
4048
4207
|
case "Path": return readPath(j);
|
|
4049
|
-
case "Sweep": return readSweep(j);
|
|
4208
|
+
case "Sweep": return readSweep(j, defs);
|
|
4050
4209
|
case "Profile": return readProfile(j);
|
|
4051
|
-
case "Color": return readColor(j);
|
|
4052
|
-
case "Fillet": return readFillet(j);
|
|
4053
|
-
case "Chamfer": return readChamfer(j);
|
|
4054
|
-
case "Shell": return readShell(j);
|
|
4210
|
+
case "Color": return readColor(j, defs);
|
|
4211
|
+
case "Fillet": return readFillet(j, defs);
|
|
4212
|
+
case "Chamfer": return readChamfer(j, defs);
|
|
4213
|
+
case "Shell": return readShell(j, defs);
|
|
4055
4214
|
default: return bad(`unknown node kind: ${String(kind)}`);
|
|
4056
4215
|
}
|
|
4057
4216
|
}
|
|
@@ -4133,10 +4292,10 @@ function readEmpty(j) {
|
|
|
4133
4292
|
default: return bad(`Empty.output: ${String(out)}`);
|
|
4134
4293
|
}
|
|
4135
4294
|
}
|
|
4136
|
-
function readBinaryBool(kind, j) {
|
|
4137
|
-
const a = readNode(j["a"]);
|
|
4295
|
+
function readBinaryBool(kind, j, defs) {
|
|
4296
|
+
const a = readNode(j["a"], defs);
|
|
4138
4297
|
if (!a.ok) return a;
|
|
4139
|
-
const b = readNode(j["b"]);
|
|
4298
|
+
const b = readNode(j["b"], defs);
|
|
4140
4299
|
if (!b.ok) return b;
|
|
4141
4300
|
const t = readOptTolerance(j);
|
|
4142
4301
|
if (!t.ok) return t;
|
|
@@ -4146,20 +4305,20 @@ function readBinaryBool(kind, j) {
|
|
|
4146
4305
|
case "Intersect": return ok(intersect$1(a.value, b.value, t.value));
|
|
4147
4306
|
}
|
|
4148
4307
|
}
|
|
4149
|
-
function readNaryBool(kind, j) {
|
|
4308
|
+
function readNaryBool(kind, j, defs) {
|
|
4150
4309
|
const t = readOptTolerance(j);
|
|
4151
4310
|
if (!t.ok) return t;
|
|
4152
4311
|
if (kind === "FuseAll") {
|
|
4153
|
-
const shapes = readNodeArray(j["shapes"], "FuseAll.shapes");
|
|
4312
|
+
const shapes = readNodeArray(j["shapes"], "FuseAll.shapes", defs);
|
|
4154
4313
|
return shapes.ok ? ok(fuseAll$1(shapes.value, t.value)) : shapes;
|
|
4155
4314
|
}
|
|
4156
|
-
const base = readNode(j["base"]);
|
|
4315
|
+
const base = readNode(j["base"], defs);
|
|
4157
4316
|
if (!base.ok) return base;
|
|
4158
|
-
const tools = readNodeArray(j["tools"], "CutAll.tools");
|
|
4317
|
+
const tools = readNodeArray(j["tools"], "CutAll.tools", defs);
|
|
4159
4318
|
return tools.ok ? ok(cutAll$1(base.value, tools.value, t.value)) : tools;
|
|
4160
4319
|
}
|
|
4161
|
-
function readTransform(kind, j) {
|
|
4162
|
-
const tgt = readNode(j["target"]);
|
|
4320
|
+
function readTransform(kind, j, defs) {
|
|
4321
|
+
const tgt = readNode(j["target"], defs);
|
|
4163
4322
|
if (!tgt.ok) return tgt;
|
|
4164
4323
|
switch (kind) {
|
|
4165
4324
|
case "Translate": return readTranslate(j, tgt.value);
|
|
@@ -4206,15 +4365,15 @@ function readMirror(j, target) {
|
|
|
4206
4365
|
at: at.value
|
|
4207
4366
|
}));
|
|
4208
4367
|
}
|
|
4209
|
-
function readExtrude(j) {
|
|
4210
|
-
const profile = readNode(j["profile"]);
|
|
4368
|
+
function readExtrude(j, defs) {
|
|
4369
|
+
const profile = readNode(j["profile"], defs);
|
|
4211
4370
|
if (!profile.ok) return profile;
|
|
4212
4371
|
const vector = readExpr(j["vector"]);
|
|
4213
4372
|
if (!vector.ok) return vector;
|
|
4214
4373
|
return ok(extrude$1(profile.value, vector.value));
|
|
4215
4374
|
}
|
|
4216
|
-
function readRevolve(j) {
|
|
4217
|
-
const profile = readNode(j["profile"]);
|
|
4375
|
+
function readRevolve(j, defs) {
|
|
4376
|
+
const profile = readNode(j["profile"], defs);
|
|
4218
4377
|
if (!profile.ok) return profile;
|
|
4219
4378
|
const angle = readExpr(j["angle"]);
|
|
4220
4379
|
if (!angle.ok) return angle;
|
|
@@ -4227,8 +4386,8 @@ function readRevolve(j) {
|
|
|
4227
4386
|
at: at.value
|
|
4228
4387
|
}));
|
|
4229
4388
|
}
|
|
4230
|
-
function readLoft(j) {
|
|
4231
|
-
const sections = readNodeArray(j["sections"], "Loft.sections");
|
|
4389
|
+
function readLoft(j, defs) {
|
|
4390
|
+
const sections = readNodeArray(j["sections"], "Loft.sections", defs);
|
|
4232
4391
|
if (!sections.ok) return sections;
|
|
4233
4392
|
const ruled = j["ruled"];
|
|
4234
4393
|
if (ruled !== void 0 && typeof ruled !== "boolean") return bad("Loft.ruled: not a boolean");
|
|
@@ -4376,8 +4535,8 @@ function readShapeRef(j, where) {
|
|
|
4376
4535
|
}
|
|
4377
4536
|
});
|
|
4378
4537
|
}
|
|
4379
|
-
function readShell(j) {
|
|
4380
|
-
const target = readNode(j["target"]);
|
|
4538
|
+
function readShell(j, defs) {
|
|
4539
|
+
const target = readNode(j["target"], defs);
|
|
4381
4540
|
if (!target.ok) return target;
|
|
4382
4541
|
const thickness = readExpr(j["thickness"]);
|
|
4383
4542
|
if (!thickness.ok) return thickness;
|
|
@@ -4391,8 +4550,8 @@ function readShell(j) {
|
|
|
4391
4550
|
}
|
|
4392
4551
|
return ok(shell$1(target.value, refs, thickness.value));
|
|
4393
4552
|
}
|
|
4394
|
-
function readFillet(j) {
|
|
4395
|
-
const target = readNode(j["target"]);
|
|
4553
|
+
function readFillet(j, defs) {
|
|
4554
|
+
const target = readNode(j["target"], defs);
|
|
4396
4555
|
if (!target.ok) return target;
|
|
4397
4556
|
const radius = readExpr(j["radius"]);
|
|
4398
4557
|
if (!radius.ok) return radius;
|
|
@@ -4400,8 +4559,8 @@ function readFillet(j) {
|
|
|
4400
4559
|
if (!ref.ok) return ref;
|
|
4401
4560
|
return ok(fillet$1(target.value, ref.value, radius.value));
|
|
4402
4561
|
}
|
|
4403
|
-
function readChamfer(j) {
|
|
4404
|
-
const target = readNode(j["target"]);
|
|
4562
|
+
function readChamfer(j, defs) {
|
|
4563
|
+
const target = readNode(j["target"], defs);
|
|
4405
4564
|
if (!target.ok) return target;
|
|
4406
4565
|
const distance = readExpr(j["distance"]);
|
|
4407
4566
|
if (!distance.ok) return distance;
|
|
@@ -4409,8 +4568,8 @@ function readChamfer(j) {
|
|
|
4409
4568
|
if (!ref.ok) return ref;
|
|
4410
4569
|
return ok(chamfer$1(target.value, ref.value, distance.value));
|
|
4411
4570
|
}
|
|
4412
|
-
function readColor(j) {
|
|
4413
|
-
const target = readNode(j["target"]);
|
|
4571
|
+
function readColor(j, defs) {
|
|
4572
|
+
const target = readNode(j["target"], defs);
|
|
4414
4573
|
if (!target.ok) return target;
|
|
4415
4574
|
const c = j["color"];
|
|
4416
4575
|
if (!Array.isArray(c) || c.length !== 4 || !c.every((v) => isNumber$1(v) && v >= 0 && v <= 1)) return bad("Color.color: expected an RGBA array of 4 numbers in [0, 1]");
|
|
@@ -4434,10 +4593,10 @@ function readProfile(j) {
|
|
|
4434
4593
|
}
|
|
4435
4594
|
return ok(profile(outline.value, holes));
|
|
4436
4595
|
}
|
|
4437
|
-
function readSweep(j) {
|
|
4438
|
-
const profile = readNode(j["profile"]);
|
|
4596
|
+
function readSweep(j, defs) {
|
|
4597
|
+
const profile = readNode(j["profile"], defs);
|
|
4439
4598
|
if (!profile.ok) return profile;
|
|
4440
|
-
const spine = readNode(j["spine"]);
|
|
4599
|
+
const spine = readNode(j["spine"], defs);
|
|
4441
4600
|
if (!spine.ok) return spine;
|
|
4442
4601
|
const frenet = readFlag(j, "frenet");
|
|
4443
4602
|
if (!frenet.ok) return frenet;
|
|
@@ -4456,15 +4615,15 @@ function readPath(j) {
|
|
|
4456
4615
|
}
|
|
4457
4616
|
return ok(path(start.value, segments));
|
|
4458
4617
|
}
|
|
4459
|
-
function readCompound(j) {
|
|
4460
|
-
const children = readNodeArray(j["children"], "Compound.children");
|
|
4618
|
+
function readCompound(j, defs) {
|
|
4619
|
+
const children = readNodeArray(j["children"], "Compound.children", defs);
|
|
4461
4620
|
return children.ok ? ok(compound$1(children.value)) : children;
|
|
4462
4621
|
}
|
|
4463
4622
|
function isMatrix4x4(v) {
|
|
4464
4623
|
return Array.isArray(v) && v.length === 4 && v.every((row) => Array.isArray(row) && row.length === 4 && row.every(isNumber$1));
|
|
4465
4624
|
}
|
|
4466
|
-
function readInstance(j) {
|
|
4467
|
-
const source = readNode(j["source"]);
|
|
4625
|
+
function readInstance(j, defs) {
|
|
4626
|
+
const source = readNode(j["source"], defs);
|
|
4468
4627
|
if (!source.ok) return source;
|
|
4469
4628
|
const placements = j["placements"];
|
|
4470
4629
|
if (!Array.isArray(placements) || !placements.every(isMatrix4x4)) return bad("Instance.placements must be an array of 4x4 number matrices");
|
|
@@ -4662,128 +4821,6 @@ function optimizeTranslate(target, vector) {
|
|
|
4662
4821
|
return translate$1(ot, ov);
|
|
4663
4822
|
}
|
|
4664
4823
|
//#endregion
|
|
4665
|
-
//#region src/csg/edit.ts
|
|
4666
|
-
function replaceNode(root, pred, replacement) {
|
|
4667
|
-
return walk(root, pred, replacement, /* @__PURE__ */ new Map());
|
|
4668
|
-
}
|
|
4669
|
-
function walk(node, pred, repl, memo) {
|
|
4670
|
-
const cached = memo.get(node);
|
|
4671
|
-
if (cached !== void 0) return cached;
|
|
4672
|
-
const out = pred(node) ? repl : rebuildChildren(node, pred, repl, memo);
|
|
4673
|
-
memo.set(node, out);
|
|
4674
|
-
return out;
|
|
4675
|
-
}
|
|
4676
|
-
function rebuildChildren(n, pred, repl, memo) {
|
|
4677
|
-
switch (n.kind) {
|
|
4678
|
-
case "Box":
|
|
4679
|
-
case "Sphere":
|
|
4680
|
-
case "Cylinder":
|
|
4681
|
-
case "Cone":
|
|
4682
|
-
case "Torus":
|
|
4683
|
-
case "Polygon":
|
|
4684
|
-
case "Circle":
|
|
4685
|
-
case "Line":
|
|
4686
|
-
case "Vertex":
|
|
4687
|
-
case "Empty":
|
|
4688
|
-
case "Path":
|
|
4689
|
-
case "Profile": return n;
|
|
4690
|
-
case "Fuse": return fuse$1(walk(n.a, pred, repl, memo), walk(n.b, pred, repl, memo), n.tolerance);
|
|
4691
|
-
case "Cut": return cut$1(walk(n.a, pred, repl, memo), walk(n.b, pred, repl, memo), n.tolerance);
|
|
4692
|
-
case "Intersect": return intersect$1(walk(n.a, pred, repl, memo), walk(n.b, pred, repl, memo), n.tolerance);
|
|
4693
|
-
case "FuseAll": return fuseAll$1(n.shapes.map((c) => walk(c, pred, repl, memo)), n.tolerance);
|
|
4694
|
-
case "CutAll": return cutAll$1(walk(n.base, pred, repl, memo), n.tools.map((c) => walk(c, pred, repl, memo)), n.tolerance);
|
|
4695
|
-
case "Translate": return translate$1(walk(n.target, pred, repl, memo), n.vector);
|
|
4696
|
-
case "Rotate": return rotate$1(walk(n.target, pred, repl, memo), n.angle, {
|
|
4697
|
-
axis: n.axis,
|
|
4698
|
-
at: n.at
|
|
4699
|
-
});
|
|
4700
|
-
case "Scale": return scale$2(walk(n.target, pred, repl, memo), n.factor, { center: n.center });
|
|
4701
|
-
case "Mirror": return mirror$1(walk(n.target, pred, repl, memo), {
|
|
4702
|
-
normal: n.normal,
|
|
4703
|
-
at: n.at
|
|
4704
|
-
});
|
|
4705
|
-
case "Compound": return compound$1(n.children.map((c) => walk(c, pred, repl, memo)));
|
|
4706
|
-
case "Instance": return instance$1(walk(n.source, pred, repl, memo), n.placements, n.fuse);
|
|
4707
|
-
case "Extrude":
|
|
4708
|
-
case "Revolve":
|
|
4709
|
-
case "Loft":
|
|
4710
|
-
case "Sweep":
|
|
4711
|
-
case "Color":
|
|
4712
|
-
case "Fillet":
|
|
4713
|
-
case "Chamfer":
|
|
4714
|
-
case "Shell": return rebuildFeature(n, pred, repl, memo);
|
|
4715
|
-
}
|
|
4716
|
-
}
|
|
4717
|
-
function rebuildFeature(n, pred, repl, memo) {
|
|
4718
|
-
switch (n.kind) {
|
|
4719
|
-
case "Extrude": return extrude$1(walk(n.profile, pred, repl, memo), n.vector);
|
|
4720
|
-
case "Revolve": return revolve$1(walk(n.profile, pred, repl, memo), n.angle, {
|
|
4721
|
-
axis: n.axis,
|
|
4722
|
-
at: n.at
|
|
4723
|
-
});
|
|
4724
|
-
case "Loft": return loft$1(n.sections.map((s) => walk(s, pred, repl, memo)), { ruled: n.ruled });
|
|
4725
|
-
case "Sweep": return sweep$2(walk(n.profile, pred, repl, memo), walk(n.spine, pred, repl, memo), { frenet: n.frenet });
|
|
4726
|
-
case "Color": return color(walk(n.target, pred, repl, memo), [...n.color]);
|
|
4727
|
-
case "Fillet": return fillet$1(walk(n.target, pred, repl, memo), n.ref, n.radius);
|
|
4728
|
-
case "Chamfer": return chamfer$1(walk(n.target, pred, repl, memo), n.ref, n.distance);
|
|
4729
|
-
case "Shell": return shell$1(walk(n.target, pred, repl, memo), n.refs, n.thickness);
|
|
4730
|
-
}
|
|
4731
|
-
}
|
|
4732
|
-
/** Visits each DISTINCT node once (identity-deduplicated), so a shared
|
|
4733
|
-
* subtree is reported once and a self-referencing DAG walks in linear time. */
|
|
4734
|
-
function forEachNode(root, fn) {
|
|
4735
|
-
const seen = /* @__PURE__ */ new Set();
|
|
4736
|
-
const visit = (node) => {
|
|
4737
|
-
if (seen.has(node)) return;
|
|
4738
|
-
seen.add(node);
|
|
4739
|
-
fn(node);
|
|
4740
|
-
for (const child of childrenOf(node)) visit(child);
|
|
4741
|
-
};
|
|
4742
|
-
visit(root);
|
|
4743
|
-
}
|
|
4744
|
-
function childrenOf(n) {
|
|
4745
|
-
switch (n.kind) {
|
|
4746
|
-
case "Box":
|
|
4747
|
-
case "Sphere":
|
|
4748
|
-
case "Cylinder":
|
|
4749
|
-
case "Cone":
|
|
4750
|
-
case "Torus":
|
|
4751
|
-
case "Polygon":
|
|
4752
|
-
case "Circle":
|
|
4753
|
-
case "Line":
|
|
4754
|
-
case "Vertex":
|
|
4755
|
-
case "Empty":
|
|
4756
|
-
case "Path":
|
|
4757
|
-
case "Profile": return [];
|
|
4758
|
-
case "Fuse":
|
|
4759
|
-
case "Cut":
|
|
4760
|
-
case "Intersect": return [n.a, n.b];
|
|
4761
|
-
case "FuseAll": return n.shapes;
|
|
4762
|
-
case "CutAll": return [n.base, ...n.tools];
|
|
4763
|
-
case "Translate":
|
|
4764
|
-
case "Rotate":
|
|
4765
|
-
case "Scale":
|
|
4766
|
-
case "Mirror":
|
|
4767
|
-
case "Color":
|
|
4768
|
-
case "Fillet":
|
|
4769
|
-
case "Chamfer":
|
|
4770
|
-
case "Shell": return [n.target];
|
|
4771
|
-
case "Compound": return n.children;
|
|
4772
|
-
case "Instance": return [n.source];
|
|
4773
|
-
case "Extrude":
|
|
4774
|
-
case "Revolve": return [n.profile];
|
|
4775
|
-
case "Loft": return n.sections;
|
|
4776
|
-
case "Sweep": return [n.profile, n.spine];
|
|
4777
|
-
}
|
|
4778
|
-
}
|
|
4779
|
-
function nodeCount(root) {
|
|
4780
|
-
let n = 0;
|
|
4781
|
-
forEachNode(root, () => {
|
|
4782
|
-
n++;
|
|
4783
|
-
});
|
|
4784
|
-
return n;
|
|
4785
|
-
}
|
|
4786
|
-
//#endregion
|
|
4787
4824
|
//#region src/sketching/blueprintContourFns.ts
|
|
4788
4825
|
var EPS$1 = 1e-6;
|
|
4789
4826
|
function p2(p) {
|
|
@@ -8741,7 +8778,7 @@ var patterns_exports = /* @__PURE__ */ __exportAll({
|
|
|
8741
8778
|
//#endregion
|
|
8742
8779
|
//#region src/ns/csg.ts
|
|
8743
8780
|
var csg_exports = /* @__PURE__ */ __exportAll({
|
|
8744
|
-
CSG_VERSION: () =>
|
|
8781
|
+
CSG_VERSION: () => 8,
|
|
8745
8782
|
Evaluator: () => Evaluator,
|
|
8746
8783
|
add: () => add$1,
|
|
8747
8784
|
arbitraryClosedProfile: () => arbitraryClosedProfile,
|