brepjs 7.3.0 → 7.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +151 -82
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,123 +1,194 @@
|
|
|
1
1
|
# brepjs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
CAD modeling for JavaScript. Build 3D geometry with code.
|
|
4
|
+
|
|
4
5
|
[](https://www.npmjs.com/package/brepjs)
|
|
6
|
+
[](https://github.com/andymai/brepjs/actions/workflows/ci.yml)
|
|
5
7
|
[](./LICENSE)
|
|
6
|
-
[](./CONTRIBUTING.md#code-coverage-requirements)
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
**[Docs](https://andymai.github.io/brepjs/)** · **[Examples](./examples/)** · **[Cheat Sheet](./docs/cheat-sheet.md)** · **[Getting Started](./docs/getting-started.md)**
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
```typescript
|
|
12
|
+
import { box, cut, cylinder, fillet, edgeFinder, exportSTEP, unwrap } from 'brepjs/quick';
|
|
13
|
+
|
|
14
|
+
const b = box(30, 20, 10);
|
|
15
|
+
const hole = cylinder(5, 15, { at: [15, 10, -2] });
|
|
16
|
+
const drilled = unwrap(cut(b, hole));
|
|
17
|
+
|
|
18
|
+
const edges = edgeFinder().inDirection('Z').findAll(drilled);
|
|
19
|
+
const part = unwrap(fillet(drilled, edges, 1.5));
|
|
20
|
+
|
|
21
|
+
const step = unwrap(exportSTEP(part));
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Why brepjs?
|
|
25
|
+
|
|
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 powered by OpenCascade's WASM build. That means exact geometry, proper booleans, fillets that actually work, and export to formats that real CAD software can open.
|
|
27
|
+
|
|
28
|
+
Use it for parametric modeling, 3D configurators, CAD file processing, or anywhere you need solid geometry in JavaScript.
|
|
29
|
+
|
|
30
|
+
## Install
|
|
11
31
|
|
|
12
32
|
```bash
|
|
13
33
|
npm install brepjs brepjs-opencascade
|
|
14
34
|
```
|
|
15
35
|
|
|
16
|
-
|
|
36
|
+
`brepjs/quick` auto-initializes the WASM kernel via top-level await (ESM only). For CJS or manual control:
|
|
17
37
|
|
|
18
38
|
```typescript
|
|
19
39
|
import opencascade from 'brepjs-opencascade';
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
makeBox,
|
|
23
|
-
makeCylinder,
|
|
24
|
-
cutShape,
|
|
25
|
-
translateShape,
|
|
26
|
-
measureVolume,
|
|
27
|
-
exportSTEP,
|
|
28
|
-
unwrap,
|
|
29
|
-
} from 'brepjs';
|
|
30
|
-
|
|
31
|
-
// Initialize the WASM kernel
|
|
40
|
+
import { initFromOC } from 'brepjs';
|
|
41
|
+
|
|
32
42
|
const oc = await opencascade();
|
|
33
43
|
initFromOC(oc);
|
|
44
|
+
```
|
|
34
45
|
|
|
35
|
-
|
|
36
|
-
const box = makeBox([0, 0, 0], [50, 30, 20]);
|
|
37
|
-
const cylinder = translateShape(makeCylinder(8, 25), [25, 15, -2]);
|
|
46
|
+
## Features
|
|
38
47
|
|
|
39
|
-
|
|
40
|
-
const withHole = unwrap(cutShape(box, cylinder));
|
|
48
|
+
**Modeling** — `box`, `cylinder`, `sphere`, `cone`, `torus`, `ellipsoid` plus `extrude`, `revolve`, `loft`, `sweep` from 2D sketches
|
|
41
49
|
|
|
42
|
-
|
|
43
|
-
const moved = translateShape(withHole, [100, 0, 0]);
|
|
50
|
+
**Booleans** — `fuse`, `cut`, `intersect`, `section`, `split`, `slice` with batch variants `fuseAll`, `cutAll`
|
|
44
51
|
|
|
45
|
-
|
|
46
|
-
console.log('Volume:', measureVolume(moved), 'mm³');
|
|
52
|
+
**Modifiers** — `fillet`, `chamfer`, `shell`, `offset`, `thicken` on any solid
|
|
47
53
|
|
|
48
|
-
|
|
49
|
-
const stepBlob = unwrap(exportSTEP(moved));
|
|
50
|
-
```
|
|
54
|
+
**Sketching** — `draw`, `drawRectangle`, `drawCircle`, `Sketcher`, `sketchCircle`, `sketchHelix` for 2D-to-3D workflows
|
|
51
55
|
|
|
52
|
-
|
|
56
|
+
**Queries** — `edgeFinder`, `faceFinder`, `wireFinder`, `vertexFinder` with composable filters like `.inDirection('Z')`, `.ofCurveType('CIRCLE')`, `.ofLength(10)`
|
|
53
57
|
|
|
54
|
-
|
|
58
|
+
**Measurement** — `measureVolume`, `measureArea`, `measureLength`, `measureDistance`, `checkInterference`
|
|
55
59
|
|
|
56
|
-
|
|
57
|
-
npm run example examples/hello-world.ts
|
|
58
|
-
```
|
|
60
|
+
**Import/Export** — STEP, STL, IGES, glTF/GLB, DXF, 3MF, OBJ, SVG. Assembly export with colors and names via `exportAssemblySTEP`
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
- **[basic-primitives.ts](./examples/basic-primitives.ts)** — Primitives and boolean operations
|
|
62
|
-
- **[mechanical-part.ts](./examples/mechanical-part.ts)** — Bracket with holes and slots
|
|
63
|
-
- **[2d-to-3d.ts](./examples/2d-to-3d.ts)** — Sketch to extrusion workflow
|
|
64
|
-
- **[parametric-part.ts](./examples/parametric-part.ts)** — Configurable flanged pipe fitting
|
|
65
|
-
- **[threejs-rendering.ts](./examples/threejs-rendering.ts)** — Mesh data for Three.js/WebGL
|
|
66
|
-
- **[import-export.ts](./examples/import-export.ts)** — Load, modify, export files
|
|
67
|
-
- **[text-engraving.ts](./examples/text-engraving.ts)** — Engrave text on shapes
|
|
68
|
-
|
|
69
|
-
## Gallery
|
|
70
|
-
|
|
71
|
-
<p align="center">
|
|
72
|
-
<img src="docs/images/examples/hello-world.svg" alt="Box" width="120" />
|
|
73
|
-
<img src="docs/images/examples/boolean-ops.svg" alt="Boolean cut" width="120" />
|
|
74
|
-
<img src="docs/images/examples/bracket.svg" alt="Bracket" width="120" />
|
|
75
|
-
<img src="docs/images/examples/2d-profile.svg" alt="2D profile" width="120" />
|
|
76
|
-
<img src="docs/images/examples/pipe-fitting.svg" alt="Pipe fitting" width="120" />
|
|
77
|
-
</p>
|
|
78
|
-
<p align="center"><em>Box · Boolean cut · Bracket · 2D profile · Pipe fitting — see <a href="./examples/">examples/</a></em></p>
|
|
62
|
+
**Rendering** — `mesh` and `toBufferGeometryData` for Three.js / WebGL integration
|
|
79
63
|
|
|
80
|
-
|
|
64
|
+
**Text** — `loadFont`, `drawText`, `sketchText` for text outlines and engraving
|
|
81
65
|
|
|
82
|
-
|
|
83
|
-
- **[B-Rep Concepts](./docs/concepts.md)** — Vertices, edges, faces, solids explained for JS developers
|
|
84
|
-
- **[Which API?](./docs/which-api.md)** — Sketcher vs functional API vs Drawing — when to use each
|
|
85
|
-
- **[Architecture](./docs/architecture.md)** — Layer diagram and module overview
|
|
86
|
-
- **[Memory Management](./docs/memory-management.md)** — Resource cleanup patterns
|
|
87
|
-
- **[Error Reference](./docs/errors.md)** — Error codes and recovery
|
|
88
|
-
- **[Performance](./docs/performance.md)** — Optimization best practices
|
|
89
|
-
- **[Compatibility](./docs/compatibility.md)** — Tested environments
|
|
66
|
+
**Healing** — `autoHeal`, `healSolid`, `healFace`, `isValid` for fixing imported geometry
|
|
90
67
|
|
|
91
|
-
|
|
68
|
+
**Patterns** — `linearPattern`, `circularPattern` for arraying shapes
|
|
69
|
+
|
|
70
|
+
**Assemblies** — `createAssemblyNode`, `addChild`, `walkAssembly`, `collectShapes` for hierarchical models
|
|
71
|
+
|
|
72
|
+
**Workers** — `createWorkerClient`, `createWorkerHandler` for off-main-thread operations
|
|
73
|
+
|
|
74
|
+
**History** — `createHistory`, `addStep`, `undoLast`, `replayHistory` for parametric undo/replay
|
|
92
75
|
|
|
93
|
-
|
|
76
|
+
## A Larger Example
|
|
94
77
|
|
|
78
|
+
A flanged pipe with bolt holes — showing booleans, shelling, fillets, and finders:
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import {
|
|
82
|
+
cylinder, fuse, cut, shell, fillet, rotate,
|
|
83
|
+
faceFinder, edgeFinder, measureVolume, unwrap,
|
|
84
|
+
} from 'brepjs/quick';
|
|
85
|
+
|
|
86
|
+
// Tube + flanges
|
|
87
|
+
const tube = cylinder(15, 100);
|
|
88
|
+
const body = unwrap(fuse(unwrap(fuse(tube, cylinder(30, 5))), cylinder(30, 5, { at: [0, 0, 95] })));
|
|
89
|
+
|
|
90
|
+
// Hollow out — find top face, shell to 2mm walls
|
|
91
|
+
const topFaces = faceFinder().parallelTo('XY').atDistance(100, [0, 0, 0]).findAll(body);
|
|
92
|
+
const hollowed = unwrap(shell(body, topFaces, 2));
|
|
93
|
+
|
|
94
|
+
// Fillet the tube-to-flange transitions
|
|
95
|
+
const filletEdges = edgeFinder().ofCurveType('CIRCLE').ofLength(2 * Math.PI * 15).findAll(hollowed);
|
|
96
|
+
let result = unwrap(fillet(hollowed, filletEdges, 3));
|
|
97
|
+
|
|
98
|
+
// Bolt holes around each flange
|
|
99
|
+
for (let i = 0; i < 6; i++) {
|
|
100
|
+
const angle = 60 * i;
|
|
101
|
+
const hole = rotate(cylinder(3, 10, { at: [22, 0, -2] }), angle, { axis: [0, 0, 1] });
|
|
102
|
+
result = unwrap(cut(result, hole));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
console.log('Volume:', measureVolume(result), 'mm³');
|
|
95
106
|
```
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
107
|
+
|
|
108
|
+
## Examples
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
npm run example examples/hello-world.ts
|
|
100
112
|
```
|
|
101
113
|
|
|
102
|
-
|
|
114
|
+
| Example | What it does |
|
|
115
|
+
|---|---|
|
|
116
|
+
| [hello-world.ts](./examples/hello-world.ts) | Create a box, measure it, export it |
|
|
117
|
+
| [basic-primitives.ts](./examples/basic-primitives.ts) | Primitives and boolean operations |
|
|
118
|
+
| [mechanical-part.ts](./examples/mechanical-part.ts) | Bracket with holes, slots, and SVG drawings |
|
|
119
|
+
| [2d-to-3d.ts](./examples/2d-to-3d.ts) | Sketch a profile, extrude to 3D |
|
|
120
|
+
| [parametric-part.ts](./examples/parametric-part.ts) | Configurable flanged pipe fitting |
|
|
121
|
+
| [threejs-rendering.ts](./examples/threejs-rendering.ts) | Generate mesh data for Three.js |
|
|
122
|
+
| [browser-viewer.ts](./examples/browser-viewer.ts) | Standalone HTML viewer with orbit controls |
|
|
123
|
+
| [import-export.ts](./examples/import-export.ts) | Load, modify, and re-export STEP files |
|
|
124
|
+
| [text-engraving.ts](./examples/text-engraving.ts) | Engrave text on a solid shape |
|
|
125
|
+
|
|
126
|
+
## Imports
|
|
127
|
+
|
|
128
|
+
Everything is available from the top level:
|
|
103
129
|
|
|
104
|
-
|
|
130
|
+
```typescript
|
|
131
|
+
import { box, translate, fuse, exportSTEP } from 'brepjs';
|
|
132
|
+
```
|
|
105
133
|
|
|
106
|
-
|
|
134
|
+
Sub-path imports for tree-shaking:
|
|
107
135
|
|
|
108
136
|
```typescript
|
|
109
|
-
import {
|
|
137
|
+
import { box, fuse, fillet } from 'brepjs/topology';
|
|
110
138
|
import { importSTEP, exportSTEP } from 'brepjs/io';
|
|
111
139
|
import { measureVolume } from 'brepjs/measurement';
|
|
140
|
+
import { edgeFinder, faceFinder } from 'brepjs/query';
|
|
141
|
+
import { sketchCircle, draw } from 'brepjs/sketching';
|
|
142
|
+
import { createAssemblyNode } from 'brepjs/operations';
|
|
112
143
|
```
|
|
113
144
|
|
|
114
|
-
|
|
145
|
+
## Error Handling
|
|
146
|
+
|
|
147
|
+
Operations that can fail return a `Result` instead of throwing:
|
|
115
148
|
|
|
116
149
|
```typescript
|
|
117
|
-
|
|
118
|
-
|
|
150
|
+
const result = fuse(a, b);
|
|
151
|
+
|
|
152
|
+
if (isOk(result)) {
|
|
153
|
+
const fused = result.value;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Or throw on failure
|
|
157
|
+
const fused = unwrap(fuse(a, b));
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Architecture
|
|
161
|
+
|
|
162
|
+
Four layers with enforced import boundaries (imports flow downward only):
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
Layer 3 sketching/, text/, projection/ High-level API
|
|
166
|
+
Layer 2 topology/, operations/, 2d/ ... Domain logic
|
|
167
|
+
Layer 1 core/ Types, memory, errors
|
|
168
|
+
Layer 0 kernel/, utils/ WASM bindings
|
|
119
169
|
```
|
|
120
170
|
|
|
171
|
+
## Documentation
|
|
172
|
+
|
|
173
|
+
- [API Reference](https://andymai.github.io/brepjs/) — Searchable TypeDoc reference
|
|
174
|
+
- [Getting Started](./docs/getting-started.md) — Install to first part
|
|
175
|
+
- [B-Rep Concepts](./docs/concepts.md) — Vertices, edges, faces, solids
|
|
176
|
+
- [Cheat Sheet](./docs/cheat-sheet.md) — Single-page reference for common operations
|
|
177
|
+
- [Which API?](./docs/which-api.md) — Sketcher vs functional vs Drawing
|
|
178
|
+
- [Function Lookup](./docs/function-lookup.md) — Alphabetical index of every export
|
|
179
|
+
- [Memory Management](./docs/memory-management.md) — Resource cleanup patterns
|
|
180
|
+
- [Error Reference](./docs/errors.md) — Error codes and recovery
|
|
181
|
+
- [Architecture](./docs/architecture.md) — Layer diagram and module overview
|
|
182
|
+
- [Performance](./docs/performance.md) — Optimization tips
|
|
183
|
+
- [Compatibility](./docs/compatibility.md) — Tested environments
|
|
184
|
+
|
|
185
|
+
## Packages
|
|
186
|
+
|
|
187
|
+
| Package | Description |
|
|
188
|
+
|---|---|
|
|
189
|
+
| [brepjs](https://www.npmjs.com/package/brepjs) | Core library |
|
|
190
|
+
| [brepjs-opencascade](https://www.npmjs.com/package/brepjs-opencascade) | OpenCascade WASM build |
|
|
191
|
+
|
|
121
192
|
## Projects Using brepjs
|
|
122
193
|
|
|
123
194
|
- [Gridfinity Layout Tool](https://github.com/andymai/gridfinity-layout-tool) — Web-based layout generator for Gridfinity storage systems
|
|
@@ -126,16 +197,14 @@ const moved = translateShape(makeBox([0, 0, 0], [10, 10, 10]), [5, 0, 0]);
|
|
|
126
197
|
|
|
127
198
|
```bash
|
|
128
199
|
npm install
|
|
129
|
-
npm run build # Build library
|
|
200
|
+
npm run build # Build library (ES + CJS)
|
|
130
201
|
npm run test # Run tests
|
|
131
|
-
npm run typecheck #
|
|
132
|
-
npm run lint #
|
|
133
|
-
npm run
|
|
202
|
+
npm run typecheck # TypeScript strict check
|
|
203
|
+
npm run lint # ESLint
|
|
204
|
+
npm run format:check # Prettier
|
|
134
205
|
```
|
|
135
206
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
See [CONTRIBUTING.md](./CONTRIBUTING.md) for development guidelines.
|
|
207
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
|
|
139
208
|
|
|
140
209
|
## License
|
|
141
210
|
|