From 2a15a370f6886d3e8695ab81c7d677e0cd484451 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Wed, 30 Sep 2026 22:39:33 +0300 Subject: [PATCH] fix(dimension): an edited dimension keeps its layer's linetype A dimension loaded from a file draws from its baked *D block, whose lines are ByBlock and so take the dimension's linetype (ByLayer: the layer's). Any edit - text colour, MATCHPROP, a grip - drops that block and the dimension draws live, where a style with no DIMLTYPE/DIMLTEX1/2 drew solid: an edited dimension on a dashed layer turned solid (#898). None or ByBlock now takes the dimension's own linetype, ByLayer its layer's. Co-Authored-By: Claude Opus 5.5 --- src/entities/dimension.rs | 53 +++++++++++++++++++++++---------------- src/scene/view/render.rs | 2 +- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/entities/dimension.rs b/src/entities/dimension.rs index a9c5b14c2..b2b3b0a45 100644 --- a/src/entities/dimension.rs +++ b/src/entities/dimension.rs @@ -3989,15 +3989,18 @@ fn tessellate_dimension_inner( // DIMLTEX (dim line) / DIMLTEX1 (ext1) / DIMLTEX2 (ext2) — linetype // handles → pattern. Looked up in document.line_types by handle. let lt_scale = document.header.linetype_scale as f32 * dim.base().common.linetype_scale as f32; - let (dim_pat_len, dim_pat) = style - .map(|s| resolve_pattern_by_handle(document, s.dimltex_handle, lt_scale)) - .unwrap_or((0.0, [0.0; 8])); - let (ext1_pat_len, ext1_pat) = style - .map(|s| resolve_pattern_by_handle(document, s.dimltex1_handle, lt_scale)) - .unwrap_or((0.0, [0.0; 8])); - let (ext2_pat_len, ext2_pat) = style - .map(|s| resolve_pattern_by_handle(document, s.dimltex2_handle, lt_scale)) - .unwrap_or((0.0, [0.0; 8])); + let pattern = |line_type: Option| { + resolve_pattern_by_handle( + document, + line_type.unwrap_or(codec::types::Handle::NULL), + &dim.base().common, + active_viewport, + lt_scale, + ) + }; + let (dim_pat_len, dim_pat) = pattern(style.map(|s| s.dimltex_handle)); + let (ext1_pat_len, ext1_pat) = pattern(style.map(|s| s.dimltex1_handle)); + let (ext2_pat_len, ext2_pat) = pattern(style.map(|s| s.dimltex2_handle)); let mut wires = Vec::new(); @@ -4399,23 +4402,31 @@ fn resolve_dim_lineweight_px(code: i16, fallback_px: f32) -> f32 { /// Look up a linetype in the document's line_types table by handle and /// resolve it to a (pattern_length, pattern) pair compatible with WireModel. +/// A dimension line's dash pattern. A linetype the style names draws as +/// itself; none or ByBlock takes the dimension's own linetype (ByLayer: its +/// layer's), which is what the ByBlock lines of its baked `*D` block drew — +/// an edited dimension, drawn live, lost its layer's dashes. (#898) fn resolve_pattern_by_handle( doc: &CadDocument, handle: codec::types::Handle, + common: &codec::entities::EntityCommon, + viewport: Option, scale: f32, ) -> (f32, [f32; 8]) { - if handle.is_null() { - return (0.0, [0.0; 8]); - } - let name = doc - .line_types - .iter() - .find(|lt| lt.handle == handle) - .map(|lt| lt.name.clone()); - match name { - Some(n) => crate::scene::view::render::resolve_pattern(&doc.line_types, &n, scale), - None => (0.0, [0.0; 8]), - } + let named = (!handle.is_null()) + .then(|| doc.line_types.iter().find(|lt| lt.handle == handle)) + .flatten() + .map(|lt| lt.name.as_str()) + .filter(|name| !name.eq_ignore_ascii_case("byblock")); + let name = match named { + Some(name) if name.eq_ignore_ascii_case("bylayer") => doc + .layers + .get(&common.layer) + .map_or("Continuous", |layer| layer.line_type.as_str()), + Some(name) => name, + None => crate::scene::view::render::linetype_name_for_common_viewport(doc, common, viewport), + }; + crate::scene::view::render::resolve_pattern(&doc.line_types, name, scale) } /// Split the combined ext-lines point list (NaN-separated segment pairs) diff --git a/src/scene/view/render.rs b/src/scene/view/render.rs index 09f986ea2..fc5316a64 100644 --- a/src/scene/view/render.rs +++ b/src/scene/view/render.rs @@ -3383,7 +3383,7 @@ pub(in crate::scene) fn linetype_name_for<'a>(document: &'a CadDocument, e: &'a linetype_name_for_viewport(document, e, None) } -pub(in crate::scene) fn linetype_name_for_common_viewport<'a>( +pub(crate) fn linetype_name_for_common_viewport<'a>( document: &'a CadDocument, common: &'a codec::entities::EntityCommon, viewport: Option,