brepjs 18.153.0 → 18.155.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 +278 -227
- package/dist/brepjs.js +278 -227
- package/dist/csg/edit.d.ts +1 -0
- package/dist/csg/serialize.d.ts +2 -1
- package/package.json +1 -1
package/dist/brepjs.cjs
CHANGED
|
@@ -3606,12 +3606,164 @@ function withEvaluator(options, fn) {
|
|
|
3606
3606
|
_usingCtx$4.d();
|
|
3607
3607
|
}
|
|
3608
3608
|
}
|
|
3609
|
+
//#endregion
|
|
3610
|
+
//#region src/csg/edit.ts
|
|
3611
|
+
function replaceNode(root, pred, replacement) {
|
|
3612
|
+
return walk(root, pred, replacement, /* @__PURE__ */ new Map());
|
|
3613
|
+
}
|
|
3614
|
+
function walk(node, pred, repl, memo) {
|
|
3615
|
+
const cached = memo.get(node);
|
|
3616
|
+
if (cached !== void 0) return cached;
|
|
3617
|
+
const out = pred(node) ? repl : rebuildChildren(node, pred, repl, memo);
|
|
3618
|
+
memo.set(node, out);
|
|
3619
|
+
return out;
|
|
3620
|
+
}
|
|
3621
|
+
function rebuildChildren(n, pred, repl, memo) {
|
|
3622
|
+
switch (n.kind) {
|
|
3623
|
+
case "Box":
|
|
3624
|
+
case "Sphere":
|
|
3625
|
+
case "Cylinder":
|
|
3626
|
+
case "Cone":
|
|
3627
|
+
case "Torus":
|
|
3628
|
+
case "Polygon":
|
|
3629
|
+
case "Circle":
|
|
3630
|
+
case "Line":
|
|
3631
|
+
case "Vertex":
|
|
3632
|
+
case "Empty":
|
|
3633
|
+
case "Path":
|
|
3634
|
+
case "Profile": return n;
|
|
3635
|
+
case "Fuse": return fuse$1(walk(n.a, pred, repl, memo), walk(n.b, pred, repl, memo), n.tolerance);
|
|
3636
|
+
case "Cut": return cut$1(walk(n.a, pred, repl, memo), walk(n.b, pred, repl, memo), n.tolerance);
|
|
3637
|
+
case "Intersect": return intersect$1(walk(n.a, pred, repl, memo), walk(n.b, pred, repl, memo), n.tolerance);
|
|
3638
|
+
case "FuseAll": return fuseAll$1(n.shapes.map((c) => walk(c, pred, repl, memo)), n.tolerance);
|
|
3639
|
+
case "CutAll": return cutAll$1(walk(n.base, pred, repl, memo), n.tools.map((c) => walk(c, pred, repl, memo)), n.tolerance);
|
|
3640
|
+
case "Translate": return translate$1(walk(n.target, pred, repl, memo), n.vector);
|
|
3641
|
+
case "Rotate": return rotate$1(walk(n.target, pred, repl, memo), n.angle, {
|
|
3642
|
+
axis: n.axis,
|
|
3643
|
+
at: n.at
|
|
3644
|
+
});
|
|
3645
|
+
case "Scale": return scale$2(walk(n.target, pred, repl, memo), n.factor, { center: n.center });
|
|
3646
|
+
case "Mirror": return mirror$1(walk(n.target, pred, repl, memo), {
|
|
3647
|
+
normal: n.normal,
|
|
3648
|
+
at: n.at
|
|
3649
|
+
});
|
|
3650
|
+
case "Compound": return compound$1(n.children.map((c) => walk(c, pred, repl, memo)));
|
|
3651
|
+
case "Instance": return instance$1(walk(n.source, pred, repl, memo), n.placements, n.fuse);
|
|
3652
|
+
case "Extrude":
|
|
3653
|
+
case "Revolve":
|
|
3654
|
+
case "Loft":
|
|
3655
|
+
case "Sweep":
|
|
3656
|
+
case "Color":
|
|
3657
|
+
case "Fillet":
|
|
3658
|
+
case "Chamfer":
|
|
3659
|
+
case "Shell": return rebuildFeature(n, pred, repl, memo);
|
|
3660
|
+
}
|
|
3661
|
+
}
|
|
3662
|
+
function rebuildFeature(n, pred, repl, memo) {
|
|
3663
|
+
switch (n.kind) {
|
|
3664
|
+
case "Extrude": return extrude$1(walk(n.profile, pred, repl, memo), n.vector);
|
|
3665
|
+
case "Revolve": return revolve$1(walk(n.profile, pred, repl, memo), n.angle, {
|
|
3666
|
+
axis: n.axis,
|
|
3667
|
+
at: n.at
|
|
3668
|
+
});
|
|
3669
|
+
case "Loft": return loft$1(n.sections.map((s) => walk(s, pred, repl, memo)), { ruled: n.ruled });
|
|
3670
|
+
case "Sweep": return sweep$2(walk(n.profile, pred, repl, memo), walk(n.spine, pred, repl, memo), { frenet: n.frenet });
|
|
3671
|
+
case "Color": return color(walk(n.target, pred, repl, memo), [...n.color]);
|
|
3672
|
+
case "Fillet": return fillet$1(walk(n.target, pred, repl, memo), n.ref, n.radius);
|
|
3673
|
+
case "Chamfer": return chamfer$1(walk(n.target, pred, repl, memo), n.ref, n.distance);
|
|
3674
|
+
case "Shell": return shell$1(walk(n.target, pred, repl, memo), n.refs, n.thickness);
|
|
3675
|
+
}
|
|
3676
|
+
}
|
|
3677
|
+
/** Visits each DISTINCT node once (identity-deduplicated), so a shared
|
|
3678
|
+
* subtree is reported once and a self-referencing DAG walks in linear time. */
|
|
3679
|
+
function forEachNode(root, fn) {
|
|
3680
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3681
|
+
const visit = (node) => {
|
|
3682
|
+
if (seen.has(node)) return;
|
|
3683
|
+
seen.add(node);
|
|
3684
|
+
fn(node);
|
|
3685
|
+
for (const child of childrenOf(node)) visit(child);
|
|
3686
|
+
};
|
|
3687
|
+
visit(root);
|
|
3688
|
+
}
|
|
3689
|
+
function childrenOf(n) {
|
|
3690
|
+
switch (n.kind) {
|
|
3691
|
+
case "Box":
|
|
3692
|
+
case "Sphere":
|
|
3693
|
+
case "Cylinder":
|
|
3694
|
+
case "Cone":
|
|
3695
|
+
case "Torus":
|
|
3696
|
+
case "Polygon":
|
|
3697
|
+
case "Circle":
|
|
3698
|
+
case "Line":
|
|
3699
|
+
case "Vertex":
|
|
3700
|
+
case "Empty":
|
|
3701
|
+
case "Path":
|
|
3702
|
+
case "Profile": return [];
|
|
3703
|
+
case "Fuse":
|
|
3704
|
+
case "Cut":
|
|
3705
|
+
case "Intersect": return [n.a, n.b];
|
|
3706
|
+
case "FuseAll": return n.shapes;
|
|
3707
|
+
case "CutAll": return [n.base, ...n.tools];
|
|
3708
|
+
case "Translate":
|
|
3709
|
+
case "Rotate":
|
|
3710
|
+
case "Scale":
|
|
3711
|
+
case "Mirror":
|
|
3712
|
+
case "Color":
|
|
3713
|
+
case "Fillet":
|
|
3714
|
+
case "Chamfer":
|
|
3715
|
+
case "Shell": return [n.target];
|
|
3716
|
+
case "Compound": return n.children;
|
|
3717
|
+
case "Instance": return [n.source];
|
|
3718
|
+
case "Extrude":
|
|
3719
|
+
case "Revolve": return [n.profile];
|
|
3720
|
+
case "Loft": return n.sections;
|
|
3721
|
+
case "Sweep": return [n.profile, n.spine];
|
|
3722
|
+
}
|
|
3723
|
+
}
|
|
3724
|
+
function nodeCount(root) {
|
|
3725
|
+
let n = 0;
|
|
3726
|
+
forEachNode(root, () => {
|
|
3727
|
+
n++;
|
|
3728
|
+
});
|
|
3729
|
+
return n;
|
|
3730
|
+
}
|
|
3609
3731
|
var MIN_CSG_VERSION = 1;
|
|
3610
3732
|
function toJSON(node) {
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3733
|
+
const ctx = {
|
|
3734
|
+
counts: countRefs(node),
|
|
3735
|
+
ids: /* @__PURE__ */ new Map(),
|
|
3736
|
+
defs: []
|
|
3614
3737
|
};
|
|
3738
|
+
const root = emitNode(node, ctx);
|
|
3739
|
+
return ctx.defs.length > 0 ? {
|
|
3740
|
+
csgVersion: 8,
|
|
3741
|
+
defs: ctx.defs,
|
|
3742
|
+
root
|
|
3743
|
+
} : {
|
|
3744
|
+
csgVersion: 8,
|
|
3745
|
+
root
|
|
3746
|
+
};
|
|
3747
|
+
}
|
|
3748
|
+
function countRefs(root) {
|
|
3749
|
+
const counts = /* @__PURE__ */ new Map();
|
|
3750
|
+
const visit = (n) => {
|
|
3751
|
+
const seen = counts.get(n) ?? 0;
|
|
3752
|
+
counts.set(n, seen + 1);
|
|
3753
|
+
if (seen === 0) for (const child of childrenOf(n)) visit(child);
|
|
3754
|
+
};
|
|
3755
|
+
visit(root);
|
|
3756
|
+
return counts;
|
|
3757
|
+
}
|
|
3758
|
+
function emitNode(n, ctx) {
|
|
3759
|
+
if ((ctx.counts.get(n) ?? 0) < 2) return nodeToJson(n, ctx);
|
|
3760
|
+
const existing = ctx.ids.get(n);
|
|
3761
|
+
if (existing !== void 0) return { $ref: existing };
|
|
3762
|
+
const body = nodeToJson(n, ctx);
|
|
3763
|
+
const id = ctx.defs.length;
|
|
3764
|
+
ctx.defs.push(body);
|
|
3765
|
+
ctx.ids.set(n, id);
|
|
3766
|
+
return { $ref: id };
|
|
3615
3767
|
}
|
|
3616
3768
|
function exprToJson(e) {
|
|
3617
3769
|
switch (e.kind) {
|
|
@@ -3710,25 +3862,25 @@ function primitiveToJson(n) {
|
|
|
3710
3862
|
default: return;
|
|
3711
3863
|
}
|
|
3712
3864
|
}
|
|
3713
|
-
function booleanToJson(n) {
|
|
3865
|
+
function booleanToJson(n, ctx) {
|
|
3714
3866
|
switch (n.kind) {
|
|
3715
3867
|
case "Fuse":
|
|
3716
3868
|
case "Cut":
|
|
3717
3869
|
case "Intersect": return {
|
|
3718
3870
|
kind: n.kind,
|
|
3719
|
-
a:
|
|
3720
|
-
b:
|
|
3871
|
+
a: emitNode(n.a, ctx),
|
|
3872
|
+
b: emitNode(n.b, ctx),
|
|
3721
3873
|
tolerance: n.tolerance
|
|
3722
3874
|
};
|
|
3723
3875
|
case "FuseAll": return {
|
|
3724
3876
|
kind: "FuseAll",
|
|
3725
|
-
shapes: n.shapes.map(
|
|
3877
|
+
shapes: n.shapes.map((s) => emitNode(s, ctx)),
|
|
3726
3878
|
tolerance: n.tolerance
|
|
3727
3879
|
};
|
|
3728
3880
|
case "CutAll": return {
|
|
3729
3881
|
kind: "CutAll",
|
|
3730
|
-
base:
|
|
3731
|
-
tools: n.tools.map(
|
|
3882
|
+
base: emitNode(n.base, ctx),
|
|
3883
|
+
tools: n.tools.map((t) => emitNode(t, ctx)),
|
|
3732
3884
|
tolerance: n.tolerance
|
|
3733
3885
|
};
|
|
3734
3886
|
default: return;
|
|
@@ -3795,103 +3947,108 @@ function contourToJson(c) {
|
|
|
3795
3947
|
segments: c.segments.map(segmentToJson)
|
|
3796
3948
|
};
|
|
3797
3949
|
}
|
|
3798
|
-
function transformToJson(n) {
|
|
3950
|
+
function transformToJson(n, ctx) {
|
|
3799
3951
|
switch (n.kind) {
|
|
3800
3952
|
case "Translate": return {
|
|
3801
3953
|
kind: "Translate",
|
|
3802
|
-
target:
|
|
3954
|
+
target: emitNode(n.target, ctx),
|
|
3803
3955
|
vector: exprToJson(n.vector)
|
|
3804
3956
|
};
|
|
3805
3957
|
case "Rotate": return {
|
|
3806
3958
|
kind: "Rotate",
|
|
3807
|
-
target:
|
|
3959
|
+
target: emitNode(n.target, ctx),
|
|
3808
3960
|
angle: exprToJson(n.angle),
|
|
3809
3961
|
axis: optExprToJson(n.axis),
|
|
3810
3962
|
at: optExprToJson(n.at)
|
|
3811
3963
|
};
|
|
3812
3964
|
case "Scale": return {
|
|
3813
3965
|
kind: "Scale",
|
|
3814
|
-
target:
|
|
3966
|
+
target: emitNode(n.target, ctx),
|
|
3815
3967
|
factor: exprToJson(n.factor),
|
|
3816
3968
|
center: optExprToJson(n.center)
|
|
3817
3969
|
};
|
|
3818
3970
|
case "Mirror": return {
|
|
3819
3971
|
kind: "Mirror",
|
|
3820
|
-
target:
|
|
3972
|
+
target: emitNode(n.target, ctx),
|
|
3821
3973
|
normal: optExprToJson(n.normal),
|
|
3822
3974
|
at: optExprToJson(n.at)
|
|
3823
3975
|
};
|
|
3824
3976
|
default: return;
|
|
3825
3977
|
}
|
|
3826
3978
|
}
|
|
3827
|
-
function
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3979
|
+
function featureToJson(n, ctx) {
|
|
3980
|
+
switch (n.kind) {
|
|
3981
|
+
case "Extrude": return {
|
|
3982
|
+
kind: "Extrude",
|
|
3983
|
+
profile: emitNode(n.profile, ctx),
|
|
3984
|
+
vector: exprToJson(n.vector)
|
|
3985
|
+
};
|
|
3986
|
+
case "Revolve": return {
|
|
3987
|
+
kind: "Revolve",
|
|
3988
|
+
profile: emitNode(n.profile, ctx),
|
|
3989
|
+
angle: exprToJson(n.angle),
|
|
3990
|
+
axis: optExprToJson(n.axis),
|
|
3991
|
+
at: optExprToJson(n.at)
|
|
3992
|
+
};
|
|
3993
|
+
case "Loft": return {
|
|
3994
|
+
kind: "Loft",
|
|
3995
|
+
sections: n.sections.map((s) => emitNode(s, ctx)),
|
|
3996
|
+
ruled: n.ruled
|
|
3997
|
+
};
|
|
3998
|
+
case "Path": return {
|
|
3999
|
+
kind: "Path",
|
|
4000
|
+
start: exprToJson(n.start),
|
|
4001
|
+
segments: n.segments.map(segmentToJson)
|
|
4002
|
+
};
|
|
4003
|
+
case "Sweep": return {
|
|
4004
|
+
kind: "Sweep",
|
|
4005
|
+
profile: emitNode(n.profile, ctx),
|
|
4006
|
+
spine: emitNode(n.spine, ctx),
|
|
4007
|
+
frenet: n.frenet
|
|
4008
|
+
};
|
|
4009
|
+
case "Profile": return {
|
|
4010
|
+
kind: "Profile",
|
|
4011
|
+
outline: contourToJson(n.outline),
|
|
4012
|
+
holes: n.holes.map(contourToJson)
|
|
4013
|
+
};
|
|
4014
|
+
default: return;
|
|
4015
|
+
}
|
|
4016
|
+
}
|
|
4017
|
+
function nodeToJson(n, ctx) {
|
|
3861
4018
|
if (n.kind === "Color") return {
|
|
3862
4019
|
kind: "Color",
|
|
3863
|
-
target:
|
|
4020
|
+
target: emitNode(n.target, ctx),
|
|
3864
4021
|
color: [...n.color]
|
|
3865
4022
|
};
|
|
3866
4023
|
if (n.kind === "Fillet") return {
|
|
3867
4024
|
kind: "Fillet",
|
|
3868
|
-
target:
|
|
4025
|
+
target: emitNode(n.target, ctx),
|
|
3869
4026
|
ref: edgeRefToJson(n.ref),
|
|
3870
4027
|
radius: exprToJson(n.radius)
|
|
3871
4028
|
};
|
|
3872
4029
|
if (n.kind === "Chamfer") return {
|
|
3873
4030
|
kind: "Chamfer",
|
|
3874
|
-
target:
|
|
4031
|
+
target: emitNode(n.target, ctx),
|
|
3875
4032
|
ref: edgeRefToJson(n.ref),
|
|
3876
4033
|
distance: exprToJson(n.distance)
|
|
3877
4034
|
};
|
|
3878
4035
|
if (n.kind === "Shell") return {
|
|
3879
4036
|
kind: "Shell",
|
|
3880
|
-
target:
|
|
4037
|
+
target: emitNode(n.target, ctx),
|
|
3881
4038
|
refs: n.refs.map(shapeRefToJson),
|
|
3882
4039
|
thickness: exprToJson(n.thickness)
|
|
3883
4040
|
};
|
|
3884
4041
|
if (n.kind === "Compound") return {
|
|
3885
4042
|
kind: "Compound",
|
|
3886
|
-
children: n.children.map(
|
|
4043
|
+
children: n.children.map((c) => emitNode(c, ctx))
|
|
3887
4044
|
};
|
|
3888
4045
|
if (n.kind === "Instance") return {
|
|
3889
4046
|
kind: "Instance",
|
|
3890
|
-
source:
|
|
4047
|
+
source: emitNode(n.source, ctx),
|
|
3891
4048
|
placements: n.placements,
|
|
3892
4049
|
fuse: n.fuse
|
|
3893
4050
|
};
|
|
3894
|
-
return primitiveToJson(n) ?? booleanToJson(n) ?? transformToJson(n);
|
|
4051
|
+
return featureToJson(n, ctx) ?? primitiveToJson(n) ?? booleanToJson(n, ctx) ?? transformToJson(n, ctx);
|
|
3895
4052
|
}
|
|
3896
4053
|
function bad(msg) {
|
|
3897
4054
|
return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.NULL_SHAPE_INPUT, `csg.fromJSON: ${msg}`));
|
|
@@ -3924,9 +4081,18 @@ function readVec2(v, where) {
|
|
|
3924
4081
|
function fromJSON(envelope) {
|
|
3925
4082
|
if (!isObj(envelope)) return bad("input is not an object");
|
|
3926
4083
|
const v = envelope["csgVersion"];
|
|
3927
|
-
if (typeof v !== "number" || !Number.isInteger(v) || v < MIN_CSG_VERSION || v >
|
|
3928
|
-
const
|
|
3929
|
-
|
|
4084
|
+
if (typeof v !== "number" || !Number.isInteger(v) || v < MIN_CSG_VERSION || v > 8) return bad(`unsupported csgVersion ${String(v)} (expected ${MIN_CSG_VERSION}..8)`);
|
|
4085
|
+
const rawDefs = envelope["defs"];
|
|
4086
|
+
const defs = [];
|
|
4087
|
+
if (rawDefs !== void 0) {
|
|
4088
|
+
if (!Array.isArray(rawDefs)) return bad("defs: not an array");
|
|
4089
|
+
for (const raw of rawDefs) {
|
|
4090
|
+
const r = readNode(raw, defs);
|
|
4091
|
+
if (!r.ok) return r;
|
|
4092
|
+
defs.push(r.value);
|
|
4093
|
+
}
|
|
4094
|
+
}
|
|
4095
|
+
return readNode(envelope["root"], defs);
|
|
3930
4096
|
}
|
|
3931
4097
|
function readExpr(j) {
|
|
3932
4098
|
if (!isObj(j)) return bad("expression: not an object");
|
|
@@ -3992,11 +4158,11 @@ function readBuildVec(j) {
|
|
|
3992
4158
|
}
|
|
3993
4159
|
return require_errors.ok(buildVec(dim, out));
|
|
3994
4160
|
}
|
|
3995
|
-
function readNodeArray(j, where) {
|
|
4161
|
+
function readNodeArray(j, where, defs) {
|
|
3996
4162
|
if (!Array.isArray(j)) return bad(`${where}: not array`);
|
|
3997
4163
|
const out = [];
|
|
3998
4164
|
for (const c of j) {
|
|
3999
|
-
const r = readNode(c);
|
|
4165
|
+
const r = readNode(c, defs);
|
|
4000
4166
|
if (!r.ok) return r;
|
|
4001
4167
|
out.push(r.value);
|
|
4002
4168
|
}
|
|
@@ -4007,8 +4173,15 @@ function readOptTolerance(j) {
|
|
|
4007
4173
|
if (t === void 0 || t === null) return require_errors.ok(void 0);
|
|
4008
4174
|
return isNumber$1(t) ? require_errors.ok(t) : bad("tolerance: not a finite number");
|
|
4009
4175
|
}
|
|
4010
|
-
function readNode(j) {
|
|
4176
|
+
function readNode(j, defs) {
|
|
4011
4177
|
if (!isObj(j)) return bad("node: not an object");
|
|
4178
|
+
const ref = j["$ref"];
|
|
4179
|
+
if (ref !== void 0) {
|
|
4180
|
+
if (!isNumber$1(ref) || !Number.isInteger(ref) || ref < 0) return bad("$ref: expected a non-negative integer def index");
|
|
4181
|
+
const node = defs[ref];
|
|
4182
|
+
if (node === void 0) return bad(`$ref: ${ref} is out of range (forward refs are rejected)`);
|
|
4183
|
+
return require_errors.ok(node);
|
|
4184
|
+
}
|
|
4012
4185
|
const kind = j["kind"];
|
|
4013
4186
|
switch (kind) {
|
|
4014
4187
|
case "Box":
|
|
@@ -4023,25 +4196,25 @@ function readNode(j) {
|
|
|
4023
4196
|
case "Empty": return readPrimitive(kind, j);
|
|
4024
4197
|
case "Fuse":
|
|
4025
4198
|
case "Cut":
|
|
4026
|
-
case "Intersect": return readBinaryBool(kind, j);
|
|
4199
|
+
case "Intersect": return readBinaryBool(kind, j, defs);
|
|
4027
4200
|
case "FuseAll":
|
|
4028
|
-
case "CutAll": return readNaryBool(kind, j);
|
|
4201
|
+
case "CutAll": return readNaryBool(kind, j, defs);
|
|
4029
4202
|
case "Translate":
|
|
4030
4203
|
case "Rotate":
|
|
4031
4204
|
case "Scale":
|
|
4032
|
-
case "Mirror": return readTransform(kind, j);
|
|
4033
|
-
case "Compound": return readCompound(j);
|
|
4034
|
-
case "Instance": return readInstance(j);
|
|
4035
|
-
case "Extrude": return readExtrude(j);
|
|
4036
|
-
case "Revolve": return readRevolve(j);
|
|
4037
|
-
case "Loft": return readLoft(j);
|
|
4205
|
+
case "Mirror": return readTransform(kind, j, defs);
|
|
4206
|
+
case "Compound": return readCompound(j, defs);
|
|
4207
|
+
case "Instance": return readInstance(j, defs);
|
|
4208
|
+
case "Extrude": return readExtrude(j, defs);
|
|
4209
|
+
case "Revolve": return readRevolve(j, defs);
|
|
4210
|
+
case "Loft": return readLoft(j, defs);
|
|
4038
4211
|
case "Path": return readPath(j);
|
|
4039
|
-
case "Sweep": return readSweep(j);
|
|
4212
|
+
case "Sweep": return readSweep(j, defs);
|
|
4040
4213
|
case "Profile": return readProfile(j);
|
|
4041
|
-
case "Color": return readColor(j);
|
|
4042
|
-
case "Fillet": return readFillet(j);
|
|
4043
|
-
case "Chamfer": return readChamfer(j);
|
|
4044
|
-
case "Shell": return readShell(j);
|
|
4214
|
+
case "Color": return readColor(j, defs);
|
|
4215
|
+
case "Fillet": return readFillet(j, defs);
|
|
4216
|
+
case "Chamfer": return readChamfer(j, defs);
|
|
4217
|
+
case "Shell": return readShell(j, defs);
|
|
4045
4218
|
default: return bad(`unknown node kind: ${String(kind)}`);
|
|
4046
4219
|
}
|
|
4047
4220
|
}
|
|
@@ -4123,10 +4296,10 @@ function readEmpty(j) {
|
|
|
4123
4296
|
default: return bad(`Empty.output: ${String(out)}`);
|
|
4124
4297
|
}
|
|
4125
4298
|
}
|
|
4126
|
-
function readBinaryBool(kind, j) {
|
|
4127
|
-
const a = readNode(j["a"]);
|
|
4299
|
+
function readBinaryBool(kind, j, defs) {
|
|
4300
|
+
const a = readNode(j["a"], defs);
|
|
4128
4301
|
if (!a.ok) return a;
|
|
4129
|
-
const b = readNode(j["b"]);
|
|
4302
|
+
const b = readNode(j["b"], defs);
|
|
4130
4303
|
if (!b.ok) return b;
|
|
4131
4304
|
const t = readOptTolerance(j);
|
|
4132
4305
|
if (!t.ok) return t;
|
|
@@ -4136,20 +4309,20 @@ function readBinaryBool(kind, j) {
|
|
|
4136
4309
|
case "Intersect": return require_errors.ok(intersect$1(a.value, b.value, t.value));
|
|
4137
4310
|
}
|
|
4138
4311
|
}
|
|
4139
|
-
function readNaryBool(kind, j) {
|
|
4312
|
+
function readNaryBool(kind, j, defs) {
|
|
4140
4313
|
const t = readOptTolerance(j);
|
|
4141
4314
|
if (!t.ok) return t;
|
|
4142
4315
|
if (kind === "FuseAll") {
|
|
4143
|
-
const shapes = readNodeArray(j["shapes"], "FuseAll.shapes");
|
|
4316
|
+
const shapes = readNodeArray(j["shapes"], "FuseAll.shapes", defs);
|
|
4144
4317
|
return shapes.ok ? require_errors.ok(fuseAll$1(shapes.value, t.value)) : shapes;
|
|
4145
4318
|
}
|
|
4146
|
-
const base = readNode(j["base"]);
|
|
4319
|
+
const base = readNode(j["base"], defs);
|
|
4147
4320
|
if (!base.ok) return base;
|
|
4148
|
-
const tools = readNodeArray(j["tools"], "CutAll.tools");
|
|
4321
|
+
const tools = readNodeArray(j["tools"], "CutAll.tools", defs);
|
|
4149
4322
|
return tools.ok ? require_errors.ok(cutAll$1(base.value, tools.value, t.value)) : tools;
|
|
4150
4323
|
}
|
|
4151
|
-
function readTransform(kind, j) {
|
|
4152
|
-
const tgt = readNode(j["target"]);
|
|
4324
|
+
function readTransform(kind, j, defs) {
|
|
4325
|
+
const tgt = readNode(j["target"], defs);
|
|
4153
4326
|
if (!tgt.ok) return tgt;
|
|
4154
4327
|
switch (kind) {
|
|
4155
4328
|
case "Translate": return readTranslate(j, tgt.value);
|
|
@@ -4196,15 +4369,15 @@ function readMirror(j, target) {
|
|
|
4196
4369
|
at: at.value
|
|
4197
4370
|
}));
|
|
4198
4371
|
}
|
|
4199
|
-
function readExtrude(j) {
|
|
4200
|
-
const profile = readNode(j["profile"]);
|
|
4372
|
+
function readExtrude(j, defs) {
|
|
4373
|
+
const profile = readNode(j["profile"], defs);
|
|
4201
4374
|
if (!profile.ok) return profile;
|
|
4202
4375
|
const vector = readExpr(j["vector"]);
|
|
4203
4376
|
if (!vector.ok) return vector;
|
|
4204
4377
|
return require_errors.ok(extrude$1(profile.value, vector.value));
|
|
4205
4378
|
}
|
|
4206
|
-
function readRevolve(j) {
|
|
4207
|
-
const profile = readNode(j["profile"]);
|
|
4379
|
+
function readRevolve(j, defs) {
|
|
4380
|
+
const profile = readNode(j["profile"], defs);
|
|
4208
4381
|
if (!profile.ok) return profile;
|
|
4209
4382
|
const angle = readExpr(j["angle"]);
|
|
4210
4383
|
if (!angle.ok) return angle;
|
|
@@ -4217,8 +4390,8 @@ function readRevolve(j) {
|
|
|
4217
4390
|
at: at.value
|
|
4218
4391
|
}));
|
|
4219
4392
|
}
|
|
4220
|
-
function readLoft(j) {
|
|
4221
|
-
const sections = readNodeArray(j["sections"], "Loft.sections");
|
|
4393
|
+
function readLoft(j, defs) {
|
|
4394
|
+
const sections = readNodeArray(j["sections"], "Loft.sections", defs);
|
|
4222
4395
|
if (!sections.ok) return sections;
|
|
4223
4396
|
const ruled = j["ruled"];
|
|
4224
4397
|
if (ruled !== void 0 && typeof ruled !== "boolean") return bad("Loft.ruled: not a boolean");
|
|
@@ -4366,8 +4539,8 @@ function readShapeRef(j, where) {
|
|
|
4366
4539
|
}
|
|
4367
4540
|
});
|
|
4368
4541
|
}
|
|
4369
|
-
function readShell(j) {
|
|
4370
|
-
const target = readNode(j["target"]);
|
|
4542
|
+
function readShell(j, defs) {
|
|
4543
|
+
const target = readNode(j["target"], defs);
|
|
4371
4544
|
if (!target.ok) return target;
|
|
4372
4545
|
const thickness = readExpr(j["thickness"]);
|
|
4373
4546
|
if (!thickness.ok) return thickness;
|
|
@@ -4381,8 +4554,8 @@ function readShell(j) {
|
|
|
4381
4554
|
}
|
|
4382
4555
|
return require_errors.ok(shell$1(target.value, refs, thickness.value));
|
|
4383
4556
|
}
|
|
4384
|
-
function readFillet(j) {
|
|
4385
|
-
const target = readNode(j["target"]);
|
|
4557
|
+
function readFillet(j, defs) {
|
|
4558
|
+
const target = readNode(j["target"], defs);
|
|
4386
4559
|
if (!target.ok) return target;
|
|
4387
4560
|
const radius = readExpr(j["radius"]);
|
|
4388
4561
|
if (!radius.ok) return radius;
|
|
@@ -4390,8 +4563,8 @@ function readFillet(j) {
|
|
|
4390
4563
|
if (!ref.ok) return ref;
|
|
4391
4564
|
return require_errors.ok(fillet$1(target.value, ref.value, radius.value));
|
|
4392
4565
|
}
|
|
4393
|
-
function readChamfer(j) {
|
|
4394
|
-
const target = readNode(j["target"]);
|
|
4566
|
+
function readChamfer(j, defs) {
|
|
4567
|
+
const target = readNode(j["target"], defs);
|
|
4395
4568
|
if (!target.ok) return target;
|
|
4396
4569
|
const distance = readExpr(j["distance"]);
|
|
4397
4570
|
if (!distance.ok) return distance;
|
|
@@ -4399,8 +4572,8 @@ function readChamfer(j) {
|
|
|
4399
4572
|
if (!ref.ok) return ref;
|
|
4400
4573
|
return require_errors.ok(chamfer$1(target.value, ref.value, distance.value));
|
|
4401
4574
|
}
|
|
4402
|
-
function readColor(j) {
|
|
4403
|
-
const target = readNode(j["target"]);
|
|
4575
|
+
function readColor(j, defs) {
|
|
4576
|
+
const target = readNode(j["target"], defs);
|
|
4404
4577
|
if (!target.ok) return target;
|
|
4405
4578
|
const c = j["color"];
|
|
4406
4579
|
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]");
|
|
@@ -4424,10 +4597,10 @@ function readProfile(j) {
|
|
|
4424
4597
|
}
|
|
4425
4598
|
return require_errors.ok(profile(outline.value, holes));
|
|
4426
4599
|
}
|
|
4427
|
-
function readSweep(j) {
|
|
4428
|
-
const profile = readNode(j["profile"]);
|
|
4600
|
+
function readSweep(j, defs) {
|
|
4601
|
+
const profile = readNode(j["profile"], defs);
|
|
4429
4602
|
if (!profile.ok) return profile;
|
|
4430
|
-
const spine = readNode(j["spine"]);
|
|
4603
|
+
const spine = readNode(j["spine"], defs);
|
|
4431
4604
|
if (!spine.ok) return spine;
|
|
4432
4605
|
const frenet = readFlag(j, "frenet");
|
|
4433
4606
|
if (!frenet.ok) return frenet;
|
|
@@ -4446,15 +4619,15 @@ function readPath(j) {
|
|
|
4446
4619
|
}
|
|
4447
4620
|
return require_errors.ok(path(start.value, segments));
|
|
4448
4621
|
}
|
|
4449
|
-
function readCompound(j) {
|
|
4450
|
-
const children = readNodeArray(j["children"], "Compound.children");
|
|
4622
|
+
function readCompound(j, defs) {
|
|
4623
|
+
const children = readNodeArray(j["children"], "Compound.children", defs);
|
|
4451
4624
|
return children.ok ? require_errors.ok(compound$1(children.value)) : children;
|
|
4452
4625
|
}
|
|
4453
4626
|
function isMatrix4x4(v) {
|
|
4454
4627
|
return Array.isArray(v) && v.length === 4 && v.every((row) => Array.isArray(row) && row.length === 4 && row.every(isNumber$1));
|
|
4455
4628
|
}
|
|
4456
|
-
function readInstance(j) {
|
|
4457
|
-
const source = readNode(j["source"]);
|
|
4629
|
+
function readInstance(j, defs) {
|
|
4630
|
+
const source = readNode(j["source"], defs);
|
|
4458
4631
|
if (!source.ok) return source;
|
|
4459
4632
|
const placements = j["placements"];
|
|
4460
4633
|
if (!Array.isArray(placements) || !placements.every(isMatrix4x4)) return bad("Instance.placements must be an array of 4x4 number matrices");
|
|
@@ -4652,128 +4825,6 @@ function optimizeTranslate(target, vector) {
|
|
|
4652
4825
|
return translate$1(ot, ov);
|
|
4653
4826
|
}
|
|
4654
4827
|
//#endregion
|
|
4655
|
-
//#region src/csg/edit.ts
|
|
4656
|
-
function replaceNode(root, pred, replacement) {
|
|
4657
|
-
return walk(root, pred, replacement, /* @__PURE__ */ new Map());
|
|
4658
|
-
}
|
|
4659
|
-
function walk(node, pred, repl, memo) {
|
|
4660
|
-
const cached = memo.get(node);
|
|
4661
|
-
if (cached !== void 0) return cached;
|
|
4662
|
-
const out = pred(node) ? repl : rebuildChildren(node, pred, repl, memo);
|
|
4663
|
-
memo.set(node, out);
|
|
4664
|
-
return out;
|
|
4665
|
-
}
|
|
4666
|
-
function rebuildChildren(n, pred, repl, memo) {
|
|
4667
|
-
switch (n.kind) {
|
|
4668
|
-
case "Box":
|
|
4669
|
-
case "Sphere":
|
|
4670
|
-
case "Cylinder":
|
|
4671
|
-
case "Cone":
|
|
4672
|
-
case "Torus":
|
|
4673
|
-
case "Polygon":
|
|
4674
|
-
case "Circle":
|
|
4675
|
-
case "Line":
|
|
4676
|
-
case "Vertex":
|
|
4677
|
-
case "Empty":
|
|
4678
|
-
case "Path":
|
|
4679
|
-
case "Profile": return n;
|
|
4680
|
-
case "Fuse": return fuse$1(walk(n.a, pred, repl, memo), walk(n.b, pred, repl, memo), n.tolerance);
|
|
4681
|
-
case "Cut": return cut$1(walk(n.a, pred, repl, memo), walk(n.b, pred, repl, memo), n.tolerance);
|
|
4682
|
-
case "Intersect": return intersect$1(walk(n.a, pred, repl, memo), walk(n.b, pred, repl, memo), n.tolerance);
|
|
4683
|
-
case "FuseAll": return fuseAll$1(n.shapes.map((c) => walk(c, pred, repl, memo)), n.tolerance);
|
|
4684
|
-
case "CutAll": return cutAll$1(walk(n.base, pred, repl, memo), n.tools.map((c) => walk(c, pred, repl, memo)), n.tolerance);
|
|
4685
|
-
case "Translate": return translate$1(walk(n.target, pred, repl, memo), n.vector);
|
|
4686
|
-
case "Rotate": return rotate$1(walk(n.target, pred, repl, memo), n.angle, {
|
|
4687
|
-
axis: n.axis,
|
|
4688
|
-
at: n.at
|
|
4689
|
-
});
|
|
4690
|
-
case "Scale": return scale$2(walk(n.target, pred, repl, memo), n.factor, { center: n.center });
|
|
4691
|
-
case "Mirror": return mirror$1(walk(n.target, pred, repl, memo), {
|
|
4692
|
-
normal: n.normal,
|
|
4693
|
-
at: n.at
|
|
4694
|
-
});
|
|
4695
|
-
case "Compound": return compound$1(n.children.map((c) => walk(c, pred, repl, memo)));
|
|
4696
|
-
case "Instance": return instance$1(walk(n.source, pred, repl, memo), n.placements, n.fuse);
|
|
4697
|
-
case "Extrude":
|
|
4698
|
-
case "Revolve":
|
|
4699
|
-
case "Loft":
|
|
4700
|
-
case "Sweep":
|
|
4701
|
-
case "Color":
|
|
4702
|
-
case "Fillet":
|
|
4703
|
-
case "Chamfer":
|
|
4704
|
-
case "Shell": return rebuildFeature(n, pred, repl, memo);
|
|
4705
|
-
}
|
|
4706
|
-
}
|
|
4707
|
-
function rebuildFeature(n, pred, repl, memo) {
|
|
4708
|
-
switch (n.kind) {
|
|
4709
|
-
case "Extrude": return extrude$1(walk(n.profile, pred, repl, memo), n.vector);
|
|
4710
|
-
case "Revolve": return revolve$1(walk(n.profile, pred, repl, memo), n.angle, {
|
|
4711
|
-
axis: n.axis,
|
|
4712
|
-
at: n.at
|
|
4713
|
-
});
|
|
4714
|
-
case "Loft": return loft$1(n.sections.map((s) => walk(s, pred, repl, memo)), { ruled: n.ruled });
|
|
4715
|
-
case "Sweep": return sweep$2(walk(n.profile, pred, repl, memo), walk(n.spine, pred, repl, memo), { frenet: n.frenet });
|
|
4716
|
-
case "Color": return color(walk(n.target, pred, repl, memo), [...n.color]);
|
|
4717
|
-
case "Fillet": return fillet$1(walk(n.target, pred, repl, memo), n.ref, n.radius);
|
|
4718
|
-
case "Chamfer": return chamfer$1(walk(n.target, pred, repl, memo), n.ref, n.distance);
|
|
4719
|
-
case "Shell": return shell$1(walk(n.target, pred, repl, memo), n.refs, n.thickness);
|
|
4720
|
-
}
|
|
4721
|
-
}
|
|
4722
|
-
/** Visits each DISTINCT node once (identity-deduplicated), so a shared
|
|
4723
|
-
* subtree is reported once and a self-referencing DAG walks in linear time. */
|
|
4724
|
-
function forEachNode(root, fn) {
|
|
4725
|
-
const seen = /* @__PURE__ */ new Set();
|
|
4726
|
-
const visit = (node) => {
|
|
4727
|
-
if (seen.has(node)) return;
|
|
4728
|
-
seen.add(node);
|
|
4729
|
-
fn(node);
|
|
4730
|
-
for (const child of childrenOf(node)) visit(child);
|
|
4731
|
-
};
|
|
4732
|
-
visit(root);
|
|
4733
|
-
}
|
|
4734
|
-
function childrenOf(n) {
|
|
4735
|
-
switch (n.kind) {
|
|
4736
|
-
case "Box":
|
|
4737
|
-
case "Sphere":
|
|
4738
|
-
case "Cylinder":
|
|
4739
|
-
case "Cone":
|
|
4740
|
-
case "Torus":
|
|
4741
|
-
case "Polygon":
|
|
4742
|
-
case "Circle":
|
|
4743
|
-
case "Line":
|
|
4744
|
-
case "Vertex":
|
|
4745
|
-
case "Empty":
|
|
4746
|
-
case "Path":
|
|
4747
|
-
case "Profile": return [];
|
|
4748
|
-
case "Fuse":
|
|
4749
|
-
case "Cut":
|
|
4750
|
-
case "Intersect": return [n.a, n.b];
|
|
4751
|
-
case "FuseAll": return n.shapes;
|
|
4752
|
-
case "CutAll": return [n.base, ...n.tools];
|
|
4753
|
-
case "Translate":
|
|
4754
|
-
case "Rotate":
|
|
4755
|
-
case "Scale":
|
|
4756
|
-
case "Mirror":
|
|
4757
|
-
case "Color":
|
|
4758
|
-
case "Fillet":
|
|
4759
|
-
case "Chamfer":
|
|
4760
|
-
case "Shell": return [n.target];
|
|
4761
|
-
case "Compound": return n.children;
|
|
4762
|
-
case "Instance": return [n.source];
|
|
4763
|
-
case "Extrude":
|
|
4764
|
-
case "Revolve": return [n.profile];
|
|
4765
|
-
case "Loft": return n.sections;
|
|
4766
|
-
case "Sweep": return [n.profile, n.spine];
|
|
4767
|
-
}
|
|
4768
|
-
}
|
|
4769
|
-
function nodeCount(root) {
|
|
4770
|
-
let n = 0;
|
|
4771
|
-
forEachNode(root, () => {
|
|
4772
|
-
n++;
|
|
4773
|
-
});
|
|
4774
|
-
return n;
|
|
4775
|
-
}
|
|
4776
|
-
//#endregion
|
|
4777
4828
|
//#region src/sketching/blueprintContourFns.ts
|
|
4778
4829
|
var EPS$1 = 1e-6;
|
|
4779
4830
|
function p2(p) {
|
|
@@ -8732,7 +8783,7 @@ var patterns_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
|
|
|
8732
8783
|
//#endregion
|
|
8733
8784
|
//#region src/ns/csg.ts
|
|
8734
8785
|
var csg_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
|
|
8735
|
-
CSG_VERSION: () =>
|
|
8786
|
+
CSG_VERSION: () => 8,
|
|
8736
8787
|
Evaluator: () => Evaluator,
|
|
8737
8788
|
add: () => add$1,
|
|
8738
8789
|
arbitraryClosedProfile: () => arbitraryClosedProfile,
|