Merge pull request #746 from gianlucafiore/fix/issues-742-743

Fix current layer handling for HATCH and DWG files
This commit is contained in:
gianlucafiore 2026-08-12 00:35:43 -03:00 • committed by GitHub
commit 5e773fbcce
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 45 additions and 5 deletions

View file

@ -1203,7 +1203,8 @@ impl OpenCADStudio {
CmdResult::CommitHatch(hatch) => { CmdResult::CommitHatch(hatch) => {
let label = self.history_label_from_active_cmd(i, "HATCH"); let label = self.history_label_from_active_cmd(i, "HATCH");
let pending = self.begin_undo(i, label, 1, true); 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() { if !new_handle.is_null() {
self.tabs[i].scene.select_entity(new_handle, true); self.tabs[i].scene.select_entity(new_handle, true);
} }
@ -2914,6 +2915,12 @@ impl OpenCADStudio {
angle, angle,
} => { } => {
if let Some(mut model) = self.tabs[i].scene.hatches.get(&handle).cloned() { 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 // Update model fields
if !name.is_empty() { if !name.is_empty() {
use crate::scene::model::hatch_model::HatchPattern; use crate::scene::model::hatch_model::HatchPattern;
@ -2933,7 +2940,7 @@ impl OpenCADStudio {
// Remove old hatch (entity + GPU model) // Remove old hatch (entity + GPU model)
self.tabs[i].scene.erase_entities(&[handle]); self.tabs[i].scene.erase_entities(&[handle]);
// Re-add with updated model // 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.tabs[i].dirty = true;
self.command_line.push_output(crate::t!("HATCHEDIT: hatch updated.").as_ref()); self.command_line.push_output(crate::t!("HATCHEDIT: hatch updated.").as_ref());
} else { } else {

View file

@ -1096,6 +1096,34 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
self.tabs[i].scene.material_base_dir = self.tabs[i].scene.material_base_dir =
path.parent().map(std::path::Path::to_path_buf); path.parent().map(std::path::Path::to_path_buf);
self.tabs[i].scene.document = doc; 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 // A file saved without the built-in Standard styles (foreign
// or damaged) gets them re-seeded so nothing dangles (#366). // or damaged) gets them re-seeded so nothing dangles (#366).
crate::app::style_ops::ensure_standard_styles( crate::app::style_ops::ensure_standard_styles(

View file

@ -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(); let mut dxf = DxfHatch::new();
dxf.is_solid = matches!( dxf.is_solid = matches!(
model.pattern, model.pattern,
@ -2117,14 +2117,19 @@ impl Scene {
}, },
]; ];
} }
// `add_entity` already builds the render model from the DXF entity via // `add_entity` already builds the render model from the DXF entity via
// `hatch_model_from_dxf` and inserts it with a correct `world_origin` // `hatch_model_from_dxf` and inserts it with a correct `world_origin`
// (AABB-centred) for the relative-to-eye fill. The command-built `model` // (AABB-centred) for the relative-to-eye fill. The command-built `model`
// carries `world_origin: [0, 0]`, which after the world_offset removal // carries `world_origin: [0, 0]`, which after the world_offset removal
// leaves the fill mis-placed and effectively invisible until a later // 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. // 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) { pub fn clear(&mut self) {