Merge pull request #1315 from ghost/ordered-perpendicular

This commit is contained in:
Hakan Seven committed 2026-09-17 07:00:52 +03:00
commit 7cd62a68f7
10 files changed
+809 -50

No files matched your search

+65
View File
@@ -3188,6 +3188,71 @@ impl OpenCADStudio {
self.commit_undo_delta(i, pd);
}
}
CmdResult::AddPerpendicularConstraint {
first,
second,
first_fixed,
second_start,
label,
} => {
use crate::scene::parametric_constraints::ConstraintKind;
let refs = vec![first, second];
if let Err(message) = self.tabs[i].scene.validate_parametric_constraint(
ConstraintKind::Perpendicular,
&refs,
None,
) {
self.tabs[i].active_cmd = None;
self.tabs[i].snap_result = None;
self.command_line.push_error(message);
return Task::none();
}
let scope = self.tabs[i].current_parametric_scope();
let constraints_before = self.tabs[i]
.scene
.parametric_constraint_set(scope)
.cloned()
.unwrap_or_else(|| {
crate::scene::parametric_constraints::ParametricConstraintSet::new(scope)
});
let touched = if first.entity == second.entity {
vec![first.entity]
} else {
vec![first.entity, second.entity]
};
let pending = self.begin_undo(i, label, touched.len(), true);
self.tabs[i]
.scene
.record_undo_parametric_constraints_before(scope, constraints_before);
let id = self.tabs[i].scene.parametric_constraint_set_mut(scope).add(
ConstraintKind::Perpendicular,
refs,
None,
);
self.tabs[i].scene.note_parametric_constraint_applied(
scope,
id,
self.constraint_bar_display,
);
let changes = touched
.into_iter()
.map(|handle| (handle, crate::scene::ChangeKind::Modified))
.collect::<Vec<_>>();
self.tabs[i].scene.bump_entities_with_parametric_policy(
&changes,
&[first_fixed, second_start],
true,
);
self.tabs[i].dirty = true;
self.tabs[i].active_cmd = None;
self.tabs[i].snap_result = None;
self.command_line.push_output("Constraint applied.");
self.refresh_properties();
if let Some(pd) = pending {
self.commit_undo_delta(i, pd);
}
}
CmdResult::AddCoincidentConstraint {
first,
second,
+40 -4
View File
@@ -1366,7 +1366,46 @@ impl OpenCADStudio {
self.tabs[i].active_cmd = Some(Box::new(new_cmd));
}
"PCONSTRAINT" | "QCONSTRAINT" | "ECONSTRAINT" | "TCONSTRAINT" | "LCONSTRAINT"
"QCONSTRAINT" | "GCPERPENDICULAR" => {
use crate::command::CmdResult;
use crate::modules::parametric::PerpendicularConstraintCommand;
let handles = self.tabs[i].scene.selected_handles_in_order();
if handles.is_empty() {
let command = PerpendicularConstraintCommand::new();
self.command_line.push_info(&command.prompt());
self.tabs[i].active_cmd = Some(Box::new(command));
} else if handles.len() != 2 {
self.command_line
.push_output("Select exactly two perpendicular-compatible objects.");
} else {
let picks = handles
.iter()
.filter_map(|handle| {
let entity = self.tabs[i].scene.document.get_entity(*handle)?;
PerpendicularConstraintCommand::preselected_reference(entity, *handle)
})
.collect::<Vec<_>>();
if picks.len() == 2 && picks[0].reference != picks[1].reference {
return Some(self.apply_cmd_result(CmdResult::AddPerpendicularConstraint {
first: picks[0].reference,
second: picks[1].reference,
first_fixed: picks[0].fixed_reference,
second_start: picks[1].start_reference,
label: "Perpendicular constraint",
}));
}
self.tabs[i].scene.deselect_all();
self.command_line.push_error(
"Invalid selection for Perpendicular. Select a line segment, polyline segment, text, MText, major or minor axis of ellipse or elliptical arc.",
);
let command = PerpendicularConstraintCommand::new();
self.command_line.push_info(&command.prompt());
self.tabs[i].active_cmd = Some(Box::new(command));
}
}
"PCONSTRAINT" | "ECONSTRAINT" | "TCONSTRAINT" | "LCONSTRAINT"
| "NRCONSTRAINT" => {
let handles = self.tabs[i].scene.selected_handles_in_order();
if handles.is_empty() {
@@ -1383,9 +1422,6 @@ impl OpenCADStudio {
use crate::scene::parametric_constraints::{ConstraintKind, ParametricRef};
let (kind, label) = match cmd {
"PCONSTRAINT" => (ConstraintKind::Parallel, "Parallel constraint"),
"QCONSTRAINT" => {
(ConstraintKind::Perpendicular, "Perpendicular constraint")
}
"TCONSTRAINT" => (ConstraintKind::Tangent, "Tangent constraint"),
"LCONSTRAINT" => (ConstraintKind::Colinear, "Colinear constraint"),
"NRCONSTRAINT" => (ConstraintKind::Normal, "Normal constraint"),