perf(scene): grip drag previews the entity instead of re-tessellating

Phase 2.2 (partial). Dragging an entity's grip called scene.apply_grip on
every mouse move, which bumped geometry and re-tessellated the whole model
per move (plus an O(N) clone of every wire to exclude the edited one from
snapping). On a large drawing that's the 30ms->400ms spike, per frame, for
the duration of the drag.

apply_grip no longer bumps. The drag flow now:
- first move: hide the edited entity from the base tessellation (one
  re-tess) and record it in grip_preview_handle;
- each move: apply the grip to the doc (no bump) and show the entity as a
  one-entity overlay preview (set_preview_wires) — the base is a cache hit;
- commit on release / Esc: un-hide, drop the preview, one final re-tess.

Because the edited entity is hidden, it's already absent from
hit_test_wires, so snapping runs against the cached set directly — no
per-move clone and no self-snap. Two re-tessellations per drag instead of
one per move.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-06-05 10:33:08 +03:00
commit 8df9bef6f8
4 changed files with 57 additions and 8 deletions

View file

@ -132,6 +132,15 @@ handles; the render path re-tessellates only those, reusing the rest.
Also useful on open: any partial cache (e.g. from block defns) can be
re-used.
**Partial (landed): grip drag.** Dragging an entity's grip called
`scene.apply_grip` every move, which `bump_geometry`'d → a full model
re-tessellation per move (plus an O(N) clone of all wires for snapping). Now
the first move hides the edited entity from the base (one re-tess) and shows
it as a one-entity overlay preview; subsequent moves only re-tessellate that
one entity (cheap) — the base stays a cache hit. Snapping runs against the
set directly (the edited entity is already hidden, so no clone and no
self-snap). The drag commits on release / Esc: un-hide + one final re-tess.
**Partial (landed): preview / interim overlays.** `set_preview_wires`,
`clear_preview_wire` and `set_interim_wire` used to `bump_geometry`, so every
rubber-band frame of a drawing command re-tessellated the whole model (the