From 4bef410abbf8d28d35179103f84365c1cde6b6d0 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Tue, 22 Sep 2026 13:46:49 +0300 Subject: [PATCH] fix: review fixes for the metric template and the radial constraint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A new drawing (#1441) recorded ISO-25 as the current dimension style by name only. Every other place that changes it sets the header's handle as well, and a DWG carries the current style by handle alone, so a saved new drawing reopened on Standard. The style's handle now comes back from the helper that adds it. A radius constraint (#1443) anchored the circle's centre from the shape of its references — one whole entity — but a single whole reference is also a line's length, whose start is what stays. The entity decides now. The two tests that encoded the replaced rules follow them: a negative radius validates by its magnitude, as a negative distance already did, and only zero is refused; a new drawing's dimension text reads at ISO-25's comma separator. Co-Authored-By: Claude Opus 5 --- src/app/dimension_preview_tests.rs | 4 +++- src/scene/creation_style.rs | 14 +++++++++----- src/scene/entity.rs | 5 ++++- src/scene/parametric_constraints.rs | 11 +++++++++-- src/scene/parametric_solve.rs | 10 +++++++++- 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/app/dimension_preview_tests.rs b/src/app/dimension_preview_tests.rs index 8268d0979..b79ae03a6 100644 --- a/src/app/dimension_preview_tests.rs +++ b/src/app/dimension_preview_tests.rs @@ -63,7 +63,9 @@ fn ordinate_preview_matches_commit() { assert!(app.dimension_preview_entities(i, DVec3::ZERO).is_none()); let _ = app.feed_command(StepInput::Point(DVec3::new(12.5, 40.0, 0.0))); let entity = commit_and_compare(&mut app, i, DVec3::new(12.5, 90.0, 0.0)); - assert_eq!(text(&app, &entity), "12.5"); + // A new drawing is metric and current on ISO-25, whose decimal separator + // is a comma and whose trailing zeros are suppressed. + assert_eq!(text(&app, &entity), "12,5"); } #[test] diff --git a/src/scene/creation_style.rs b/src/scene/creation_style.rs index de4bd2f8a..4313cf1b5 100644 --- a/src/scene/creation_style.rs +++ b/src/scene/creation_style.rs @@ -36,14 +36,16 @@ fn named_text_style(doc: &CadDocument, name: &str) -> Option { } /// Adds the reference's ISO-25 dimension style (the current style of its -/// metric template) when the drawing has none of that name. -pub fn ensure_iso_dim_style(doc: &mut CadDocument) { - if doc +/// metric template) when the drawing has none of that name, and hands back its +/// handle: the header records the current dimension style by handle as well as +/// by name, and a DWG carries only the handle. +pub fn ensure_iso_dim_style(doc: &mut CadDocument) -> Handle { + if let Some(style) = doc .dim_styles .iter() - .any(|style| style.name.eq_ignore_ascii_case("ISO-25")) + .find(|style| style.name.eq_ignore_ascii_case("ISO-25")) { - return; + return style.handle; } let mut style = DimStyle::new("ISO-25"); style.handle = doc.allocate_handle(); @@ -82,7 +84,9 @@ pub fn ensure_iso_dim_style(doc: &mut CadDocument) { style.dimjogang = std::f64::consts::FRAC_PI_2; style.dimmzf = 100.0; style.dimaltmzf = 100.0; + let handle = style.handle; let _ = doc.dim_styles.add(style); + handle } fn named_dim_style(doc: &CadDocument, name: &str) -> Option { diff --git a/src/scene/entity.rs b/src/scene/entity.rs index e85a2551e..cbfd84344 100644 --- a/src/scene/entity.rs +++ b/src/scene/entity.rs @@ -2733,8 +2733,11 @@ impl Scene { // current. Standard stays available for imperial work. self.document.header.measurement = 1; self.document.header.insertion_units = 4; - crate::scene::creation_style::ensure_iso_dim_style(&mut self.document); + let iso = crate::scene::creation_style::ensure_iso_dim_style(&mut self.document); self.document.header.current_dimstyle_name = "ISO-25".to_string(); + // The name alone leaves the header pointing at the previous style, and + // a DWG writes the current style by handle only. + self.document.header.current_dimstyle_handle = iso; for obj in self.document.objects.values_mut() { if let acadrust::objects::ObjectType::Layout(l) = obj { if l.name != "Model" { diff --git a/src/scene/parametric_constraints.rs b/src/scene/parametric_constraints.rs index 160ae481b..f6eb587a7 100644 --- a/src/scene/parametric_constraints.rs +++ b/src/scene/parametric_constraints.rs @@ -732,8 +732,15 @@ pub(crate) fn dimensional_anchor_refs( return Vec::new(); }; // A whole circle or arc (a radius or diameter): its center stays and the - // value resizes it. - if refs.len() == 1 && first.marker.is_none() { + // value resizes it. A single whole reference can also be a line's length, + // whose start is what stays, so the entity decides. + if refs.len() == 1 + && first.marker.is_none() + && matches!( + document.get_entity(first.entity), + Some(acadrust::EntityType::Circle(_) | acadrust::EntityType::Arc(_)) + ) + { return vec![ParametricRef::center(first.entity)]; } // Three point references: a three-point angle `[first, vertex, second]`. diff --git a/src/scene/parametric_solve.rs b/src/scene/parametric_solve.rs index 63b71a19a..1fbf8589c 100644 --- a/src/scene/parametric_solve.rs +++ b/src/scene/parametric_solve.rs @@ -4152,7 +4152,8 @@ mod tests { ))); let refs = [ParametricRef::point(line, 0), ParametricRef::point(line, 1)]; // A distance keeps a negative value's sign in the parameter and - // measures its magnitude (`d1=-50`); a radius has no such reading. + // measures its magnitude (`d1=-50`); a radius reads the same way + // (`rad1=-20` is a radius of 20), and only zero leaves no circle. assert!(scene .validate_parametric_constraint( ConstraintKind::Distance, @@ -4170,6 +4171,13 @@ mod tests { &[ParametricRef::whole(circle)], Some(&DrivingValue::Literal(-1.0)), ) + .is_ok()); + assert!(scene + .validate_parametric_constraint( + ConstraintKind::Radius, + &[ParametricRef::whole(circle)], + Some(&DrivingValue::Literal(0.0)), + ) .is_err()); assert!(scene .validate_parametric_constraint(