DWF and DGN underlays: attach, display, snaps, frames and references

DWFATTACH / -DWFATTACH and DGNATTACH / -DGNATTACH attach a DWF / DWFx sheet
or a DGN (V7 or V8) model with the reference's prompts; ATTACH routes the
file types to them. The sheet or model is read into vector paths, drawn as a
transparent underlay raster (contrast, fade, monochrome and background
adjustment apply) and offers its geometry to object snaps. Definitions are
kept in ACAD_DWFDEFINITIONS / ACAD_DGNDEFINITIONS, the External References
palette lists and reloads them, and image textures get line-keeping mip
levels so thin underlay lines stay visible when zoomed out.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
ramox81andClaude Opus 5.5 committed 2026-09-28 12:53:25 +03:00
1 parent 7f8f8457c7
commit cb7860e50e
46 files changed
+2723 -129

No files matched your search

+13 -6
View File
@@ -1087,7 +1087,6 @@ impl XrefManagerPanel {
/// directly — mirrors the three [`collect_entries`] scans so nested entries
/// (foreign handles) classify correctly even on handle collisions.
fn direct_identities(doc: &CadDocument) -> HashSet<(u64, String)> {
use codec::entities::UnderlayType;
use codec::objects::ObjectType;
let mut ids: HashSet<(u64, String)> = HashSet::new();
@@ -1102,9 +1101,7 @@ fn direct_identities(doc: &CadDocument) -> HashSet<(u64, String)> {
ids.insert((handle.value(), def.file_name.clone()));
}
ObjectType::UnderlayDefinition(def) => {
if def.underlay_type == UnderlayType::Pdf {
ids.insert((handle.value(), def.file_path.clone()));
}
ids.insert((handle.value(), def.file_path.clone()));
}
_ => {}
}
@@ -1185,7 +1182,17 @@ fn type_text(entry: &ReferenceEntry) -> std::borrow::Cow<'static, str> {
// Raster images display their file format (spec: type column shows
// the image format); unknown extensions fall back to Image.
RefKind::Image => image_format(&entry.saved_path),
RefKind::Pdf => crate::t!("PDF"),
RefKind::Underlay => {
let ext = std::path::Path::new(&entry.saved_path.replace('\\', "/"))
.extension()
.map(|e| e.to_string_lossy().to_ascii_uppercase())
.unwrap_or_default();
match ext.as_str() {
"DWF" | "DWFX" => crate::t!("DWF"),
"DGN" => crate::t!("DGN"),
_ => crate::t!("PDF"),
}
}
}
}
@@ -2118,7 +2125,7 @@ fn reference_preview(entry: &ReferenceEntry) -> Option<image::RgbaImage> {
let img = image::open(found).ok()?;
Some(img.thumbnail(PREVIEW_MAX, PREVIEW_MAX).to_rgba8())
}
RefKind::Pdf => None,
RefKind::Underlay => None,
}
}