103 lines
4 KiB
Markdown
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
|
|
|