Docs
Enough to get a painted model into your slicer, plus the matrix that says which slicers that sentence is currently true of.
Quickstart
- Open the app, or install it. Nothing to sign up for either way.
- Drag an STL, OBJ, PLY or 3MF onto the window. Read the report it gives you.
- Segment the model at its creases, assign filaments to the regions, then brush the parts the geometry got wrong.
- Cut it to fit your plate, or separate it by colour if you print one filament at a time.
- Export a painted 3MF in your slicer's dialect, and save the project beside it.
The full version, with what goes wrong at each step, is the workflow page. The reference documentation lives with the source, because it is generated from the same notes as the work.
Slicers
A painted export is only worth something if the slicer honours the paint, so this is measured as paint arriving in G-code rather than as a file that opens. Right now that is true of one slicer out of three, and saying so is the point of the table.
| Slicer | Opens | Slices | Paint verified |
|---|---|---|---|
| PrusaSlicer 2.9.6 | Yes | Yes | Yes — as tool changes, in the right order |
| OrcaSlicer V2.4.2 | Yes | Yes | Yes — as tool changes, in the right order |
| Bambu Studio | Untested | Untested | Untested — the dialect is written from its own importer and has opened nothing |
Serving the browser version yourself
Static files, no backend. The server must send Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp.
Cancelling a running operation uses shared memory — a worker busy inside geometry code cannot check its messages — and browsers only allow shared memory on a cross-origin isolated page. Without the headers everything still works except cancelling.
Where every number on this site comes from
Each one names the file that carries it, and a test fails the site build if the file stops saying so. That is a deliberate response to a habit worth avoiding: a figure that was true when someone typed it and has not been true since.
| Claim | Value | Kind | Source |
|---|---|---|---|
| One brush stamp on a five-million-triangle model, CPU side. | 4.46 ms | Benchmark | docs/perf/paint-baseline.md |
| Read, weld, inspect and repair a million-triangle model — the whole pipeline. | 979 ms | Benchmark | docs/perf/import-pipeline-baseline.md |
| A plane cut through a three-million-triangle model. | 5.4 s | Benchmark | docs/perf/cut-baseline.md |
| Writing a painted 3MF from a five-million-triangle model with every slot used. | 8.2 s | Benchmark | docs/perf/export-baseline.md |
| The project size the save below was measured on. | 507 MB | Benchmark | docs/perf/save-baseline.md |
| Writing that project to a file. | 2.1 s | Benchmark | docs/perf/save-baseline.md |
| Undoing a step on a five-million-triangle document, renderer update included. | 0.07 ms | Benchmark | docs/perf/undo-baseline.md |
| Peak memory while importing a twenty-million-triangle model. | 3.9 GB | Benchmark | docs/perf/memory-audit.md |
| Real models from two public corpora, run through the pipeline on every change. | 124 | Benchmark | docs/compat/corpus.md |
| How many of them import. | 103 | Benchmark | docs/compat/corpus.md |
| How many are refused — point clouds, empty exports, one corrupt file. Each says why. | 21 | Benchmark | docs/compat/corpus.md |
| Filament slots, which is what the target slicers consume. | sixteen | Product source | packages/shared/src/mesh.ts |
| The slicer that opened a painted export with the paint reaching G-code. | PrusaSlicer 2.9.6 | Verified session | docs/compat/prusaslicer.md |
| The second slicer to put our paint into G-code in the right tool-change order. | OrcaSlicer V2.4.2 | Verified session | docs/compat/orcaslicer.md |
Benchmarks were taken on a mid-range desktop, CPU side. Frame rate while orbiting and cold start time are missing from that list because nobody has measured them on hardware worth trusting — they are absent rather than passing.