fix(dim): draw a dimension from the picture it carries

A DIMENSION references the block "that contains the entities that make up
the dimension picture", and that block is the picture: AutoCAD requires
it and draws it, BricsCAD draws it when present and only renders from the
dimension variables when it is missing. OCS re-derived the picture from
DIMVARS every time and ignored the block entirely.

That works while a style agrees with what the drawing actually drew. A
Revit-exported schedule here does not: its style stores DIMTXT already in
drawing units beside a DIMSCALE meant to scale it, so the text came out
three hundred times too tall, and each dimension carries a DIMFXL
override that is likewise already in drawing units, so the extension
lines ran nearly a million units past the points they measure.

Neither is guesswork about units now. The block holds the geometry the
drawing was authored with, so it is drawn: the contents are already in
world space and the block's base point is the origin, and the identity
instance that carries them exists only to reuse the scene graph's
ByBlock / layer-0 colour resolution. Every wire answers to the dimension,
so a pick still selects the dimension rather than one of its pieces.
Re-deriving stays as the fallback for a dimension with no block.

Annotative dimensions keep the old path: their several representations
are separate blocks and choosing between them is what the annotation
machinery already does, while the doctrine above assumes one picture.

A picture is only good while its inputs hold, so it is dropped when they
change: editing a dimension's properties, and saving the dimension style
it is drawn with. Entity edits already dropped it.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 5 committed 2026-08-08 02:44:30 +03:00
1 parent 039f703d7f
commit 188d1a9ccb
3 files changed
+141

No files matched your search

+23
View File
@@ -467,6 +467,29 @@ impl OpenCADStudio {
ds.dimtofl = self.ds_dimtofl;
ds.dimalt = self.ds_dimalt;
ds.dimapost = self.ds_dimapost.clone();
// Same reason as a per-dimension edit: every dimension on this style is
// drawn from a block made under the settings that just changed, so the
// pictures are stale. Drop them and let each be drawn again. Without
// this an edit here would move the numbers and leave the drawing alone.
let edited = self.dimstyle_selected.clone();
let stale: Vec<acadrust::Handle> = self.tabs[tab]
.scene
.document
.entities()
.filter_map(|entity| match entity {
acadrust::EntityType::Dimension(dim)
if dim.base().style_name.eq_ignore_ascii_case(&edited) =>
{
Some(entity.common().handle)
}
_ => None,
})
.collect();
for handle in stale {
self.tabs[tab].scene.invalidate_dim_block_recorded(handle);
}
self.command_line
.push_output(crate::tf!("DimStyle '{}' updated.", self.dimstyle_selected).as_ref());
}