From 0996b75bddd276e0301955172cc53eb21a4ccf33 Mon Sep 17 00:00:00 2001 From: Hakan Date: Thu, 14 May 2026 14:14:07 +0300 Subject: [PATCH] Revert: stop honoring BlockRecord.is_loaded for xref skip decision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Empirically the DWG \"loaded\" bit doesn't track AutoCAD's XREF Manager \"Loaded\"/\"Unloaded\" state reliably: - File A: manager \"Loaded\", on-disk is_loaded = Some(true) - File B: manager \"Loaded\", on-disk is_loaded = Some(false) Same UI state, opposite bit values, so we were incorrectly skipping xrefs the user wants loaded. Drop the `is_loaded == Some(false)` skip and auto-resolve every xref again. The OOM problem this was meant to mitigate is now addressed by the frustum culler, so loading more xrefs no longer threatens the GPU budget. The `BlockRecord::is_loaded` field + acadrust patch stay in place so we can revisit once we identify the actual on-disk representation of XREF→Unload (likely an XREF dependency record or ACAD_XREF_PANEL_DATA xrecord). Co-Authored-By: Claude Opus 4.7 --- src/io/xref.rs | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/io/xref.rs b/src/io/xref.rs index d8a83de73..8a00bcfe5 100644 --- a/src/io/xref.rs +++ b/src/io/xref.rs @@ -34,28 +34,25 @@ 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, 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 + // Collect xref blocks: (name, raw_path, block_record_handle) + // + // Note: `BlockRecord::is_loaded` (the DWG R2000+ "loaded" bit) turned out + // to be unreliable as a signal of AutoCAD's Unload state — different + // files with xrefs the manager calls "Loaded" carry both `Some(true)` + // and `Some(false)` on disk. Until we identify the actual on-disk + // representation of XREF→Unload (likely in an XREF dependency record + // or ACAD_XREF_PANEL_DATA xrecord), we auto-resolve every xref and + // rely on frustum culling to keep the GPU bounded. + let xref_entries: Vec<(String, String, Handle)> = 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, br.is_loaded)) + .map(|br| (br.name.clone(), br.xref_path.clone(), br.handle)) .collect(); let mut result = Vec::new(); - 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; - } - + for (block_name, raw_path, br_handle) in xref_entries { let resolved = resolve_path(&raw_path, base_dir); let status = match &resolved {