Simulator — how it should be¶
This page collects everything the repo itself says about where the Simulator is heading, and nothing more. Every item is tagged:
- STATED — written down in a doc, bead, memory, or ADR. The citation is the claim; this page adds no interpretation.
- INFERENCE — a reading of the evidence, marked bold. Not a plan, not a promise.
There is currently no open implementation epic for the Simulator. The only
open product-facing bead is nps-0m7 (IN_PROGRESS, P2), which is a docs bead:
build this share-vs-split site, simulator-first. Recent git history is shared
shell work and a Slicer parity pass (20c54fa …), and the Simulator
visualization epic nps-f8v is closed. Everything below is therefore direction
recorded at close-out time, not scheduled work.
Stated direction¶
Product statement¶
The README defines the Simulator as the physics counterpart to the Slicer:
| Statement | Source |
|---|---|
| Simulator performs physics simulation on the same mesh/field data — stress, temperature, deformation — in the same viewport. | README.md:15 |
| Monorepo = Non-Planar Slicer + companion Simulator; shared UI kit, 3D viewport, one engine. | README.md:3 |
| Docs map: Simulator = Slicer's toolpath/analysis surface plus background mesh polygons. | docs/guide/docs/codebase/overview.md (SlicerApp / SimulatorApp bullets) |
Note the gap this creates: the product statement promises stress / temperature / deformation physics; the shipped Simulator is a G-code analysis and playback host. See the INFERENCE section.
The f8v direction: viewer3d features into Avalonia + ABI¶
The closed epic nps-f8v set the Simulator's visual direction, and its memory
record is explicit law about where each JS-prototype feature should land:
| Direction | Source |
|---|---|
| Epic intent: rich G-code visualization, playback simulation, multi-engine analysis (thermal / structural / motion / warp / holes) into the shared viewport and Simulator. | bead nps-f8v (CLOSED), description + AC |
| C++ owns parse and analysis; the viewport handles rendering; JS patterns are adapted, not ported wholesale. | bead nps-f8v DESIGN |
| viewer3d ribbons, MVP, clip, 3-pass sim, warp-grid are mapped to "inform Avalonia render + engine data ABI"; analyzers map to C++. | bead nps-f8v.2 DESIGN §3 VIEWER (viewer3d → Avalonia/ABI mapping); session memory nps-f8v-2-gcode-study-key-extracts-parser (restates it) |
| Warp / holes / retraction / flow delivered as additional overlays and findings in the Simulator. | bead nps-f8v.5 (CLOSED) |
| Overlays, findings, and playback sim integrated in the Avalonia shell, with follow-up for full Slicer shell parity. | beads nps-f8v.6, nps-f8v.6.1 (CLOSED) |
The scratch_gcode/ prototype remains reference material only, not runtime
architecture (docs/architecture.md:439-446, README.md:146-153).
Viewport headroom (engine facts that shape the future)¶
These are HOW IT IS facts that the stated direction builds on:
| Fact | Source |
|---|---|
Sim state limits drawing via moveOffsets_ / simMoveIndex; ribbon half-width ~0.2 mm. |
docs/modules/viewport.md:22-24, :45-48, :68-69 |
| Richer move types can be added without an ABI break. | docs/modules/viewport.md:25-27 |
A clip plane exists C++-internal only — "No ViewportSetClipPlane export exists." The f8v mapping wants clip to inform the ABI; today it has not crossed the border. |
docs/modules/viewport.md:91-92 |
ABI evolution policy: additive growth via trailing reserved[] fields or new exports; breaking changes are a separate class. |
docs/adr/0001-abi-change-policy.md:42-98 |
UI future specs — including one honest contradiction¶
docs/ui-shell-and-viewport.md records both a future list and a skip list, and
they overlap. This page reports the contradiction rather than resolving it:
| Item | Listed as FUTURE | Listed as SKIPPED |
|---|---|---|
| Center splits | ui-shell-and-viewport.md:122-124 |
:191-196 |
| XYZ snap buttons | :122-124 |
:191-196 |
| View-mode toolbar | :122-124 |
:191-196 |
| Shader passes | :122-124 |
:191-196 |
The same file also states a future persistence spec: sidebar widths,
open/closed state, selected tab, camera, and field mode should persist
(ui-shell-and-viewport.md:184-187). A closed bead nps-fp1 (Viewport Toolbar
and Camera Snaps) suggests the docs may lag the code on the snap row; no open
bead exists for the rest.
The mesh background contract¶
The shell contract assigns the Simulator a capability the Slicer explicitly does not get:
| Statement | Source |
|---|---|
Simulator only paints the loaded mesh via MeshController + MeshCanvasPainter; the Slicer stays toolpath-focused and skips the background mesh. |
docs/ui-shell-and-viewport.md:112-118 |
The Slicer parity pass (nps-3a3, closed) deliberately dropped Simulator-only playback/mesh concerns from the Slicer rather than copying them over. |
bead nps-3a3 (CLOSED); git 20c54fa |
Auto-pause: a docs-lag example¶
The playback spec says auto-pause on findings is a "stub comment only"
(docs/ui-shell-and-viewport.md:100-104), but SimulatorApp still carries real
_autoPause wiring in code. The doc understates the code here — a concrete
reminder that how-it-is claims must be verified against source, and that this
page's STATED items inherit whatever lag their citations carry.
Sharing direction that touches the Simulator¶
The share-vs-split analysis (see Sharing plan) reaches Simulator-specific verdicts from today's code:
| Verdict | Source |
|---|---|
GcodeToolpathPainter was written for both apps (maxMoveIndexExclusive exists for the sim playhead); the Simulator should consume it instead of its inlined ~70-line paint loop. |
SimulatorApp/MainWindow.axaml.cs:748-817 vs Nps.Shell/Controls/GcodeToolpathPainter.cs:24 |
The Simulator should load findings through FindingFormatter.ProjectFromSession like the Slicer does, instead of holding raw NpsAbi summaries in the window. |
SimulatorApp/MainWindow.axaml.cs:51,332-355 |
Playback timer ownership, auto-pause policy, and scrub resume stay Simulator product; PlaybackPanel stays a pure UI surface in the shell. |
sharing analysis, block Q |
ADR 0002 (Accepted) would collapse both apps into one binary with ProductMode {Slicer, Simulator} and an IProductMode panel seam. |
docs/adr/0002-one-binary-product-mode.md:69-109 |
Inference¶
Everything below is INFERENCE — a reading of the evidence, not a stated plan.
Not scheduled work
None of the following has an open bead. Treat each as context for reading the STATED section, not as a roadmap.
-
INFERENCE — FEA-level physics is not scheduled. The README promises stress / temperature / deformation simulation (
README.md:15), but the landed Simulator is G-code analysis overlays, a warp grid, and canvas playback. No open bead exists for continuum or FEA-style physics. The product statement currently overshoots the shipped app, and nothing in the tracker closes that gap. -
INFERENCE — viewer3d's 3-pass GPU fidelity is only partially landed. The f8v memory says clip and the 3-pass sim should inform the Avalonia render and ABI, but the clip plane has no export (
docs/modules/viewport.md:91-92) and Simulator playback is a DispatcherTimer plussimMoveIndexover a 2D canvas projection — not the WebGL three-pass pipeline ofscratch_gcode/viewer3d.js:851. "Inform" has so far meant "guide the data model," not "reproduce the renderer." -
INFERENCE — a ProductMode collapse would reshape this app. ADR 0002 is Accepted with follow-up implementation beads promised (
docs/adr/0002-one-binary-product-mode.md:183-186), but no open child beads exist and the tree still buildsSlicerApp+SimulatorApp. If the collapse ever lands, the Simulator stops being an app and becomes a mode behind anIProductModeseam — which would reframe every STATED item on this page that says "Simulator owns." -
INFERENCE — "Simulator is the active focus" is a docs framing. The one open bead is this docs site (
nps-0m7), and its "simulator-first" wording describes documentation order, not an implementation priority. Recent commits are shared-shell and Slicer-parity work.
Related pages¶
- Sharing plan — which blocks should move to the shell, stay per-app, or stop being cloned.
- Site index