forked from 1b-agent/opencadstudio-upstream
perf(scene): make geometry edits incremental
Avoid full document, cache, and GPU rebuilds for entity deltas so add, delete, history, selection, and live polyline edits stay responsive on large drawings.
This commit is contained in:
1 parent
73b8dbe9d4
commit
05b044f367
32 files changed
+1936
-516
No files matched your search
@@ -370,6 +370,7 @@ impl OpenCADStudio {
|
||||
.unwrap_or_default();
|
||||
self.push_undo_snapshot(i, "ATTSYNC");
|
||||
let mut synced = 0usize;
|
||||
let mut changes = Vec::new();
|
||||
for e in self.tabs[i].scene.document.entities_mut() {
|
||||
if let acadrust::EntityType::Insert(ins) = e {
|
||||
if ins.block_name.eq_ignore_ascii_case(&block) {
|
||||
@@ -390,10 +391,11 @@ impl OpenCADStudio {
|
||||
}
|
||||
}
|
||||
synced += 1;
|
||||
changes.push((ins.common.handle, crate::scene::ChangeKind::Modified));
|
||||
}
|
||||
}
|
||||
}
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
self.tabs[i].scene.bump_entities(&changes);
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
"ATTSYNC: synchronised {synced} insert(s) of \"{block}\" against {} attribute definition(s).",
|
||||
|
||||
+20
-4
@@ -169,7 +169,11 @@ impl OpenCADStudio {
|
||||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
let changes: Vec<_> = handles
|
||||
.into_iter()
|
||||
.map(|handle| (handle, crate::scene::ChangeKind::Modified))
|
||||
.collect();
|
||||
self.tabs[i].scene.bump_entities(&changes);
|
||||
self.command_line
|
||||
.push_output(&format!("JUSTIFYTEXT: updated {n} text object(s)."));
|
||||
}
|
||||
@@ -253,7 +257,11 @@ impl OpenCADStudio {
|
||||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
let changes: Vec<_> = handles
|
||||
.into_iter()
|
||||
.map(|handle| (handle, crate::scene::ChangeKind::Modified))
|
||||
.collect();
|
||||
self.tabs[i].scene.bump_entities(&changes);
|
||||
self.command_line
|
||||
.push_output(&format!("TCASE: updated {n} text object(s)."));
|
||||
}
|
||||
@@ -397,7 +405,11 @@ impl OpenCADStudio {
|
||||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
let changes: Vec<_> = handles
|
||||
.into_iter()
|
||||
.map(|handle| (handle, crate::scene::ChangeKind::Modified))
|
||||
.collect();
|
||||
self.tabs[i].scene.bump_entities(&changes);
|
||||
self.command_line.push_output(&format!(
|
||||
"TEXTFIT: fitted {n} text object(s) to width {target}."
|
||||
));
|
||||
@@ -459,7 +471,11 @@ impl OpenCADStudio {
|
||||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
let changes: Vec<_> = texts
|
||||
.iter()
|
||||
.map(|(handle, _, _)| (*handle, crate::scene::ChangeKind::Modified))
|
||||
.collect();
|
||||
self.tabs[i].scene.bump_entities(&changes);
|
||||
self.command_line.push_output(&format!(
|
||||
"TCOUNT: numbered {} text object(s) from {start}.",
|
||||
texts.len()
|
||||
|
||||
@@ -686,7 +686,11 @@ impl OpenCADStudio {
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
let changes: Vec<_> = handles
|
||||
.into_iter()
|
||||
.map(|handle| (handle, crate::scene::ChangeKind::Modified))
|
||||
.collect();
|
||||
self.tabs[i].scene.bump_entities(&changes);
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
"OBJECTSCALE: marked {n} object(s) annotative (they scale with the annotation scale)."
|
||||
@@ -776,6 +780,7 @@ impl OpenCADStudio {
|
||||
let v = v.min(100);
|
||||
self.push_undo_snapshot(i, "ADJUST");
|
||||
let mut changed = 0usize;
|
||||
let mut changed_handles = Vec::new();
|
||||
for h in &handles {
|
||||
if let Some(acadrust::EntityType::RasterImage(img)) = self.tabs[i]
|
||||
.scene
|
||||
@@ -787,14 +792,17 @@ impl OpenCADStudio {
|
||||
"BRIGHTNESS" => {
|
||||
img.brightness = v;
|
||||
changed += 1;
|
||||
changed_handles.push(*h);
|
||||
}
|
||||
"CONTRAST" => {
|
||||
img.contrast = v;
|
||||
changed += 1;
|
||||
changed_handles.push(*h);
|
||||
}
|
||||
"FADE" => {
|
||||
img.fade = v;
|
||||
changed += 1;
|
||||
changed_handles.push(*h);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@@ -802,7 +810,14 @@ impl OpenCADStudio {
|
||||
}
|
||||
if changed > 0 {
|
||||
self.tabs[i].dirty = true;
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
for &handle in &changed_handles {
|
||||
self.tabs[i].scene.reseed_derived_caches(handle);
|
||||
}
|
||||
let changes: Vec<_> = changed_handles
|
||||
.into_iter()
|
||||
.map(|handle| (handle, crate::scene::ChangeKind::Modified))
|
||||
.collect();
|
||||
self.tabs[i].scene.bump_entities(&changes);
|
||||
self.command_line
|
||||
.push_output(&format!("ADJUST: {action} = {v} on {changed} image(s)."));
|
||||
} else {
|
||||
@@ -860,7 +875,7 @@ impl OpenCADStudio {
|
||||
let hdr = &mut self.tabs[i].scene.document.header;
|
||||
hdr.current_annotation_scale = arg.clone();
|
||||
hdr.annotation_scale_value = 1.0 / v as f64;
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
self.tabs[i].scene.invalidate_annotation_dependencies();
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("Annotation scale: {arg}"));
|
||||
@@ -1014,7 +1029,6 @@ impl OpenCADStudio {
|
||||
self.tabs[i]
|
||||
.scene
|
||||
.add_entity_clone(acadrust::EntityType::Table(table));
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
"DATALINK: imported {nrows}×{ncols} cells into a table at the origin."
|
||||
@@ -1061,7 +1075,6 @@ impl OpenCADStudio {
|
||||
.scene
|
||||
.add_entity_clone(acadrust::EntityType::Point(p));
|
||||
}
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!(
|
||||
"LANDXMLIMPORT: imported {} survey point(s). Use ZOOM EXTENTS to view.",
|
||||
|
||||
@@ -453,7 +453,9 @@ impl OpenCADStudio {
|
||||
self.grip_hover = None;
|
||||
self.grip_popup = None;
|
||||
self.visibility_popup = None;
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
// Entering BEDIT changes which block is assembled, not the
|
||||
// cached geometry of that block's entities.
|
||||
self.tabs[i].scene.bump_geometry_no_blocks();
|
||||
// Frame the camera on the block's own geometry (block-local, near
|
||||
// origin) — fit_all() goes through current_layout_block_handle so
|
||||
// it already scopes to the edited block. Without this the view
|
||||
|
||||
@@ -129,9 +129,14 @@ impl OpenCADStudio {
|
||||
self.push_undo_snapshot(i, "LAYER COLOR");
|
||||
self.tabs[i].dirty = true;
|
||||
// By-layer colour is baked into every wire on
|
||||
// this layer — re-tessellate so they repaint
|
||||
// immediately (issue #231 class).
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
// this layer. The dependency index maps block
|
||||
// children back to their top-level INSERTs, so
|
||||
// unrelated entities stay warm.
|
||||
self.tabs[i]
|
||||
.scene
|
||||
.invalidate_layer_dependencies(std::slice::from_ref(
|
||||
&layer_name,
|
||||
));
|
||||
self.command_line.push_output(&format!(
|
||||
"LAYER: '{}' color set to ACI {}.",
|
||||
layer_name, idx
|
||||
|
||||
@@ -200,7 +200,10 @@ impl OpenCADStudio {
|
||||
}
|
||||
}
|
||||
self.tabs[i].scene.document.layers.remove(&src);
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
self.tabs[i].scene.invalidate_dependency_index();
|
||||
self.tabs[i]
|
||||
.scene
|
||||
.invalidate_layer_dependencies(std::slice::from_ref(&dst));
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_layer_panel();
|
||||
self.command_line.push_output(&format!(
|
||||
|
||||
@@ -725,7 +725,11 @@ impl OpenCADStudio {
|
||||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
let changes: Vec<_> = handles
|
||||
.into_iter()
|
||||
.map(|handle| (handle, crate::scene::ChangeKind::Modified))
|
||||
.collect();
|
||||
self.tabs[i].scene.bump_entities(&changes);
|
||||
self.command_line.push_output(&format!(
|
||||
"SETBYLAYER: reset {changed} entity/entities to ByLayer."
|
||||
));
|
||||
@@ -1593,7 +1597,9 @@ impl OpenCADStudio {
|
||||
// TEXTFILL reset the glyph atlas; re-tessellate so text picks
|
||||
// up the re-baked filled / hollow tiles.
|
||||
if name == "TEXTFILL" {
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
self.tabs[i]
|
||||
.scene
|
||||
.invalidate_text_geometry_dependencies();
|
||||
}
|
||||
// ORTHOMODE / OSMODE set the header directly; mirror them into
|
||||
// the live Ortho / running OSNAP so the constraint + status
|
||||
@@ -1902,7 +1908,7 @@ impl OpenCADStudio {
|
||||
self.push_undo_snapshot(i, "PDMODE");
|
||||
self.tabs[i].scene.document.header.point_display_mode = v;
|
||||
// Point glyphs are built at tessellation time — rebuild them.
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
self.tabs[i].scene.invalidate_point_dependencies();
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output(&format!("PDMODE set to {v}"));
|
||||
} else {
|
||||
@@ -2046,7 +2052,7 @@ impl OpenCADStudio {
|
||||
} else if let Ok(v) = val_str.parse::<f64>() {
|
||||
self.push_undo_snapshot(i, "PDSIZE");
|
||||
self.tabs[i].scene.document.header.point_display_size = v;
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
self.tabs[i].scene.invalidate_point_dependencies();
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(&format!("PDSIZE set to {v:.4}"));
|
||||
|
||||
@@ -956,7 +956,9 @@ impl OpenCADStudio {
|
||||
// render-side `sort_cache` rebuilds per geometry epoch.
|
||||
// Bump it so the new draw order shows immediately
|
||||
// instead of waiting for an unrelated geometry change.
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
// Draw order changes submission order only; all
|
||||
// per-entity tessellation remains valid.
|
||||
self.tabs[i].scene.bump_geometry_no_blocks();
|
||||
self.tabs[i].dirty = true;
|
||||
} else {
|
||||
self.command_line.push_info(
|
||||
|
||||
Reference in new issue
Block a user