forked from 1b-agent/opencadstudio-upstream
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:
1 parent
971abe64a4
commit
0b5c686371
6 files changed
+75
-4
No files matched your search
@@ -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.
|
||||
|
||||
Reference in new issue
Block a user