From e88a94617676fcd4e41d4f0164e1ac0ee45f9ce6 Mon Sep 17 00:00:00 2001 From: Hakan Date: Thu, 14 May 2026 11:20:11 +0300 Subject: [PATCH] =?UTF-8?q?feat(xref):=20honor=20BlockRecord=20is=5Floaded?= =?UTF-8?q?=20=E2=80=94=20skip=20Unloaded=20xrefs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the host DWG marks an xref as Unloaded (via XREF→Unload in AutoCAD), the user explicitly chose NOT to load that reference. We were ignoring that and pulling the external file in anyway, which on large drawings could push GPU memory past the device budget. Bump the acadrust dep to the branch that exposes `BlockRecord::is_loaded`, then short-circuit `resolve_xrefs` for any entry with `is_loaded == Some(false)`. New `XrefStatus::Unloaded` surfaces this in the command-line log so the user can see which references were skipped (and can re-load them via the XREF dialog). Co-Authored-By: Claude Opus 4.7 --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/app/commands.rs | 6 ++++++ src/app/update.rs | 6 ++++++ src/io/xref.rs | 22 ++++++++++++++++++---- 5 files changed, 32 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d6201360e..639ce1351 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,7 +41,7 @@ checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" [[package]] name = "acadrust" version = "0.3.4" -source = "git+https://github.com/HakanSeven12/acadrust?rev=622729f#622729f961dae4d29fbc890d3622a3a86294ec8d" +source = "git+https://github.com/HakanSeven12/acadrust?branch=feat%2Fexpose-blockrecord-is-loaded#44ee57604af6f29a3f3ace05c2e49879fb8ae18a" dependencies = [ "ahash", "anyhow", diff --git a/Cargo.toml b/Cargo.toml index b94917e91..b06aacac1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,4 +23,4 @@ rayon = "1" windows-sys = { version = "0.59", features = ["Win32_UI_Shell", "Win32_UI_WindowsAndMessaging"] } [patch.crates-io] -acadrust = { git = "https://github.com/HakanSeven12/acadrust", rev = "622729f" } +acadrust = { git = "https://github.com/HakanSeven12/acadrust", branch = "feat/expose-blockrecord-is-loaded" } diff --git a/src/app/commands.rs b/src/app/commands.rs index a95b24a28..122be5918 100644 --- a/src/app/commands.rs +++ b/src/app/commands.rs @@ -584,6 +584,12 @@ impl H7CAD { info.name, info.path )); } + crate::io::xref::XrefStatus::Unloaded => { + self.command_line.push_info(&format!( + "XREF Unloaded (skipped): \"{}\"", + info.name + )); + } } } self.tabs[i].scene.populate_hatches_from_document(); diff --git a/src/app/update.rs b/src/app/update.rs index 8afcfe9ef..977454778 100644 --- a/src/app/update.rs +++ b/src/app/update.rs @@ -155,6 +155,12 @@ impl H7CAD { info.name, info.path )); } + crate::io::xref::XrefStatus::Unloaded => { + self.command_line.push_info(&format!( + "XREF Unloaded (skipped): \"{}\"", + info.name + )); + } } } } diff --git a/src/io/xref.rs b/src/io/xref.rs index 6b57772c9..d8a83de73 100644 --- a/src/io/xref.rs +++ b/src/io/xref.rs @@ -13,6 +13,9 @@ pub enum XrefStatus { Loaded, /// File path is set but the file could not be found or read. NotFound, + /// XRef is marked Unloaded in the host DWG — we honor that and + /// skip resolving the external file. The user can re-load via UI. + Unloaded, } /// Describes a single external reference found in a document. @@ -31,17 +34,28 @@ pub struct XrefInfo { /// /// Returns a list of [`XrefInfo`] describing each xref block found. pub fn resolve_xrefs(doc: &mut CadDocument, base_dir: &Path) -> Vec { - // Collect xref blocks: (name, raw_path, block_record_handle) - let xref_entries: Vec<(String, String, Handle)> = doc + // Collect xref blocks: (name, raw_path, block_record_handle, is_loaded) + // is_loaded == Some(false) means the host DWG marked this xref Unloaded + // via XREF→Unload; respect that and skip reading the external file. + let xref_entries: Vec<(String, String, Handle, Option)> = doc .block_records .iter() .filter(|br| (br.flags.is_xref || br.flags.is_xref_overlay) && !br.xref_path.is_empty()) - .map(|br| (br.name.clone(), br.xref_path.clone(), br.handle)) + .map(|br| (br.name.clone(), br.xref_path.clone(), br.handle, br.is_loaded)) .collect(); let mut result = Vec::new(); - for (block_name, raw_path, br_handle) in xref_entries { + for (block_name, raw_path, br_handle, is_loaded) in xref_entries { + if is_loaded == Some(false) { + result.push(XrefInfo { + name: block_name, + path: raw_path, + status: XrefStatus::Unloaded, + }); + continue; + } + let resolved = resolve_path(&raw_path, base_dir); let status = match &resolved {