engine: geometry.faces.merge, faces meshed as one (virtual topology, #505)

geometry.faces.merge {name, faces} records a face merge in the model;
it is applied after the partitions whenever the design is opened or cut
again, undoes through the journal and is saved with the model. Meshers,
mesh.plan (features and rings see merge:<name>; a merged face is
prismatic when its B-rep faces are), checks and the viewport see one
face, drawn in the warm colour. geometry.faces.merge.delete removes it.

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 22d709e604
commit ce02d263c7
17 files changed
+464 -22

No files matched your search

+4
View File
@@ -217,6 +217,8 @@ pub enum Collection {
/// A datum point.
DatumPoint,
Partition,
/// A face merge (`geometry.faces.merge`).
FaceMerge,
}
impl Collection {
@@ -242,6 +244,7 @@ impl Collection {
Collection::DatumAxis => "datum axis",
Collection::DatumPoint => "datum point",
Collection::Partition => "partition",
Collection::FaceMerge => "face merge",
}
}
}
@@ -271,6 +274,7 @@ impl Session {
Collection::DatumAxis => Box::new(m.datums().iter().filter(|(_, d)| d.axis().is_some()).map(|(n, _)| n.as_str())),
Collection::DatumPoint => Box::new(m.datums().iter().filter(|(_, d)| d.point().is_some()).map(|(n, _)| n.as_str())),
Collection::Partition => Box::new(m.partitions().iter().map(|p| p.name.as_str())),
Collection::FaceMerge => Box::new(m.face_merges().iter().map(|f| f.name.as_str())),
};
names.take(MAX_NAMES).map(str::to_string).collect()
}