epiphany/crates/epiphany-layout-ir/src
Levi Neuwirth 8bffd2f2fd editor-core: a staff_pitch_at click→pitch vertical inverse
The vertical half of click-to-insert: resolve a world point to the staff
under the cursor and the natural diatonic pitch at that height under the
staff's clef.

Staff selection is manifestation-aware. Each rendered bottom staff line
carries its staff's manifestation id as the stroke's stable_id, so a click
maps back to a concrete (region, staff_instance) by matching that id, then
chooses the nearest staff by 2D proximity — horizontal span first (which
region, since one staff tiles across regions that can share a y band), then
the vertical band. The earlier StaffId-collapsing helpers are gone.

The clef is resolved by time, not vector order: render_score builds a
per-staff start-clef table from the logical layout via active_clef (now
exported from epiphany-layout-ir) and threads it through open/commit, so a
mid-vector [bass@1, treble@0] still spells the staff start as treble.

A non-finite click is rejected up front — NaN would slip through
dist_to_band's comparisons as distance 0 and saturate the round() as i32
step into a bogus pitch.

Tests cover finite resolution, x-aware manifestation selection across staves
sharing a y band, non-finite rejection, and time-ordered clef resolution.
The GUI surfaces the resolved pitch on an empty-staff click.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NAtEiJtt9yKVV1zjKYmZhS
2026-06-29 18:56:34 -04:00
..
barrier.rs Land epiphany-layout-ir (Agent E): layout IR + solver interface 2026-06-19 19:58:01 -04:00
cache.rs Land epiphany-layout-ir (Agent E): layout IR + solver interface 2026-06-19 19:58:01 -04:00
constrained.rs editor-core: a staff_pitch_at click→pitch vertical inverse 2026-06-29 18:56:34 -04:00
engrave_theory.rs layout-ir: staff_step_pitch, the clef-relative position inverse 2026-06-29 17:28:23 -04:00
engraving.rs P12-I2: wire the ratified MUSCLOID layout-object id derivation 2026-06-27 12:46:19 -04:00
glyph.rs Agent I-4a: reconcile the Bravura metrics with the 1.392 outlines 2026-06-26 22:45:33 -04:00
hittest.rs layout-ir: a render-to-hit-test contract at the RenderIR boundary 2026-06-27 14:25:53 -04:00
lib.rs editor-core: a staff_pitch_at click→pitch vertical inverse 2026-06-29 18:56:34 -04:00
logical.rs Agent I Phase 2-3: engrave recognizable notation from Score to SVG 2026-06-26 20:46:33 -04:00
provenance.rs P12-I2: wire the ratified MUSCLOID layout-object id derivation 2026-06-27 12:46:19 -04:00
render.rs Agent I Phase 2-3: engrave recognizable notation from Score to SVG 2026-06-26 20:46:33 -04:00
resolved.rs Agent I Phase 2-3: engrave recognizable notation from Score to SVG 2026-06-26 20:46:33 -04:00
roundtrip.rs Agent I-3: criterion-6 round-trip and golden lock on the real Engraver 2026-06-26 21:58:31 -04:00
solver.rs Agent I Phase 2-3: engrave recognizable notation from Score to SVG 2026-06-26 20:46:33 -04:00
spatial.rs Land epiphany-layout-ir (Agent E): layout IR + solver interface 2026-06-19 19:58:01 -04:00
time_axis.rs Agent I Phase 2-3: engrave recognizable notation from Score to SVG 2026-06-26 20:46:33 -04:00
vertical_band.rs Land epiphany-layout-ir (Agent E): layout IR + solver interface 2026-06-19 19:58:01 -04:00