From 7bae75f5d654b5992a4d8379bc8b6b172e054538 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Mon, 27 Apr 2026 02:30:56 +0300 Subject: [PATCH] feat: dimension extension lines respect DIMEXO offset and DIMEXE overshoot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extension lines for linear and aligned dimensions now start at DIMEXO × DIMSCALE distance from the definition point (instead of at the point itself) and extend DIMEXE × DIMSCALE units past the dimension line, matching AutoCAD rendering. Both values fall back to 0 when the dimstyle is not found. Co-Authored-By: Claude Sonnet 4.6 --- src/scene/tessellate.rs | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/scene/tessellate.rs b/src/scene/tessellate.rs index 13101e675..a87277c93 100644 --- a/src/scene/tessellate.rs +++ b/src/scene/tessellate.rs @@ -229,18 +229,21 @@ pub fn tessellate_dimension( }; let name = handle.value().to_string(); let style_name = &dim.base().style_name; - let arrow_size = document + let (arrow_size, dimexo, dimexe) = document .dim_styles .iter() .find(|s| s.name.eq_ignore_ascii_case(style_name) || (style_name.trim().is_empty() && s.name.eq_ignore_ascii_case("Standard"))) .map(|s| { let scale = if s.dimscale > 1e-6 { s.dimscale } else { 1.0 }; - (s.dimasz * scale) as f32 + ( + ((s.dimasz * scale) as f32).max(0.001), + (s.dimexo * scale) as f32, + (s.dimexe * scale) as f32, + ) }) - .unwrap_or(0.12) - .max(0.001); - let points = dimension_geometry(dim, arrow_size); + .unwrap_or((0.12, 0.0, 0.0)); + let points = dimension_geometry(dim, arrow_size, dimexo, dimexe); let key_vertices = points .iter() .copied() @@ -683,7 +686,7 @@ fn solid_wire_fallback(entity: &EntityType) -> Vec<[f32; 3]> { pts } -fn dimension_geometry(dim: &Dimension, arrow_size: f32) -> Vec<[f32; 3]> { +fn dimension_geometry(dim: &Dimension, arrow_size: f32, dimexo: f32, dimexe: f32) -> Vec<[f32; 3]> { let mut points = Vec::new(); match dim { Dimension::Aligned(d) => { @@ -691,14 +694,14 @@ fn dimension_geometry(dim: &Dimension, arrow_size: f32) -> Vec<[f32; 3]> { let second = vec3(d.second_point); let def = vec3(d.definition_point); let axis = normalized_or(second - first, Vec3::X); - append_linear_dimension(&mut points, first, second, def, axis, arrow_size); + append_linear_dimension(&mut points, first, second, def, axis, arrow_size, dimexo, dimexe); } Dimension::Linear(d) => { let first = vec3(d.first_point); let second = vec3(d.second_point); let def = vec3(d.definition_point); let axis = Vec3::new(d.rotation.cos() as f32, d.rotation.sin() as f32, 0.0); - append_linear_dimension(&mut points, first, second, def, normalized_or(axis, Vec3::X), arrow_size); + append_linear_dimension(&mut points, first, second, def, normalized_or(axis, Vec3::X), arrow_size, dimexo, dimexe); } Dimension::Radius(d) => { let center = vec3(d.angle_vertex); @@ -750,13 +753,26 @@ fn append_linear_dimension( def: Vec3, axis: Vec3, arrow_size: f32, + dimexo: f32, + dimexe: f32, ) { let perp = Vec3::new(-axis.y, axis.x, 0.0); let dim_line_pos = def.dot(perp); - let d1 = first + perp * (dim_line_pos - first.dot(perp)); - let d2 = second + perp * (dim_line_pos - second.dot(perp)); - add_segment(points, first, d1); - add_segment(points, second, d2); + // Perpendicular offset from each defpoint to the dimension line (signed). + let offset1 = dim_line_pos - first.dot(perp); + let offset2 = dim_line_pos - second.dot(perp); + let d1 = first + perp * offset1; + let d2 = second + perp * offset2; + // DIMEXO: gap from the definition point toward the dimension line. + // DIMEXE: overshoot past the dimension line. + let sign1 = if offset1 >= 0.0 { 1.0_f32 } else { -1.0 }; + let sign2 = if offset2 >= 0.0 { 1.0_f32 } else { -1.0 }; + let ext1_start = first + perp * (sign1 * dimexo); + let ext1_end = d1 + perp * (sign1 * dimexe); + let ext2_start = second + perp * (sign2 * dimexo); + let ext2_end = d2 + perp * (sign2 * dimexe); + add_segment(points, ext1_start, ext1_end); + add_segment(points, ext2_start, ext2_end); add_segment(points, d1, d2); append_arrow(points, d1, normalized_or(d2 - d1, axis), arrow_size); append_arrow(points, d2, normalized_or(d1 - d2, -axis), arrow_size);