Put the region map behind the sliders that were already there

A mask layer holds a real develop chain, so the develop panel can edit one
with no new controls: select a layer and the same sliders read and write
its chain instead of the graph's. An operation declared in `ops/` tomorrow
becomes locally adjustable by existing, which is the payoff for making a
layer a chain rather than a handful of special-cased parameters.

`segmentation.rs` joins the two arms into the one thing the view needs.
The model reads the image through a neutral graph rather than the edited
one, so a segmentation survives an exposure change instead of being
invalidated by every slider. Arm B failing is not fatal: a missing or
unreadable model leaves a working watershed map, because refusing to
segment at all would trade a working feature for a strict one.

The overlay colours groups by a golden-angle walk over hue. Deterministic
rather than random, so a region keeps its colour across a level change and
the eye can track it; boundaries drawn black over the fill, because two
adjacent groups landing on near hues read as one region and telling them
apart is the whole reason to look at it.

Clicking the photograph creates the layer if none is selected — that is how
a local adjustment begins, and making the user press "add layer" first
would be a step with no decision in it. Shift-click extends, and clicking a
region already selected removes it, so one gesture both adds and corrects.

`segment-readback` is a new dr-gpu feature and not a loosening of
`readback`. The region-graph transfer is once per image on a worker; the
one AC-8 forbids is per frame in the render loop. Sharing a switch would
have forced a build wanting local masking to unlock the other. F3 still
stands and the feature name says so.
This commit is contained in:
2026-08-22 08:39:17 +02:00
parent 94cfea4748
commit 5ecb35864f
8 changed files with 1080 additions and 21 deletions
+8 -1
View File
@@ -11,7 +11,14 @@ dr-types.workspace = true
# the compositor the texture itself and there is no display round-trip left to
# gate (ARCH §6.1, AC-8). The export path reads pixels back through
# `export_pixels`, which is ungated and always was.
dr-gpu.workspace = true
#
# `segment-readback` *is* on, and it is not a contradiction of the above. It
# gates the region-graph transfer that local masking is built on: once per
# image, on a worker, off the frame path. The display round-trip AC-8 forbids
# stays behind its own switch, which remains off. See `dr-gpu/src/segment.rs`.
dr-gpu = { workspace = true, features = ["segment-readback"] }
# The semantic arm and its weights, for local adjustments (FR-DEV-3, D14).
dr-segment = { workspace = true, features = ["semantic", "embedded-model"] }
dr-decode.workspace = true
serde_json.workspace = true
tokio.workspace = true