brepjs 18.134.0 → 18.136.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.
Files changed (91) hide show
  1. package/dist/2d/lib/svgPath.d.ts +0 -11
  2. package/dist/2d.cjs +6 -6
  3. package/dist/2d.js +6 -6
  4. package/dist/{adjacencyFns-CwcdjOsT.js → adjacencyFns-BMgFDWFO.js} +3 -3
  5. package/dist/{adjacencyFns-BhdfZany.cjs → adjacencyFns-Clu4DbkI.cjs} +3 -3
  6. package/dist/{blueprint-DRvc1LOz.js → blueprint-BzDq9Rfb.js} +40 -15
  7. package/dist/{blueprint-BgbVmx4L.cjs → blueprint-CdOcvuG4.cjs} +40 -15
  8. package/dist/{blueprintFns-COSD5yZH.js → blueprintFns-B0wbS9PN.js} +2 -2
  9. package/dist/{blueprintFns-oatmkSjh.cjs → blueprintFns-B6zG47o1.cjs} +2 -2
  10. package/dist/{blueprintSketcher-yZiAeqft.js → blueprintSketcher-DI_qQhBg.js} +3 -3
  11. package/dist/{blueprintSketcher-B5UqD0FO.cjs → blueprintSketcher-DeQYScWX.cjs} +3 -3
  12. package/dist/{boolean2D-p7RMNFtG.cjs → boolean2D-C-Azd06V.cjs} +4 -4
  13. package/dist/{boolean2D-BuM5xJSa.js → boolean2D-CdDn7AFp.js} +4 -4
  14. package/dist/brepjs.cjs +200 -37
  15. package/dist/brepjs.js +201 -38
  16. package/dist/{cameraFns-VVI0cWLa.js → cameraFns-BqSTuHN2.js} +3 -3
  17. package/dist/{cameraFns-i1otOZ0V.cjs → cameraFns-CdPdw2Ma.cjs} +3 -3
  18. package/dist/core.cjs +2 -2
  19. package/dist/core.js +2 -2
  20. package/dist/{cornerFinder-CiHpo7kU.js → cornerFinder-CBNgUcWy.js} +1 -1
  21. package/dist/{cornerFinder-DIe6pMPU.cjs → cornerFinder-WICP_RPb.cjs} +1 -1
  22. package/dist/csg/builders.d.ts +8 -2
  23. package/dist/csg/evaluators/shell.d.ts +5 -0
  24. package/dist/csg/index.d.ts +2 -2
  25. package/dist/csg/serialize.d.ts +1 -1
  26. package/dist/csg/types.d.ts +10 -2
  27. package/dist/{curveFns-jmKL1KZp.cjs → curveFns-BYcLLDAB.cjs} +1 -1
  28. package/dist/{curveFns-Bh_PHl9N.js → curveFns-BtXR6kJ7.js} +1 -1
  29. package/dist/{drawFns-BFktlDIi.js → drawFns-BAwR4uoC.js} +12 -12
  30. package/dist/{drawFns-CP82Xdma.cjs → drawFns-CYW65QTr.cjs} +12 -12
  31. package/dist/{faceFns-C0A8O-2a.cjs → faceFns-B5UiJH4H.cjs} +2 -2
  32. package/dist/{faceFns-CaBQNffu.js → faceFns-BfTHYEiw.js} +2 -2
  33. package/dist/{healingFns-BqmIvfPm.cjs → healingFns-ChcvzVB8.cjs} +4 -4
  34. package/dist/{healingFns-BrrTpxjI.js → healingFns-DAVYFXVB.js} +4 -4
  35. package/dist/{helpers-DLZUxawd.cjs → helpers-C9PIppuU.cjs} +12 -6
  36. package/dist/{helpers-BiqV-wPK.js → helpers-CvwerZfP.js} +7 -7
  37. package/dist/{importFns-ncp_0vEl.cjs → importFns-Bt9YEImO.cjs} +2 -2
  38. package/dist/{importFns-BId6d2pt.js → importFns-DSY1pI70.js} +2 -2
  39. package/dist/io.cjs +2 -2
  40. package/dist/io.js +2 -2
  41. package/dist/kernel/occtWasm/occtWasmAdapter.cjs +1 -1
  42. package/dist/kernel/occtWasm/occtWasmAdapter.js +1 -1
  43. package/dist/{loftFns-m7LoJWE2.js → loftFns-Bl8reWqk.js} +1 -1
  44. package/dist/{loftFns-u-yPHpJ9.cjs → loftFns-CdwKSxw1.cjs} +1 -1
  45. package/dist/{measureFns-CaEuNAZO.cjs → measureFns-B-UbL3Rw.cjs} +3 -3
  46. package/dist/{measureFns-9-1Ng0wR.js → measureFns-DtiZvj_X.js} +3 -3
  47. package/dist/measurement.cjs +1 -1
  48. package/dist/measurement.js +1 -1
  49. package/dist/{meshFns-CB7HsxzB.cjs → meshFns-B461Ku2S.cjs} +3 -3
  50. package/dist/{meshFns-CpfeEN1b.js → meshFns-CqJScqWa.js} +3 -3
  51. package/dist/{occtWasmAdapter-BEe---7w.js → occtWasmAdapter-Bzx2d8zN.js} +39 -10
  52. package/dist/{occtWasmAdapter-DEpy64ji.cjs → occtWasmAdapter-G8mkVxgw.cjs} +39 -10
  53. package/dist/operations.cjs +2 -2
  54. package/dist/operations.js +2 -2
  55. package/dist/{originTrackingFns-JxAlPJXX.js → originTrackingFns-BWA8gv5V.js} +2 -2
  56. package/dist/{originTrackingFns-CKKmLIUH.cjs → originTrackingFns-rh_FbN6R.cjs} +2 -2
  57. package/dist/{primitiveFns-C6Trlz8m.cjs → primitiveFns-BTxppy_Y.cjs} +4 -4
  58. package/dist/{primitiveFns-BSMbMRf1.js → primitiveFns-C-p7jKZt.js} +4 -4
  59. package/dist/projection.cjs +1 -1
  60. package/dist/projection.js +1 -1
  61. package/dist/query.cjs +2 -2
  62. package/dist/query.js +2 -2
  63. package/dist/{refResolveFns-DcyIQSDi.js → refResolveFns-BPnjuRUW.js} +6 -6
  64. package/dist/{refResolveFns-c7RWIsZy.cjs → refResolveFns-DEU2yvJU.cjs} +6 -6
  65. package/dist/{shapeFns-DyDRpo6K.js → shapeFns-s6VgcNkU.js} +2 -2
  66. package/dist/{shapeFns-DDTLk0mJ.cjs → shapeFns-xApQafn6.cjs} +2 -2
  67. package/dist/shapeRef.cjs +1 -1
  68. package/dist/shapeRef.js +1 -1
  69. package/dist/{shapeTypes-pxoxsXIo.js → shapeTypes-D3bntzog.js} +1 -1
  70. package/dist/{shapeTypes-DVExh1xP.cjs → shapeTypes-Dz5JzlYx.cjs} +1 -1
  71. package/dist/sketching.cjs +3 -3
  72. package/dist/sketching.js +3 -3
  73. package/dist/{solidBuilders-CgW7Ge_s.cjs → solidBuilders-B3EZcVNw.cjs} +5 -5
  74. package/dist/{solidBuilders-Devga1Vk.js → solidBuilders-FOfRGZq0.js} +5 -5
  75. package/dist/{surfaceBuilders-DUTDN2Ay.cjs → surfaceBuilders-CVLhWPtB.cjs} +3 -3
  76. package/dist/{surfaceBuilders-B7WlmoVr.js → surfaceBuilders-Dcf7LRqM.js} +3 -3
  77. package/dist/text.cjs +2 -2
  78. package/dist/text.js +2 -2
  79. package/dist/{textBlueprints-BMvBJ79v.cjs → textBlueprints-hV1kO8tW.cjs} +7 -7
  80. package/dist/{textBlueprints-myJW6Fzl.js → textBlueprints-kwXeudLb.js} +7 -7
  81. package/dist/{textMetrics-CPFqh2a1.js → textMetrics-BlhkYGHT.js} +1 -1
  82. package/dist/{textMetrics-Byfb_37y.cjs → textMetrics-BmN3SBkI.cjs} +1 -1
  83. package/dist/{threadFns-B6-3UeCZ.js → threadFns-CQErpnNd.js} +7 -7
  84. package/dist/{threadFns-BQIE5dO9.cjs → threadFns-Dd0C7WLp.cjs} +7 -7
  85. package/dist/topology.cjs +9 -9
  86. package/dist/topology.js +9 -9
  87. package/dist/{topologyQueryFns-BtLGfXgL.cjs → topologyQueryFns-DzYSYw51.cjs} +1 -1
  88. package/dist/{topologyQueryFns-CwYkfE3v.js → topologyQueryFns-qvptbhqO.js} +1 -1
  89. package/dist/{validityTypes-C2nklkrH.cjs → validityTypes-Beci6AC-.cjs} +1 -1
  90. package/dist/{validityTypes-Bl3adWZb.js → validityTypes-DF2h0WJo.js} +1 -1
  91. package/package.json +1 -1
package/dist/brepjs.cjs CHANGED
@@ -1,41 +1,41 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
3
- const require_shapeTypes = require("./shapeTypes-DVExh1xP.cjs");
4
- const require_occtWasmAdapter = require("./occtWasmAdapter-DEpy64ji.cjs");
3
+ const require_shapeTypes = require("./shapeTypes-Dz5JzlYx.cjs");
4
+ const require_occtWasmAdapter = require("./occtWasmAdapter-G8mkVxgw.cjs");
5
5
  const require_bug = require("./bug-O02CsAmt.cjs");
6
6
  const require_errors = require("./errors-RHkKO5bZ.cjs");
7
- const require_topologyQueryFns = require("./topologyQueryFns-BtLGfXgL.cjs");
8
- const require_validityTypes = require("./validityTypes-C2nklkrH.cjs");
7
+ const require_topologyQueryFns = require("./topologyQueryFns-DzYSYw51.cjs");
8
+ const require_validityTypes = require("./validityTypes-Beci6AC-.cjs");
9
9
  const require_constants = require("./constants-BOVyEYGH.cjs");
10
10
  const require_types = require("./types-KjA8tY4Y.cjs");
11
11
  const require_vecOps = require("./vecOps-CCnJt-yH.cjs");
12
12
  const require_planeOps = require("./planeOps-VlFxtvzY.cjs");
13
- const require_faceFns = require("./faceFns-C0A8O-2a.cjs");
14
- const require_originTrackingFns = require("./originTrackingFns-CKKmLIUH.cjs");
15
- const require_solidBuilders = require("./solidBuilders-CgW7Ge_s.cjs");
16
- const require_primitiveFns = require("./primitiveFns-C6Trlz8m.cjs");
17
- const require_shapeFns = require("./shapeFns-DDTLk0mJ.cjs");
18
- const require_curveFns = require("./curveFns-jmKL1KZp.cjs");
19
- const require_meshFns = require("./meshFns-CB7HsxzB.cjs");
13
+ const require_faceFns = require("./faceFns-B5UiJH4H.cjs");
14
+ const require_originTrackingFns = require("./originTrackingFns-rh_FbN6R.cjs");
15
+ const require_solidBuilders = require("./solidBuilders-B3EZcVNw.cjs");
16
+ const require_primitiveFns = require("./primitiveFns-BTxppy_Y.cjs");
17
+ const require_shapeFns = require("./shapeFns-xApQafn6.cjs");
18
+ const require_curveFns = require("./curveFns-BYcLLDAB.cjs");
19
+ const require_meshFns = require("./meshFns-B461Ku2S.cjs");
20
20
  const require_arrayAccess = require("./arrayAccess-e4H9cBfh.cjs");
21
- const require_surfaceBuilders = require("./surfaceBuilders-DUTDN2Ay.cjs");
22
- const require_healingFns = require("./healingFns-BqmIvfPm.cjs");
23
- const require_threadFns = require("./threadFns-BQIE5dO9.cjs");
24
- const require_blueprintSketcher = require("./blueprintSketcher-B5UqD0FO.cjs");
25
- const require_helpers = require("./helpers-DLZUxawd.cjs");
26
- const require_blueprint = require("./blueprint-BgbVmx4L.cjs");
27
- const require_drawFns = require("./drawFns-CP82Xdma.cjs");
28
- const require_measureFns = require("./measureFns-CaEuNAZO.cjs");
29
- const require_cornerFinder = require("./cornerFinder-DIe6pMPU.cjs");
30
- const require_boolean2D = require("./boolean2D-p7RMNFtG.cjs");
31
- const require_blueprintFns = require("./blueprintFns-oatmkSjh.cjs");
32
- const require_importFns = require("./importFns-ncp_0vEl.cjs");
33
- const require_loftFns = require("./loftFns-u-yPHpJ9.cjs");
34
- const require_textBlueprints = require("./textBlueprints-BMvBJ79v.cjs");
35
- const require_refResolveFns = require("./refResolveFns-c7RWIsZy.cjs");
36
- const require_adjacencyFns = require("./adjacencyFns-BhdfZany.cjs");
37
- const require_cameraFns = require("./cameraFns-i1otOZ0V.cjs");
38
- const require_textMetrics = require("./textMetrics-Byfb_37y.cjs");
21
+ const require_surfaceBuilders = require("./surfaceBuilders-CVLhWPtB.cjs");
22
+ const require_healingFns = require("./healingFns-ChcvzVB8.cjs");
23
+ const require_threadFns = require("./threadFns-Dd0C7WLp.cjs");
24
+ const require_blueprintSketcher = require("./blueprintSketcher-DeQYScWX.cjs");
25
+ const require_helpers = require("./helpers-C9PIppuU.cjs");
26
+ const require_blueprint = require("./blueprint-CdOcvuG4.cjs");
27
+ const require_drawFns = require("./drawFns-CYW65QTr.cjs");
28
+ const require_measureFns = require("./measureFns-B-UbL3Rw.cjs");
29
+ const require_cornerFinder = require("./cornerFinder-WICP_RPb.cjs");
30
+ const require_boolean2D = require("./boolean2D-C-Azd06V.cjs");
31
+ const require_blueprintFns = require("./blueprintFns-B6zG47o1.cjs");
32
+ const require_importFns = require("./importFns-Bt9YEImO.cjs");
33
+ const require_loftFns = require("./loftFns-CdwKSxw1.cjs");
34
+ const require_textBlueprints = require("./textBlueprints-hV1kO8tW.cjs");
35
+ const require_refResolveFns = require("./refResolveFns-DEU2yvJU.cjs");
36
+ const require_adjacencyFns = require("./adjacencyFns-Clu4DbkI.cjs");
37
+ const require_cameraFns = require("./cameraFns-CdPdw2Ma.cjs");
38
+ const require_textMetrics = require("./textMetrics-BmN3SBkI.cjs");
39
39
  const require_workerPool = require("./workerPool-D30NsiIW.cjs");
40
40
  //#region src/kernel/types.ts
41
41
  /** Check if the kernel supports hidden-line-removal projection. */
@@ -1852,6 +1852,55 @@ function chamfer$1(target, ref, distance) {
1852
1852
  freeParams: depsOf(target, de)
1853
1853
  };
1854
1854
  }
1855
+ function hashShapeRef(h0, ref) {
1856
+ let h = fnvMixString(h0, ref.origin);
1857
+ h = fnvMixString(h, ref.role);
1858
+ const hint = ref.hint;
1859
+ h = fnvMixBool(h, hint.surfaceType !== void 0);
1860
+ if (hint.surfaceType !== void 0) h = fnvMixString(h, hint.surfaceType);
1861
+ h = fnvMixBool(h, hint.normal !== void 0);
1862
+ if (hint.normal) for (const c of hint.normal) h = fnvMixNumber(h, c);
1863
+ h = fnvMixBool(h, hint.centroid !== void 0);
1864
+ if (hint.centroid) for (const c of hint.centroid) h = fnvMixNumber(h, c);
1865
+ h = fnvMixBool(h, hint.area !== void 0);
1866
+ if (hint.area !== void 0) h = fnvMixNumber(h, hint.area);
1867
+ return h;
1868
+ }
1869
+ function copyShapeRef(ref) {
1870
+ const hint = ref.hint;
1871
+ return {
1872
+ origin: ref.origin,
1873
+ role: ref.role,
1874
+ hint: {
1875
+ entityType: "face",
1876
+ ...hint.surfaceType !== void 0 ? { surfaceType: hint.surfaceType } : {},
1877
+ ...hint.normal ? { normal: [...hint.normal] } : {},
1878
+ ...hint.centroid ? { centroid: [...hint.centroid] } : {},
1879
+ ...hint.area !== void 0 ? { area: hint.area } : {}
1880
+ }
1881
+ };
1882
+ }
1883
+ /** Hollow the evaluated target to walls of `thickness`, leaving the faces
1884
+ * named by `refs` open. Refs are serializable node data (the cache key stays
1885
+ * purely structural); they resolve against the materialized target at
1886
+ * evaluation, so an upstream parameter edit re-targets the same faces by
1887
+ * role. Ref order is content-significant. */
1888
+ function shell$1(target, refs, thickness) {
1889
+ const copied = refs.map(copyShapeRef);
1890
+ const te = asScalarExpr(thickness);
1891
+ let h = fnvMixInt32(startHash("Shell"), copied.length);
1892
+ h = mix(h, target);
1893
+ for (const ref of copied) h = hashShapeRef(h, ref);
1894
+ h = mix(h, te);
1895
+ return {
1896
+ kind: "Shell",
1897
+ target,
1898
+ refs: copied,
1899
+ thickness: te,
1900
+ structuralHash: h,
1901
+ freeParams: depsOf(target, te)
1902
+ };
1903
+ }
1855
1904
  /** Attach a color (hex string or RGB/RGBA tuple, canonicalized to RGBA) to
1856
1905
  * the evaluated result of `target`. Metadata rides beside the geometry: the
1857
1906
  * evaluator re-tags the shared target materialization with an independent
@@ -2005,7 +2054,8 @@ function outputKindOf(node) {
2005
2054
  case "Loft":
2006
2055
  case "Sweep":
2007
2056
  case "Fillet":
2008
- case "Chamfer": return "Solid";
2057
+ case "Chamfer":
2058
+ case "Shell": return "Solid";
2009
2059
  case "Profile": return "Face";
2010
2060
  case "Path": return "Wire";
2011
2061
  case "Compound": return "Compound";
@@ -3044,6 +3094,27 @@ function evalChamfer(node, ctx) {
3044
3094
  return require_healingFns.chamfer(solid.value, [resolved.entity], distance.value);
3045
3095
  }
3046
3096
  //#endregion
3097
+ //#region src/csg/evaluators/shell.ts
3098
+ function evalShell(node, ctx) {
3099
+ const thickness = evalScalar(node.thickness, ctx.env, "Shell.thickness");
3100
+ if (!thickness.ok) return thickness;
3101
+ if (!Number.isFinite(thickness.value) || thickness.value <= 0) return require_errors.err(require_errors.validationError("CSG_SHELL_THICKNESS", `Shell.thickness must be positive, got ${thickness.value}`));
3102
+ if (node.refs.length === 0) return require_errors.err(require_errors.validationError("CSG_SHELL_REFS", "Shell needs at least one face ref"));
3103
+ const t = ctx.evalNode(node.target);
3104
+ if (!t.ok) return t;
3105
+ if (!require_shapeTypes.isSolid(t.value)) return require_errors.err(require_errors.validationError("CSG_SHELL_TARGET", "Shell.target did not produce a Solid"));
3106
+ const solid = require_validityTypes.validSolid(t.value);
3107
+ if (!solid.ok) return require_errors.err(require_errors.validationError("CSG_SHELL_TARGET", solid.error));
3108
+ const faces = [];
3109
+ for (const ref of node.refs) {
3110
+ const resolved = require_refResolveFns.resolveRefIn(ref, t.value);
3111
+ if (!resolved.ok) return require_errors.err(require_errors.validationError("CSG_SHELL_REF", `Shell ref '${ref.role}' did not resolve: ${resolved.reason}`));
3112
+ if (!require_shapeTypes.isFace(resolved.entity)) return require_errors.err(require_errors.validationError("CSG_SHELL_REF", `Shell ref '${ref.role}' resolved to a non-face`));
3113
+ faces.push(resolved.entity);
3114
+ }
3115
+ return require_healingFns.shell(solid.value, faces, thickness.value);
3116
+ }
3117
+ //#endregion
3047
3118
  //#region src/csg/evaluate.ts
3048
3119
  function dispatch(node, ctx) {
3049
3120
  switch (node.kind) {
@@ -3076,7 +3147,8 @@ function dispatch(node, ctx) {
3076
3147
  case "Profile":
3077
3148
  case "Color":
3078
3149
  case "Fillet":
3079
- case "Chamfer": return dispatchFeature(node, ctx);
3150
+ case "Chamfer":
3151
+ case "Shell": return dispatchFeature(node, ctx);
3080
3152
  }
3081
3153
  }
3082
3154
  function dispatchFeature(node, ctx) {
@@ -3090,6 +3162,7 @@ function dispatchFeature(node, ctx) {
3090
3162
  case "Color": return evalColor(node, ctx);
3091
3163
  case "Fillet": return evalFillet(node, ctx);
3092
3164
  case "Chamfer": return evalChamfer(node, ctx);
3165
+ case "Shell": return evalShell(node, ctx);
3093
3166
  }
3094
3167
  }
3095
3168
  function hashExprValue(h, v) {
@@ -3499,7 +3572,7 @@ function withEvaluator(options, fn) {
3499
3572
  var MIN_CSG_VERSION = 1;
3500
3573
  function toJSON(node) {
3501
3574
  return {
3502
- csgVersion: 6,
3575
+ csgVersion: 7,
3503
3576
  root: nodeToJson(node)
3504
3577
  };
3505
3578
  }
@@ -3666,6 +3739,19 @@ function edgeRefToJson(ref) {
3666
3739
  }
3667
3740
  };
3668
3741
  }
3742
+ function shapeRefToJson(ref) {
3743
+ return {
3744
+ origin: ref.origin,
3745
+ role: ref.role,
3746
+ hint: {
3747
+ entityType: "face",
3748
+ surfaceType: ref.hint.surfaceType,
3749
+ normal: ref.hint.normal ? [...ref.hint.normal] : void 0,
3750
+ centroid: ref.hint.centroid ? [...ref.hint.centroid] : void 0,
3751
+ area: ref.hint.area
3752
+ }
3753
+ };
3754
+ }
3669
3755
  function contourToJson(c) {
3670
3756
  return {
3671
3757
  start: exprToJson(c.start),
@@ -3752,6 +3838,12 @@ function nodeToJson(n) {
3752
3838
  ref: edgeRefToJson(n.ref),
3753
3839
  distance: exprToJson(n.distance)
3754
3840
  };
3841
+ if (n.kind === "Shell") return {
3842
+ kind: "Shell",
3843
+ target: nodeToJson(n.target),
3844
+ refs: n.refs.map(shapeRefToJson),
3845
+ thickness: exprToJson(n.thickness)
3846
+ };
3755
3847
  if (n.kind === "Compound") return {
3756
3848
  kind: "Compound",
3757
3849
  children: n.children.map(nodeToJson)
@@ -3795,7 +3887,7 @@ function readVec2(v, where) {
3795
3887
  function fromJSON(envelope) {
3796
3888
  if (!isObj(envelope)) return bad("input is not an object");
3797
3889
  const v = envelope["csgVersion"];
3798
- if (typeof v !== "number" || !Number.isInteger(v) || v < MIN_CSG_VERSION || v > 6) return bad(`unsupported csgVersion ${String(v)} (expected ${MIN_CSG_VERSION}..6)`);
3890
+ if (typeof v !== "number" || !Number.isInteger(v) || v < MIN_CSG_VERSION || v > 7) return bad(`unsupported csgVersion ${String(v)} (expected ${MIN_CSG_VERSION}..7)`);
3799
3891
  const root = envelope["root"];
3800
3892
  return readNode(root);
3801
3893
  }
@@ -3912,6 +4004,7 @@ function readNode(j) {
3912
4004
  case "Color": return readColor(j);
3913
4005
  case "Fillet": return readFillet(j);
3914
4006
  case "Chamfer": return readChamfer(j);
4007
+ case "Shell": return readShell(j);
3915
4008
  default: return bad(`unknown node kind: ${String(kind)}`);
3916
4009
  }
3917
4010
  }
@@ -4187,6 +4280,70 @@ function readEdgeRef(j, where) {
4187
4280
  }
4188
4281
  });
4189
4282
  }
4283
+ var SURFACE_TYPES = /* @__PURE__ */ new Set([
4284
+ "PLANE",
4285
+ "CYLINDRE",
4286
+ "CONE",
4287
+ "SPHERE",
4288
+ "TORUS",
4289
+ "BEZIER_SURFACE",
4290
+ "BSPLINE_SURFACE",
4291
+ "REVOLUTION_SURFACE",
4292
+ "EXTRUSION_SURFACE",
4293
+ "OFFSET_SURFACE",
4294
+ "OTHER_SURFACE"
4295
+ ]);
4296
+ function readShapeRef(j, where) {
4297
+ if (!isObj(j)) return bad(`${where}: not an object`);
4298
+ const origin = j["origin"];
4299
+ if (!isString(origin)) return bad(`${where}.origin: not a string`);
4300
+ const role = j["role"];
4301
+ if (!isString(role)) return bad(`${where}.role: not a string`);
4302
+ const hintRaw = j["hint"];
4303
+ if (!isObj(hintRaw)) return bad(`${where}.hint: not an object`);
4304
+ const surfaceType = hintRaw["surfaceType"];
4305
+ if (surfaceType !== void 0 && (!isString(surfaceType) || !SURFACE_TYPES.has(surfaceType))) return bad(`${where}.hint.surfaceType`);
4306
+ const area = hintRaw["area"];
4307
+ if (area !== void 0 && !isNumber$1(area)) return bad(`${where}.hint.area`);
4308
+ let normal;
4309
+ if (hintRaw["normal"] !== void 0) {
4310
+ const n = readVec3(hintRaw["normal"], `${where}.hint.normal`);
4311
+ if (!n.ok) return n;
4312
+ normal = n.value;
4313
+ }
4314
+ let centroid;
4315
+ if (hintRaw["centroid"] !== void 0) {
4316
+ const c = readVec3(hintRaw["centroid"], `${where}.hint.centroid`);
4317
+ if (!c.ok) return c;
4318
+ centroid = c.value;
4319
+ }
4320
+ return require_errors.ok({
4321
+ origin,
4322
+ role,
4323
+ hint: {
4324
+ entityType: "face",
4325
+ ...surfaceType !== void 0 ? { surfaceType } : {},
4326
+ ...normal ? { normal } : {},
4327
+ ...centroid ? { centroid } : {},
4328
+ ...area !== void 0 ? { area } : {}
4329
+ }
4330
+ });
4331
+ }
4332
+ function readShell(j) {
4333
+ const target = readNode(j["target"]);
4334
+ if (!target.ok) return target;
4335
+ const thickness = readExpr(j["thickness"]);
4336
+ if (!thickness.ok) return thickness;
4337
+ const rawRefs = j["refs"];
4338
+ if (!Array.isArray(rawRefs) || rawRefs.length === 0) return bad("Shell.refs: expected a non-empty array");
4339
+ const refs = [];
4340
+ for (const [i, raw] of rawRefs.entries()) {
4341
+ const ref = readShapeRef(raw, `Shell.refs[${i}]`);
4342
+ if (!ref.ok) return ref;
4343
+ refs.push(ref.value);
4344
+ }
4345
+ return require_errors.ok(shell$1(target.value, refs, thickness.value));
4346
+ }
4190
4347
  function readFillet(j) {
4191
4348
  const target = readNode(j["target"]);
4192
4349
  if (!target.ok) return target;
@@ -4365,7 +4522,8 @@ function optimizeNode(n) {
4365
4522
  case "Path":
4366
4523
  case "Color":
4367
4524
  case "Fillet":
4368
- case "Chamfer": return optimizeFeature(n);
4525
+ case "Chamfer":
4526
+ case "Shell": return optimizeFeature(n);
4369
4527
  }
4370
4528
  }
4371
4529
  function optimizeFeature(n) {
@@ -4382,6 +4540,7 @@ function optimizeFeature(n) {
4382
4540
  case "Color": return color(optimizeNode(n.target), [...n.color]);
4383
4541
  case "Fillet": return fillet$1(optimizeNode(n.target), n.ref, foldExpr(n.radius));
4384
4542
  case "Chamfer": return chamfer$1(optimizeNode(n.target), n.ref, foldExpr(n.distance));
4543
+ case "Shell": return shell$1(optimizeNode(n.target), n.refs, foldExpr(n.thickness));
4385
4544
  }
4386
4545
  }
4387
4546
  function optimizeTransform(n) {
@@ -4493,7 +4652,8 @@ function rebuildChildren(n, pred, repl) {
4493
4652
  case "Sweep":
4494
4653
  case "Color":
4495
4654
  case "Fillet":
4496
- case "Chamfer": return rebuildFeature(n, pred, repl);
4655
+ case "Chamfer":
4656
+ case "Shell": return rebuildFeature(n, pred, repl);
4497
4657
  }
4498
4658
  }
4499
4659
  function rebuildFeature(n, pred, repl) {
@@ -4508,6 +4668,7 @@ function rebuildFeature(n, pred, repl) {
4508
4668
  case "Color": return color(walk(n.target, pred, repl), [...n.color]);
4509
4669
  case "Fillet": return fillet$1(walk(n.target, pred, repl), n.ref, n.radius);
4510
4670
  case "Chamfer": return chamfer$1(walk(n.target, pred, repl), n.ref, n.distance);
4671
+ case "Shell": return shell$1(walk(n.target, pred, repl), n.refs, n.thickness);
4511
4672
  }
4512
4673
  }
4513
4674
  function forEachNode(root, fn) {
@@ -4539,7 +4700,8 @@ function childrenOf(n) {
4539
4700
  case "Mirror":
4540
4701
  case "Color":
4541
4702
  case "Fillet":
4542
- case "Chamfer": return [n.target];
4703
+ case "Chamfer":
4704
+ case "Shell": return [n.target];
4543
4705
  case "Compound": return n.children;
4544
4706
  case "Instance": return [n.source];
4545
4707
  case "Extrude":
@@ -8550,7 +8712,7 @@ var patterns_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
8550
8712
  //#endregion
8551
8713
  //#region src/ns/csg.ts
8552
8714
  var csg_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
8553
- CSG_VERSION: () => 6,
8715
+ CSG_VERSION: () => 7,
8554
8716
  Evaluator: () => Evaluator,
8555
8717
  add: () => add$1,
8556
8718
  arbitraryClosedProfile: () => arbitraryClosedProfile,
@@ -8612,6 +8774,7 @@ var csg_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
8612
8774
  revolve: () => revolve$1,
8613
8775
  rotate: () => rotate$1,
8614
8776
  scale: () => scale$2,
8777
+ shell: () => shell$1,
8615
8778
  sphere: () => sphere$2,
8616
8779
  sweep: () => sweep$2,
8617
8780
  tShapeProfile: () => tShapeProfile,