Dynamic dimensions: reference text format, horizontal text, lock after the text

A plain number shows as typed (d1=100), an expression under the fx: prefix
(fx: d2=d1*2); the text stays horizontal through DIMTIH/DIMTOH overrides
and the lock mark follows the text.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
ramox81andClaude Fable 5.1 committed 2026-09-21 13:57:06 +03:00
1 parent 0b5c686371
commit aa51765a62
3 files changed
+52 -25

No files matched your search

+1
View File
@@ -3611,6 +3611,7 @@ impl OpenCADStudio {
}; };
let text = dynamic_dimension_text( let text = dynamic_dimension_text(
&name, &name,
&expression,
value, value,
self.tabs[i].scene.constraint_name_format, self.tabs[i].scene.constraint_name_format,
); );
+3 -9
View File
@@ -6295,8 +6295,8 @@ fn dimension_text_is_outside(dim: &Dimension, style: Option<&DimStyle>) -> bool
} }
} }
/// Where a dynamic dimension's lock mark sits: just before the text on its /// Where a dynamic dimension's lock mark sits: just after the (horizontal)
/// baseline, with the direction that points away from the text. /// text, with the direction that points away from the text.
pub(crate) fn dynamic_dimension_lock_anchor( pub(crate) fn dynamic_dimension_lock_anchor(
document: &CadDocument, document: &CadDocument,
dim: &Dimension, dim: &Dimension,
@@ -6317,13 +6317,7 @@ pub(crate) fn dynamic_dimension_lock_anchor(
let stack_scale = style.map(dimtfac_or_one).unwrap_or(1.0); let stack_scale = style.map(dimtfac_or_one).unwrap_or(1.0);
let half_width = text_cells(&value, stack_scale) * text_height * CELL_WIDTH * 0.5; let half_width = text_cells(&value, stack_scale) * text_height * CELL_WIDTH * 0.5;
let pos = dimension_text_pos_f64(dim, style, text_height, dim_scale); let pos = dimension_text_pos_f64(dim, style, text_height, dim_scale);
let rot = if dim.base().text_rotation.abs() > 1e-9 { let outward = Vector3::new(1.0, 0.0, 0.0);
dim.base().text_rotation
} else {
dimension_text_natural_rotation(dim)
};
let (sr, cr) = rot.sin_cos();
let outward = Vector3::new(-cr, -sr, 0.0);
Some(( Some((
Vector3::new( Vector3::new(
pos.x + outward.x * half_width, pos.x + outward.x * half_width,
+48 -16
View File
@@ -368,12 +368,23 @@ pub const DYNAMIC_DIMENSION_GLYPH: &str = "\u{1F512}";
pub const DYNAMIC_DIMENSION_TEXT_PX: f32 = 12.0; pub const DYNAMIC_DIMENSION_TEXT_PX: f32 = 12.0;
/// The text a dynamic dimension shows: CONSTRAINTNAMEFORMAT 0 = name, /// The text a dynamic dimension shows: CONSTRAINTNAMEFORMAT 0 = name,
/// 1 = value, 2 = name=value. /// 1 = value, 2 = name=value. A plain number shows as typed (`d1=100`); an
pub(crate) fn dynamic_dimension_text(name: &str, value: f64, format: u8) -> String { /// expression shows the expression under the reference's `fx:` prefix
/// (`fx: d2=d1*2`).
pub(crate) fn dynamic_dimension_text(name: &str, source: &str, value: f64, format: u8) -> String {
let source = source.trim();
let literal = source.parse::<f64>().is_ok();
let shown = if literal {
source.to_string()
} else {
measured_expression(value)
};
match format { match format {
0 => name.to_string(), 0 => name.to_string(),
1 => format!("{value:.4}"), 1 if literal => shown,
_ => format!("{name}={value:.4}"), 1 => format!("fx: {shown}"),
_ if literal => format!("{name}={shown}"),
_ => format!("fx: {name}={source}"),
} }
} }
@@ -1477,14 +1488,24 @@ impl super::Scene {
let Some(constraint) = set.get(*id) else { let Some(constraint) = set.get(*id) else {
continue; continue;
}; };
let (name, value) = match &constraint.driving_param { let (name, source, value) = match &constraint.driving_param {
Some(DrivingValue::Named(name)) => { Some(DrivingValue::Named(name)) => (
(name.clone(), table.resolve(name).unwrap_or(f64::NAN)) name.clone(),
table
.get(name)
.map(|parameter| parameter.source.clone())
.unwrap_or_default(),
table.resolve(name).unwrap_or(f64::NAN),
),
Some(DrivingValue::Literal(value)) => {
(String::new(), measured_expression(*value), *value)
} }
Some(DrivingValue::Literal(value)) => (String::new(), *value),
None => continue, None => continue,
}; };
updates.push((*dimension, dynamic_dimension_text(&name, value, format))); updates.push((
*dimension,
dynamic_dimension_text(&name, &source, value, format),
));
} }
} }
for (handle, text) in updates { for (handle, text) in updates {
@@ -1615,19 +1636,30 @@ impl super::Scene {
.filter(|height| *height > 1e-9) .filter(|height| *height > 1e-9)
.unwrap_or(0.18); .unwrap_or(0.18);
let scale = f64::from(band) * f64::from(DYNAMIC_DIMENSION_TEXT_PX) / text_height; let scale = f64::from(band) * f64::from(DYNAMIC_DIMENSION_TEXT_PX) / text_height;
let current = crate::entities::dim_override::real( use crate::entities::dim_override as ov;
&dimension.base().common.extended_data, let xdata = &dimension.base().common.extended_data;
crate::entities::dim_override::DIMSCALE, let current = ov::real(xdata, ov::DIMSCALE);
); // The reference draws dynamic dimension text horizontally.
if current.is_some_and(|value| (value - scale).abs() < 1e-9) { let horizontal = ov::int(xdata, ov::DIMTIH) == Some(1) && ov::int(xdata, ov::DIMTOH) == Some(1);
if current.is_some_and(|value| (value - scale).abs() < 1e-9) && horizontal {
continue; continue;
} }
crate::entities::dim_override::set( ov::set(
&mut self.document, &mut self.document,
handle, handle,
crate::entities::dim_override::DIMSCALE, ov::DIMSCALE,
Some(acadrust::xdata::XDataValue::Real(scale)), Some(acadrust::xdata::XDataValue::Real(scale)),
); );
if !horizontal {
for code in [ov::DIMTIH, ov::DIMTOH] {
ov::set(
&mut self.document,
handle,
code,
Some(acadrust::xdata::XDataValue::Integer16(1)),
);
}
}
changes.push((handle, super::ChangeKind::Modified)); changes.push((handle, super::ChangeKind::Modified));
} }
if !changes.is_empty() { if !changes.is_empty() {