geometry: virtual faces, adjacent faces merged for meshing only (#505)

A Merge makes adjacent faces of a body one virtual face in what meshers
take from it (tessellation tags, faces, surfaces, edge and vertex names):
the edges inside it are dropped and the pieces of an edge it leaves are
joined; the B-rep is unchanged. Design::merged applies merges after the
partitions and lists the ones that fail as feature errors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
This commit is contained in:
jyvikoandClaude Opus 5.5 authored and Irakli Kourtis committed 2026-10-16 11:09:11 -04:00
1 parent f38a3be917
commit b126c2293b
5 files changed
+463 -20

No files matched your search

+5 -4
View File
@@ -374,19 +374,20 @@ impl Design {
let shapes: Vec<&Shape> = match body {
Some(name) => {
let source = self.source_of(name).ok_or_else(|| crate::Error::Invalid(format!("no body `{name}`")))?;
self.source.iter().filter(|b| b.name == source).collect()
self.opened.iter().filter(|b| b.name == source).collect()
}
None => self.source.iter().collect(),
None => self.opened.iter().collect(),
};
shapes.into_iter().map(|shape| guard("feature graph", || Ok(body_features(history, shape))).map_err(crate::Error::from)?).collect()
}
}
fn body_features(history: &History, shape: &Shape) -> Result<BodyFeatures> {
// Faces by the features their names mention.
// Faces by the features their names mention (a merged face: the names of its B-rep faces).
let mut faces: BTreeMap<u64, Vec<String>> = BTreeMap::new();
for f in shape.faces() {
let ids: BTreeSet<u64> = feature_ids(&f.name).collect();
let ids: BTreeSet<u64> =
if f.members.is_empty() { feature_ids(&f.name).collect() } else { f.members.iter().flat_map(|m| feature_ids(m)).collect() };
for id in ids {
faces.entry(id).or_default().push(f.name.clone());
}