ThePirateRay/docs/research/rayforge-layer-model-spike.md

103 lines
4 KiB
Markdown

# Rayforge layer visibility and output spike
- Date: 2026-10-20
- Rayforge commit: `c28918c87f8273dd1d244f5a057addc192807fa5`
- Scope: layer model, workflow output, ordering and serialization
- Transport: none
## Result
Rayforge already separates the two behaviors required by the PirateRay UX,
but at different levels of its model:
- `Layer.visible` controls whether a layer is rendered on the canvas and in
visual previews;
- `Step.visible` controls whether a workflow operation participates in the
generated job pipeline.
The states are independent. A hidden layer can retain an enabled operation,
which matches LightBurn's rule that hiding artwork does not silently disable
output. Conversely, disabling a workflow step removes that operation from job
generation without changing the layer's canvas visibility.
The pinned model round-trip preserved:
- layer name `Engraving`;
- layer color `#123456`;
- hidden layer state;
- operation name `Mark outline`;
- enabled operation state;
- an explicitly reordered layer list (`Second`, then `First`).
The deterministic result is stored in
`tests/fixtures/rayforge-layer-model.json`.
## UX fit
Rayforge's existing layer header exposes one eye control for
`Layer.visible`. Its operation editor exposes a visibility switch for each
`Step.visible`. The pipeline checks step visibility and does not check layer
visibility when constructing job nodes.
This means the required Show/Output semantics do **not** require a new pipeline
field or a duplicate layer model. The smallest PirateRay-facing extension is
an aggregate **Output** control in the layer presentation:
- on: all supported workflow steps in the layer are enabled;
- off: all workflow steps in the layer are disabled;
- mixed: some workflow steps are enabled and some are disabled.
An aggregate toggle must preserve or deliberately define what happens to a
previous mixed selection. The safest interaction is to expose the mixed state,
let the layer toggle affect all steps, and leave per-operation switches
available in Advanced view. This is a UI policy decision over existing model
state, not a serialization migration.
## Ordering
`Doc.layers` is the single ordered layer list. Drag-and-drop calls the
undoable `reorder_layers` command, canvas stacking follows the same list, and
the intent builder iterates it in order when constructing job nodes. The
serialized document retains that order.
The source documentation states that layers execute left to right. A packaged
no-device GUI checkpoint should still confirm that the visible ordering affordance
is understandable to a casual maker and that preview communicates the same
order.
## Remaining interaction evidence
The source and model evidence close the data-model question, but not the human
interaction checkpoint. A packaged no-device test should verify:
1. the layer eye changes only canvas/preview visibility;
2. a disabled operation remains visibly distinct from a hidden layer;
3. the proposed aggregate Output control reports on/off/mixed correctly;
4. save/reload retains names, colors, order and both states;
5. preview and no-device job output omit disabled steps but retain hidden,
enabled layers.
No USB enumeration, controller command, motion, physical framing, or emission
occurred.
## Reproduce
Run against the pinned checkout with the already isolated Rayforge Python
environment:
```powershell
python scripts/spike_rayforge_layer_model.py <rayforge-checkout> `
--output tests/fixtures/rayforge-layer-model.json
```
## Source anchors
- `rayforge/core/layer.py`: layer visibility, color and serialization
- `rayforge/core/step.py`: operation visibility and serialization
- `rayforge/pipeline/intent_builder.py`: step filtering and ordered job nodes
- `rayforge/ui_gtk/doceditor/layer_column.py`: layer eye control
- `rayforge/ui_gtk/doceditor/step_box.py`: operation visibility control
- `rayforge/ui_gtk/doceditor/layers_tab.py`: undoable drag ordering
- `rayforge/ui_gtk/canvas2d/surface.py`: canvas stacking order
- `website/docs/features/multi-layer.md`: documented execution semantics