Linear dimensional constraints: point flow, dynamic dimension, driving parameter

DCLINEAR, DCHORIZONTAL, DCVERTICAL and DCALIGNED follow the reference flow:
`Specify first constraint point or [Object] <Object>:`, `Specify second
constraint point:`, `Specify dimension line location:`, then `Dimension
text = …` and `Enter value or name and value <d1=100>:`. Linear reads
horizontal or vertical from the dimension line location the way a linear
dimension does; Object takes a line's, an arc's or a polyline segment's
ends. A miss reports `No valid constraint point found.` / `No object
found.` and asks again; another object type reports `Invalid selection for
Linear. Select a line, polyline segment or arc.`.

Each constraint creates a drawing parameter (`d1`, `d2`, …, or the typed
`name=expression`), drives the constraint through it, and draws a dynamic
dimension in constraint gray whose text follows CONSTRAINTNAMEFORMAT
(`d1=100.0000`); the dimension is associated with the constrained objects
and its text is refreshed after every solve. A typed value other than the
measured one moves the second point while the first stays, and so does a
later parameter edit. Deleting the constraint removes its dimension and,
when nothing else reads it, its parameter.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
ramox81andClaude Fable 5.1 committed 2026-09-21 11:53:19 +03:00
1 parent fd2062bdec
commit 72fd3fd35b
9 files changed
+898 -36

No files matched your search

+39 -3
View File
@@ -1131,7 +1131,26 @@ impl OpenCADStudio {
self.command_line.push_output("No constraints found.");
return None;
}
let pending = self.begin_undo(i, "Delete constraints", handles.len(), true);
let dimensions: Vec<acadrust::Handle> = ids
.iter()
.filter_map(|id| before.dimensions.get(id).copied())
.collect();
let parameters: Vec<String> = ids
.iter()
.filter_map(|id| before.get(*id))
.filter_map(|constraint| match &constraint.driving_param {
Some(crate::scene::named_parameters::DrivingValue::Named(name)) => {
Some(name.clone())
}
_ => None,
})
.collect();
let pending = self.begin_undo(
i,
"Delete constraints",
handles.len(),
dimensions.is_empty(),
);
self.tabs[i]
.scene
.record_undo_parametric_constraints_before(scope, before);
@@ -1139,6 +1158,7 @@ impl OpenCADStudio {
for id in &ids {
set.remove(*id);
}
self.purge_dimensional_extras(i, dimensions, parameters);
let changes: Vec<_> = handles
.iter()
.copied()
@@ -1726,8 +1746,24 @@ impl OpenCADStudio {
}
}
"DCONSTRAINT" | "DCLINEAR" | "DCHORIZONTAL" | "DCVERTICAL" | "DCALIGNED"
| "DCRADIUS" | "DCDIAMETER" => {
"DCLINEAR" | "DCHORIZONTAL" | "DCVERTICAL" | "DCALIGNED" => {
use crate::modules::parametric::{DimConstraintAxis, DimConstraintCommand};
use crate::scene::parametric_constraints::next_dimensional_parameter_name;
let axis = match cmd {
"DCHORIZONTAL" => DimConstraintAxis::Horizontal,
"DCVERTICAL" => DimConstraintAxis::Vertical,
"DCALIGNED" => DimConstraintAxis::Aligned,
_ => DimConstraintAxis::Linear,
};
let name = next_dimensional_parameter_name(self.tabs[i].scene.named_parameters());
// Both constraint points are picked inside the command.
self.tabs[i].scene.deselect_all();
let command = DimConstraintCommand::new(axis, name);
self.command_line.push_info(&command.prompt());
self.tabs[i].active_cmd = Some(Box::new(command));
}
"DCONSTRAINT" | "DCRADIUS" | "DCDIAMETER" => {
let handles = self.tabs[i].scene.selected_handles_in_order();
if handles.is_empty() {
use crate::modules::draw::select::SelectObjectsCommand;