From db653c5a07d129cc482138e162b3815437f0549e Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Sun, 26 Apr 2026 17:08:12 +0300 Subject: [PATCH] fix: derive dimension text rotation from axis geometry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit acadrust's DXF reader does not parse group code 53 (text rotation), so DimensionBase.text_rotation is always zero for DXF-loaded files. Fall back to the natural axis-aligned rotation computed from geometry: Linear dimensions use d.rotation (radians), Aligned dimensions use atan2 of the second-first vector. Normalize to (-π/2, π/2] so text never appears upside-down. Explicit non-zero overrides stored by the DWG reader are preserved. Co-Authored-By: Claude Sonnet 4.6 --- src/scene/tessellate.rs | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/scene/tessellate.rs b/src/scene/tessellate.rs index f12f13bb7..f052ec2c8 100644 --- a/src/scene/tessellate.rs +++ b/src/scene/tessellate.rs @@ -799,14 +799,44 @@ fn dimension_text_entity(dim: &Dimension) -> Option { let value = dimension_text_value(dim)?; let pos = dimension_text_position(dim); let base = dim.base(); + // acadrust's DXF reader never parses group code 53 (text rotation), so + // base.text_rotation is always 0 for DXF files. Fall back to the natural + // axis-aligned rotation derived from geometry; only use the stored value + // when it represents a genuine user override (non-zero). + let rotation = if base.text_rotation.abs() > 1e-9 { + base.text_rotation + } else { + dimension_text_natural_rotation(dim) + }; let mut text = Text::with_value(value, Vector3::new(pos.x as f64, pos.y as f64, pos.z as f64)) .with_height(dimension_text_height(dim)) - .with_rotation(base.text_rotation); + .with_rotation(rotation); text.style = base.style_name.clone(); text.common = base.common.clone(); Some(text) } +fn dimension_text_natural_rotation(dim: &Dimension) -> f64 { + let angle = match dim { + Dimension::Linear(d) => d.rotation, + Dimension::Aligned(d) => { + let dx = d.second_point.x - d.first_point.x; + let dy = d.second_point.y - d.first_point.y; + dy.atan2(dx) + } + _ => 0.0, + }; + // Clamp to (-π/2, π/2] so text never appears upside-down. + let pi = std::f64::consts::PI; + if angle > pi / 2.0 { + angle - pi + } else if angle <= -pi / 2.0 { + angle + pi + } else { + angle + } +} + fn dimension_text_value(dim: &Dimension) -> Option { let base = dim.base(); if let Some(user_text) = &base.user_text {