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
@@ -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");new file mode 100644@@ -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");+}