Skip to content

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.

  1. 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.

  2. 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 plus simMoveIndex over a 2D canvas projection — not the WebGL three-pass pipeline of scratch_gcode/viewer3d.js:851. "Inform" has so far meant "guide the data model," not "reproduce the renderer."

  3. 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 builds SlicerApp + SimulatorApp. If the collapse ever lands, the Simulator stops being an app and becomes a mode behind an IProductMode seam — which would reframe every STATED item on this page that says "Simulator owns."

  4. 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.