From cda06278047a18800c6651010cc5f8ce5728d2f5 Mon Sep 17 00:00:00 2001 From: ramox81 <184937705+ramox81@users.noreply.github.com> Date: Fri, 18 Sep 2026 20:36:01 +0300 Subject: [PATCH] Report a missed first 2Points pick at once for Horizontal/Vertical The first empty-space click of the 2Points flow was only resolved against the document together with the second one, so "No valid constraint point found." appeared one pick late. The command now hands the first pick to the host (`CmdResult::CheckHorizontalPoint`), which resolves it right away: a miss reports and re-asks for the first point, a hit moves on to the second point. Co-Authored-By: Claude Fable 5.1 --- src/app/command_driver.rs | 25 +++++++++++++++++++++++++ src/command.rs | 7 +++++++ src/modules/parametric/horizontal.rs | 20 ++++++++++++-------- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/app/command_driver.rs b/src/app/command_driver.rs index d8a2f787a..d483d8b13 100644 --- a/src/app/command_driver.rs +++ b/src/app/command_driver.rs @@ -3318,6 +3318,31 @@ impl OpenCADStudio { } }; } + CmdResult::CheckHorizontalPoint { kind, pick } => { + use crate::modules::parametric::HorizontalConstraintCommand; + use crate::scene::parametric_constraints::nearest_parametric_point; + + // The reference rejects a missed first point right away and + // asks for it again; a hit moves on to the second point. + let scope = self.tabs[i].current_parametric_scope(); + let found = nearest_parametric_point( + &self.tabs[i].scene.document, + scope, + acadrust::types::Vector3::new(pick.point.x, pick.point.y, pick.point.z), + None, + ) + .is_some(); + if !found { + self.command_line + .push_error("No valid constraint point found."); + } + let command = HorizontalConstraintCommand::resume(kind, found.then_some(pick)); + self.command_line + .push_info(&crate::command::CadCommand::prompt(&command)); + self.tabs[i].active_cmd = Some(Box::new(command)); + self.tabs[i].snap_result = None; + return Task::none(); + } CmdResult::AddHorizontalConstraint { kind, selection, diff --git a/src/command.rs b/src/command.rs index 5b3159445..74333ff0c 100644 --- a/src/command.rs +++ b/src/command.rs @@ -1592,6 +1592,13 @@ pub enum CmdResult { direction: acadrust::types::Vector3, label: &'static str, }, + /// Resolves the first 2Points pick of a Horizontal or Vertical constraint + /// against the live document so a miss is reported at once, before the + /// second point is asked for. + CheckHorizontalPoint { + kind: crate::scene::parametric_constraints::ConstraintKind, + pick: CoincidentPick, + }, /// Adds a point or object symmetry relation around a picked line. The /// first reference and axis remain fixed during initial placement. AddSymmetricConstraint { diff --git a/src/modules/parametric/horizontal.rs b/src/modules/parametric/horizontal.rs index 987cccf48..a343b476b 100644 --- a/src/modules/parametric/horizontal.rs +++ b/src/modules/parametric/horizontal.rs @@ -321,10 +321,12 @@ impl CadCommand for HorizontalConstraintCommand { fn on_point(&mut self, point: DVec3) -> CmdResult { let pick = Self::point_pick(None, point); match self.step { - Step::ObjectOrTwoPoints | Step::FirstPoint => { - self.step = Step::SecondPoint(pick); - CmdResult::NeedPoint - } + // The host resolves the pick against the document: a hit resumes + // at the second point, a miss re-asks for the first one at once. + Step::ObjectOrTwoPoints | Step::FirstPoint => CmdResult::CheckHorizontalPoint { + kind: self.kind, + pick, + }, Step::SecondPoint(first) => self.finish_points(first, pick), } } @@ -375,10 +377,12 @@ mod tests { fn enter_starts_the_two_point_flow() { let mut command = HorizontalConstraintCommand::new(); assert!(matches!(command.on_enter(), CmdResult::NeedPoint)); - assert!(matches!( - command.on_point(DVec3::new(1.0, 2.0, 0.0)), - CmdResult::NeedPoint - )); + let CmdResult::CheckHorizontalPoint { kind, pick } = + command.on_point(DVec3::new(1.0, 2.0, 0.0)) + else { + panic!("the host must check the first point"); + }; + let mut command = HorizontalConstraintCommand::resume(kind, Some(pick)); let CmdResult::AddHorizontalConstraint { selection: HorizontalConstraintSelection::Points(first, second), direction,