diff --git a/src/entities/dimension.rs b/src/entities/dimension.rs index f546f5da2..7e0e47339 100644 --- a/src/entities/dimension.rs +++ b/src/entities/dimension.rs @@ -7860,10 +7860,7 @@ fn radial_leader_tip(dim: &Dimension, text: Vector3) -> Vector3 { /// A dimensional constraint's dynamic dimension: the reference keeps it on /// its own hidden layer and draws it by its own rules. fn dynamic_constraint_dimension(dim: &Dimension) -> bool { - dim.base() - .common - .layer - .eq_ignore_ascii_case(crate::scene::parametric_constraints::DYNAMIC_DIMENSION_LAYER) + crate::scene::parametric_constraints::is_dynamic_dimension_layer(&dim.base().common.layer) } /// How far a radial leader runs out from the rim before its hook, and how diff --git a/src/scene/dwg_native_constraints.rs b/src/scene/dwg_native_constraints.rs index 5fd805699..152b3168c 100644 --- a/src/scene/dwg_native_constraints.rs +++ b/src/scene/dwg_native_constraints.rs @@ -4075,6 +4075,7 @@ impl Scene { // writes, which happen on the local set during decode. self.bump_constraints_epoch(); self.import_sweep_expression_links(); + self.refresh_hidden_dynamic_dimensions(); } /// Makes the standard associative graph match the live command model. diff --git a/src/scene/mod.rs b/src/scene/mod.rs index 17541b093..367d92d26 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -3098,6 +3098,11 @@ impl Scene { /// so only immutable geometry is transferred and re-stamped here. The /// optional interaction index is cached against the exact same `Arc`. pub fn install_prepared_open_geometry(&self, prepared: PreparedOpenGeometry) { + // The loader tessellated before the constraints were read, so its + // wires still hold the dynamic dimensions that must stay hidden. + if !self.hidden_dynamic_dimensions.is_empty() { + return; + } let block = self.model_space_block_handle(); let scale = crate::scene::annotative::scale_handle_by_name( &self.document, diff --git a/src/scene/parametric_constraints.rs b/src/scene/parametric_constraints.rs index 833cf42ca..4accc1dfe 100644 --- a/src/scene/parametric_constraints.rs +++ b/src/scene/parametric_constraints.rs @@ -435,6 +435,13 @@ pub const DYNAMIC_DIMENSION_TEXT_PX: f32 = 12.0; /// dimensional constraint sits on an ordinary layer instead. pub(crate) const DYNAMIC_DIMENSION_LAYER: &str = "*ADSK_CONSTRAINTS"; +/// Whether `layer` holds dynamic dimensions. Drawings from the first +/// parametric release keep them on `*LayerNameForDynamicConstraint`. +pub(crate) fn is_dynamic_dimension_layer(layer: &str) -> bool { + layer.eq_ignore_ascii_case(DYNAMIC_DIMENSION_LAYER) + || layer.eq_ignore_ascii_case("*LayerNameForDynamicConstraint") +} + /// The text a dynamic dimension shows: CONSTRAINTNAMEFORMAT 0 = name, /// 1 = value, 2 = name=value, the value with its trailing zeros dropped /// (`d9=80`, `d1=111.8034`). A parameter defined by a formula shows the @@ -2499,12 +2506,9 @@ impl super::Scene { /// form: on an ordinary layer instead of the reference's constraints /// layer, drawn with its style, plotted, never rescaled to the screen. pub(crate) fn dimension_is_annotational(&self, handle: Handle) -> bool { - self.document.get_entity(handle).is_some_and(|entity| { - !entity - .common() - .layer - .eq_ignore_ascii_case(DYNAMIC_DIMENSION_LAYER) - }) + self.document + .get_entity(handle) + .is_some_and(|entity| !is_dynamic_dimension_layer(&entity.common().layer)) } /// The document as written to a file: a dynamic dimension's screen-size @@ -2669,7 +2673,24 @@ impl super::Scene { /// DYNCONSTRAINTDISPLAY 0 for all of them) and redraws the ones that /// changed. pub(crate) fn refresh_hidden_dynamic_dimensions(&mut self) { - let desired: rustc_hash::FxHashSet = self + let linked: rustc_hash::FxHashSet = self + .parametric_constraints + .iter() + .flat_map(|set| set.dimensions.values().copied()) + .collect(); + // A dynamic dimension whose constraint did not load cannot be driven + // or placed on screen; like a viewer, leave it undrawn. + let orphans: Vec = self + .document + .entities() + .filter(|entity| { + matches!(entity, codec::EntityType::Dimension(_)) + && is_dynamic_dimension_layer(&entity.common().layer) + && !linked.contains(&entity.common().handle) + }) + .map(|entity| entity.common().handle) + .collect(); + let mut desired: rustc_hash::FxHashSet = self .parametric_constraints .iter() .flat_map(|set| { @@ -2681,6 +2702,7 @@ impl super::Scene { }) }) .collect(); + desired.extend(orphans); if desired == self.hidden_dynamic_dimensions { return; }