Record intersection as built in the requirement and the mask plan
FR-DEV-19a said a part is added to the mask or taken out of it, and mask-editing.md listed Intersect as an M2 item with nothing built. Both now say what shipped: the requirement names the third join and why it is a product rather than a minimum, and how old and new sidecars read across it; the plan marks the blend-table row built, names the tests that hold the GPU to the definition, and splits M2 into what is done and what is still outstanding (joining non-painted parts from the panel, per-part distance fields, folding two layers).
This commit is contained in:
@@ -269,7 +269,7 @@ The set operations are already expressible in fixed-function blending over
|
|||||||
|------|-------------------------------|--------|-------|
|
|------|-------------------------------|--------|-------|
|
||||||
| Union | `One`, `One`, `Max` | `max(dst, src)` | M1 |
|
| Union | `One`, `One`, `Max` | `max(dst, src)` | M1 |
|
||||||
| Subtract | `Zero`, `OneMinusSrc`, `Add` | `dst · (1 − src)` | M1 |
|
| Subtract | `Zero`, `OneMinusSrc`, `Add` | `dst · (1 − src)` | M1 |
|
||||||
| Intersect | `Zero`, `Src`, `Add` | `dst · src` | M2 |
|
| Intersect | `Zero`, `Src`, `Add` | `dst · src` | M2 (built 2026-09-24) |
|
||||||
|
|
||||||
The middle row is `brush_erase`, already constructed in
|
The middle row is `brush_erase`, already constructed in
|
||||||
[`MaskPass::new`](../../core/dr-gpu/src/mask.rs). The other two are the same
|
[`MaskPass::new`](../../core/dr-gpu/src/mask.rs). The other two are the same
|
||||||
@@ -292,6 +292,16 @@ rendering as it did. `an_erase_stroke_holes_its_own_part_and_not_the_mask` in
|
|||||||
[`local_adjustments.rs`](../../core/dr-gpu/tests/local_adjustments.rs) is the test
|
[`local_adjustments.rs`](../../core/dr-gpu/tests/local_adjustments.rs) is the test
|
||||||
that holds this in place.
|
that holds this in place.
|
||||||
|
|
||||||
|
Intersection, as built, is exactly the table's row: a third pipeline beside
|
||||||
|
the other two in `MaskPass::new`, `Join::apply` stating the three on the CPU,
|
||||||
|
and `a_part_unioned_subtracted_and_intersected_gives_the_three_fields` and
|
||||||
|
`the_joins_match_their_definition` in `local_adjustments.rs` holding the GPU
|
||||||
|
to it. It is a product, not a minimum: the two agree wherever either side is
|
||||||
|
fully in or out, and between two soft edges the product is the softer reading,
|
||||||
|
which is the right way for an overlap of two partial selections to be wrong.
|
||||||
|
Its blend is `Add`, not `Max`, so it adds nothing to the Android question
|
||||||
|
below.
|
||||||
|
|
||||||
`Max` blending on `r8unorm` is core WGPU and universally supported on the
|
`Max` blending on `r8unorm` is core WGPU and universally supported on the
|
||||||
desktop backends; **verify it on the Android adapter before M2 lands**, since
|
desktop backends; **verify it on the Android adapter before M2 lands**, since
|
||||||
that is the platform where a blend mode is most likely to be quietly emulated
|
that is the platform where a blend mode is most likely to be quietly emulated
|
||||||
@@ -689,6 +699,14 @@ nothing, and every report of it came back as "the masks do not work".
|
|||||||
per-part distance fields (§5.5), the part list with its join chips, folding
|
per-part distance fields (§5.5), the part list with its join chips, folding
|
||||||
two layers.
|
two layers.
|
||||||
|
|
||||||
|
Done (2026-09-24): `Intersect` — the join, its blend state, the sidecar word
|
||||||
|
`intersect`, the part row's chip cycling + / − / ∩, and an "∩ Intersect"
|
||||||
|
button beside Add and Subtract (§7.1). The part list with its chips and a
|
||||||
|
per-part eye was already there from M1. Outstanding: joining a model,
|
||||||
|
gradient or range part from the panel (the buttons still join a painted
|
||||||
|
part, so an intersection is painted where the mask should survive), per-part
|
||||||
|
distance fields, and folding two layers.
|
||||||
|
|
||||||
**M3 — Push, and cling.** The warp pass (§5.3) and edge-aware deposit (§5.6).
|
**M3 — Push, and cling.** The warp pass (§5.3) and edge-aware deposit (§5.6).
|
||||||
Both are refinements of a tool that already works, which is the right place
|
Both are refinements of a tool that already works, which is the right place
|
||||||
for the two riskiest pieces.
|
for the two riskiest pieces.
|
||||||
|
|||||||
@@ -544,9 +544,17 @@ decade; a mask that cannot be corrected is the reason an edit leaves this applic
|
|||||||
editor.
|
editor.
|
||||||
|
|
||||||
**FR-DEV-19a — Mask composition.** A layer's mask is an ordered list of parts, each naming a source
|
**FR-DEV-19a — Mask composition.** A layer's mask is an ordered list of parts, each naming a source
|
||||||
and how it joins the mask before it — added to it, or taken out of it. A layer of one part is
|
and how it joins the mask before it — added to it, taken out of it, or intersected with it, keeping
|
||||||
exactly the layer that existed before this, and reads and writes the same sidecar. The parts of a
|
only where both agree. A layer of one part is exactly the layer that existed before this, and reads
|
||||||
layer merge under FR-NC-9 as the layer does, and each carries its own edge treatment.
|
and writes the same sidecar. The parts of a layer merge under FR-NC-9 as the layer does, and each
|
||||||
|
carries its own edge treatment.
|
||||||
|
|
||||||
|
*Intersection added 2026-09-24* (issue #9, `mask-editing.md` M2). Union and subtraction were built
|
||||||
|
first; the selections that most need composing — the sky that is also bright, the subject that is
|
||||||
|
also skin — are intersections, and spelling one as a subtraction needs a part that selects the
|
||||||
|
complement. Intersection is the product of the two coverages, which is the minimum wherever either
|
||||||
|
side is fully in or out. A sidecar written before it never names it; a build from before it reads
|
||||||
|
the word as a union, which keeps the part visible rather than dropping it.
|
||||||
|
|
||||||
**FR-DEV-19b — Hand correction.** A part may be painted, with add and erase strokes, at a radius,
|
**FR-DEV-19b — Hand correction.** A part may be painted, with add and erase strokes, at a radius,
|
||||||
hardness and flow the photographer sets. Strokes are stored as normalised source coordinates and
|
hardness and flow the photographer sets. Strokes are stored as normalised source coordinates and
|
||||||
|
|||||||
Reference in New Issue
Block a user