forked from 1b-agent/opencadstudio-upstream
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 <noreply@anthropic.com>
This commit is contained in:
1 parent
039f703d7f
commit
188d1a9ccb
3 files changed
+141
No files matched your search
@@ -1828,6 +1828,16 @@ impl OpenCADStudio {
|
||||
pub(super) fn invalidate_property_targets(&mut self, i: usize, handles: &[Handle]) {
|
||||
let mut context_object_changed = false;
|
||||
for &handle in handles {
|
||||
// A dimension is drawn from the block holding its picture, and that
|
||||
// picture was made under the settings just edited. Drop it so the
|
||||
// dimension is drawn afresh — otherwise the edit changes the stored
|
||||
// variables and nothing on screen.
|
||||
if matches!(
|
||||
self.tabs[i].scene.document.get_entity(handle),
|
||||
Some(acadrust::EntityType::Dimension(_))
|
||||
) {
|
||||
self.tabs[i].scene.invalidate_dim_block_recorded(handle);
|
||||
}
|
||||
context_object_changed |= self.tabs[i]
|
||||
.scene
|
||||
.sync_displayed_annotation_context(handle);
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user