fix(dimension): bake a *D block on save so dimensions survive in other CAD

A DWG DIMENSION references an anonymous *D<n> block that holds its drawn
geometry; AutoCAD-family readers render that block rather than re-deriving it
from the definition points. OCS re-tessellates dimensions for display and never
materialises the block, so on save a created dimension goes out referencing a
block that doesn't exist and the writer emits a null block handle. Strict
readers (DWG TrueView, QCAD) then drop the dimension or demand a recovery, and
lenient ones (BricsCAD) regenerate it at a different position.

Add bake_dimension_blocks(), called on the cloned document in
io::save_as_version / save_to_bytes, which builds a *D<n> anonymous block from
each block-less dimension's exploded geometry (extension lines + dimension line
+ measurement text) and points its block_name at it. Dimensions that already
own a block (imported, or copied via the *D-cloning copy path) are left
untouched.

Verified end-to-end: before, AutoCAD/Civil 3D 2026 reads 0 dimensions from an
OCS-saved file; after baking it reads all of them.

Fixes #178, #181, #182.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Kevin GriffinandClaude Opus 4.8 committed 2026-06-25 17:01:10 -07:00
1 parent dee5a05652
commit d477c39cbe
2 files changed
+147 -1

No files matched your search

+2
View File
@@ -465,6 +465,7 @@ pub fn save_as_version(
let mut doc = doc.clone();
doc.version = version;
sync_current_styles_on_save(&mut doc);
crate::modules::draw::modify::explode::bake_dimension_blocks(&mut doc);
let ext = path
.extension()
.map(|e| e.to_string_lossy().to_lowercase())
@@ -496,6 +497,7 @@ pub fn save_to_bytes(
let mut doc = doc.clone();
doc.version = version;
sync_current_styles_on_save(&mut doc);
crate::modules::draw::modify::explode::bake_dimension_blocks(&mut doc);
match ext.to_lowercase().as_str() {
"dxf" => DxfWriter::new(&doc).write_to_vec().map_err(|e| e.to_string()),
_ => {