From 71cebbb3fef470eb5609fa60c8a05cc5fc73602e Mon Sep 17 00:00:00 2001 From: ramox81 <184937705+ramox81@users.noreply.github.com> Date: Tue, 6 Oct 2026 10:37:04 +0300 Subject: [PATCH] Plot: redraw PlotDate hosts inside blocks and attributes A plot stamps PlotDate fields, but the redraw only dropped the host's own tessellation: an attribute is drawn by its INSERT and a host inside a block definition by every reference to the block, so both still showed the old value on screen and in the plotted output. The changed hosts now redraw through their INSERT / the block's references (block cache refreshed), without re-tessellating anything else. The codec is patched to the field format code fixes. Co-Authored-By: Claude Opus 5.5 --- Cargo.lock | 2 +- Cargo.toml | 3 +++ src/app/update/file.rs | 3 +-- src/scene/mod.rs | 45 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 85762f6fa..7b35d3a90 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4206,7 +4206,7 @@ dependencies = [ [[package]] name = "opencadcodec" version = "0.5.5" -source = "git+https://github.com/HakanSeven12/opencadcodec.git?rev=04b26f2#04b26f2c992110c1da4ed6bc0491d76906fbf4e5" +source = "git+https://github.com/ramox81/cadcodec.git?rev=f51f468#f51f4682c656d9d932c881918e3b8106446f013d" dependencies = [ "ahash 0.8.12", "anyhow", diff --git a/Cargo.toml b/Cargo.toml index 86fcca40e..8d37d1fbe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -94,6 +94,9 @@ objc2-foundation = { version = "0.2", features = ["NSArray", "NSURL", "NSString" iced_core = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39" } iced_widget = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39" } +[patch."https://github.com/HakanSeven12/opencadcodec.git"] +opencadcodec = { git = "https://github.com/ramox81/cadcodec.git", rev = "f51f468" } + [target.'cfg(not(target_arch = "wasm32"))'.dependencies] getrandom = "0.3" ocs_plugin_api = { path = "crates/ocs_plugin_api", features = ["host"] } diff --git a/src/app/update/file.rs b/src/app/update/file.rs index fe0e4d946..24ce4b7b0 100644 --- a/src/app/update/file.rs +++ b/src/app/update/file.rs @@ -3771,8 +3771,7 @@ impl OpenCADStudio { let i = self.active_tab; let hosts = crate::entities::field::stamp_plot_fields(&mut self.tabs[i].scene.document); if !hosts.is_empty() { - let changes: Vec<_> = hosts.into_iter().map(|h| (h, crate::scene::ChangeKind::Modified)).collect(); - self.tabs[i].scene.bump_entities(&changes); + self.tabs[i].scene.bump_text_hosts(&hosts); self.tabs[i].dirty = true; } } diff --git a/src/scene/mod.rs b/src/scene/mod.rs index 67335f4bb..71d538ef6 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -567,6 +567,9 @@ struct SceneDependencyIndex { text_geometry: DependencyTargets, annotation_geometry: DependencyTargets, signatures: HashMap, + /// Block name (normalised) → the layout entities that draw it, nested + /// references included. + block_roots: HashMap>, } fn hatch_interaction_aabb(hatch: &model::hatch_model::HatchModel) -> Option<[f64; 4]> { @@ -3393,6 +3396,47 @@ impl Scene { self.bump_entities_with_parametric_policy(changes, &[], false); } + /// Redraw text hosts whose stored text changed (re-evaluated fields). An + /// attribute is drawn by its INSERT, and a host inside a block definition + /// by every reference to that block, so those redraw instead of the host; + /// nothing else re-tessellates. + pub fn bump_text_hosts(&mut self, hosts: &[Handle]) { + if self.dependency_index_cache.borrow().is_none() { + *self.dependency_index_cache.borrow_mut() = Some(self.rebuild_dependency_index()); + } + let mut targets = DependencyTargets::default(); + for &host in hosts { + let drawn = match self.document.get_entity(host) { + Some(entity) => entity, + None => match self.document.entities().find(|e| { + matches!(e, EntityType::Insert(i) if i.attributes.iter().any(|a| a.common.handle == host)) + }) { + Some(insert) => insert, + None => continue, + }, + }; + let handle = drawn.common().handle; + let owner = drawn.common().owner_handle; + if !self.changes_touch_block_definition(&[(handle, ChangeKind::Modified)]) { + targets.render_handles.insert(handle); + continue; + } + let Some(record) = self.document.block_records.iter().find(|r| { + r.handle == owner || r.entity_handles.contains(&handle) + }) else { + continue; + }; + let name = normalize_name(&record.name); + if let Some(index) = self.dependency_index_cache.borrow().as_ref() { + if let Some(users) = index.block_roots.get(&name) { + targets.render_handles.extend(users.iter().copied()); + } + } + targets.touches_block_definition = true; + } + self.invalidate_dependency_targets(targets); + } + pub fn bump_entities_with_parametric_driven( &mut self, changes: &[(Handle, ChangeKind)], @@ -11565,6 +11609,7 @@ vis_index={:.1} visible_probe={:.1}", _ => {} } } + index.block_roots = roots; index }