three-slicer 0.1.0 → 0.1.2

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 (64) hide show
  1. package/README.md +342 -24
  2. package/components/README.md +1 -1
  3. package/components/dist/SettingsPanel.js +111 -112
  4. package/components/styles.css +9 -9
  5. package/data/invalidation-map.json +1 -1
  6. package/engine/examples/headless.mjs +2 -2
  7. package/engine/index.d.ts +3 -1
  8. package/engine/index.js +2 -2
  9. package/engine/src/data.js +12 -0
  10. package/engine/src/settings.js +35 -35
  11. package/engine/src/slicer.worker.js +25 -22
  12. package/engine/src/slicer_core.js +0 -0
  13. package/engine/src/slicer_core.mt.js +0 -0
  14. package/engine/src/toggle_eval.js +12 -13
  15. package/package.json +54 -26
  16. package/types/components.d.ts +19 -0
  17. package/types/data/config-schema.json.d.ts +55 -0
  18. package/types/data/invalidation-map.json.d.ts +15 -0
  19. package/types/data/toggle-rules.json.d.ts +20 -0
  20. package/types/data/ui-tree.json.d.ts +19 -0
  21. package/types/data.d.ts +17 -0
  22. package/types/gen_settings_types.mjs +70 -0
  23. package/types/settings-keys.d.ts +1704 -0
  24. package/types/settings.d.ts +19 -0
  25. package/types/toggle.d.ts +22 -0
  26. package/types/viewer-loaders.d.ts +33 -0
  27. package/types/viewer-toolpath.d.ts +105 -0
  28. package/types/viewer.d.ts +15 -0
  29. package/types/wasm.d.ts +5 -0
  30. package/types/worker.d.ts +3 -0
  31. package/viewer/README.md +1 -1
  32. package/viewer/dist/Viewport.js +1774 -923
  33. package/viewer/dist/make_worker.js +6 -6
  34. package/viewer/dist/model_loaders.js +221 -109
  35. package/viewer/dist/toolpath_gpu.js +146 -147
  36. package/viewer/styles.css +27 -25
  37. package/data/config-schema-builddump.json +0 -12921
  38. package/viewer/src/Viewport.jsx +0 -1353
  39. package/viewer/src/assets/add.svg +0 -1
  40. package/viewer/src/assets/arrange.svg +0 -1
  41. package/viewer/src/assets/boolean.svg +0 -1
  42. package/viewer/src/assets/cut.svg +0 -1
  43. package/viewer/src/assets/delete.svg +0 -1
  44. package/viewer/src/assets/deleteall.svg +0 -1
  45. package/viewer/src/assets/duplicate.svg +0 -1
  46. package/viewer/src/assets/measure.svg +0 -1
  47. package/viewer/src/assets/mmu.svg +0 -1
  48. package/viewer/src/assets/move.svg +0 -1
  49. package/viewer/src/assets/negative.svg +0 -1
  50. package/viewer/src/assets/onbed.svg +0 -1
  51. package/viewer/src/assets/open.svg +0 -1
  52. package/viewer/src/assets/orient.svg +0 -1
  53. package/viewer/src/assets/paint.svg +0 -1
  54. package/viewer/src/assets/rotate.svg +0 -1
  55. package/viewer/src/assets/scale.svg +0 -1
  56. package/viewer/src/assets/seam.svg +0 -1
  57. package/viewer/src/assets/split.svg +0 -1
  58. package/viewer/src/assets/textmark.svg +0 -1
  59. package/viewer/src/assets/varlayer.svg +0 -1
  60. package/viewer/src/icons.js +0 -23
  61. package/viewer/src/make_worker.js +0 -9
  62. package/viewer/src/model_loaders.js +0 -178
  63. package/viewer/src/shadow_host.jsx +0 -30
  64. package/viewer/src/toolpath_gpu.js +0 -430
package/README.md CHANGED
@@ -1,44 +1,362 @@
1
1
  # three-slicer
2
2
 
3
- Browser/WASM 3D-printing slicer, reverse-engineered from [OrcaSlicer](https://github.com/SoftFever/OrcaSlicer).
4
- Slices STL to G-code entirely in the browser (or Node) — no server.
3
+ Browser/WASM 3D-printing slicer package derived from [OrcaSlicer](https://github.com/OrcaSlicer/OrcaSlicer). It can slice binary STL files to G-code in Node or the browser, and it also ships React UI pieces for building a browser slicer: a three.js viewport, GPU toolpath preview, and a schema-driven settings panel.
5
4
 
6
- - **Engine** — WASM kernel: Arachne variable-width walls, gyroid/honeycomb/crosshatch infill,
7
- tree/grid supports, support painting, raft/brim/skirt, ironing, arc fitting, multi-material,
8
- layer streaming (OOM-tolerant), multithreaded kernel auto-selected on cross-origin-isolated sites.
9
- - **Viewer** — React `<Viewport/>`: model import (STL/OBJ/3MF/AMF/PLY), transform gizmos,
10
- multi-plate, GPU toolpath preview (libvgcode port). Shadow-DOM isolated — no CSS collisions.
11
- - **Settings UI** — React `<SettingsPanel/>`: 907 options driven by the extracted OrcaSlicer
12
- config schema, with search, mode filters, and custom widget registry.
5
+ The package is published as a single npm package, `three-slicer`, with subpath exports for the engine, viewer, components, worker, and extracted OrcaSlicer data.
13
6
 
14
- ## Install
7
+ ## Links
8
+
9
+ - Package: [npmjs.com/package/three-slicer](https://www.npmjs.com/package/three-slicer)
10
+ - Source: [kimgh06/Web_Three_Slicer](https://github.com/kimgh06/Web_Three_Slicer)
11
+ - Demo: [slicer.kimgh06.com](https://slicer.kimgh06.com/)
12
+
13
+ ## Features
14
+
15
+ - WASM slicing engine with Arachne walls, infill patterns, supports, raft/brim/skirt, ironing, arc fitting, multi-material paths, and layer streaming.
16
+ - Headless SDK for Node or browser use with no `three.js` dependency.
17
+ - Browser worker entry for off-main-thread slicing.
18
+ - React `<Viewport/>` for model import, plate layout, transform controls, slicing, G-code export, and GPU toolpath preview.
19
+ - React `<SettingsPanel/>` generated from extracted OrcaSlicer metadata.
20
+ - Extracted data files for custom UIs: config schema, UI tree, toggle rules, and invalidation map.
21
+ - Automatic multithreaded WASM selection on cross-origin-isolated browser pages.
22
+
23
+ ## Installation
15
24
 
16
25
  ```bash
17
- npm i three-slicer # engine only (Node-safe)
18
- npm i three-slicer react react-dom three # + viewer/components
26
+ npm i three-slicer
19
27
  ```
20
28
 
21
- ## Use
29
+ `react`, `react-dom`, and `three` are peer dependencies and npm installs them for you. They stay peers rather than dependencies because React and three must be single instances — a duplicate copy breaks hooks and `instanceof`.
30
+
31
+ Only the viewer and components import them. If you use the headless engine, they are installed into `node_modules` but never enter your bundle:
32
+
33
+ | Import path | Needs react/three at runtime |
34
+ | --- | --- |
35
+ | `three-slicer`, `/settings`, `/toggle`, `/worker`, `/wasm`, `/data` | no |
36
+ | `three-slicer/viewer`, `/viewer/toolpath`, `/viewer/loaders` | yes |
37
+ | `three-slicer/components` | react only |
38
+
39
+ ## Quick Start: Headless Slicing
40
+
41
+ Use the root import when you only need STL-to-G-code slicing.
22
42
 
23
43
  ```js
24
- // Headless slicing (Node or browser main thread)
25
44
  import { createSlicer } from 'three-slicer'
26
- const s = await createSlicer()
27
- const { gcode, stats } = s.slice(stlArrayBuffer, params)
28
45
 
29
- // React viewer + settings panel
46
+ const slicer = await createSlicer()
47
+
48
+ const result = slicer.slice(stlArrayBuffer, {
49
+ layer_height: 0.2,
50
+ first_layer_height: 0.2,
51
+ line_width: 0.42,
52
+ wall_loops: 2,
53
+ infill_density: 0.15,
54
+ nozzle_diameter: 0.4,
55
+ filament_diameter: 1.75,
56
+ })
57
+
58
+ console.log(result.stats.layers)
59
+ console.log(result.gcode)
60
+
61
+ slicer.dispose()
62
+ ```
63
+
64
+ `slice()` accepts a binary STL as an `ArrayBuffer` or `Uint8Array`. Parameters can be either a kernel params object or a JSON string.
65
+
66
+ ## Streaming Layers
67
+
68
+ For large models, pass callbacks to receive each sliced layer as it is produced. This avoids keeping the full G-code and layer payload in memory at once.
69
+
70
+ ```js
71
+ const chunks = []
72
+
73
+ const result = slicer.slice(stlArrayBuffer, params, {
74
+ onProgress(done, total) {
75
+ console.log(`${done}/${total}`)
76
+ },
77
+ onLayer(layer) {
78
+ chunks.push(layer.gcode)
79
+ },
80
+ })
81
+
82
+ const gcode = chunks.join('')
83
+ console.log(result.stats)
84
+ ```
85
+
86
+ When `onLayer` is set, the returned result carries stats; assemble G-code from the layer callback if you need the full file.
87
+
88
+ ## Quick Start: React Viewer
89
+
90
+ Use `three-slicer/viewer` when you want a ready-made browser slicer viewport.
91
+
92
+ ```jsx
93
+ import { useState } from 'react'
94
+ import Viewport from 'three-slicer/viewer'
95
+
96
+ export default function App() {
97
+ const [settings, setSettings] = useState({})
98
+
99
+ return (
100
+ <Viewport
101
+ settings={settings}
102
+ setSettings={setSettings}
103
+ />
104
+ )
105
+ }
106
+ ```
107
+
108
+ The viewer handles model loading, drag and drop, transform controls, multi-plate layout, worker slicing, GPU toolpath preview, and G-code export. It supports STL, OBJ, 3MF (including the production extension used by Orca/Bambu/Prusa), AMF, and PLY out of the box; other formats such as STEP can be added with `registerLoader()`. Viewer and component styles are bundled into their Shadow DOM roots, so host app CSS does not need to import package CSS.
109
+
110
+ ## Quick Start: Settings Panel
111
+
112
+ Use `three-slicer/components` when you want the OrcaSlicer-style settings UI without building the form yourself.
113
+
114
+ ```jsx
115
+ import { useState } from 'react'
116
+ import SettingsPanel from 'three-slicer/components'
117
+
118
+ export default function App() {
119
+ const [settings, setSettings] = useState({})
120
+
121
+ return (
122
+ <SettingsPanel
123
+ settings={settings}
124
+ setSettings={setSettings}
125
+ />
126
+ )
127
+ }
128
+ ```
129
+
130
+ `settings` is a sparse object keyed by OrcaSlicer setting names. Store only edited values; missing keys fall back to schema defaults.
131
+
132
+ ## Full React Example
133
+
134
+ The viewer and settings panel are designed to share the same `settings` state.
135
+
136
+ ```jsx
137
+ import { useState } from 'react'
30
138
  import Viewport from 'three-slicer/viewer'
31
139
  import SettingsPanel from 'three-slicer/components'
32
- // <Viewport settings={settings} setSettings={setSettings} />
33
140
 
34
- // Extracted data
35
- import schema from 'three-slicer/data/config-schema.json'
141
+ export default function App() {
142
+ const [settings, setSettings] = useState({})
143
+
144
+ return (
145
+ <main style={{ display: 'flex', height: '100vh' }}>
146
+ <Viewport
147
+ settings={settings}
148
+ setSettings={setSettings}
149
+ />
150
+ <SettingsPanel
151
+ settings={settings}
152
+ setSettings={setSettings}
153
+ />
154
+ </main>
155
+ )
156
+ }
36
157
  ```
37
158
 
38
- Vite consumers need `worker: { format: 'es' }` and `build: { target: 'es2022' }`.
39
- Serve with COOP/COEP headers to enable the multithreaded kernel (~2.2× faster).
159
+ The same sparse settings map can feed the settings panel, the viewer, and `deriveKernelParams()`.
160
+
161
+ ## Import Paths
162
+
163
+ ```js
164
+ import { createSlicer, engineWorkerURL } from 'three-slicer'
165
+ import { deriveKernelParams } from 'three-slicer/settings'
166
+ import { disabledKeys, makeCfg } from 'three-slicer/toggle'
167
+ import Viewport from 'three-slicer/viewer'
168
+ import SettingsPanel from 'three-slicer/components'
169
+ import { schema, uiTree } from 'three-slicer/data'
170
+ ```
171
+
172
+ Available subpaths:
173
+
174
+ | Import path | Use |
175
+ | --- | --- |
176
+ | `three-slicer` | Headless WASM engine SDK |
177
+ | `three-slicer/settings` | Schema defaults and settings-to-kernel mapping |
178
+ | `three-slicer/toggle` | Enable/disable rule evaluation for settings UIs |
179
+ | `three-slicer/worker` | Browser worker entry |
180
+ | `three-slicer/wasm` | Single-threaded Emscripten WASM glue |
181
+ | `three-slicer/wasm-mt` | Multithreaded Emscripten WASM glue |
182
+ | `three-slicer/viewer` | React `<Viewport/>` |
183
+ | `three-slicer/viewer/toolpath` | GPU toolpath renderer utilities |
184
+ | `three-slicer/viewer/loaders` | Model loaders |
185
+ | `three-slicer/components` | React `<SettingsPanel/>` |
186
+ | `three-slicer/data` | Named exports for extracted metadata |
187
+ | `three-slicer/data/*.json` | Extracted OrcaSlicer metadata |
188
+
189
+ ## TypeScript
190
+
191
+ Type declarations ship with the package — no `@types/*` needed. All 907 setting keys are typed from the config schema, enum values included:
192
+
193
+ ```ts
194
+ import { createSlicer, type SlicerSettings } from 'three-slicer'
195
+ import { deriveKernelParams } from 'three-slicer/settings'
196
+
197
+ const settings: SlicerSettings = {
198
+ layer_height: 0.2,
199
+ sparse_infill_pattern: 'gyroid', // autocompletes; 'nope' is a type error
200
+ }
201
+
202
+ const slicer = await createSlicer()
203
+ slicer.slice(stlArrayBuffer, deriveKernelParams(settings))
204
+ ```
205
+
206
+ Requires `"moduleResolution": "bundler"`, `"node16"`, or `"nodenext"`. The declarations are wired through the `exports` field, which the legacy `"node"` resolution ignores.
207
+
208
+ ## Settings Model
209
+
210
+ There are two related settings shapes:
211
+
212
+ | Shape | Used by | Description |
213
+ | --- | --- | --- |
214
+ | Sparse OrcaSlicer settings map | `<SettingsPanel/>`, `<Viewport/>` | Object keyed by original OrcaSlicer schema keys. Missing keys use schema defaults. |
215
+ | Kernel params | `slicer.slice()` | Flat object consumed directly by the WASM kernel. |
216
+
217
+ To convert UI settings to kernel params:
218
+
219
+ ```js
220
+ import { deriveKernelParams } from 'three-slicer/settings'
221
+
222
+ const settings = {
223
+ layer_height: 0.25,
224
+ sparse_infill_density: 15,
225
+ wall_loops: 3,
226
+ }
227
+
228
+ const params = deriveKernelParams(settings)
229
+ const result = slicer.slice(stlArrayBuffer, params)
230
+ ```
231
+
232
+ `deriveKernelParams()` maps the curated set of schema keys currently supported by the kernel. Other schema keys can still be displayed by the UI, but they may not affect slicing output yet. Vector options are simplified to their first element.
233
+
234
+ ## Worker Usage
235
+
236
+ Use a module worker to run slicing off the browser main thread.
237
+
238
+ ```js
239
+ import { engineWorkerURL } from 'three-slicer'
240
+
241
+ const worker = new Worker(engineWorkerURL(), { type: 'module' })
242
+
243
+ worker.onmessage = (event) => {
244
+ const message = event.data
245
+
246
+ if (message.type === 'progress') {
247
+ console.log(message.done, message.total)
248
+ }
249
+
250
+ if (message.type === 'layer') {
251
+ console.log(message.idx, message.z, message.gcode)
252
+ }
253
+
254
+ if (message.type === 'done') {
255
+ console.log(message.stats)
256
+ }
257
+
258
+ if (message.type === 'error') {
259
+ console.error(message.error)
260
+ }
261
+ }
262
+ ```
263
+
264
+ The worker protocol emits `progress`, `layer`, `done`, and `error` messages. For bundler-specific setups, `three-slicer/worker` exposes the worker entry directly.
265
+
266
+ ## Bundler Notes
267
+
268
+ Vite consumers should enable ES module workers and an ES2022 build target:
269
+
270
+ ```js
271
+ import { defineConfig } from 'vite'
272
+
273
+ export default defineConfig({
274
+ worker: { format: 'es' },
275
+ build: { target: 'es2022' },
276
+ })
277
+ ```
278
+
279
+ For Next.js or webpack apps, render the viewer on the client side and disable Node-only module aliases used by Emscripten guards.
280
+
281
+ ```js
282
+ module.exports = {
283
+ webpack: (config) => {
284
+ for (const moduleName of [
285
+ 'node:module',
286
+ 'node:fs',
287
+ 'node:path',
288
+ 'node:url',
289
+ 'node:crypto',
290
+ 'node:worker_threads',
291
+ ]) {
292
+ config.resolve.alias[moduleName] = false
293
+ }
294
+ return config
295
+ },
296
+ }
297
+ ```
298
+
299
+ ## Multithreaded WASM
300
+
301
+ The engine ships single-threaded and multithreaded WASM builds. The browser worker automatically uses the multithreaded kernel when the page is cross-origin isolated.
302
+
303
+ Serve these headers to enable it:
304
+
305
+ ```txt
306
+ Cross-Origin-Opener-Policy: same-origin
307
+ Cross-Origin-Embedder-Policy: require-corp
308
+ ```
309
+
310
+ Without those headers, the engine falls back to the single-threaded kernel.
311
+
312
+ ## Data Files
313
+
314
+ The package includes extracted OrcaSlicer metadata for custom interfaces:
315
+
316
+ | File | Use |
317
+ | --- | --- |
318
+ | `three-slicer/data/config-schema.json` | Setting definitions, defaults, labels, units, and option metadata |
319
+ | `three-slicer/data/ui-tree.json` | Tab, page, group, and option layout |
320
+ | `three-slicer/data/toggle-rules.json` | Original enable/disable rule metadata |
321
+ | `three-slicer/data/invalidation-map.json` | Setting invalidation/dependency metadata |
322
+
323
+ ## API Reference
324
+
325
+ | API | Description |
326
+ | --- | --- |
327
+ | `createSlicer()` | Loads the WASM kernel and returns a slicer handle |
328
+ | `slicer.slice(stl, params, callbacks?)` | Slices binary STL input to G-code or streamed layers |
329
+ | `slicer.paintPrepare(stl)` | Prepares support painting against a model |
330
+ | `slicer.paint(args)` | Paints support enforcer/blocker data |
331
+ | `slicer.paintClear()` | Clears support painting data |
332
+ | `slicer.overlay(enforcer)` | Returns support painting overlay data |
333
+ | `slicer.heapSize()` | Returns current WASM heap size |
334
+ | `slicer.dispose()` | Releases the slicer handle for garbage collection |
335
+ | `engineWorkerURL()` | Returns a browser worker URL |
336
+ | `deriveKernelParams(settings)` | Converts sparse OrcaSlicer settings to kernel params |
337
+ | `<Viewport/>` | React slicer viewport |
338
+ | `<SettingsPanel/>` | React settings form |
339
+
340
+ ## Runtime Support
341
+
342
+ | Environment | Supported use |
343
+ | --- | --- |
344
+ | Node ESM | Headless slicing |
345
+ | Browser main thread | Headless slicing |
346
+ | Browser worker | Off-main-thread slicing and streaming |
347
+ | React | Viewer and settings panel |
348
+ | three.js | Required by `three-slicer/viewer` |
349
+
350
+ ## Known Limits
351
+
352
+ - `slice()` currently takes binary STL input at the engine API boundary.
353
+ - The viewer can import STL, OBJ, 3MF, AMF, and PLY, then converts them for slicing.
354
+ - `registerLoader(exts, fn)` from `three-slicer/viewer/loaders` adds any other format. Formats needing a heavy dependency are kept out of the package so it stays runtime-dependency-free — see `web/viewer/src/step_loader.js` for a STEP loader built on `occt-import-js` (OCCT WASM).
355
+ - Not every OrcaSlicer schema key is wired into the WASM kernel yet.
356
+ - Some vector settings are simplified to their first element.
357
+ - Multithreaded WASM requires cross-origin isolation.
358
+ - `three` is pinned as a peer dependency because viewer internals depend on the `TransformControls` API shape.
40
359
 
41
360
  ## License
42
361
 
43
- AGPL-3.0-or-later — derived from OrcaSlicer.
44
- Source: https://github.com/kimgh06/Web_Three_Slicer
362
+ AGPL-3.0-or-later. This package is derived from OrcaSlicer. Source is available at [kimgh06/Web_Three_Slicer](https://github.com/kimgh06/Web_Three_Slicer). If you embed it in a web app, make sure your app complies with the AGPL network-use requirements, including offering source code to users where required.
@@ -1,6 +1,6 @@
1
1
  # three-slicer/components
2
2
 
3
- Reusable React components for the browser slicer. Props-driven — no global state, no React context, no router coupling (proven standalone by the tarball consumer gate `web/pack_check.sh`).
3
+ Reusable React components for the browser slicer. Props-driven — no global state, no React context, no router coupling (proven standalone by the tarball consumer gate `packages/pack_check.sh`).
4
4
 
5
5
  ## `<SettingsPanel/>`
6
6