refactor(snap): measure typed distance along the guide that is drawn

Extension answered "which acquired ray is this snap on?" twice, from two
different tests: the overlay picked its guide by off-ray distance in
screen pixels, while typed-distance entry re-searched the tracking set in
world space. Two tests can disagree, and the ways they disagree are both
bad -- a guide on screen that typing ignores, or a distance running off
along a ray the user cannot see. The second search could also come up
empty on its own, since only four acquisitions are kept and the oldest is
dropped as new ones arrive.

Ask once. The search that draws the guide now also reports the endpoint it
drew from, the snap carries it, and typed distance reads the ray straight
off that -- the direction is just the way from the endpoint to the snap,
which sits beyond it by construction. The screen-space test stays the only
one, which is what the guide wanted anyway: it stays scale-independent
where a world test would not.

Also correct the tracking-point doc: it claims XZ with Y=0, but
`edge_dirs_at` builds every direction from X/Y with Z zeroed and the rays
follow it.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 5 committed 2026-08-07 11:29:15 +03:00
1 parent b8f9727a27
commit 0af6b470ed
3 files changed
+32 -73

No files matched your search

+12 -7
View File
@@ -31,15 +31,20 @@ impl OpenCADStudio {
return Some((base, dir));
}
// Extension stores the snapped point. Recover the acquired endpoint
// and outward segment direction that produced that snap.
// Extension measures along the ray its guide is drawn on. The snap
// carries the acquired endpoint that guide starts from, so read the ray
// off that rather than searching the tracking set again — a second
// search can disagree with the guide the user is looking at, and the
// acquisition it needs may already have aged out of the set.
let snap = self.tabs[i].snap_result?;
if snap.snap_type == crate::snap::SnapType::Extension {
return self.snapper.extension_input_ray(snap.world);
if snap.snap_type != crate::snap::SnapType::Extension {
return None;
}
None
let origin = snap.extension_origin?;
// The snap sits beyond its endpoint by construction, so the outward
// direction is simply the way from one to the other.
let dir = snap.world - origin;
Some((origin, dir.try_normalize()?))
}
/// Rebuild the active tab's dynamic-input field set to match what the
/// command is currently asking for. Called on cursor move and after
+1
View File
@@ -1647,6 +1647,7 @@ impl OpenCADStudio {
tangent_obj: None,
extension_base: None,
extension_base2: None,
extension_origin: None,
});
if let Some(cmd) = self.tabs[i].active_cmd.as_mut() {
cmd.set_acquisition_hint(Some(pick.label));