fix(snap): object snap takes precedence over ortho/polar

When drawing with Ortho (or Polar) on, a point that snapped to an object
(e.g. an Endpoint) was still pulled onto the ortho axis, so you couldn't
close a shape exactly on an existing vertex. Skip the ortho/polar
constraint while an object snap is locked, in both the preview and commit
paths. Grid snap is positional rather than an object snap, so it still
combines with ortho/polar. (#132)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-06-19 00:05:41 +03:00
commit 2be26e9e2e

View file

@ -2760,18 +2760,27 @@ impl OpenCADStudio {
.snap_result .snap_result
.map(|s| self.tabs[i].scene.paper_to_model(s.world)) .map(|s| self.tabs[i].scene.paper_to_model(s.world))
.unwrap_or(cursor_world); .unwrap_or(cursor_world);
if let Some(base) = self.last_point { // Object snap wins over ortho/polar: a snapped point
if self.ortho_mode { // is taken as-is so it isn't pulled onto the ortho
pt = ortho_constrain(pt, base); // axis. Grid snap is positional, not an object snap,
} else if self.polar_mode { // so it still combines with ortho/polar. (#132)
pt = polar_constrain_near( let osnap_locked = self.tabs[i]
pt, .snap_result
base, .is_some_and(|s| s.snap_type != crate::snap::SnapType::Grid);
self.polar_increment_deg, if !osnap_locked {
view_proj, if let Some(base) = self.last_point {
bounds, if self.ortho_mode {
self.snapper.osnap_radius_px, pt = ortho_constrain(pt, base);
); } else if self.polar_mode {
pt = polar_constrain_near(
pt,
base,
self.polar_increment_deg,
view_proj,
bounds,
self.snapper.osnap_radius_px,
);
}
} }
} }
pt pt
@ -3360,18 +3369,24 @@ impl OpenCADStudio {
if self.tabs[i].active_ucs.is_none() { if self.tabs[i].active_ucs.is_none() {
pt.z = 0.0; pt.z = 0.0;
} }
} else if let Some(base) = self.last_point { } else if !snap_hit
if self.ortho_mode { .is_some_and(|s| s.snap_type != crate::snap::SnapType::Grid)
pt = ortho_constrain(pt, base); {
} else if self.polar_mode { // Object snap wins over ortho/polar — a snapped point
pt = polar_constrain_near( // commits as-is. Grid snap still combines. (#132)
pt, if let Some(base) = self.last_point {
base, if self.ortho_mode {
self.polar_increment_deg, pt = ortho_constrain(pt, base);
vp_mat, } else if self.polar_mode {
bounds, pt = polar_constrain_near(
self.snapper.osnap_radius_px, pt,
); base,
self.polar_increment_deg,
vp_mat,
bounds,
self.snapper.osnap_radius_px,
);
}
} }
} }
pt pt