forked from 1b-agent/opencadstudio-upstream
feat(text): SDF for tolerance + complex-linetype text; per-group model; pick cycle
Extend SDF text to the remaining text kinds and make the Text arm decide SDF per group instead of per entity type. - Text arm: a stroke group renders as SDF glyph quads when it carries a GlyphRun (strokes suppressed); a run-less group keeps its strokes. TEXT / MTEXT / dim / block / mleader are unchanged (all run-groups). A composite Text object can now mix geometry + text: its run-less groups stay strokes and its run-groups become SDF. The glyph-bounds AABB is hoisted so both the bins-empty and bins-non-empty paths stamp it on the text wire. - Tolerance: refactored to emit the feature-control frame (border, separators, dividers) as run-less stroke groups and each cell's text as a run-group, so the frame stays crisp geometry while the values/symbols render as SDF text. - Complex linetypes: embedded LtSeg::Text renders as SDF glyph quads on an extra text wire (glyph-bounds AABB) instead of stroke polylines. - click_hits_all: include SDF text boxes so selection cycling steps through text too, ranked after real geometry. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
96181563fb
commit
d9a2c8245c
4 files changed
+263
-89
No files matched your search
@@ -215,6 +215,38 @@ pub fn click_hits_all<'a>(
|
||||
hits.push((best_for_wire, &wire.name));
|
||||
}
|
||||
}
|
||||
// SDF text: include a text whose box contains the cursor (an empty-stroke
|
||||
// wire carrying glyph quads) so selection cycling steps through text too —
|
||||
// the same discriminator/fallback `click_hit` uses. Ranked after real
|
||||
// geometry (distance = the click threshold, above every proximity hit).
|
||||
if crate::scene::text::sdf_atlas::sdf_text_enabled() {
|
||||
for wire in wires {
|
||||
if wire.text_verts.is_empty()
|
||||
|| !wire.points.is_empty()
|
||||
|| !wire.fill_tris.is_empty()
|
||||
|| wire.aabb == WireModel::UNBOUNDED_AABB
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let [minx, miny, maxx, maxy] = wire.aabb;
|
||||
let (mut sx0, mut sy0, mut sx1, mut sy1) = (f32::MAX, f32::MAX, f32::MIN, f32::MIN);
|
||||
for (cx, cy) in [(minx, miny), (maxx, miny), (maxx, maxy), (minx, maxy)] {
|
||||
let s = world_to_screen(
|
||||
glam::DVec3::new(cx as f64, cy as f64, 0.0),
|
||||
view_rot,
|
||||
eye,
|
||||
bounds,
|
||||
);
|
||||
sx0 = sx0.min(s.x);
|
||||
sx1 = sx1.max(s.x);
|
||||
sy0 = sy0.min(s.y);
|
||||
sy1 = sy1.max(s.y);
|
||||
}
|
||||
if cursor.x >= sx0 && cursor.x <= sx1 && cursor.y >= sy0 && cursor.y <= sy1 {
|
||||
hits.push((CLICK_THRESHOLD_PX, &wire.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
hits.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or(std::cmp::Ordering::Equal));
|
||||
hits.into_iter().map(|(_, name)| name).collect()
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user