brepjs 12.3.0 → 12.5.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 (65) hide show
  1. package/README.md +82 -259
  2. package/dist/2d/blueprints/Blueprint.d.ts +1 -1
  3. package/dist/2d/blueprints/Blueprint.d.ts.map +1 -1
  4. package/dist/2d.cjs +2 -2
  5. package/dist/2d.js +3 -3
  6. package/dist/{Blueprint-Bh6166KA.cjs → Blueprint-CoFJDAQd.cjs} +6 -6
  7. package/dist/{Blueprint-BBLKmtl9.js → Blueprint-CtuUvzex.js} +6 -6
  8. package/dist/{boolean2D-Bl4iyJfa.cjs → boolean2D-Dk-vLBdl.cjs} +8 -8
  9. package/dist/{boolean2D-D2s-G0Wm.js → boolean2D-x2irapGj.js} +8 -8
  10. package/dist/{booleanFns-DdbAk1KC.cjs → booleanFns-BJjYqwJ5.cjs} +3 -3
  11. package/dist/{booleanFns-CKWVFBtF.js → booleanFns-DtOkwLHI.js} +3 -3
  12. package/dist/brepjs.cjs +218 -17
  13. package/dist/brepjs.js +229 -28
  14. package/dist/core.cjs +1 -1
  15. package/dist/core.js +1 -1
  16. package/dist/{cornerFinder-zd2oBgyp.cjs → cornerFinder-BESZIitp.cjs} +2 -2
  17. package/dist/{cornerFinder-C-o3TN3q.js → cornerFinder-FY38t0zq.js} +2 -2
  18. package/dist/{curveFns-p0x8jy0i.cjs → curveFns-Ch87sD5O.cjs} +1 -1
  19. package/dist/{curveFns-DyVPTb1r.js → curveFns-LRNGcHXh.js} +1 -1
  20. package/dist/{drawFns-DXwZzno9.cjs → drawFns-BEeoD1yO.cjs} +16 -16
  21. package/dist/{drawFns-DpAQM_F6.js → drawFns-D8QyY7cg.js} +16 -16
  22. package/dist/{faceFns-CvR-ZEQA.js → faceFns-B6ebRh5I.js} +1 -1
  23. package/dist/{faceFns-SVADeb01.cjs → faceFns-BLTEPBKq.cjs} +1 -1
  24. package/dist/{helpers-3fsqd4mW.cjs → helpers-DNzVfe-Z.cjs} +4 -4
  25. package/dist/{helpers-F_D1WON3.js → helpers-DeFPsrcI.js} +4 -4
  26. package/dist/io.cjs +3 -3
  27. package/dist/io.js +3 -3
  28. package/dist/kernel/brepkitAdapter.d.ts +30 -0
  29. package/dist/kernel/brepkitAdapter.d.ts.map +1 -1
  30. package/dist/kernel/brepkitWasmTypes.d.ts +2 -2
  31. package/dist/kernel/brepkitWasmTypes.d.ts.map +1 -1
  32. package/dist/kernel/defaultAdapter.d.ts +34 -0
  33. package/dist/kernel/defaultAdapter.d.ts.map +1 -1
  34. package/dist/kernel/types.d.ts +68 -0
  35. package/dist/kernel/types.d.ts.map +1 -1
  36. package/dist/{loft-98s9uwpg.cjs → loft-DR1UN5uN.cjs} +4 -4
  37. package/dist/{loft-BvZFfPqO.js → loft-DsVv4yxU.js} +4 -4
  38. package/dist/{measurement-g8ldN7oe.cjs → measurement-DoYXRaKI.cjs} +2 -2
  39. package/dist/{measurement-vbHd9lpV.js → measurement-oWvhSVZG.js} +2 -2
  40. package/dist/measurement.cjs +1 -1
  41. package/dist/measurement.js +1 -1
  42. package/dist/{meshFns-CF-JdX5P.cjs → meshFns-BU2l_yOm.cjs} +2 -2
  43. package/dist/{meshFns-RN83Wiry.js → meshFns-HNwWuM4v.js} +2 -2
  44. package/dist/{operations-CrLZ6fyL.cjs → operations-D-gTZNtM.cjs} +6 -6
  45. package/dist/{operations-CxvdnWzU.js → operations-D_3rrfrE.js} +6 -6
  46. package/dist/operations.cjs +2 -2
  47. package/dist/operations.js +2 -2
  48. package/dist/query.cjs +4 -4
  49. package/dist/query.js +5 -5
  50. package/dist/{shapeFns-38GljA_p.js → shapeFns-CbXxLvV_.js} +2 -2
  51. package/dist/{shapeFns-BoN5g5Bx.cjs → shapeFns-DHlLNHTn.cjs} +2 -2
  52. package/dist/{shapeTypes-DTGA0liC.cjs → shapeTypes-7xEam9Ri.cjs} +103 -0
  53. package/dist/{shapeTypes-5DPsHB8i.js → shapeTypes-CpSaBLDv.js} +103 -0
  54. package/dist/sketching.cjs +2 -2
  55. package/dist/sketching.js +2 -2
  56. package/dist/{solidBuilders-BWkneWjU.js → solidBuilders-BXhh5hP2.js} +2 -2
  57. package/dist/{solidBuilders-CUc2rvWv.cjs → solidBuilders-BzfRBizW.cjs} +2 -2
  58. package/dist/{surfaceBuilders-tYoe8sri.cjs → surfaceBuilders-Be_ENWSA.cjs} +2 -2
  59. package/dist/{surfaceBuilders-CXbEDGBQ.js → surfaceBuilders-D7ZH2QNS.js} +2 -2
  60. package/dist/topology/adjacencyFns.d.ts.map +1 -1
  61. package/dist/{topology-CH4LBfQg.cjs → topology-BHnY7Szr.cjs} +8 -8
  62. package/dist/{topology-Bq7mZh3W.js → topology-C1eZ86dI.js} +8 -8
  63. package/dist/topology.cjs +6 -6
  64. package/dist/topology.js +6 -6
  65. package/package.json +5 -7
package/README.md CHANGED
@@ -1,14 +1,15 @@
1
1
  # brepjs
2
2
 
3
- CAD modeling for JavaScript. Build 3D geometry with code.
3
+ CAD modeling for JavaScript.
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/brepjs)](https://www.npmjs.com/package/brepjs)
6
6
  [![CI](https://github.com/andymai/brepjs/actions/workflows/ci.yml/badge.svg)](https://github.com/andymai/brepjs/actions/workflows/ci.yml)
7
7
  [![License](https://img.shields.io/badge/License-AGPL_3.0-blue.svg)](./LICENSE)
8
8
 
9
- **[Docs](https://andymai.github.io/brepjs/)** · **[Examples](./examples/)** · **[Cheat Sheet](./docs/cheat-sheet.md)** · **[Getting Started](./docs/getting-started.md)**
9
+ **[Docs](https://andymai.github.io/brepjs/)** · **[Cheat Sheet](./docs/cheat-sheet.md)** · **[Getting Started](./docs/getting-started.md)**
10
10
 
11
11
  ```typescript
12
+ // Drill a hole, fillet the vertical edges, export to STEP
12
13
  import { box, cut, cylinder, fillet, edgeFinder, exportSTEP, unwrap } from 'brepjs/quick';
13
14
 
14
15
  const b = box(30, 20, 10);
@@ -21,297 +22,117 @@ const part = unwrap(fillet(drilled, edges, 1.5));
21
22
  const step = unwrap(exportSTEP(part));
22
23
  ```
23
24
 
24
- ## Why brepjs?
25
+ ## Why?
25
26
 
26
- Most CAD libraries for the web are mesh-based they work with triangles, not real geometry. brepjs gives you boundary representation (B-Rep) modeling with a pluggable geometry kernel. Exact booleans, fillets, and export to formats real CAD software can open.
27
+ brepjs grew out of the love and care I put into [gridfinitylayouttool.com](https://gridfinitylayouttool.com). I needed parametric CAD in the browser and I'm not a 3D modeler, but I know TypeScript. [OpenSCAD](https://openscad.org/) nailed code-first CAD but lives outside the JS ecosystem. [replicad](https://replicad.xyz/) proved OpenCascade works in JS but I kept hitting performance walls and fighting the API.
27
28
 
28
- ## Install
29
-
30
- ```bash
31
- npm install brepjs brepjs-opencascade
32
- ```
33
-
34
- `brepjs/quick` auto-initializes the WASM kernel via top-level await (ESM only). For CJS or manual control:
35
-
36
- ```typescript
37
- import opencascade from 'brepjs-opencascade';
38
- import { initFromOC } from 'brepjs';
39
-
40
- const oc = await opencascade();
41
- initFromOC(oc);
42
- ```
43
-
44
- ## Features
45
-
46
- **Modeling** — `box`, `cylinder`, `sphere`, `cone`, `torus`, `ellipsoid`, `polyhedron` plus `extrude`, `revolve`, `loft`, `sweep` from 2D sketches
47
-
48
- **Booleans** — `fuse`, `cut`, `intersect`, `section`, `split`, `slice` with batch variants `fuseAll`, `cutAll`
49
-
50
- **Modifiers** — `fillet`, `chamfer`, `shell`, `offset`, `thicken`, `resize`. Accepts `ShapeFinder` directly
51
-
52
- **Transforms** — `translate`, `rotate`, `mirror`, `scale`, `applyMatrix`, `composeTransforms`, `transformCopy`
29
+ Neither had the type safety I wanted, so brepjs leans hard on it: branded types, `Result<T,E>`, phantom types that prove invariants at compile time. If it compiles, the geometry is valid.
53
30
 
54
- **Sketching** — `draw`, `drawRectangle`, `drawCircle`, `Sketcher`, `sketchCircle`, `sketchHelix` for 2D-to-3D workflows
31
+ ## Status
55
32
 
56
- **Queries** `edgeFinder`, `faceFinder`, `wireFinder`, `vertexFinder` with composable filters like `.inDirection('Z')`, `.ofCurveType('CIRCLE')`, `.ofLength(10)`
33
+ Production-ready with the OpenCascade kernel. [brepkit](https://github.com/andymai/brepkit), a Rust-based kernel, is in active development as a faster replacement but not yet production-ready. The kernel abstraction layer means switching is a one-line change.
57
34
 
58
- **Measurement** — `measureVolume`, `measureArea`, `measureLength`, `measureDistance`, `checkInterference`
35
+ ## Benchmarks
59
36
 
60
- **Import/Export** — STEP, STL, glTF/GLB, DXF (import + export), 3MF, OBJ, SVG (import). Assembly export with colors and names via `exportAssemblySTEP`
37
+ Median times, 5 iterations, Node.js on Linux x86_64. Full results in [`benchmarks/results/latest.md`](./benchmarks/results/latest.md).
61
38
 
62
- **Advanced Geometry** `hull`, `minkowski`, `fill`, `roof`, `surfaceFromGrid`
39
+ ### WASM bundle size
63
40
 
64
- **Colors** Per-shape colors that propagate through booleans and modifiers
41
+ | Kernel | Size |
42
+ | ---------------------------------------------------------------------- | ------ |
43
+ | [brepjs-opencascade](https://www.npmjs.com/package/brepjs-opencascade) | 11 MB |
44
+ | [brepkit](https://github.com/andymai/brepkit) (Rust, in development) | 1.8 MB |
65
45
 
66
- **Rendering** `mesh` and `toBufferGeometryData` for Three.js / WebGL integration
46
+ brepjs-opencascade is a heavily optimized custom build of OpenCascade: trimmed to only the classes brepjs needs, with custom C++ bulk-extraction classes (mesh, booleans, topology) that bypass the JS-WASM bridge for hot paths. It's already about as fast as OCCT gets in the browser.
67
47
 
68
- **Text** `loadFont`, `drawText`, `sketchText`, `textMetrics`
48
+ ### Boolean operations
69
49
 
70
- **Healing** `autoHeal`, `healSolid`, `healFace`, `isValid` for fixing imported geometry
50
+ | Operation | brepjs-opencascade | brepkit | Speedup |
51
+ | ---------------------- | ------------------ | ------- | ------- |
52
+ | fuse(box, box) | 83.7 ms | 5.7 ms | 15x |
53
+ | cut(box, cylinder) | 123.8 ms | 4.2 ms | 29x |
54
+ | intersect(box, sphere) | 107.1 ms | 31.9 ms | 3.4x |
71
55
 
72
- **Patterns** — `linearPattern`, `circularPattern` for arraying shapes
56
+ ### Primitives
73
57
 
74
- **Assemblies** `createAssemblyNode`, `addChild`, `walkAssembly`, `collectShapes`, assembly mates
58
+ | Operation | brepjs-opencascade | brepkit | Speedup |
59
+ | ------------ | ------------------ | ------- | ------- |
60
+ | makeBox | 5.9 ms | 0.2 ms | 25x |
61
+ | makeCylinder | 2.3 ms | 0.1 ms | 16x |
62
+ | makeSphere | 1.4 ms | 0.5 ms | 3x |
75
63
 
76
- **Face Tracking** — Face origin tracking and face tags across boolean operations
64
+ ### End-to-end
77
65
 
78
- **Workers** `createWorkerClient`, `createWorkerHandler` for off-main-thread operations
79
-
80
- **History** `createHistory`, `addStep`, `undoLast`, `replayHistory` for parametric undo/replay
81
-
82
- ## A Larger Example
83
-
84
- A flanged pipe with bolt holes showing booleans, shelling, fillets, and finders:
85
-
86
- ```typescript
87
- import {
88
- cylinder,
89
- fuse,
90
- cut,
91
- shell,
92
- fillet,
93
- rotate,
94
- faceFinder,
95
- edgeFinder,
96
- measureVolume,
97
- unwrap,
98
- } from 'brepjs/quick';
99
-
100
- // Tube + flanges
101
- const tube = cylinder(15, 100);
102
- const body = unwrap(fuse(unwrap(fuse(tube, cylinder(30, 5))), cylinder(30, 5, { at: [0, 0, 95] })));
103
-
104
- // Hollow out — find top face, shell to 2mm walls
105
- const topFaces = faceFinder().parallelTo('XY').atDistance(100, [0, 0, 0]).findAll(body);
106
- const hollowed = unwrap(shell(body, topFaces, 2));
107
-
108
- // Fillet the tube-to-flange transitions
109
- const filletEdges = edgeFinder()
110
- .ofCurveType('CIRCLE')
111
- .ofLength(2 * Math.PI * 15)
112
- .findAll(hollowed);
113
- let result = unwrap(fillet(hollowed, filletEdges, 3));
114
-
115
- // Bolt holes around each flange
116
- for (let i = 0; i < 6; i++) {
117
- const angle = 60 * i;
118
- const hole = rotate(cylinder(3, 10, { at: [22, 0, -2] }), angle, { axis: [0, 0, 1] });
119
- result = unwrap(cut(result, hole));
120
- }
121
-
122
- console.log('Volume:', measureVolume(result), 'mm³');
123
- ```
124
-
125
- ## Common Patterns
126
-
127
- ### Memory cleanup
128
-
129
- WASM objects aren't garbage-collected. Use `using` (TS 5.9+) or `DisposalScope` for deterministic cleanup:
130
-
131
- ```typescript
132
- import { box, cylinder, cut, unwrap, DisposalScope } from 'brepjs/quick';
133
-
134
- // Option 1: using keyword — auto-disposed at block end
135
- {
136
- using temp = box(10, 10, 10);
137
- using hole = cylinder(3, 15);
138
- const result = unwrap(cut(temp, hole));
139
- // temp and hole freed here; result survives
140
- }
141
-
142
- // Option 2: DisposalScope — deterministic cleanup
143
- function buildPart() {
144
- using scope = new DisposalScope();
145
- const b = scope.register(box(10, 10, 10));
146
- const hole = scope.register(cylinder(3, 15));
147
- return unwrap(cut(b, hole)); // b and hole freed when scope exits
148
- }
149
- ```
150
-
151
- ### Immutability
152
-
153
- All operations return new shapes — the original is never modified:
154
-
155
- ```typescript
156
- import { box, translate, rotate, measureVolume } from 'brepjs/quick';
157
-
158
- const original = box(30, 20, 10);
159
- const moved = translate(original, [100, 0, 0]);
160
- const rotated = rotate(moved, 45, { axis: [0, 0, 1] });
161
-
162
- // original is unchanged
163
- console.log(measureVolume(original) === measureVolume(moved)); // true — same geometry, different position
164
- ```
66
+ | Operation | brepjs-opencascade | brepkit | Speedup |
67
+ | ---------------------- | ------------------ | ------- | ------- |
68
+ | box + chamfer | 7.8 ms | 0.1 ms | 70x |
69
+ | box + fillet | 8.1 ms | 0.3 ms | 28x |
70
+ | multi-boolean model | 52.0 ms | 1.7 ms | 31x |
71
+ | mesh sphere (tol=0.01) | 61.3 ms | 20.0 ms | 3x |
72
+ | exportSTEP x10 | 19.2 ms | 0.9 ms | 21x |
165
73
 
166
- ### Chaining transforms
74
+ ## What you can build
167
75
 
168
- Apply translation then rotation (functional or wrapper style):
76
+ Code-as-CAD is great for parts defined by parameters - enclosures, brackets, fixtures, gridfinity bins. Less suited for organic sculpting. Think parametric part generators, browser-based CAD tools, automated manufacturing pipelines, 3D printing workflows.
169
77
 
170
- ```typescript
171
- import { box, translate, rotate, shape } from 'brepjs/quick';
172
-
173
- // Functional — each call returns a new shape
174
- const b = box(30, 20, 10);
175
- const moved = translate(b, [50, 0, 0]);
176
- const result = rotate(moved, 45, { axis: [0, 0, 1] });
177
-
178
- // Wrapper — fluent chaining
179
- const same = shape(box(30, 20, 10))
180
- .translate([50, 0, 0])
181
- .rotate(45, { axis: [0, 0, 1] }).val;
182
- ```
183
-
184
- ### 2D sketch to 3D extrusion
185
-
186
- Draw a 2D profile, then extrude it to create a solid:
187
-
188
- ```typescript
189
- import { drawRectangle, drawCircle, drawingCut, drawingToSketchOnPlane, shape } from 'brepjs/quick';
190
-
191
- // Draw 2D rectangle with a hole
192
- const profile = drawingCut(drawRectangle(50, 30), drawCircle(8).translate([25, 15]));
193
-
194
- // Convert to sketch on XY plane, extrude 20mm
195
- const sketch = drawingToSketchOnPlane(profile, 'XY');
196
- const solid = shape(sketch.face()).extrude(20).val;
78
+ ## Install
197
79
 
198
- // Or use the sketch shortcut directly
199
- import { sketchRectangle } from 'brepjs/quick';
200
- const quickBox = sketchRectangle(50, 30).extrude(20);
80
+ ```bash
81
+ npm install brepjs brepjs-opencascade
201
82
  ```
202
83
 
203
- ### STEP import and export
204
-
205
- Load a STEP file, modify it, and re-export:
84
+ `brepjs/quick` handles WASM init automatically via top-level await (ESM only). Manual setup:
206
85
 
207
86
  ```typescript
208
- import { importSTEP, exportSTEP, shape, unwrap } from 'brepjs/quick';
209
-
210
- // Import from Blob (e.g., from file input or fs.readFileSync)
211
- const imported = unwrap(await importSTEP(stepBlob));
212
-
213
- // Modify the imported shape
214
- const modified = shape(imported).fillet(2).translate([0, 0, 10]).val;
215
-
216
- // Export back to STEP
217
- const outputBlob = unwrap(exportSTEP(modified));
87
+ import opencascade from 'brepjs-opencascade';
88
+ import { initFromOC } from 'brepjs';
218
89
 
219
- // Save to disk (Node.js)
220
- import { writeFileSync } from 'fs';
221
- writeFileSync('output.step', Buffer.from(await outputBlob.arrayBuffer()));
90
+ const oc = await opencascade();
91
+ initFromOC(oc);
222
92
  ```
223
93
 
224
- ### Custom geometry kernel
94
+ ## Features
225
95
 
226
- brepjs is kernel-agnostic you can register alternative geometry kernels at runtime:
96
+ **Modeling** - `box`, `cylinder`, `sphere`, `cone`, `torus`, `ellipsoid`, `polyhedron` plus `extrude`, `revolve`, `loft`, `sweep` from 2D sketches
227
97
 
228
- ```typescript
229
- import { registerKernel, withKernel, box } from 'brepjs';
98
+ **Booleans** - `fuse`, `cut`, `intersect`, `section`, `split`, `slice` with batch variants `fuseAll`, `cutAll`
230
99
 
231
- registerKernel('my-kernel', myAdapter);
232
- const result = box(10, 10, 10); // uses your kernel
233
- ```
100
+ **Modifiers** - `fillet`, `chamfer`, `shell`, `offset`, `thicken`, `resize`
234
101
 
235
- The kernel abstraction layer in `src/kernel/` ensures brepjs code never touches kernel internals directly. See the [Custom Kernel Guide](docs/kernel-swap.md) for writing your own `KernelAdapter`.
102
+ **Transforms** - `translate`, `rotate`, `mirror`, `scale`, `applyMatrix`, `composeTransforms`, `transformCopy`
236
103
 
237
- ### Parametric variations
104
+ **Sketching** - `draw`, `drawRectangle`, `drawCircle`, `Sketcher`, `sketchCircle`, `sketchHelix` for 2D profiles and paths
238
105
 
239
- Generate multiple part variations by iterating over dimensions:
106
+ **Queries** - `edgeFinder`, `faceFinder`, `wireFinder`, `vertexFinder` with composable filters like `.inDirection('Z')`, `.ofCurveType('CIRCLE')`, `.ofLength(10)`
240
107
 
241
- ```typescript
242
- import { box, cylinder, cut, fillet, edgeFinder, unwrap, exportSTEP } from 'brepjs/quick';
243
-
244
- function makeBracket(width: number, holeRadius: number) {
245
- const base = box(width, 20, 10);
246
- const hole = cylinder(holeRadius, 15, { at: [width / 2, 10, -2] });
247
- const drilled = unwrap(cut(base, hole));
248
- const edges = edgeFinder().inDirection('Z').findAll(drilled);
249
- return unwrap(fillet(drilled, edges, 1.5));
250
- }
251
-
252
- // Generate variants
253
- for (const width of [30, 40, 50, 60]) {
254
- const part = makeBracket(width, width / 10);
255
- const step = unwrap(exportSTEP(part));
256
- console.log(`${width}mm bracket: ${step.size} bytes`);
257
- }
258
- ```
108
+ **Measurement** - `measureVolume`, `measureArea`, `measureLength`, `measureDistance`, `checkInterference`
259
109
 
260
- ## Examples
110
+ **Import/Export** - STEP, STL, glTF/GLB, DXF (import + export), 3MF, OBJ, SVG (import). Assembly export with colors and names via `exportAssemblySTEP`
261
111
 
262
- ```bash
263
- npm run example examples/mounting-block.ts
264
- ```
112
+ **Advanced Geometry** - `hull`, `minkowski`, `fill`, `roof`, `surfaceFromGrid`
265
113
 
266
- | Example | Level | What it does |
267
- | ----------------------------------------------------- | ------------ | -------------------------------------------------------------- |
268
- | [mounting-block.ts](./examples/mounting-block.ts) | Beginner | Game die with filleted edges and `cutAll` dot indentations |
269
- | [shelf-bracket.ts](./examples/shelf-bracket.ts) | Intermediate | Spur gear with `rotate` patterning and `fuseAll` teeth |
270
- | [pen-cup.ts](./examples/pen-cup.ts) | Intermediate | Hollowed container using `shell` and `faceFinder` |
271
- | [lofted-vase.ts](./examples/lofted-vase.ts) | Advanced | Multi-section `loft` through circular profiles, then shelled |
272
- | [compartment-tray.ts](./examples/compartment-tray.ts) | Advanced | Storage tray with dividers: `fuseAll` → `intersect` → `cutAll` |
114
+ **Colors** - Per-shape colors that propagate through booleans and modifiers
273
115
 
274
- ## Imports
116
+ **Rendering** - `mesh` and `toBufferGeometryData` for Three.js / WebGL integration
275
117
 
276
- Everything is available from the top level:
118
+ **Text** - `loadFont`, `drawText`, `sketchText`, `textMetrics`
277
119
 
278
- ```typescript
279
- import { box, translate, fuse, exportSTEP } from 'brepjs';
280
- ```
120
+ **Healing** - `autoHeal`, `healSolid`, `healFace`, `isValid` for fixing imported geometry
281
121
 
282
- Sub-path imports for tree-shaking:
122
+ **Patterns** - `linearPattern`, `circularPattern` for arraying shapes
283
123
 
284
- ```typescript
285
- import { box, fuse, fillet } from 'brepjs/topology';
286
- import { importSTEP, exportSTEP } from 'brepjs/io';
287
- import { measureVolume } from 'brepjs/measurement';
288
- import { edgeFinder, faceFinder } from 'brepjs/query';
289
- import { sketchCircle, draw, drawRectangle, drawCircle } from 'brepjs/sketching';
290
- import { createAssemblyNode } from 'brepjs/operations';
291
- import { createWorkerClient } from 'brepjs/worker';
292
- import { Result, isOk, unwrap } from 'brepjs/result';
293
- import { toVec3, vecAdd, vecNormalize } from 'brepjs/vectors';
294
- ```
124
+ **Assemblies** - `createAssemblyNode`, `addChild`, `addMate`, `walkAssembly`, `collectShapes`
295
125
 
296
- ## Error Handling
126
+ **Face Tracking** - Face origin tracking and face tags across boolean operations
297
127
 
298
- Operations that can fail return a `Result` instead of throwing:
128
+ **Workers** - `createWorkerClient`, `createWorkerHandler` for off-main-thread operations
299
129
 
300
- ```typescript
301
- const result = fuse(a, b);
130
+ **History** - `createHistory`, `addStep`, `undoLast`, `replayHistory` for parametric undo/replay
302
131
 
303
- if (isOk(result)) {
304
- const fused = result.value;
305
- }
306
-
307
- // Or throw on failure
308
- const fused = unwrap(fuse(a, b));
309
- ```
132
+ **Error Handling** - `Result<T,E>` instead of exceptions. `isOk()`, `unwrap()`, `match()`
310
133
 
311
134
  ## Architecture
312
135
 
313
- Four layers with enforced import boundaries (imports flow downward only):
314
-
315
136
  ```
316
137
  Layer 3 sketching/, text/, projection/ High-level API
317
138
  Layer 2 topology/, operations/, 2d/ ... Domain logic
@@ -319,21 +140,23 @@ Layer 1 core/ Types, memory, errors
319
140
  Layer 0 kernel/, utils/ WASM bindings
320
141
  ```
321
142
 
143
+ Imports flow downward only. Boundaries are enforced in CI.
144
+
322
145
  ## Documentation
323
146
 
324
- - [API Reference](https://andymai.github.io/brepjs/) Searchable TypeDoc reference
325
- - [Zero to Shape](./docs/zero-to-shape.md) First shape in 60 seconds
326
- - [Getting Started](./docs/getting-started.md) Install to first part
327
- - [B-Rep Concepts](./docs/concepts.md) Vertices, edges, faces, solids
328
- - [Cheat Sheet](./docs/cheat-sheet.md) Single-page reference for common operations
329
- - [Cookbook](./docs/cookbook.md) Practical recipes for common CAD workflows
330
- - [Which API?](./docs/which-api.md) Sketcher vs functional vs Drawing
331
- - [Function Lookup](./docs/function-lookup.md) Alphabetical index of every export
332
- - [Memory Management](./docs/memory-management.md) Resource cleanup patterns
333
- - [Error Reference](./docs/errors.md) Error codes and recovery
334
- - [Architecture](./docs/architecture.md) Layer diagram and module overview
335
- - [Performance](./docs/performance.md) Optimization tips
336
- - [Compatibility](./docs/compatibility.md) Tested environments
147
+ - [API Reference](https://andymai.github.io/brepjs/): Searchable TypeDoc reference
148
+ - [Zero to Shape](./docs/zero-to-shape.md): First shape in 60 seconds
149
+ - [Getting Started](./docs/getting-started.md): From install to first shape
150
+ - [B-Rep Concepts](./docs/concepts.md): Vertices, edges, faces, solids
151
+ - [Cheat Sheet](./docs/cheat-sheet.md): Single-page reference for common operations
152
+ - [Cookbook](./docs/cookbook.md): Practical recipes for common CAD workflows
153
+ - [Which API?](./docs/which-api.md): Sketcher vs functional vs Drawing
154
+ - [Function Lookup](./docs/function-lookup.md): Alphabetical index of every export
155
+ - [Memory Management](./docs/memory-management.md): Resource cleanup patterns
156
+ - [Error Reference](./docs/errors.md): Error codes and recovery
157
+ - [Architecture](./docs/architecture.md): Layer diagram and module overview
158
+ - [Performance](./docs/performance.md): Optimization tips
159
+ - [Compatibility](./docs/compatibility.md): Tested environments
337
160
 
338
161
  ## Packages
339
162
 
@@ -344,7 +167,7 @@ Layer 0 kernel/, utils/ WASM bindings
344
167
 
345
168
  ## Projects Using brepjs
346
169
 
347
- - [Gridfinity Layout Tool](https://github.com/andymai/gridfinity-layout-tool) Web-based layout generator for Gridfinity storage systems
170
+ - [Gridfinity Layout Tool](https://github.com/andymai/gridfinity-layout-tool): Web-based layout generator for Gridfinity storage systems
348
171
 
349
172
  ## Development
350
173
 
@@ -123,7 +123,7 @@ export default class Blueprint implements DrawingInterface {
123
123
  * @param origin - Optional UV origin offset (defaults to the face center).
124
124
  * @returns A new Face bounded by the blueprint's profile.
125
125
  */
126
- subFace(face: Face, origin?: PointInput | null): Face;
126
+ private subFace;
127
127
  /**
128
128
  * Cut a prism-shaped hole through a solid along a face using this blueprint.
129
129
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Blueprint.d.ts","sourceRoot":"","sources":["../../../src/2d/blueprints/Blueprint.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAY9C,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAQvE,OAAO,KAAK,EAAE,QAAQ,EAAc,SAAS,EAAE,IAAI,EAAQ,MAAM,0BAA0B,CAAC;AAQ5F,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAWzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,OAAO,OAAO,SAAU,YAAW,gBAAgB;IACxD,6DAA6D;IAC7D,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,SAAS,CAAC,YAAY,EAAE,IAAI,GAAG,aAAa,CAAC;IAC7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA0C;IACvE,OAAO,CAAC,mBAAmB,CAA0C;IACrE;;;OAGG;gBACS,MAAM,EAAE,OAAO,EAAE;IAW7B,6EAA6E;IAC7E,MAAM;IAON,4CAA4C;IAC5C,KAAK,IAAI,SAAS;IAIlB,+DAA+D;IAC/D,IAAI,IAAI,WAEP;IAED,uEAAuE;IACvE,IAAI,WAAW,IAAI,aAAa,CAK/B;IAED;;;;OAIG;IACH,IAAI,WAAW,IAAI,WAAW,GAAG,kBAAkB,CAuBlD;IAED;;;;;;;OAOG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAE,OAAgB,GAAG,SAAS;IAK/E;;;;;;OAMG;IACH,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS;IAMvD;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS;IAKlD;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS;IAClD,SAAS,CAAC,iBAAiB,EAAE,OAAO,GAAG,SAAS;IAShD;;;;;;;OAOG;IACH,MAAM,CACJ,iBAAiB,EAAE,OAAO,EAC1B,MAAM,GAAE,OAAgB,EACxB,IAAI,GAAE,QAAQ,GAAG,OAAkB,GAClC,SAAS;IAKZ;;;;;;OAMG;IACH,aAAa,CAAC,UAAU,CAAC,EAAE,SAAS,GAAG,KAAK,EAAE,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,UAAU;IAgBvF;;;;;;OAMG;IACH,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,SAAS,GAAG,UAAU;IAY3D;;;;;;OAMG;IACH,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI;IAQrD;;;;;;;;;;OAUG;IACH,SAAS,CACP,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,EAC1B,IAAI,EAAE,UAAU,EAChB,EACE,MAAa,EACb,MAAa,EACb,UAAc,GACf,GAAE;QACD,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;QAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;KAChB;IAgBR,iEAAiE;IACjE,UAAU;IAcV,2DAA2D;IAC3D,SAAS;IAIT;;;;OAIG;IACH,YAAY,CAAC,MAAM,SAAI;IAIvB,sEAAsE;IACtE,UAAU;IAIV;;;;OAIG;IACH,KAAK,CAAC,MAAM,SAAI;IAIhB,8CAA8C;IAC9C,IAAI,UAAU,IAAI,OAAO,CAGxB;IAED,2CAA2C;IAC3C,IAAI,SAAS,IAAI,OAAO,CAGvB;IAED;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;IAmBjC,gFAAgF;IAChF,QAAQ;IAIR;;;;OAIG;IACH,UAAU,CAAC,KAAK,EAAE,SAAS;CAc5B"}
1
+ {"version":3,"file":"Blueprint.d.ts","sourceRoot":"","sources":["../../../src/2d/blueprints/Blueprint.ts"],"names":[],"mappings":"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"}
package/dist/2d.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const Blueprint = require("./Blueprint-Bh6166KA.cjs");
4
- const boolean2D = require("./boolean2D-Bl4iyJfa.cjs");
3
+ const Blueprint = require("./Blueprint-CoFJDAQd.cjs");
4
+ const boolean2D = require("./boolean2D-Dk-vLBdl.cjs");
5
5
  function reverseCurve(curve) {
6
6
  const cloned = curve.clone();
7
7
  cloned.reverse();
package/dist/2d.js CHANGED
@@ -1,6 +1,6 @@
1
- import { B as Blueprint } from "./Blueprint-BBLKmtl9.js";
2
- import { d, C } from "./Blueprint-BBLKmtl9.js";
3
- import { e, C as C2, f, l, g, n, k, q, o, p, r } from "./boolean2D-D2s-G0Wm.js";
1
+ import { B as Blueprint } from "./Blueprint-CtuUvzex.js";
2
+ import { d, C } from "./Blueprint-CtuUvzex.js";
3
+ import { e, C as C2, f, l, g, n, k, q, o, p, r } from "./boolean2D-x2irapGj.js";
4
4
  function reverseCurve(curve) {
5
5
  const cloned = curve.clone();
6
6
  cloned.reverse();
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  const vectors = require("./vectors-TlfO1hu2.cjs");
3
3
  const types = require("./types-CA_xrgDq.cjs");
4
- const shapeTypes = require("./shapeTypes-DTGA0liC.cjs");
5
- const faceFns = require("./faceFns-SVADeb01.cjs");
6
- const curveFns = require("./curveFns-p0x8jy0i.cjs");
4
+ const shapeTypes = require("./shapeTypes-7xEam9Ri.cjs");
5
+ const faceFns = require("./faceFns-BLTEPBKq.cjs");
6
+ const curveFns = require("./curveFns-Ch87sD5O.cjs");
7
7
  const errors = require("./errors-9fDehDNc.cjs");
8
- const helpers = require("./helpers-3fsqd4mW.cjs");
8
+ const helpers = require("./helpers-DNzVfe-Z.cjs");
9
9
  const vecOps = require("./vecOps-CjRL1jau.cjs");
10
- const surfaceBuilders = require("./surfaceBuilders-tYoe8sri.cjs");
10
+ const surfaceBuilders = require("./surfaceBuilders-Be_ENWSA.cjs");
11
11
  const result = require("./result.cjs");
12
12
  function makePlane(plane, origin) {
13
13
  if (plane && typeof plane !== "string") {
@@ -340,7 +340,7 @@ class Curve2D {
340
340
  if (Math.abs(parameters[0] - firstParam) < precision * 100) parameters = parameters.slice(1);
341
341
  if (!parameters.length) return [this];
342
342
  if (
343
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
343
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- parameters is non-empty
344
344
  Math.abs(parameters[parameters.length - 1] - lastParam) < precision * 100
345
345
  )
346
346
  parameters = parameters.slice(0, -1);
@@ -1,12 +1,12 @@
1
1
  import { r as resolvePlane } from "./vectors-cec8p8NQ.js";
2
2
  import { a as toVec3 } from "./types-CWDdqcrq.js";
3
- import { B as getKernel, J as getKernel2D, K as registerForCleanup, L as unregisterFromCleanup, H as createEdge, G as createWire } from "./shapeTypes-5DPsHB8i.js";
4
- import { u as uvBounds, f as faceGeomType, e as faceCenter, h as uvCoordinates, c as cast } from "./faceFns-CvR-ZEQA.js";
5
- import { g as getOrientation } from "./curveFns-DyVPTb1r.js";
3
+ import { B as getKernel, J as getKernel2D, K as registerForCleanup, L as unregisterFromCleanup, H as createEdge, G as createWire } from "./shapeTypes-CpSaBLDv.js";
4
+ import { u as uvBounds, f as faceGeomType, e as faceCenter, h as uvCoordinates, c as cast } from "./faceFns-B6ebRh5I.js";
5
+ import { g as getOrientation } from "./curveFns-LRNGcHXh.js";
6
6
  import { o as ok, e as err, b as computationError, r as unwrap, y as validationError } from "./errors-B7kgv0cd.js";
7
- import { d as distance2d, s as samePoint, b as scalarMultiply2d, c as add2d, e as subtract2d, g as getSingleFace } from "./helpers-F_D1WON3.js";
7
+ import { d as distance2d, s as samePoint, b as scalarMultiply2d, c as add2d, e as subtract2d, g as getSingleFace } from "./helpers-DeFPsrcI.js";
8
8
  import { R as RAD2DEG, D as DEG2RAD } from "./vecOps-ZDdZWbwT.js";
9
- import { m as makeFace } from "./surfaceBuilders-CXbEDGBQ.js";
9
+ import { m as makeFace } from "./surfaceBuilders-D7ZH2QNS.js";
10
10
  import { bug } from "./result.js";
11
11
  function makePlane(plane, origin) {
12
12
  if (plane && typeof plane !== "string") {
@@ -339,7 +339,7 @@ class Curve2D {
339
339
  if (Math.abs(parameters[0] - firstParam) < precision * 100) parameters = parameters.slice(1);
340
340
  if (!parameters.length) return [this];
341
341
  if (
342
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
342
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- parameters is non-empty
343
343
  Math.abs(parameters[parameters.length - 1] - lastParam) < precision * 100
344
344
  )
345
345
  parameters = parameters.slice(0, -1);
@@ -46,16 +46,16 @@ var __callDispose = (stack, error, hasError) => {
46
46
  };
47
47
  const vectors = require("./vectors-TlfO1hu2.cjs");
48
48
  const errors = require("./errors-9fDehDNc.cjs");
49
- const faceFns = require("./faceFns-SVADeb01.cjs");
49
+ const faceFns = require("./faceFns-BLTEPBKq.cjs");
50
50
  const types = require("./types-CA_xrgDq.cjs");
51
51
  const vecOps = require("./vecOps-CjRL1jau.cjs");
52
- const loft = require("./loft-98s9uwpg.cjs");
53
- const shapeTypes = require("./shapeTypes-DTGA0liC.cjs");
54
- const curveFns = require("./curveFns-p0x8jy0i.cjs");
55
- const surfaceBuilders = require("./surfaceBuilders-tYoe8sri.cjs");
52
+ const loft = require("./loft-DR1UN5uN.cjs");
53
+ const shapeTypes = require("./shapeTypes-7xEam9Ri.cjs");
54
+ const curveFns = require("./curveFns-Ch87sD5O.cjs");
55
+ const surfaceBuilders = require("./surfaceBuilders-Be_ENWSA.cjs");
56
56
  const result = require("./result.cjs");
57
- const helpers = require("./helpers-3fsqd4mW.cjs");
58
- const Blueprint = require("./Blueprint-Bh6166KA.cjs");
57
+ const helpers = require("./helpers-DNzVfe-Z.cjs");
58
+ const Blueprint = require("./Blueprint-CoFJDAQd.cjs");
59
59
  const intersectCurves = (first, second, precision = 1e-9) => {
60
60
  if (first.boundingBox.isOut(second.boundingBox))
61
61
  return errors.ok({ intersections: [], commonSegments: [], commonSegmentsPoints: [] });
@@ -704,7 +704,7 @@ class CompoundBlueprint {
704
704
  return [
705
705
  "Compound Blueprints",
706
706
  "-- Outline",
707
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
707
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- compound always has outer boundary
708
708
  this.blueprints[0].repr,
709
709
  "-- Holes",
710
710
  ...this.blueprints.slice(1).map((b) => b.repr)
@@ -45,16 +45,16 @@ var __callDispose = (stack, error, hasError) => {
45
45
  };
46
46
  import { a as createPlane } from "./vectors-cec8p8NQ.js";
47
47
  import { o as ok, e as err, b as computationError, r as unwrap, g as isOk } from "./errors-B7kgv0cd.js";
48
- import { d as downcast, u as uvBounds, p as pointOnSurface, n as normalAt } from "./faceFns-CvR-ZEQA.js";
48
+ import { d as downcast, u as uvBounds, p as pointOnSurface, n as normalAt } from "./faceFns-B6ebRh5I.js";
49
49
  import { a as toVec3 } from "./types-CWDdqcrq.js";
50
50
  import { n as vecScale, j as vecNormalize, b as vecCross, D as DEG2RAD, R as RAD2DEG } from "./vecOps-ZDdZWbwT.js";
51
- import { r as revolution, c as complexExtrude, t as twistExtrude, b as basicFaceExtrusion, g as genericSweep, l as loft } from "./loft-BvZFfPqO.js";
52
- import { J as getKernel2D, I as createFace, G as createWire, B as getKernel, H as createEdge, D as DisposalScope } from "./shapeTypes-5DPsHB8i.js";
53
- import { d as curveStartPoint, c as curveTangentAt, e as curveIsClosed } from "./curveFns-DyVPTb1r.js";
54
- import { m as makeFace, l as makeNewFaceWithinFace, b as assembleWire, z as zip } from "./surfaceBuilders-CXbEDGBQ.js";
51
+ import { r as revolution, c as complexExtrude, t as twistExtrude, b as basicFaceExtrusion, g as genericSweep, l as loft } from "./loft-DsVv4yxU.js";
52
+ import { J as getKernel2D, I as createFace, G as createWire, B as getKernel, H as createEdge, D as DisposalScope } from "./shapeTypes-CpSaBLDv.js";
53
+ import { d as curveStartPoint, c as curveTangentAt, e as curveIsClosed } from "./curveFns-LRNGcHXh.js";
54
+ import { m as makeFace, l as makeNewFaceWithinFace, b as assembleWire, z as zip } from "./surfaceBuilders-D7ZH2QNS.js";
55
55
  import { bug } from "./result.js";
56
- import { s as samePoint$1, e as subtract2d, c as add2d, i as crossProduct2d, b as scalarMultiply2d, f as polarToCartesian, r as rotate2d, j as cartesianToPolar, d as distance2d, p as polarAngle2d, k as PRECISION_INTERSECTION } from "./helpers-F_D1WON3.js";
57
- import { C as Curve2D, a as make2dSegmentCurve, j as approximateAsBSpline, n as normalize2d, b as make2dArcFromCenter, k as isPoint2D, g as make2dCircle, l as make2dThreePointArc, d as BoundingBox2d, v as viewbox, o as asSVG, B as Blueprint, p as make2dEllipseArc, q as make2dTangentArc, r as make2dBezierCurve, s as removeDuplicatePoints } from "./Blueprint-BBLKmtl9.js";
56
+ import { s as samePoint$1, e as subtract2d, c as add2d, i as crossProduct2d, b as scalarMultiply2d, f as polarToCartesian, r as rotate2d, j as cartesianToPolar, d as distance2d, p as polarAngle2d, k as PRECISION_INTERSECTION } from "./helpers-DeFPsrcI.js";
57
+ import { C as Curve2D, a as make2dSegmentCurve, j as approximateAsBSpline, n as normalize2d, b as make2dArcFromCenter, k as isPoint2D, g as make2dCircle, l as make2dThreePointArc, d as BoundingBox2d, v as viewbox, o as asSVG, B as Blueprint, p as make2dEllipseArc, q as make2dTangentArc, r as make2dBezierCurve, s as removeDuplicatePoints } from "./Blueprint-CtuUvzex.js";
58
58
  const intersectCurves = (first, second, precision = 1e-9) => {
59
59
  if (first.boundingBox.isOut(second.boundingBox))
60
60
  return ok({ intersections: [], commonSegments: [], commonSegmentsPoints: [] });
@@ -703,7 +703,7 @@ class CompoundBlueprint {
703
703
  return [
704
704
  "Compound Blueprints",
705
705
  "-- Outline",
706
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
706
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- compound always has outer boundary
707
707
  this.blueprints[0].repr,
708
708
  "-- Holes",
709
709
  ...this.blueprints.slice(1).map((b) => b.repr)
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
- const shapeTypes = require("./shapeTypes-DTGA0liC.cjs");
2
+ const shapeTypes = require("./shapeTypes-7xEam9Ri.cjs");
3
3
  const errors = require("./errors-9fDehDNc.cjs");
4
4
  const vectors = require("./vectors-TlfO1hu2.cjs");
5
5
  const vecOps = require("./vecOps-CjRL1jau.cjs");
6
- const shapeFns = require("./shapeFns-BoN5g5Bx.cjs");
7
- const surfaceBuilders = require("./surfaceBuilders-tYoe8sri.cjs");
6
+ const shapeFns = require("./shapeFns-DHlLNHTn.cjs");
7
+ const surfaceBuilders = require("./surfaceBuilders-Be_ENWSA.cjs");
8
8
  const shapeTagStore = /* @__PURE__ */ new WeakMap();
9
9
  const tagMetadataStore = /* @__PURE__ */ new WeakMap();
10
10
  function hasFaceTags(shape) {
@@ -1,9 +1,9 @@
1
- import { B as getKernel, c as castShape, p as isShape3D } from "./shapeTypes-5DPsHB8i.js";
1
+ import { B as getKernel, c as castShape, p as isShape3D } from "./shapeTypes-CpSaBLDv.js";
2
2
  import { o as ok, d as isErr, e as err, y as validationError, B as BrepErrorCode, p as typeCastError, k as kernelError } from "./errors-B7kgv0cd.js";
3
3
  import { r as resolvePlane } from "./vectors-cec8p8NQ.js";
4
4
  import { H as HASH_CODE_MAX, n as vecScale, v as vecAdd } from "./vecOps-ZDdZWbwT.js";
5
- import { a as getFaces, p as propagateOriginsByHash, b as propagateOriginsFromEvolution, c as getWires, d as getEdges, e as getVertices, g as getFaceOrigins } from "./shapeFns-38GljA_p.js";
6
- import { m as makeFace } from "./surfaceBuilders-CXbEDGBQ.js";
5
+ import { a as getFaces, p as propagateOriginsByHash, b as propagateOriginsFromEvolution, c as getWires, d as getEdges, e as getVertices, g as getFaceOrigins } from "./shapeFns-CbXxLvV_.js";
6
+ import { m as makeFace } from "./surfaceBuilders-D7ZH2QNS.js";
7
7
  const shapeTagStore = /* @__PURE__ */ new WeakMap();
8
8
  const tagMetadataStore = /* @__PURE__ */ new WeakMap();
9
9
  function hasFaceTags(shape) {