three-slicer 0.2.5 → 0.3.1

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 (44) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/README.md +13 -8
  3. package/THIRD-PARTY-NOTICES.md +7 -2
  4. package/components/dist/SettingsPanel.js +12 -198
  5. package/data/config-schema-lean.json +1 -0
  6. package/data/processes.js +1 -1
  7. package/data/ui-tree-keys.json +1 -0
  8. package/engine/src/client.js +9 -0
  9. package/engine/src/data.js +6 -0
  10. package/engine/src/settings.js +12 -627
  11. package/engine/src/sla_core.js +14 -8
  12. package/engine/src/toggle_eval.js +9 -77
  13. package/package.json +24 -17
  14. package/types/client.d.ts +3 -0
  15. package/types/components.d.ts +3 -29
  16. package/types/settings.d.ts +15 -0
  17. package/types/toggle.d.ts +2 -22
  18. package/types/viewer-gcode.d.ts +2 -29
  19. package/types/viewer-loaders.d.ts +1 -33
  20. package/types/viewer-toolpath.d.ts +3 -113
  21. package/types/viewer.d.ts +6 -213
  22. package/viewer/dist/Viewport.js +9 -6571
  23. package/viewer/dist/gcode_reexport.js +1 -0
  24. package/viewer/dist/loaders_reexport.js +1 -0
  25. package/viewer/dist/toolpath_reexport.js +1 -0
  26. package/components/README.md +0 -44
  27. package/components/styles.css +0 -88
  28. package/engine/src/kernel_setting_keys.js +0 -132
  29. package/engine/src/preset_file.js +0 -99
  30. package/types/.omc/state/sessions/02e5ddf5-4378-46e1-8fca-e90412c30804/pre-tool-advisory-throttle.json +0 -10
  31. package/viewer/README.md +0 -423
  32. package/viewer/dist/gcode_parse.js +0 -190
  33. package/viewer/dist/make_worker.js +0 -31
  34. package/viewer/dist/model_loaders.js +0 -184
  35. package/viewer/dist/parse_3mf-C2X_W442.js +0 -300
  36. package/viewer/dist/parse_3mf.worker.js +0 -10
  37. package/viewer/dist/sl1_encode.worker.js +0 -10
  38. package/viewer/dist/sl1_write-CtX8cVL7.js +0 -302
  39. package/viewer/dist/sla_reconstruct-CXkYhux2.js +0 -176
  40. package/viewer/dist/sla_reconstruct.worker.js +0 -24
  41. package/viewer/dist/sla_slice.worker.js +0 -74
  42. package/viewer/dist/toolpath_gpu-4foc4FaU.js +0 -482
  43. package/viewer/dist/toolpath_gpu.js +0 -13
  44. package/viewer/styles.css +0 -394
package/types/viewer.d.ts CHANGED
@@ -1,214 +1,7 @@
1
- // three-slicer/viewer
2
- import type * as React from 'react'
3
- import type { SlicerSettings } from './settings-keys.d.ts'
4
-
5
- export interface ViewportProps {
6
- /**
7
- * Sparse settings map. Defaults to `{}`. Two viewer knobs ride in it beside the schema keys: `sla_antialias`
8
- * (SL1 mask MSAA, 1|2|4) and `slice_workers` — how many plates an all-plates run slices at once (0/absent =
9
- * Auto: half the cores on the threaded kernel, one per core on the single-threaded one; the in-app select
10
- * writes it). Neither reaches a 3mf.
11
- */
12
- settings?: SlicerSettings
13
- /** React setState shape. Defaults to a no-op. */
14
- setSettings?: React.Dispatch<React.SetStateAction<SlicerSettings>>
15
- /**
16
- * Per-plate overrides: `{[plateIndex]: sparse map}`, merged over `settings` for that plate's slice only —
17
- * a key's absence means "follow the global value" (delete the key to clear an override). Plate identity is
18
- * the plate index; deleting the last plate truncates its entry. Editing one plate's override invalidates only
19
- * that plate's cached result. Any key can be overridden: `printer_technology` routes that plate to the
20
- * FFF or SLA slicer (an SLA plate's grid cell is sized to its resin display), and a bed override
21
- * (`printable_area`/`printable_height`) resizes that plate's own grid cell. What a 3mf cannot represent —
22
- * a mixed-technology or mixed-bed project — is refused at project export with a typed error
23
- * (`error.code` `'UNSUPPORTED_MIXED_TECH_3MF'` / `'UNSUPPORTED_MIXED_BED_3MF'`); per-plate G-code/.sl1
24
- * exports always work. Defaults to `{}`.
25
- */
26
- plateSettings?: Record<number, SlicerSettings>
27
- /** React setState shape for {@link ViewportProps.plateSettings}. Defaults to a no-op. */
28
- setPlateSettings?: React.Dispatch<React.SetStateAction<Record<number, SlicerSettings>>>
29
- /**
30
- * Left process-panel slot — usually `<SettingsPanel embedded/>`. Defaults to null.
31
- *
32
- * Pass a FUNCTION to opt into the per-plate scope toggle (shown with more than one plate): in plate scope
33
- * the panel receives the selected plate's EFFECTIVE map and a setter that writes only the changed keys into
34
- * {@link ViewportProps.plateSettings}; `meta.overriddenKeys`/`meta.onRevertKey` drive the override badges
35
- * (`<SettingsPanel overriddenKeys={...} onRevertKey={...}/>`). In global scope the pair is simply
36
- * `settings`/`setSettings`. A plain node keeps the global-only binding.
37
- */
38
- processPanel?: React.ReactNode
39
- | ((settings: SlicerSettings, setSettings: React.Dispatch<React.SetStateAction<SlicerSettings>>,
40
- meta: { scope: 'global' | 'plate', selectedPlate: number, overriddenKeys: string[],
41
- onRevertKey: ((key: string) => void) | null }) => React.ReactNode)
42
- /** Motion-limits editor, folded into the printer card — usually `<SettingsPanel only={{builder:'TabPrinter::build_kinematics_page'}}/>`. */
43
- motionPanel?: React.ReactNode
44
- /**
45
- * Filament editor, folded into the filament card. Pass a function rather than a node: with more than one
46
- * extruder loaded the card projects that extruder's slice of the per-extruder columns and writes the form's
47
- * edits back at its index, so the panel must bind to the pair it is given.
48
- */
49
- filamentPanel?: React.ReactNode
50
- | ((settings: SlicerSettings, setSettings: React.Dispatch<React.SetStateAction<SlicerSettings>>) => React.ReactNode)
51
- /**
52
- * Per-panel visibility. Every panel is visible unless its key is explicitly `false`, so a host only opts out —
53
- * and a panel added in a later version does not disappear for hosts that listed the ones they wanted.
54
- *
55
- * A {@link LockablePanel} also accepts `'readonly'`: the panel is drawn but nothing inside it can be clicked,
56
- * typed into or tabbed to — including any node the host passed into it. That is the shape a host wants when it
57
- * presets the printer, process and filament itself and does not want the user changing them.
58
- *
59
- * Note what it locks: the UI path, not the value. `settings` is still the host's own prop, and other paths
60
- * inside the viewer still write it — importing a 3mf project applies that project's settings either way.
61
- */
62
- panels?: Partial<Record<ViewportPanel, boolean>> & Partial<Record<LockablePanel, boolean | 'readonly'>>
63
- /**
64
- * Behaviour switches, following the same opt-out rule as {@link ViewportProps.panels}: everything is on unless
65
- * its key is explicitly `false`. These are the things the component does *outside* its own box — take the page's
66
- * keyboard, load the WASM kernel, write to the console — which a host embedding it in a larger app may already
67
- * be doing itself. See {@link ViewportFeature}.
68
- */
69
- features?: Partial<Record<ViewportFeature, boolean>>
70
- /**
71
- * Intercepts every file the viewer would otherwise hand to the browser as a download — the 3mf project, the STL,
72
- * and each plate's G-code. Return anything truthy to say it is handled and suppress the download; return nothing
73
- * to let it proceed as well. This is the only way in: the save buttons live inside the component.
74
- *
75
- * ```jsx
76
- * <Viewport onExport={(blob, filename) => { upload(blob, filename); return true }} />
77
- * ```
78
- */
79
- onExport?: (file: Blob, filename: string) => boolean | void
80
- /**
81
- * G-code text to render instead of a slice result. Parsed into the same layer stream the kernel produces and
82
- * shown on the selected plate; the kernel is never started. While it is set, auto re-slice leaves that plate alone.
83
- */
84
- gcode?: string | null
85
- /**
86
- * An `.sl1` archive rendered as a raster preview — the SLA half of {@link ViewportProps.gcode}'s contract: it
87
- * lands on the selected plate and the kernel is never started. Set both and the G-code wins; one plate holds
88
- * one artifact.
89
- *
90
- * Two things it does that `gcode` does not. It writes to your `settings` — the archive's own job description,
91
- * `printer_technology` included, because an .sl1 opened in an FFF session has to switch it. And it reconstructs
92
- * a surface from the masks in the background, so the preview fills in a moment after the layers appear.
93
- *
94
- * Re-injects whenever the value's IDENTITY changes, so hold the File/buffer in state rather than building it
95
- * during render — a fresh `new Uint8Array(...)` each render re-imports each render. `{name, data}` exists
96
- * because the name is the import notice's subject and the filename a re-export hands back.
97
- */
98
- sl1?: File | Blob | ArrayBuffer | Uint8Array | { name?: string, data: ArrayBuffer | Uint8Array } | null
99
- /**
100
- * Content imported once on mount, through the same extension dispatch as a drop: models (STL/OBJ/3MF/AMF/PLY —
101
- * a 3mf project applies its settings, plates and painting), `.sl1` raster archives, and preset files
102
- * (`.json` / `.orca_printer` / `.orca_bundle` / `.orca_filament` / `.zip`). The `{name, data}` form exists
103
- * because the dispatch runs on the file NAME's extension. Deliberately mount-only — recreating the array on a
104
- * later render does not re-import; runtime loading is the picker, drop, or a remount.
105
- */
106
- files?: Array<File | { name: string, data: ArrayBuffer | Uint8Array }>
107
- /**
108
- * A token whose identity CHANGE requests one slice of the current plate — the host's Slice button:
109
- * keep a counter in state and bump it. The mount value is inert (0 and null both slice nothing), so is
110
- * setting it back to `null`. Ignored while a `gcode`/`sl1` injection holds the plate or the scene is
111
- * empty — the same conditions under which the built-in slice bar is not pressable. A change while a
112
- * slice is running cancels it and re-slices: the last request wins.
113
- */
114
- sliceRequest?: number | string | object | null
115
-
116
- /** Initial filament colours (hex), one per extruder. Defaults to the built-in T1/T2 pair. */
117
- defaultExtruderColors?: string[] | null
118
- /**
119
- * Start with auto re-slice on. Unlike the in-app toggle's original behaviour this also performs the FIRST slice,
120
- * which is what makes a panel-less embed able to slice at all.
121
- */
122
- defaultAutoSlice?: boolean
123
- /** Every value change in one channel. See {@link ViewportEvent}. */
124
- onEvent?: (event: ViewportEvent) => void
125
- /** A finished slice, fired where the result is cached — switching plate tabs does not re-fire it. */
126
- /** `throughput` is how fast the slice ran — see `SliceThroughput` in the engine entry. Absent on a kernel
127
- * result that carried none (a cached plate re-announced from before the field existed). */
128
- onSliced?: (result: {
129
- plate: number; stats: Record<string, unknown>; gcode: string
130
- throughput?: { ms: number; kernelMs: number | null; layersPerSecond: number; msPerMsegment: number | null }
131
- }) => void
132
- /**
133
- * An all-plates run as it moves: the run map on every change, `null` when none is on. `workers.pool` is how
134
- * many slice at once, `workers.kernel` which kernel loaded ('mt' threads / 'st'); each plate carries its state
135
- * and its own progress (0..1) and layers/second. Fired several times a second while a run is on.
136
- */
137
- onSliceRun?: (run: {
138
- workers: { pool: number; active: number; kernel: 'mt' | 'st' | null }
139
- plates: Record<number, { state: 'queued' | 'busy' | 'done' | 'failed'; progress: number; rate: number }>
140
- } | null) => void
141
- }
142
-
143
- /**
144
- * Behaviour keys accepted by {@link ViewportProps.features}. All default to enabled.
145
- *
146
- * - `shortcuts` — the keyboard bindings. They are installed on `window`, so while the viewer is mounted they fire
147
- * wherever focus is (except inside inputs) and `Ctrl+C` in particular preventDefaults. Turn them off when the
148
- * host page has its own.
149
- * - `warmup` — loading the WASM kernel on mount, ahead of the first slice. Off, nothing is downloaded or compiled
150
- * until something actually slices — which for a `gcode`-only viewer is never.
151
- * - `drop` — drag and drop onto the canvas.
152
- * - `filePicker` — the file dialog, from every button that opens it.
153
- * - `contextMenu` — the right-click menu. Note that the browser's own menu stays suppressed over the canvas either
154
- * way: OrbitControls preventDefaults `contextmenu` itself.
155
- * - `logs` — console diagnostics, from the component and from the slice worker.
156
- */
157
- export type ViewportFeature = 'shortcuts' | 'warmup' | 'drop' | 'filePicker' | 'contextMenu' | 'logs'
158
-
159
- /**
160
- * The panels that accept `'readonly'` as well as `true`/`false` — the right column and the cards in it. Everything
161
- * else takes a boolean only: locking the gizmo rail or the plate tabs is what `features` and `panels: false` are
162
- * for, and pretending otherwise would mean a `'readonly'` that silently does nothing on half the keys.
163
- *
164
- * `sidebar: 'readonly'` locks the whole column in one go, so the per-card keys are for mixing — a locked printer
165
- * card above a live object list, say.
166
- */
167
- export type LockablePanel =
168
- | 'sidebar' | 'printerCard' | 'filamentCard' | 'objectList' | 'towerCard'
169
- | 'previewControls' | 'processCard' | 'sliceBar'
170
-
171
- /** Panel keys accepted by {@link ViewportProps.panels}. `sidebar: false` hides the whole right column at once. */
172
- export type ViewportPanel =
173
- | 'topBar' | 'gizmoRail' | 'objectToolbar' | 'paintPanel' | 'statsCard' | 'plateBar' | 'emptyHint' | 'status'
174
- | 'sidebar' | 'printerCard' | 'filamentCard' | 'objectList' | 'previewControls' | 'processCard' | 'sliceBar'
175
- /** The horizontal move scrub under the canvas — how far into the top shown layer the print has got. Preview
176
- * and FFF only: a resin layer is cured in one exposure and has no intra-layer order to walk. */
177
- | 'moveBar'
178
- /** The over-the-bed warning, shown in Prepare when something leaves the printable area. */
179
- | 'bedWarn'
180
- /** The prime tower card. Only rendered anyway once a second filament exists. */
181
- | 'towerCard'
182
- /** The resin (SLA) card. Takes the filament card's place when the printer profile declares SLA. */
183
- | 'resinCard'
184
-
185
- /** Value changes reported through {@link ViewportProps.onEvent}. Not fired for the initial values. */
186
- export type ViewportEvent =
187
- | { type: 'canvasMode'; value: 'prepare' | 'preview' }
188
- | { type: 'objects'; value: Array<{ id: number; name: string; extruder: number; visible: boolean }> }
189
- | { type: 'selectedPlate'; value: number }
190
- | { type: 'plateCount'; value: number }
191
- | { type: 'extruderColors'; value: string[] }
192
- | { type: 'autoSlice'; value: boolean }
193
- | { type: 'slicing'; value: boolean }
194
- /** 0..1. Fires several times a second while slicing — throttle on the host side if that matters. */
195
- | { type: 'progress'; value: number }
196
- /**
197
- * Live throughput: layers finished per second over a 250ms window, `0` between slices. An SLA slice reports it
198
- * throughout. An FFF slice reports it only once the emission pass begins streaming layers — the earlier passes
199
- * publish no per-layer progress, so nothing is measured there and none is invented. For the whole-slice figure
200
- * use `throughput` from `onSliced`.
201
- */
202
- | { type: 'sliceRate'; value: number }
203
- | { type: 'viewType'; value: 'feature' | 'speed' | 'height' | 'width' | 'fan' | 'temp' | 'filament' }
204
- | { type: 'paintMode'; value: 'off' | 'enforcer' | 'blocker' | 'material' }
205
- | { type: 'layerCount'; value: number }
206
- | { type: 'layerRange'; value: { lo: number; hi: number } }
207
- /** The move scrub's position within the top shown layer; `max` is that layer's move count, extrusions and
208
- * travels together. Not fired while the whole layer is shown. */
209
- | { type: 'moveScrub'; value: { at: number; max: number } }
210
- | { type: 'error'; value: string }
211
- | { type: 'notice'; value: string }
212
-
213
- declare const Viewport: React.FC<ViewportProps>
1
+ // three-slicer/viewer — the permissive viewer (three-slicer-viewer, MIT) with the kernel plugged in.
2
+ export * from 'three-slicer-viewer'
3
+ import type { ViewportProps, SlicerHandle } from 'three-slicer-viewer'
4
+ /** The permissive `useSlicer` bound to the WASM kernel worker (three-slicer/client's makeSlicerWorker). */
5
+ export function useSlicer(deps: Record<string, unknown>): SlicerHandle
6
+ declare function Viewport(props: ViewportProps): JSX.Element
214
7
  export default Viewport