From ff61164d8b38a8db34b30b772d3ace30cd50c7cd Mon Sep 17 00:00:00 2001 From: gianlucafiore Date: Wed, 12 Aug 2026 00:23:21 -0300 Subject: [PATCH] fix: preserve current layer for hatches and DWG loading --- src/app/command_driver.rs | 11 +++++++++-- src/app/update/file.rs | 28 ++++++++++++++++++++++++++++ src/scene/entity.rs | 11 ++++++++--- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/app/command_driver.rs b/src/app/command_driver.rs index 025581bc..e53c6aa2 100644 --- a/src/app/command_driver.rs +++ b/src/app/command_driver.rs @@ -1203,7 +1203,8 @@ impl OpenCADStudio { CmdResult::CommitHatch(hatch) => { let label = self.history_label_from_active_cmd(i, "HATCH"); let pending = self.begin_undo(i, label, 1, true); - let new_handle = self.tabs[i].scene.add_hatch(hatch); + let layer = self.tabs[i].active_layer.clone(); + let new_handle = self.tabs[i].scene.add_hatch(hatch, Some(&layer)); if !new_handle.is_null() { self.tabs[i].scene.select_entity(new_handle, true); } @@ -2914,6 +2915,12 @@ impl OpenCADStudio { angle, } => { if let Some(mut model) = self.tabs[i].scene.hatches.get(&handle).cloned() { + let layer = self.tabs[i] + .scene + .document + .get_entity(handle) + .map(|entity| entity.as_entity().layer().to_string()) + .unwrap_or_else(|| "0".to_string()); // Update model fields if !name.is_empty() { use crate::scene::model::hatch_model::HatchPattern; @@ -2933,7 +2940,7 @@ impl OpenCADStudio { // Remove old hatch (entity + GPU model) self.tabs[i].scene.erase_entities(&[handle]); // Re-add with updated model - self.tabs[i].scene.add_hatch(model); + self.tabs[i].scene.add_hatch(model, Some(&layer)); self.tabs[i].dirty = true; self.command_line.push_output(crate::t!("HATCHEDIT: hatch updated.").as_ref()); } else { diff --git a/src/app/update/file.rs b/src/app/update/file.rs index eec6232d..7f89dc2c 100644 --- a/src/app/update/file.rs +++ b/src/app/update/file.rs @@ -1096,6 +1096,34 @@ pub(super) fn on_open_file(&mut self) -> Task { self.tabs[i].scene.material_base_dir = path.parent().map(std::path::Path::to_path_buf); self.tabs[i].scene.document = doc; + // DWG stores CLAYER as a layer handle. Resolve that handle back to + // the layer name after opening so the per-tab creation state and + // header name stay in sync. DXF already provides current_layer_name, + // so keep it as a fallback. + let current_layer = { + let doc = &self.tabs[i].scene.document; + + doc.layers + .iter() + .find(|layer| layer.handle == doc.header.current_layer_handle) + .map(|layer| (layer.name.clone(), layer.handle)) + .or_else(|| { + doc.layers + .get(&doc.header.current_layer_name) + .map(|layer| (layer.name.clone(), layer.handle)) + }) + .or_else(|| { + doc.layers + .get("0") + .map(|layer| (layer.name.clone(), layer.handle)) + }) + }; + + if let Some((name, handle)) = current_layer { + self.tabs[i].scene.document.header.current_layer_name = name.clone(); + self.tabs[i].scene.document.header.current_layer_handle = handle; + self.tabs[i].active_layer = name; + } // A file saved without the built-in Standard styles (foreign // or damaged) gets them re-seeded so nothing dangles (#366). crate::app::style_ops::ensure_standard_styles( diff --git a/src/scene/entity.rs b/src/scene/entity.rs index b06c644b..2e315f17 100644 --- a/src/scene/entity.rs +++ b/src/scene/entity.rs @@ -2000,7 +2000,7 @@ impl Scene { } } - pub fn add_hatch(&mut self, model: HatchModel) -> Handle { + pub fn add_hatch(&mut self, model: HatchModel, layer: Option<&str>) -> Handle { let mut dxf = DxfHatch::new(); dxf.is_solid = matches!( model.pattern, @@ -2117,14 +2117,19 @@ impl Scene { }, ]; } - // `add_entity` already builds the render model from the DXF entity via // `hatch_model_from_dxf` and inserts it with a correct `world_origin` // (AABB-centred) for the relative-to-eye fill. The command-built `model` // carries `world_origin: [0, 0]`, which after the world_offset removal // leaves the fill mis-placed and effectively invisible until a later // edit rebuilds it from the DXF — so keep the seed, don't overwrite it. - self.add_entity(EntityType::Hatch(dxf)) + let mut entity = EntityType::Hatch(dxf); + + if let Some(layer) = layer { + entity.as_entity_mut().set_layer(layer.to_string()); + } + + self.add_entity(entity) } pub fn clear(&mut self) {