From 4aa4b72d17267c0da2e249e68676922dbbb5312a Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Sat, 17 Oct 2026 22:22:19 +0300 Subject: [PATCH] TRIM / EXTEND: a large cutting-edge selection no longer stalls each pick MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In Standard mode the chosen edges sat in a Vec, and every trim rebuilt the boundary by asking it about each object of the drawing: edges × objects per click, seconds once a crossing window picked thousands of edges. Look them up in a set. TRIM's edge-selection hover also searched all objects for every picked edge on each mouse move; it uses the command's handle index like EXTEND. Refs #1867 Co-Authored-By: Claude Opus 5.5 --- src/modules/draw/modify/trim.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/modules/draw/modify/trim.rs b/src/modules/draw/modify/trim.rs index 0445c99fc..24ad76945 100644 --- a/src/modules/draw/modify/trim.rs +++ b/src/modules/draw/modify/trim.rs @@ -2734,10 +2734,13 @@ impl TrimCommand { self.geos = if self.edge_set.is_empty() { build_geos(&self.all_entities) } else { + // A set, not the Vec: every trim rebuilds this, and a selection + // of thousands of edges made it edges × objects per click (#1867). + let edges: std::collections::HashSet = self.edge_set.iter().copied().collect(); let picked: Vec = self .all_entities .iter() - .filter(|e| self.edge_set.contains(&e.common().handle)) + .filter(|e| edges.contains(&e.common().handle)) .cloned() .collect(); build_geos(&picked) @@ -3005,15 +3008,11 @@ impl CadCommand for TrimCommand { let mut out: Vec = self .edge_set .iter() - .filter_map(|h| self.all_entities.iter().find(|e| e.common().handle == *h)) + .filter_map(|h| self.entity_index.get(&self.all_entities, *h)) .map(|e| WireModel::solid("edge_sel".into(), entity_pts(e), OPT_YELLOW, false)) .collect(); if !handle.is_null() && !self.edge_set.contains(&handle) { - if let Some(e) = self - .all_entities - .iter() - .find(|e| e.common().handle == handle) - { + if let Some(e) = self.entity_index.get(&self.all_entities, handle) { let mut c = OPT_YELLOW; c[3] = 0.45; out.push(WireModel::solid( @@ -3480,10 +3479,13 @@ impl ExtendCommand { self.geos = if self.edge_set.is_empty() { build_geos(&self.all_entities) } else { + // A set, not the Vec: every trim rebuilds this, and a selection + // of thousands of edges made it edges × objects per click (#1867). + let edges: std::collections::HashSet = self.edge_set.iter().copied().collect(); let picked: Vec = self .all_entities .iter() - .filter(|e| self.edge_set.contains(&e.common().handle)) + .filter(|e| edges.contains(&e.common().handle)) .cloned() .collect(); build_geos(&picked)