three-slicer 0.1.5 → 0.1.7
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 +256 -21
- package/components/README.md +2 -2
- package/data/README.md +2 -2
- package/data/filaments.js +1 -1
- package/data/preset-keys.json +1 -0
- package/data/processes.js +1 -1
- package/engine/README.md +261 -5
- package/engine/index.d.ts +74 -5
- package/engine/index.js +9 -4
- package/engine/src/client.js +136 -0
- package/engine/src/data.js +3 -0
- package/engine/src/preset_file.js +99 -0
- package/engine/src/settings.js +120 -3
- package/engine/src/slicer.worker.js +30 -3
- package/engine/src/slicer_core.js +0 -0
- package/engine/src/slicer_core.mt.js +0 -0
- package/package.json +20 -10
- package/types/client.d.ts +74 -0
- package/types/components.d.ts +10 -0
- package/types/data/preset-keys.json.d.ts +20 -0
- package/types/data/printers.json.d.ts +2 -2
- package/types/data.d.ts +4 -0
- package/types/settings.d.ts +90 -2
- package/types/viewer.d.ts +57 -1
- package/types/worker.d.ts +87 -0
- package/viewer/README.md +162 -3
- package/viewer/dist/Viewport.js +3350 -2273
- package/viewer/styles.css +31 -3
- package/types/gen_settings_types.mjs +0 -70
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@ Browser/WASM 3D-printing slicer package derived from [OrcaSlicer](https://github
|
|
|
4
4
|
|
|
5
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.
|
|
6
6
|
|
|
7
|
+

|
|
8
|
+
|
|
7
9
|
## Links
|
|
8
10
|
|
|
9
11
|
- Package: [npmjs.com/package/three-slicer](https://www.npmjs.com/package/three-slicer)
|
|
@@ -19,6 +21,7 @@ The package is published as a single npm package, `three-slicer`, with subpath e
|
|
|
19
21
|
- React `<SettingsPanel/>` generated from extracted OrcaSlicer metadata.
|
|
20
22
|
- Vendor printer, print-process and filament preset catalogs, with one material assignable per extruder.
|
|
21
23
|
- Support painting and material painting, plus per-tool filament and purge statistics.
|
|
24
|
+
- 3MF **project** import in the viewer: a slicer-written `.3mf` (OrcaSlicer/BambuStudio save, MakerWorld download) restores its plate layout, project settings, and painted facets — not just the meshes.
|
|
22
25
|
- Extracted data files for custom UIs: config schema, UI tree, toggle rules, invalidation map, and the printer/process/filament catalogs.
|
|
23
26
|
- Automatic multithreaded WASM selection on cross-origin-isolated browser pages.
|
|
24
27
|
|
|
@@ -28,14 +31,18 @@ The package is published as a single npm package, `three-slicer`, with subpath e
|
|
|
28
31
|
npm i three-slicer
|
|
29
32
|
```
|
|
30
33
|
|
|
31
|
-
`react`, `react-dom`, and `three` are peer dependencies
|
|
34
|
+
`react`, `react-dom`, and `three` are **optional** peer dependencies. They stay peers rather than dependencies because React and three must be single instances — a duplicate copy breaks hooks and `instanceof` — and optional because only the UI half needs them: a headless consumer installs none of the three.
|
|
35
|
+
|
|
36
|
+
Install them yourself when you use the viewer or the settings panel:
|
|
32
37
|
|
|
33
|
-
|
|
38
|
+
```bash
|
|
39
|
+
npm i three-slicer react react-dom three
|
|
40
|
+
```
|
|
34
41
|
|
|
35
|
-
| Import path | Needs react/three
|
|
42
|
+
| Import path | Needs react/three |
|
|
36
43
|
| --- | --- |
|
|
37
|
-
| `three-slicer`, `/settings`, `/toggle`, `/worker`, `/wasm`, `/data` | no |
|
|
38
|
-
| `three-slicer/viewer`, `/viewer/toolpath`, `/viewer/loaders` | yes |
|
|
44
|
+
| `three-slicer`, `/settings`, `/toggle`, `/client`, `/worker`, `/wasm`, `/data` | no |
|
|
45
|
+
| `three-slicer/viewer`, `/viewer/toolpath`, `/viewer/loaders`, `/viewer/gcode` | yes |
|
|
39
46
|
| `three-slicer/components` | react only |
|
|
40
47
|
|
|
41
48
|
## Quick Start: Headless Slicing
|
|
@@ -63,7 +70,11 @@ console.log(result.gcode)
|
|
|
63
70
|
slicer.dispose()
|
|
64
71
|
```
|
|
65
72
|
|
|
66
|
-
`slice()` accepts a binary STL as an `ArrayBuffer` or `Uint8Array`. Parameters can be either a kernel params object or a JSON string.
|
|
73
|
+
`slice()` accepts a binary STL as an `ArrayBuffer` or `Uint8Array`. Parameters can be either a kernel params object or a JSON string — every accepted parameter is listed in the [kernel parameter reference](engine/README.md#kernel-parameter-reference), which is generated from the kernel's own reader.
|
|
74
|
+
|
|
75
|
+
A runnable version of the above ships with the package: `node node_modules/three-slicer/engine/examples/headless.mjs` writes a cube, slices it batch and streamed, and prints the stats.
|
|
76
|
+
|
|
77
|
+
`result.error` is set instead of a result when a slice fails or is cancelled — check it before reading `gcode`.
|
|
67
78
|
|
|
68
79
|
## Streaming Layers
|
|
69
80
|
|
|
@@ -99,15 +110,22 @@ export default function App() {
|
|
|
99
110
|
const [settings, setSettings] = useState({})
|
|
100
111
|
|
|
101
112
|
return (
|
|
102
|
-
<
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
113
|
+
<div style={{ position: 'relative', width: '100%', height: '100vh' }}>
|
|
114
|
+
<Viewport
|
|
115
|
+
settings={settings}
|
|
116
|
+
setSettings={setSettings}
|
|
117
|
+
/>
|
|
118
|
+
</div>
|
|
106
119
|
)
|
|
107
120
|
}
|
|
108
121
|
```
|
|
109
122
|
|
|
110
|
-
The
|
|
123
|
+
**The container is not optional.** The viewer fills its nearest *positioned* ancestor — the shadow host is
|
|
124
|
+
`display: contents` and the shell inside is `position: absolute; inset: 0` — so it needs a parent with
|
|
125
|
+
`position: relative` and a real height. In a plain static `<div>` it escapes to the page instead. There is no width
|
|
126
|
+
or height prop.
|
|
127
|
+
|
|
128
|
+
The viewer handles model loading, drag and drop, transform controls, multi-plate layout, worker slicing, GPU toolpath preview, and G-code export. Its keyboard and mouse bindings, the undo boundary, and what a host cannot drive are documented in [viewer/README.md](viewer/README.md). 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()`. A `.3mf` written by a slicer is treated as a project, not just geometry: its plate layout, project settings, and support/material painting are restored on import (where a facet carries both paint kinds, material paint wins and the dropped support paint is reported). Viewer and component styles are bundled into their Shadow DOM roots, so host app CSS does not need to import package CSS.
|
|
111
129
|
|
|
112
130
|
## Quick Start: Settings Panel
|
|
113
131
|
|
|
@@ -178,12 +196,14 @@ Available subpaths:
|
|
|
178
196
|
| `three-slicer` | Headless WASM engine SDK |
|
|
179
197
|
| `three-slicer/settings` | Schema defaults and settings-to-kernel mapping |
|
|
180
198
|
| `three-slicer/toggle` | Enable/disable rule evaluation for settings UIs |
|
|
181
|
-
| `three-slicer/worker` | Browser worker entry |
|
|
199
|
+
| `three-slicer/worker` | Browser worker entry, and the typed message protocol |
|
|
200
|
+
| `three-slicer/client` | `createSlicerClient()` — promises over that protocol |
|
|
182
201
|
| `three-slicer/wasm` | Single-threaded Emscripten WASM glue |
|
|
183
202
|
| `three-slicer/wasm-mt` | Multithreaded Emscripten WASM glue |
|
|
184
203
|
| `three-slicer/viewer` | React `<Viewport/>` |
|
|
185
204
|
| `three-slicer/viewer/toolpath` | GPU toolpath renderer utilities |
|
|
186
205
|
| `three-slicer/viewer/loaders` | Model loaders |
|
|
206
|
+
| `three-slicer/viewer/gcode` | `parseGcode(text)` — G-code back into the layer stream the renderer consumes |
|
|
187
207
|
| `three-slicer/components` | React `<SettingsPanel/>` |
|
|
188
208
|
| `three-slicer/data` | Named exports for extracted metadata |
|
|
189
209
|
| `three-slicer/data/*.json` | Extracted OrcaSlicer metadata |
|
|
@@ -233,6 +253,91 @@ const result = slicer.slice(stlArrayBuffer, params)
|
|
|
233
253
|
|
|
234
254
|
`deriveKernelParams()` maps the curated set of schema keys currently supported by the kernel (92 today). 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, except the filament options described below, which keep every extruder's entry.
|
|
235
255
|
|
|
256
|
+
## 3MF Projects
|
|
257
|
+
|
|
258
|
+
A slicer-written `.3mf` is a project, not a mesh file: `Metadata/project_settings.config` holds the flattened
|
|
259
|
+
preset its author sliced with. `<Viewport/>` reads all of it on import, and the two codecs behind that are exported
|
|
260
|
+
for hosts doing it themselves.
|
|
261
|
+
|
|
262
|
+
**Every value in that file is a string**, and reading it raw is not a cosmetic problem — a disabled option is the
|
|
263
|
+
string `"0"`, and `"0"` is truthy, so a raw import turns every disabled option ON. A point is the string `"256x256"`
|
|
264
|
+
while every consumer indexes it as `[x, y]`, so a raw `printable_area[1][0]` is the character `'2'`. Both are
|
|
265
|
+
handled by coercing each value by its config-schema type:
|
|
266
|
+
|
|
267
|
+
```js
|
|
268
|
+
import { normalizeProjectSettings, serializeProjectSettings } from 'three-slicer/settings'
|
|
269
|
+
|
|
270
|
+
const { settings, applied, skipped } = normalizeProjectSettings(rawConfig)
|
|
271
|
+
// settings: real JS types, ready for deriveKernelParams() and <SettingsPanel/>
|
|
272
|
+
// applied : how many keys survived
|
|
273
|
+
// skipped : keys the config schema does not define (preset bookkeeping, version fields) — dropped, not coerced
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Writing one back is the exact inverse, and it matters for the same reason: a raw JS `false` would be read by any
|
|
277
|
+
other slicer's parser as the string `"false"`, which is truthy.
|
|
278
|
+
|
|
279
|
+
```js
|
|
280
|
+
const config = serializeProjectSettings(settings) // bool -> "1"/"0", point -> "XxY", points group -> "X1xY1,X2xY2"
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Upstream's `inherits` / `different_settings_to_system` reconciliation is deliberately not reproduced: it exists to
|
|
284
|
+
rebase a stored preset onto a local vendor preset database, and `project_settings.config` is already flattened, so
|
|
285
|
+
its values are taken as written.
|
|
286
|
+
|
|
287
|
+
## Preset Files
|
|
288
|
+
|
|
289
|
+
OrcaSlicer's "Config files" dialog imports a `.json` holding one preset — a printer (`machine`), print settings
|
|
290
|
+
(`process`) or a material (`filament`) — plus the zip forms `.orca_printer` / `.orca_bundle` / `.orca_filament`.
|
|
291
|
+
Both directions are supported.
|
|
292
|
+
|
|
293
|
+
```js
|
|
294
|
+
import { writePresetFile, readPresetFile, presetOptionKeys, printerSettings } from 'three-slicer/settings'
|
|
295
|
+
|
|
296
|
+
// Write. Flattened on purpose: every option of that type, no `inherits`, so the file stands on its own.
|
|
297
|
+
const file = writePresetFile(settings, { type: 'machine', name: 'My printer' })
|
|
298
|
+
// -> { type: 'machine', name: 'My printer', from: 'User', printable_area: ['0x0','256x0',…], … }
|
|
299
|
+
|
|
300
|
+
// Read. `resolveParent` follows `inherits`; without it a vendor file arrives incomplete (see below).
|
|
301
|
+
const { settings: loaded, missingParent, skipped } = readPresetFile(file,
|
|
302
|
+
{ resolveParent: (name) => printerSettings(name) })
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
`presetOptionKeys(type)` is the key set for one type — 175 for `machine`, 370 for `process`, 149 for `filament`,
|
|
306
|
+
taken from upstream's own `Preset::printer_options()` and friends. It is what splits a settings map, which holds
|
|
307
|
+
every type's keys at once, into the file for one of them.
|
|
308
|
+
|
|
309
|
+
**A vendor preset is a diff, not a preset.** Upstream saves a derived preset as the difference against its parent
|
|
310
|
+
(`Preset::save`: *"only save difference if it has parent"*), so a file off the vendor profiles carries a fraction
|
|
311
|
+
of what it appears to. Read Bambu's X1C machine file without resolving `inherits` and it has no `printable_area`
|
|
312
|
+
and no `printable_height` at all — the bed is in the parent. `missingParent` names the parent when it could not be
|
|
313
|
+
resolved; the file's own values are still applied, because dropping the file entirely loses more than it protects.
|
|
314
|
+
|
|
315
|
+
Values are written and read in upstream's own encoding — every value a string, a point as `"XxY"`, per-extruder
|
|
316
|
+
options as arrays of strings — the same shape [3MF Projects](#3mf-projects) uses, since upstream writes both
|
|
317
|
+
through the same serializer.
|
|
318
|
+
|
|
319
|
+
The viewer adds the zip forms and a UI: the printer card's **Load** and **Save** read and write these files, and a
|
|
320
|
+
save routes through [`onExport`](viewer/README.md#taking-the-saves) like every other download.
|
|
321
|
+
|
|
322
|
+
## Settings UI: Enable/Disable Rules
|
|
323
|
+
|
|
324
|
+
OrcaSlicer greys out options that another option makes irrelevant. Those rules are extracted, and
|
|
325
|
+
`three-slicer/toggle` evaluates them against a settings map — the panel does this internally, and a custom UI can
|
|
326
|
+
do the same:
|
|
327
|
+
|
|
328
|
+
```js
|
|
329
|
+
import { makeCfg, disabledKeys } from 'three-slicer/toggle'
|
|
330
|
+
|
|
331
|
+
const disabled = disabledKeys(makeCfg(settings))
|
|
332
|
+
// setting key -> the enable_if expression that evaluated false, e.g.
|
|
333
|
+
// { outer_wall_jerk: 'false, variant_index', … }
|
|
334
|
+
if (disabled.outer_wall_jerk) { /* grey the control out; the value says why */ }
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
Only rules that evaluate to an unambiguous `false` are reported — an expression referring to something the
|
|
338
|
+
evaluator cannot resolve is left out rather than guessed at, so a key missing from the map means "not known to be
|
|
339
|
+
disabled", not "definitely enabled".
|
|
340
|
+
|
|
236
341
|
## Materials and Multi-Material
|
|
237
342
|
|
|
238
343
|
A material is a filament preset — temperatures, flow, diameter, cooling, and the retraction/z-hop overrides a material may apply on top of the machine's. Read the catalog through the facade rather than decoding the data file:
|
|
@@ -246,7 +351,22 @@ filaments.recommendedFor('Bambu Lab X1 Carbon 0.4 nozzle') // the vendor's sho
|
|
|
246
351
|
const material = filaments.settingsFor('Bambu PLA Basic @BBL X1C')
|
|
247
352
|
```
|
|
248
353
|
|
|
249
|
-
|
|
354
|
+
**Clear before you apply.** A preset carries only the keys it sets, so merging one over another leaves the previous
|
|
355
|
+
pick's leftovers behind — an ABS material followed by a PLA one keeps ABS's chamber temperature. Every facade
|
|
356
|
+
exposes the exact key set to remove first:
|
|
357
|
+
|
|
358
|
+
```js
|
|
359
|
+
function applyPreset(settings, preset, keys) {
|
|
360
|
+
const next = { ...settings }
|
|
361
|
+
for (const key of keys) delete next[key]
|
|
362
|
+
return Object.assign(next, preset)
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
setSettings(s => applyPreset(s, filaments.settingsFor(name), filaments.keys))
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
The same applies to `processPresets().keys` and `printerKeys`. The filament key set is disjoint from the process key
|
|
369
|
+
set, so applying a material never clears a process pick and vice versa.
|
|
250
370
|
|
|
251
371
|
**One material per extruder.** OrcaSlicer stores every filament option as one entry per extruder, so a multi-material settings map writes each extruder's material at its own index:
|
|
252
372
|
|
|
@@ -280,13 +400,49 @@ Because a single enum serves both jobs, a support blocker paint and an Extruder
|
|
|
280
400
|
|
|
281
401
|
## Worker Usage
|
|
282
402
|
|
|
283
|
-
|
|
403
|
+
Slicing blocks its thread for seconds, so in a browser it belongs in a worker. `three-slicer/client` wraps the
|
|
404
|
+
worker's message protocol in promises:
|
|
405
|
+
|
|
406
|
+
```js
|
|
407
|
+
import { createSlicerClient } from 'three-slicer/client'
|
|
408
|
+
import { deriveKernelParams } from 'three-slicer/settings'
|
|
409
|
+
|
|
410
|
+
const client = createSlicerClient() // creates and owns the worker
|
|
411
|
+
await client.warmup() // optional: load the kernel before the first slice needs it
|
|
412
|
+
|
|
413
|
+
const { gcode, stats } = await client.slice(stlArrayBuffer, deriveKernelParams(settings), {
|
|
414
|
+
onProgress: (done, total) => setProgress(done / total),
|
|
415
|
+
})
|
|
416
|
+
|
|
417
|
+
client.cancel() // stops a running slice — see below
|
|
418
|
+
client.terminate()
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
Pass `onLayer` to take the layers as they are produced instead of having them assembled, which is what keeps a
|
|
422
|
+
large model out of memory:
|
|
423
|
+
|
|
424
|
+
```js
|
|
425
|
+
await client.slice(stl, params, { onLayer: ({ z, idx, gcode }) => append(gcode) })
|
|
426
|
+
// the result then carries stats only
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
The same client drives painting — `prepare`, `paint`, `erase`, `clear`, `overlay`, `importPaint`, `exportPaint`.
|
|
430
|
+
It deliberately leaves two things to the host: the viewer's progress weighting (measured against its own models)
|
|
431
|
+
and its out-of-memory retry ladder, both of which are UI policy rather than protocol.
|
|
432
|
+
|
|
433
|
+
### Driving the worker directly
|
|
434
|
+
|
|
435
|
+
`createSlicerClient` is a thin wrapper; the protocol underneath is a plain message contract, fully typed in
|
|
436
|
+
`three-slicer/worker`.
|
|
284
437
|
|
|
285
438
|
```js
|
|
286
439
|
import { engineWorkerURL } from 'three-slicer'
|
|
440
|
+
import { deriveKernelParams } from 'three-slicer/settings'
|
|
287
441
|
|
|
288
442
|
const worker = new Worker(engineWorkerURL(), { type: 'module' })
|
|
289
443
|
|
|
444
|
+
const chunks = []
|
|
445
|
+
|
|
290
446
|
worker.onmessage = (event) => {
|
|
291
447
|
const message = event.data
|
|
292
448
|
|
|
@@ -295,20 +451,50 @@ worker.onmessage = (event) => {
|
|
|
295
451
|
}
|
|
296
452
|
|
|
297
453
|
if (message.type === 'layer') {
|
|
298
|
-
|
|
454
|
+
chunks.push(message.gcode) // paths/widths arrive transferred, not copied
|
|
299
455
|
}
|
|
300
456
|
|
|
301
457
|
if (message.type === 'done') {
|
|
302
|
-
console.log(message.stats)
|
|
458
|
+
console.log(chunks.join(''), message.result.stats)
|
|
303
459
|
}
|
|
304
460
|
|
|
305
461
|
if (message.type === 'error') {
|
|
306
462
|
console.error(message.error)
|
|
307
463
|
}
|
|
308
464
|
}
|
|
465
|
+
|
|
466
|
+
// A slice request carries NO `cmd` — it is the worker's default action. Every other message (paint, prepare,
|
|
467
|
+
// overlay, …) is addressed by `cmd`, so leaving it off is what selects slicing.
|
|
468
|
+
// `params` must be a JSON STRING here. The direct handle's slice() also accepts an object and stringifies it for
|
|
469
|
+
// you; the worker hands its argument straight to the kernel, which parses JSON text.
|
|
470
|
+
worker.postMessage({ stl: stlArrayBuffer, params: JSON.stringify(deriveKernelParams(settings)) }, [stlArrayBuffer])
|
|
309
471
|
```
|
|
310
472
|
|
|
311
|
-
The worker
|
|
473
|
+
The worker replies with `progress`, `layer`, `done`, and `error` while slicing. `done` carries `{result}` — its
|
|
474
|
+
`stats` when the layers were streamed, plus `gcode` and `layers` when they were not. For bundler-specific setups,
|
|
475
|
+
`three-slicer/worker` exposes the worker entry directly.
|
|
476
|
+
|
|
477
|
+
### Cancelling a slice
|
|
478
|
+
|
|
479
|
+
Cancellation is a flag the kernel polls from inside its C++ loop, so it works even while the worker is blocked in
|
|
480
|
+
WASM. It lives in a `SharedArrayBuffer`, which means it is only available on the multithreaded kernel — that is, on
|
|
481
|
+
a [cross-origin isolated](#multithreaded-wasm) page. `client.cancel()` handles this and returns `false` when there
|
|
482
|
+
is no flag to write. Driving the worker yourself, the address arrives once, unprompted:
|
|
483
|
+
|
|
484
|
+
```js
|
|
485
|
+
let cancelView = null
|
|
486
|
+
|
|
487
|
+
worker.addEventListener('message', ({ data }) => {
|
|
488
|
+
if (data.type === 'supsab' && data.cancelPtr) {
|
|
489
|
+
cancelView = new Uint32Array(data.buf, data.cancelPtr, 1)
|
|
490
|
+
}
|
|
491
|
+
})
|
|
492
|
+
|
|
493
|
+
const cancel = () => cancelView && Atomics.store(cancelView, 0, 1)
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
Without cross-origin isolation the engine runs single-threaded, no `supsab` message arrives, and a slice in
|
|
497
|
+
progress cannot be interrupted — terminate the worker instead.
|
|
312
498
|
|
|
313
499
|
## Bundler Notes
|
|
314
500
|
|
|
@@ -376,23 +562,72 @@ the layout by hand.
|
|
|
376
562
|
|
|
377
563
|
## API Reference
|
|
378
564
|
|
|
565
|
+
### `three-slicer`
|
|
566
|
+
|
|
379
567
|
| API | Description |
|
|
380
568
|
| --- | --- |
|
|
381
569
|
| `createSlicer()` | Loads the WASM kernel and returns a slicer handle |
|
|
382
570
|
| `slicer.slice(stl, params, callbacks?)` | Slices binary STL input to G-code or streamed layers |
|
|
383
|
-
| `slicer.paintPrepare(stl)` | Prepares painting against a model |
|
|
571
|
+
| `slicer.paintPrepare(stl)` | Prepares painting against a model; returns the facet count |
|
|
384
572
|
| `slicer.paint(args)` | Paints enforcer/blocker data (boolean pair; the state-addressed form is worker-only) |
|
|
385
573
|
| `slicer.paintClear()` | Clears painting data for every state |
|
|
386
|
-
| `slicer.overlay(enforcer)` |
|
|
387
|
-
| `slicer.heapSize()` |
|
|
574
|
+
| `slicer.overlay(enforcer)` | The painted overlay triangles for one state, as a `Float32Array` |
|
|
575
|
+
| `slicer.heapSize()` | Current WASM heap size, bytes (peak, monotonic) |
|
|
388
576
|
| `slicer.dispose()` | Releases the slicer handle for garbage collection |
|
|
389
577
|
| `engineWorkerURL()` | Returns a browser worker URL |
|
|
390
|
-
|
|
578
|
+
|
|
579
|
+
### `three-slicer/settings`
|
|
580
|
+
|
|
581
|
+
| API | Description |
|
|
582
|
+
| --- | --- |
|
|
583
|
+
| `deriveKernelParams(settings, opts?)` | Converts sparse OrcaSlicer settings to kernel params. `opts.plate` picks a plate's entry from per-plate options |
|
|
584
|
+
| `schemaDefault(key)` | The config-schema default for a key |
|
|
585
|
+
| `settingRaw(settings, key)` | The map's value, or the schema default |
|
|
586
|
+
| `settingScalar(settings, key)` | The same, reduced to a scalar — the first set entry of a per-extruder column |
|
|
587
|
+
| `normalizeProjectSettings(raw)` | A 3mf's all-strings `project_settings.config` → a typed settings map |
|
|
588
|
+
| `serializeProjectSettings(settings)` | The inverse, for writing one |
|
|
589
|
+
| `writePresetFile(settings, opts)` | A settings map → an OrcaSlicer preset `.json`, flattened |
|
|
590
|
+
| `presetFileText(settings, opts)` | The same, stringified |
|
|
591
|
+
| `readPresetFile(raw, opts)` | A preset `.json` → a settings map; follows `inherits` via `resolveParent` |
|
|
592
|
+
| `presetOptionKeys(type)` | The option keys belonging to `machine` / `process` / `filament` |
|
|
593
|
+
| `printersByVendor` | Vendor → profile name → entry, for building a picker |
|
|
391
594
|
| `printerSettings(name)` | Settings a vendor machine profile applies |
|
|
595
|
+
| `printerKeys` | Every key a printer profile can set — clear these before applying another |
|
|
596
|
+
| `printerDefaultPreset(name)` | The vendor's recommended process preset for that printer |
|
|
597
|
+
| `machineLimitKeys` | The schema keys the kernel's machine limits are read from |
|
|
392
598
|
| `processPresets()` | Lazy facade over the print (process) preset catalog |
|
|
393
599
|
| `filamentPresets()` | Lazy facade over the material preset catalog |
|
|
600
|
+
|
|
601
|
+
### `three-slicer/toggle`
|
|
602
|
+
|
|
603
|
+
| API | Description |
|
|
604
|
+
| --- | --- |
|
|
605
|
+
| `makeCfg(settings)` | Wraps a settings map for rule evaluation |
|
|
606
|
+
| `disabledKeys(cfg)` | Setting key → the `enable_if` expression that evaluated false |
|
|
607
|
+
| `evalEnableIf(expr, locals, cfg)` | Evaluates a single rule; `null` when it cannot be resolved |
|
|
608
|
+
|
|
609
|
+
### `three-slicer/viewer` and `three-slicer/components`
|
|
610
|
+
|
|
611
|
+
| API | Description |
|
|
612
|
+
| --- | --- |
|
|
394
613
|
| `<Viewport/>` | React slicer viewport |
|
|
395
614
|
| `<SettingsPanel/>` | React settings form |
|
|
615
|
+
| `loadModel(name, buffer)` | Parses STL/OBJ/3MF/AMF/PLY into objects |
|
|
616
|
+
| `registerLoader(exts, fn)` | Adds a format — STEP and anything else needing a heavy dependency |
|
|
617
|
+
| `SUPPORTED_EXT` / `fileExt(name)` | The known extensions, and one file's |
|
|
618
|
+
| `splitConnectedComponents(pos)` | Splits a mesh into its connected components; `null` when there is only one |
|
|
619
|
+
| `parseGcode(text)` | G-code text → the layer stream the renderer consumes |
|
|
620
|
+
| `buildSegmentData(layers, w)` | Layers → the packed segment buffers |
|
|
621
|
+
| `computeColors(data, view, ctx)` | Per-segment colours for a view type |
|
|
622
|
+
| `makeToolpath(THREE, data)` | The GPU toolpath mesh handle |
|
|
623
|
+
| `VIEW_TYPES` / `roleRatios(lengths)` | The preview's view types, and the per-role length split |
|
|
624
|
+
|
|
625
|
+
### `three-slicer/data`
|
|
626
|
+
|
|
627
|
+
| API | Description |
|
|
628
|
+
| --- | --- |
|
|
629
|
+
| `schema`, `uiTree`, `toggleRules`, `invalidationMap`, `printers` | The extracted metadata, import attributes already applied |
|
|
630
|
+
| `loadProcesses()` / `loadFilaments()` | The two large catalogs, on demand — prefer the `settings` facades |
|
|
396
631
|
|
|
397
632
|
## Runtime Support
|
|
398
633
|
|
package/components/README.md
CHANGED
|
@@ -4,10 +4,10 @@ Reusable React components for the browser slicer. Props-driven — no global sta
|
|
|
4
4
|
|
|
5
5
|
## `<SettingsPanel/>`
|
|
6
6
|
|
|
7
|
-
An OrcaSlicer-style settings form generated from
|
|
7
|
+
An OrcaSlicer-style settings form generated from `three-slicer/data` (schema + UI tree + toggle rules): tab/page/group navigation, mode filter (simple/advanced/expert), search across 923 options, dirty markers with per-option reset, and enable/disable rules evaluation.
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npm i three-slicer
|
|
10
|
+
npm i three-slicer # react is a peer dependency — npm installs it for you
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
```jsx
|
package/data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# three-slicer/data
|
|
2
2
|
|
|
3
|
-
OrcaSlicer configuration metadata extracted from the original C++ sources, as
|
|
3
|
+
OrcaSlicer configuration metadata extracted from the original C++ sources, shipped inside the `three-slicer` package as its `/data` subpath. Used by `three-slicer` (defaults, settings mapping) and `three-slicer/components` (settings UI), and usable standalone for building slicer UIs.
|
|
4
4
|
|
|
5
5
|
| File | Contents |
|
|
6
6
|
|---|---|
|