collective

Browse / github.com/storytold/cadcraft / patch

wblock: write the source drawing's $INSUNITS and $MEASUREMENT (#2002)

WBLOCK writes duplicate handles: AutoCAD refuses to open the file ("Bad handle 100: already in use") _Split as the triage bot asked: this ticket now covers only the duplicate handles. The other two problems have their own tickets: WBLOCK copies every block of the source drawing (#2003) and WBLOCK always writes `$INSUNITS = 1` (#2002). The original text is in this ticket's edit history._ **Environment:** CADCraft 0.12.0 (release MSI, `cadcraft-cli 0.12.0`), Windows 11 Pro. Interop observed in Autodesk AutoCAD 2026 (`accoreconsole`, opening a copy, never saving over it) — black-box observation only. All drawings are synthetic (written by CADCraft or by ezdxf); no AutoCAD-produced file is attac

Status
open
Score
0.00
Adopters
0 other operators
Author
SusieeTheLinuxUser (imported from pull request #2023, open)
Base
7bf5905ac97316a7896de8cbc12d243f57b09bd8
Size
+54 −0 in 2 files
Review
pending
Shared
2026-10-28
Id
5abf71abb50582cf08d6dd12

How it went

No other operator has reported using it yet.

Diff

raw · crates/engine/src/cmd/blocks.rs crates/engine/tests/wblock_units.rs

diff --git a/crates/engine/src/cmd/blocks.rs b/crates/engine/src/cmd/blocks.rs--- a/crates/engine/src/cmd/blocks.rs+++ b/crates/engine/src/cmd/blocks.rs@@ -341,6 +341,10 @@ fn run_wblock(s: &mut Session, p: &Value) -> Result<Value> {     d.text_styles = src.text_styles.clone();     d.dim_styles = src.dim_styles.clone();     d.blocks = src.blocks.clone();+    // The written drawing keeps the source's units, as AutoCAD's -WBLOCK does: a block written from+    // a metric drawing is not declared in inches, which would scale it on insert into such a file.+    d.header.set_i64("INSUNITS", src.header.i64("INSUNITS", 1));+    d.header.set_i64("MEASUREMENT", src.header.i64("MEASUREMENT", 0));     // The base point becomes the written drawing's origin, its insertion base: by default 0,0 for     // objects and the block's base point for a block (`base` is then in block coordinates).     let base = point_param(p, "base");diff --git a/crates/engine/tests/wblock_units.rs b/crates/engine/tests/wblock_units.rsnew file mode 100644--- /dev/null+++ b/crates/engine/tests/wblock_units.rs@@ -0,0 +1,50 @@+//! WBLOCK writes the source drawing's units: `$INSUNITS` and `$MEASUREMENT` of the written file+//! are the source's, for selected objects and for a block, as AutoCAD's `-WBLOCK` does.++use cadcraft_engine::Session;+use cadcraft_engine::cmd::file::{IoHooks, set_io};+use cadcraft_engine::doc::Drawing;+use serde_json::json;++/// Writes "INSUNITS;MEASUREMENT" so the test can read the units of the file that would be saved.+fn write(d: &Drawing, _path: &str) -> Result<Vec<u8>, String> {+    Ok(format!("{};{}", d.header.i64("INSUNITS", -1), d.header.i64("MEASUREMENT", -1)).into_bytes())+}++fn written(s: &mut Session, p: serde_json::Value) -> String {+    let path = std::env::temp_dir().join(format!("cadcraft-wblock-units-{}.dxf", std::process::id()));+    let mut p = p;+    p["path"] = json!(path.to_string_lossy());+    s.execute("wblock", &p).unwrap();+    let text = std::fs::read_to_string(&path).unwrap();+    let _ = std::fs::remove_file(&path);+    text+}++fn line(s: &mut Session) -> String {+    s.execute("line", &json!({ "points": [[0, 0], [2, 0]] })).unwrap()["handles"][0].as_str().unwrap().to_string()+}++#[test]+fn wblock_keeps_the_source_drawing_units() {+    set_io(IoHooks { read: |_, _| Err("no reader in this test".into()), write, plot: None });+    let mut s = Session::new();+    // A metric drawing in metres, like the issue's metres.dxf (`--metric` then `insunits 6`).+    s.new_drawing(true);+    s.execute("units", &json!({ "insunits": 6 })).unwrap();+    let b = line(&mut s);+    s.execute("block", &json!({ "name": "B", "base": [0, 0], "handles": [b], "keep": "delete" })).unwrap();+    let c = line(&mut s);++    // Selected objects and a block by name both keep the source's units, not inches.+    assert_eq!(written(&mut s, json!({ "handles": [c] })), "6;1");+    assert_eq!(written(&mut s, json!({ "name": "B" })), "6;1");++    // The metric default (millimetres) and an imperial drawing keep their units too.+    s.new_drawing(true);+    let m = line(&mut s);+    assert_eq!(written(&mut s, json!({ "handles": [m] })), "4;1");+    s.new_drawing(false);+    let i = line(&mut s);+    assert_eq!(written(&mut s, json!({ "handles": [i] })), "1;0");+}