perf(clipboard): keep large copy/paste responsive

Copying and pasting a whole drawing froze the app. Three synchronous,
main-thread hot spots scaled with the full document rather than the
selection:

- Copy centroid did a linear document scan per selected handle
  (wire_models_for / mirror_preview_parts), making copy O(H*N). Use the
  document's O(1) handle index instead.
- The paste ghost translated every point of every clipboard wire on each
  mouse move — O(points) per frame, which stalls placement of a huge
  selection. Above a point budget, rubber-band a single bounding-box
  outline instead (O(1) per frame).
- finalize_paste re-tessellated every solid in the document on each
  paste. add_entity already tessellates pasted solids, so switch to the
  incremental populate_missing_meshes_from_document.
This commit is contained in:
sLuCHa committed 2026-07-08 16:09:35 +02:00
1 parent a4f7ee376f
commit 30b907cdd6
3 files changed
+76 -6

No files matched your search

+2 -2
View File
@@ -26,7 +26,7 @@ impl Scene {
handles
.iter()
.flat_map(|h| {
match self.document.entities().find(|e| e.common().handle == *h) {
match self.document.get_entity(*h) {
// Hatches carry no outline in the normal wire set, but an
// edit preview (move / copy / array / grip-drag) needs to
// show the shape following the cursor. Build a live boundary
@@ -54,7 +54,7 @@ impl Scene {
let mut plain: Vec<WireModel> = Vec::new();
let mut texts: Vec<(WireModel, glam::DVec3)> = Vec::new();
for h in handles {
let Some(e) = self.document.entities().find(|e| e.common().handle == *h) else {
let Some(e) = self.document.get_entity(*h) else {
continue;
};
if matches!(e, EntityType::Text(_)) {