fix(snap): priority-based osnap selection + true perpendicular
Object snaps were chosen purely by nearest screen distance, so the "continuous" snaps that sit on the geometry (Nearest, Perpendicular) were almost always closer than a discrete Endpoint/Midpoint/Center and silently suppressed every other enabled snap. Selection is now priority-then-distance: a higher-priority snap inside the aperture wins, distance only breaks ties within a priority. (#118) The aperture gate is `!(d2 < radius2)` rather than `d2 >= radius2` so a NaN distance from degenerate geometry is rejected instead of passing the gate and being chosen on rank alone (which fed a NaN point to the fill tessellator and panicked). Perpendicular now drops its foot from the command's drawing origin (`Snapper::from_point`, set before each snap) instead of the cursor, so the new segment is genuinely perpendicular to the target line rather than just the nearest point on it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
47f74a9b98
commit
e1d128c4dc
2 changed files with 71 additions and 7 deletions
|
|
@ -2507,6 +2507,8 @@ impl OpenCADStudio {
|
|||
// `hit_test_wires` — snap against the set directly, no clone
|
||||
// and no self-snap.
|
||||
let all_wires = self.tabs[i].scene.hit_test_wires();
|
||||
// Grip drag has no single rubber-band origin for a perp foot.
|
||||
self.snapper.from_point = None;
|
||||
let snap_hit = self.snapper.snap(raw, p, &all_wires[..], vp_mat, bounds);
|
||||
let mut snapped = snap_hit.map(|s| s.world).unwrap_or(raw);
|
||||
self.tabs[i].snap_result = snap_hit;
|
||||
|
|
@ -2679,6 +2681,7 @@ impl OpenCADStudio {
|
|||
bounds,
|
||||
)
|
||||
} else {
|
||||
self.snapper.from_point = self.last_point;
|
||||
self.snapper
|
||||
.snap(cursor_world, p, &all_wires[..], view_proj, bounds)
|
||||
};
|
||||
|
|
@ -3292,6 +3295,7 @@ impl OpenCADStudio {
|
|||
self.snapper
|
||||
.snap_tangent_only(raw, p, &all_wires[..], vp_mat, bounds)
|
||||
} else {
|
||||
self.snapper.from_point = self.last_point;
|
||||
self.snapper.snap(raw, p, &all_wires[..], vp_mat, bounds)
|
||||
};
|
||||
// snap.world is in paper-space (projected wire coords in MSPACE);
|
||||
|
|
|
|||
Loading…
Reference in a new issue