ifcgeom: keep one copy of repeated faces in faceset helper duplicate removal

Port of #8772 to v0.9.0 (open_cascade_kernel::faceset_helper is the
renamed class, same logic). When an IfcConnectedFaceSet repeats the
same IfcFace, wires() still dropped every occurrence via duplicates_,
leaving a hole in the shell; this counts the redundant occurrences
and skips only those, keeping one copy of each repeated face.
This commit is contained in:
Petru Conduraru
2026-08-30 14:16:30 +03:00
committed by Thomas Krijnen
parent 66bcddc277
commit 1207338fa9
2 changed files with 7 additions and 1 deletions
@@ -108,6 +108,7 @@ ifcopenshell::geom::open_cascade_kernel::faceset_helper::faceset_helper(
vertex_mapping_.clear();
duplicates_.clear();
duplicate_skips_remaining_.clear();
edge_use.clear();
@@ -175,6 +176,7 @@ ifcopenshell::geom::open_cascade_kernel::faceset_helper::faceset_helper(
if (edge_sets.find(edge_set_key) != edge_sets.end()) {
duplicate_faces++;
duplicates_.insert(loop->identity());
duplicate_skips_remaining_[loop->identity()]++;
continue;
}
edge_sets.insert(edge_set_key);
@@ -251,7 +253,10 @@ bool ifcopenshell::geom::open_cascade_kernel::faceset_helper::wire(const ifcopen
}
bool ifcopenshell::geom::open_cascade_kernel::faceset_helper::wires(const ifcopenshell::geom::taxonomy::loop::ptr loop, NCollection_List<TopoDS_Shape>& wires) {
if (duplicates_.find(loop->identity()) != duplicates_.end()) {
// Skip only the redundant occurrences, keep one copy of the face.
auto it = duplicate_skips_remaining_.find(loop->identity());
if (it != duplicate_skips_remaining_.end() && it->second > 0) {
--it->second;
return false;
}
TopoDS_Wire wire;
@@ -86,6 +86,7 @@ private:
private:
open_cascade_kernel* kernel_;
std::set<int> duplicates_;
std::map<int, int> duplicate_skips_remaining_;
std::map<int, int> vertex_mapping_;
std::map<std::pair<int, int>, TopoDS_Edge> edges_;
double eps_;