perf: viewport wire cache, Arc hit_test_wires, snap world-space pre-rejection (I+J+K)

Option I: add per-viewport Arc wire cache so paper-space viewport rendering
no longer re-tessellates model content every frame.

Option J: hit_test_wires() returns Arc<Vec<WireModel>> — O(1) pointer copy
in model space instead of a full Vec clone on every mouse move during commands.
paper_canvas_hatches/wipeouts() now route through the epoch caches added in F.

Option K: add world_snap_r + wire_in_range() pre-check to Snapper::snap().
All Endpoint/Midpoint/Nearest/Perpendicular/Intersection loops skip wires
whose chord sphere is outside the snap circle using O(1) scalar comparisons,
eliminating O(entities × vertices) matrix multiply cost when zoomed in.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-04-26 11:55:08 +03:00
commit 2da9301a2b
6 changed files with 149 additions and 32 deletions

View file

@ -83,12 +83,12 @@ impl<'a> canvas::Program<Message> for PaperCanvas<'a> {
}
// ── Wipeout fills (rendered before wires, cover background) ──────────
for hatch in &self.scene.paper_canvas_wipeouts() {
for hatch in self.scene.paper_canvas_wipeouts().iter() {
draw_hatch(&mut frame, hatch, &to_px);
}
// ── Hatch fills ───────────────────────────────────────────────────────
for hatch in &self.scene.paper_canvas_hatches() {
for hatch in self.scene.paper_canvas_hatches().iter() {
draw_hatch(&mut frame, hatch, &to_px);
}