diff --git a/src/ifcgeom/kernels/opencascade/faceset_helper.cpp b/src/ifcgeom/kernels/opencascade/faceset_helper.cpp index b139c521c8..ee13448d90 100644 --- a/src/ifcgeom/kernels/opencascade/faceset_helper.cpp +++ b/src/ifcgeom/kernels/opencascade/faceset_helper.cpp @@ -108,7 +108,7 @@ ifcopenshell::geom::open_cascade_kernel::faceset_helper::faceset_helper( vertex_mapping_.clear(); duplicates_.clear(); - duplicate_skips_remaining_.clear(); + duplicate_identities_built_.clear(); edge_use.clear(); @@ -176,7 +176,6 @@ 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); @@ -253,11 +252,13 @@ 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& wires) { - // 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; + // A loop whose edge set duplicates another's is skipped. When the duplicates + // share one identity (the same IfcFace listed repeatedly, #418), set semantics + // keep exactly one copy: the first occurrence builds, the rest are skipped. + if (duplicates_.find(loop->identity()) != duplicates_.end()) { + if (!duplicate_identities_built_.insert(loop->identity()).second) { + return false; + } } TopoDS_Wire wire; BRep_Builder builder; diff --git a/src/ifcgeom/kernels/opencascade/opencascade_kernel.h b/src/ifcgeom/kernels/opencascade/opencascade_kernel.h index 6350f92b22..8fc43f8f23 100644 --- a/src/ifcgeom/kernels/opencascade/opencascade_kernel.h +++ b/src/ifcgeom/kernels/opencascade/opencascade_kernel.h @@ -86,7 +86,7 @@ private: private: open_cascade_kernel* kernel_; std::set duplicates_; - std::map duplicate_skips_remaining_; + std::set duplicate_identities_built_; std::map vertex_mapping_; std::map, TopoDS_Edge> edges_; double eps_;