mirror of
https://github.com/penpot/penpot.git
synced 2026-05-25 18:03:43 +00:00
🎉 Optimize drag-crop cache rebuild path
This commit is contained in:
parent
d4be6686c7
commit
575f4b9df0
@ -1739,18 +1739,41 @@ impl RenderState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Filter out any candidate that overlaps with any other candidate.
|
// Filter out any candidate that overlaps with any other candidate.
|
||||||
let mut non_overlapping: Vec<(Uuid, Rect, Rect)> = Vec::new();
|
// Sort by left edge so the inner loop can break early once no further
|
||||||
'outer: for (i, (id, bounds, selrect)) in candidates.iter().enumerate() {
|
// x-overlap is possible, reducing comparisons from O(N²) to O(N log N)
|
||||||
for (j, (_id2, bounds2, _sel2)) in candidates.iter().enumerate() {
|
// in typical layouts where shapes are spread out.
|
||||||
if i == j {
|
candidates.sort_unstable_by(|a, b| {
|
||||||
continue;
|
a.1.left
|
||||||
|
.partial_cmp(&b.1.left)
|
||||||
|
.unwrap_or(std::cmp::Ordering::Equal)
|
||||||
|
});
|
||||||
|
let n = candidates.len();
|
||||||
|
let mut is_overlapping = vec![false; n];
|
||||||
|
for i in 0..n {
|
||||||
|
for j in (i + 1)..n {
|
||||||
|
if candidates[j].1.left >= candidates[i].1.right {
|
||||||
|
break; // sorted: no further x-overlap possible for i
|
||||||
}
|
}
|
||||||
if bounds.intersects(*bounds2) {
|
if is_overlapping[i] && is_overlapping[j] {
|
||||||
continue 'outer;
|
continue; // both already excluded, skip check
|
||||||
|
}
|
||||||
|
if candidates[i].1.intersects(candidates[j].1) {
|
||||||
|
is_overlapping[i] = true;
|
||||||
|
is_overlapping[j] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
non_overlapping.push((*id, *bounds, *selrect));
|
|
||||||
}
|
}
|
||||||
|
let non_overlapping: Vec<(Uuid, Rect, Rect)> = candidates
|
||||||
|
.iter()
|
||||||
|
.zip(is_overlapping.iter())
|
||||||
|
.filter_map(|((id, bounds, selrect), ov)| {
|
||||||
|
if !ov {
|
||||||
|
Some((*id, *bounds, *selrect))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
let vb_left = self.viewbox.area.left;
|
let vb_left = self.viewbox.area.left;
|
||||||
let vb_top = self.viewbox.area.top;
|
let vb_top = self.viewbox.area.top;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user