fix(dimension): zero the group-12 insertion point on baked blocks (#181)

A dimension's *D block is baked in absolute WCS, so the DWG group-12
insertion point must be the origin. OCS's dimension commands seeded it
with the text anchor, so a reader that positions the block by that point
(BricsCAD / ODA) drew the dimension shifted by the offset, while OCS —
which renders the block in place — showed it correctly.

Reset base.insertion_point to the origin in bake_dimension_blocks, where
the absolute-WCS block is created. Only dimensions whose block OCS bakes
are touched; blocks preserved from other applications (baseline/continue
dimensions with a legitimate non-zero clone insertion) are left alone.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 4.8 committed 2026-07-08 09:58:09 +03:00
1 parent 0e368934ea
commit aca2b952a5
1 file changed
+39
+39
View File
@@ -1060,6 +1060,15 @@ pub fn bake_dimension_blocks(doc: &mut CadDocument) {
if let Some(EntityType::Dimension(d)) = doc.get_entity_mut(handle) {
d.base_mut().block_name = name;
// The block we just baked holds the dimension graphics in absolute
// WCS, so the DWG group-12 insertion point (base.insertion_point)
// MUST be the origin. A reader that positions the *D block by that
// point (BricsCAD / ODA) otherwise draws it shifted by the offset,
// while OCS — which renders the block in place — shows it correctly.
// OCS's dimension commands seed insertion_point with the text
// anchor; reset it here so the saved dimension lands identically in
// every application. (#181)
d.base_mut().insertion_point = Vector3::new(0.0, 0.0, 0.0);
}
}
}
@@ -1136,6 +1145,36 @@ mod tests {
);
}
/// Baking a blockless dimension resets its group-12 insertion point to the
/// origin. OCS's commands seed it with the text anchor; left non-zero, a
/// reader that positions the absolute-WCS block by that point draws the
/// dimension shifted. Regression test for #181.
#[test]
fn bake_zeroes_insertion_point() {
let mut doc = CadDocument::new();
let mut d = DimensionLinear::new(Vector3::new(0.0, 0.0, 0.0), Vector3::new(10.0, 0.0, 0.0));
d.definition_point = Vector3::new(0.0, 5.0, 0.0);
d.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0);
// Exactly what OCS-created dimensions carry: insertion == text anchor.
d.base.insertion_point = d.base.text_middle_point;
let handle = doc
.add_entity(EntityType::Dimension(Dimension::Linear(d)))
.unwrap();
bake_dimension_blocks(&mut doc);
let ins = match doc.get_entity(handle) {
Some(EntityType::Dimension(d)) => d.base().insertion_point,
_ => panic!("dimension missing"),
};
assert_eq!(
ins,
Vector3::new(0.0, 0.0, 0.0),
"baked dimension must carry a zero insertion point (#181)"
);
}
// Collect the line segments baked into the dimension's `*D` block.
fn baked_segments(doc: &CadDocument, block_name: &str) -> Vec<(Vector3, Vector3)> {
let rec = doc.block_records.get(block_name).expect("block record");