perf(scene): zoom-adaptive arc tessellation for hatch boundary outlines
The shared `arc_segments` helper now takes (radius, span, chord_tol) so each call site can pick its own tolerance: * Hatch fill polygon (built at load / on edit, never re-tessellated) uses `fill_chord_tol(r) = max(0.001*r, 1µm)` — fixed high quality so zoom-in stays sharp without rebuilding the boundary. * Hatch wire outline (rebuilt every frame inside the render scope) uses `wire_chord_tol(r) = min(scene_override, fill_chord_tol(r))` — reads the per-frame `truck_tess::set_curve_tol_override` (the Scene already sets it to `world_per_pixel × 0.5` for Phase 3.2 wires) so far-out boundary arcs collapse to a handful of segments at low zoom while staying at least as sharp as the underlying fill at high zoom. Same arc_segments switch applied to the legacy 16-segments-per-circle formula in `hatch_model_from_dxf`'s polyline-bulge tessellation, so fill boundaries with bulged polylines also gain the proper chord-error target. Also expose `truck_tess::current_curve_tol` (pub(crate)) and add `active_curve_tol()` returning Option so the new wire path can distinguish "scene override active" from "load-time, no zoom info". Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
9b4ded79be
commit
dc80968023
3 changed files with 69 additions and 17 deletions
|
|
@ -2492,9 +2492,12 @@ impl Scene {
|
|||
-std::f32::consts::TAU
|
||||
};
|
||||
}
|
||||
let segs = ((sweep.abs() / std::f32::consts::TAU) * 16.0)
|
||||
.ceil()
|
||||
.max(4.0) as u32;
|
||||
let r64 = r as f64;
|
||||
let segs = tessellate::arc_segments(
|
||||
r64,
|
||||
sweep.abs() as f64,
|
||||
tessellate::fill_chord_tol(r64),
|
||||
);
|
||||
for j in 0..segs {
|
||||
let a = a0 + sweep * (j as f32 / segs as f32);
|
||||
boundary.push(to_xy(
|
||||
|
|
@ -2520,7 +2523,11 @@ impl Scene {
|
|||
arc.end_angle,
|
||||
arc.counter_clockwise,
|
||||
);
|
||||
let segs = tessellate::arc_segments(span.abs());
|
||||
let segs = tessellate::arc_segments(
|
||||
arc.radius,
|
||||
span.abs(),
|
||||
tessellate::fill_chord_tol(arc.radius),
|
||||
);
|
||||
for i in 0..=segs {
|
||||
let t = sa + span * (i as f64 / segs as f64);
|
||||
boundary.push(to_xy(
|
||||
|
|
@ -2543,7 +2550,11 @@ impl Scene {
|
|||
ell.end_angle,
|
||||
ell.counter_clockwise,
|
||||
);
|
||||
let segs = tessellate::arc_segments(span.abs());
|
||||
let segs = tessellate::arc_segments(
|
||||
r_maj,
|
||||
span.abs(),
|
||||
tessellate::fill_chord_tol(r_maj),
|
||||
);
|
||||
let (cr, sr) = (rot.cos(), rot.sin());
|
||||
for i in 0..=segs {
|
||||
let t = sa + span * (i as f64 / segs as f64);
|
||||
|
|
|
|||
Loading…
Reference in a new issue