Dynamic dimensions: constant screen size, transform keeps the second constraint point

Every dynamic dimension gets a DIMSCALE override for 12 px text, refreshed
per zoom band, at creation and after load. A SCALE/ROTATE of an entity whose
own end points a driving dimension measures now pins its second constraint
point so the dimension moves the first end, as the reference does.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
ramox81andClaude Fable 5.1 committed 2026-09-21 13:36:01 +03:00
1 parent 971abe64a4
commit 0b5c686371
6 files changed
+75 -4

No files matched your search

+60
View File
@@ -364,6 +364,9 @@ pub(crate) fn next_dimensional_parameter_name(
/// The constraint-bar label that draws a dynamic dimension's lock mark.
pub const DYNAMIC_DIMENSION_GLYPH: &str = "\u{1F512}";
/// The on-screen text height of a dynamic dimension, in pixels.
pub const DYNAMIC_DIMENSION_TEXT_PX: f32 = 12.0;
/// The text a dynamic dimension shows: CONSTRAINTNAMEFORMAT 0 = name,
/// 1 = value, 2 = name=value.
pub(crate) fn dynamic_dimension_text(name: &str, value: f64, format: u8) -> String {
@@ -1575,6 +1578,63 @@ impl super::Scene {
.any(|set| set.dimensions.values().any(|dimension| *dimension == handle))
}
/// Gives every dynamic dimension a DIMSCALE override that keeps its
/// text, arrows and offsets at a screen size (the reference draws them
/// at a constant pixel size whatever the zoom). Runs once per zoom band;
/// `force` re-applies after a dimension was created or loaded.
pub fn refresh_dynamic_dimension_scales(&mut self, force: bool) {
let Some(band) = super::Scene::quantize_wpp(self.world_per_pixel()) else {
return;
};
if !force && band == self.dynamic_dimension_band {
return;
}
self.dynamic_dimension_band = band;
let handles: Vec<Handle> = self
.parametric_constraints
.iter()
.flat_map(|set| set.dimensions.values().copied())
.collect();
let mut changes = Vec::new();
for handle in handles {
let Some(acadrust::EntityType::Dimension(dimension)) = self.document.get_entity(handle)
else {
continue;
};
let style_name = dimension.base().style_name.clone();
let text_height = self
.document
.dim_styles
.iter()
.find(|style| {
style.name.eq_ignore_ascii_case(&style_name)
|| (style_name.trim().is_empty()
&& style.name.eq_ignore_ascii_case("Standard"))
})
.map(|style| style.dimtxt)
.filter(|height| *height > 1e-9)
.unwrap_or(0.18);
let scale = f64::from(band) * f64::from(DYNAMIC_DIMENSION_TEXT_PX) / text_height;
let current = crate::entities::dim_override::real(
&dimension.base().common.extended_data,
crate::entities::dim_override::DIMSCALE,
);
if current.is_some_and(|value| (value - scale).abs() < 1e-9) {
continue;
}
crate::entities::dim_override::set(
&mut self.document,
handle,
crate::entities::dim_override::DIMSCALE,
Some(acadrust::xdata::XDataValue::Real(scale)),
);
changes.push((handle, super::ChangeKind::Modified));
}
if !changes.is_empty() {
self.bump_entities(&changes);
}
}
/// Re-derives which dynamic dimensions stay off screen (DCHIDE, or
/// DYNCONSTRAINTDISPLAY 0 for all of them) and redraws the ones that
/// changed.