From eaab2053025df1dcc909cf61fe4362200fd680be Mon Sep 17 00:00:00 2001 From: bherbruck Date: Tue, 13 Oct 2026 19:42:31 -0400 Subject: [PATCH] Open large designs faster: name a moved body's faces only when asked (#913) NameCell::same now refers to its source body and takes the source's names on first request, instead of naming every face of every moved or placed body up front. Names are unchanged. --- crates/doc/src/naming.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/crates/doc/src/naming.rs b/crates/doc/src/naming.rs index 4f32705f..b8848bf2 100644 --- a/crates/doc/src/naming.rs +++ b/crates/doc/src/naming.rs @@ -60,16 +60,19 @@ impl NameCell { pub fn known(names: Arc>) -> Self { let legacy = OnceLock::new(); let _ = legacy.set(names.clone()); - NameCell { legacy: Arc::new(legacy), ..Self::shared(Arc::new(Names::given(names)), None) } + NameCell { legacy: Arc::new(legacy), ..Self::shared(Arc::new(Names::given(names))) } } /// The names of `body` (a moved copy of a body keeps its faces' names, and how sure they are). + /// + /// Worked out on first request, from the source: moving a body (a transfer into a + /// component, a placed instance) does not name every face of every moved body up front. pub fn same(body: &ModelBody) -> Self { - Self::shared(names(body), Some(Arc::new(body.clone()))) + NameCell { copy_of: Some(Arc::new(body.clone())), ..NameCell::default() } } - fn shared(names: Arc, copy_of: Option>) -> Self { + fn shared(names: Arc) -> Self { let cell = OnceLock::new(); let _ = cell.set(names); - NameCell { names: Arc::new(cell), copy_of, ..NameCell::default() } + NameCell { names: Arc::new(cell), ..NameCell::default() } } } @@ -206,6 +209,10 @@ pub fn face_name_exact(b: &ModelBody, index: usize) -> bool { /// A body's names, with what finding them again needs: from the history of the feature that /// made it where it reports one, else from geometry (unverified). pub(crate) fn names(b: &ModelBody) -> Arc { + // A moved copy has its source's names (the source's cell keeps them for both). + if let Some(source) = &b.names.copy_of { + return b.names.names.get_or_init(|| names(source)).clone(); + } b.names .names .get_or_init(|| {