mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 23:00:53 +00:00
ifcgeom: keep one copy of same-identity duplicate loops via set semantics
Adopt the reviewer's suggestion on #9396: instead of counting how many skips each duplicate identity has earned, record which duplicate identities have already built once. The first occurrence builds, the rest are skipped. Distinct-identity loops that only become duplicates after point mapping behave as before. Set semantics are also robust if the helper is ever driven over the same shell twice, where a consumed counter would under-build.
This commit is contained in:
committed by
Thomas Krijnen
parent
1207338fa9
commit
e4190a1636
@@ -108,7 +108,7 @@ ifcopenshell::geom::open_cascade_kernel::faceset_helper::faceset_helper(
|
|||||||
|
|
||||||
vertex_mapping_.clear();
|
vertex_mapping_.clear();
|
||||||
duplicates_.clear();
|
duplicates_.clear();
|
||||||
duplicate_skips_remaining_.clear();
|
duplicate_identities_built_.clear();
|
||||||
|
|
||||||
edge_use.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()) {
|
if (edge_sets.find(edge_set_key) != edge_sets.end()) {
|
||||||
duplicate_faces++;
|
duplicate_faces++;
|
||||||
duplicates_.insert(loop->identity());
|
duplicates_.insert(loop->identity());
|
||||||
duplicate_skips_remaining_[loop->identity()]++;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
edge_sets.insert(edge_set_key);
|
edge_sets.insert(edge_set_key);
|
||||||
@@ -253,12 +252,14 @@ 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) {
|
bool ifcopenshell::geom::open_cascade_kernel::faceset_helper::wires(const ifcopenshell::geom::taxonomy::loop::ptr loop, NCollection_List<TopoDS_Shape>& wires) {
|
||||||
// Skip only the redundant occurrences, keep one copy of the face.
|
// A loop whose edge set duplicates another's is skipped. When the duplicates
|
||||||
auto it = duplicate_skips_remaining_.find(loop->identity());
|
// share one identity (the same IfcFace listed repeatedly, #418), set semantics
|
||||||
if (it != duplicate_skips_remaining_.end() && it->second > 0) {
|
// keep exactly one copy: the first occurrence builds, the rest are skipped.
|
||||||
--it->second;
|
if (duplicates_.find(loop->identity()) != duplicates_.end()) {
|
||||||
|
if (!duplicate_identities_built_.insert(loop->identity()).second) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
TopoDS_Wire wire;
|
TopoDS_Wire wire;
|
||||||
BRep_Builder builder;
|
BRep_Builder builder;
|
||||||
builder.MakeWire(wire);
|
builder.MakeWire(wire);
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
open_cascade_kernel* kernel_;
|
open_cascade_kernel* kernel_;
|
||||||
std::set<int> duplicates_;
|
std::set<int> duplicates_;
|
||||||
std::map<int, int> duplicate_skips_remaining_;
|
std::set<int> duplicate_identities_built_;
|
||||||
std::map<int, int> vertex_mapping_;
|
std::map<int, int> vertex_mapping_;
|
||||||
std::map<std::pair<int, int>, TopoDS_Edge> edges_;
|
std::map<std::pair<int, int>, TopoDS_Edge> edges_;
|
||||||
double eps_;
|
double eps_;
|
||||||
|
|||||||
Reference in New Issue
Block a user