forked from 1b-agent/opencadstudio-upstream
feat(snap): parallel object snap (#277)
Parallel snap did nothing — the type was in the osnap set, priority and marker, but there was no logic behind it. Implement it: hovering a line (or polyline segment) for a short dwell acquires its direction as a reference; then while drawing from the last point, when the cursor runs parallel to that reference the point locks onto the line through the last point parallel to it, showing the ∥ marker and the alignment guide. Curves (circle/arc/ellipse) are ignored — parallel to a curve is undefined. Works with only the Parallel object snap on, independent of OTRACK; the reference clears with the command's tracking state. Closes #277 Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
8ad0c8918a
commit
e85cec8274
3 files changed
+184
-1
No files matched your search
@@ -906,6 +906,16 @@ pub(super) fn on_tick(&mut self, t: Instant) -> Task<Message> {
|
||||
bounds,
|
||||
Instant::now(),
|
||||
);
|
||||
// Parallel snap: acquire the reference line under the
|
||||
// cursor (independent of OTRACK). (#277)
|
||||
self.snapper.update_parallel(
|
||||
cursor_world.as_vec3(),
|
||||
&all_wires[..],
|
||||
view_rot,
|
||||
eye,
|
||||
bounds,
|
||||
Instant::now(),
|
||||
);
|
||||
if self.tabs[i].snap_result.is_none() {
|
||||
let step = if self.polar_mode {
|
||||
Some(self.polar_increment_deg)
|
||||
@@ -929,6 +939,27 @@ pub(super) fn on_tick(&mut self, t: Instant) -> Task<Message> {
|
||||
};
|
||||
self.otrack_active = otrack_hit.map(|h| (h.base, h.dir));
|
||||
|
||||
// Parallel snap: with nothing else snapped or tracked, lock
|
||||
// the point onto the line through last_point parallel to the
|
||||
// acquired reference, and drive the alignment guide off it.
|
||||
// (#277)
|
||||
if self.tabs[i].snap_result.is_none() && otrack_hit.is_none() {
|
||||
if let Some(par) = self.snapper.parallel_snap(
|
||||
cursor_world.as_vec3(),
|
||||
self.last_point,
|
||||
view_rot,
|
||||
eye,
|
||||
bounds,
|
||||
) {
|
||||
if let (Some(base), Some(dir)) =
|
||||
(self.last_point, self.snapper.parallel_ref)
|
||||
{
|
||||
self.otrack_active = Some((base, dir));
|
||||
}
|
||||
self.tabs[i].snap_result = Some(par);
|
||||
}
|
||||
}
|
||||
|
||||
let effective = {
|
||||
let mut pt: glam::DVec3 = if let Some(h) = otrack_hit {
|
||||
// Tracking alignment wins over the free cursor;
|
||||
|
||||
+1
-1
@@ -340,7 +340,7 @@ impl OpenCADStudio {
|
||||
// Shared OTRACK projection basis: the active pane's camera + rect
|
||||
// (canvas offset included), matching the grips / UCS icon above.
|
||||
let otrack_proj: Option<(glam::Mat4, glam::DVec3, iced::Rectangle)> =
|
||||
if self.snapper.tracking_active() {
|
||||
if self.snapper.alignment_active() {
|
||||
Some(
|
||||
if let Some((vp_cam, full)) = tab.scene.viewport_edit_frame((vw, vh)) {
|
||||
(vp_cam.view_proj_rte(full), vp_cam.eye(), full)
|
||||
|
||||
Reference in new issue
Block a user