mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-17 14:02:27 +00:00
Remove duplicate faces in faceset_helper. Fixes #600
This commit is contained in:
@@ -119,6 +119,7 @@ private:
|
|||||||
class faceset_helper {
|
class faceset_helper {
|
||||||
private:
|
private:
|
||||||
MAKE_TYPE_NAME(Kernel)* kernel_;
|
MAKE_TYPE_NAME(Kernel)* kernel_;
|
||||||
|
std::set<const IfcSchema::IfcPolyLoop*> duplicates_;
|
||||||
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_;
|
||||||
@@ -173,6 +174,9 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool wire(const IfcSchema::IfcPolyLoop* loop, TopoDS_Wire& wire) {
|
bool wire(const IfcSchema::IfcPolyLoop* loop, TopoDS_Wire& wire) {
|
||||||
|
if (duplicates_.find(loop) != duplicates_.end()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
BRep_Builder builder;
|
BRep_Builder builder;
|
||||||
builder.MakeWire(wire);
|
builder.MakeWire(wire);
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|||||||
@@ -4173,19 +4173,36 @@ IfcGeom::Kernel::faceset_helper::faceset_helper(Kernel* kernel, const IfcSchema:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @todo, there a tiny possibility that the duplicate faces are triggered
|
||||||
|
// for an internal boundary, that is also present as an external boundary.
|
||||||
|
// This will result in non-manifold configuration then, but this is deemed
|
||||||
|
// such as corner-case that it is not considered.
|
||||||
IfcSchema::IfcPolyLoop::list::ptr loops = IfcParse::traverse((IfcUtil::IfcBaseClass*)l)->as<IfcSchema::IfcPolyLoop>();
|
IfcSchema::IfcPolyLoop::list::ptr loops = IfcParse::traverse((IfcUtil::IfcBaseClass*)l)->as<IfcSchema::IfcPolyLoop>();
|
||||||
|
|
||||||
size_t loops_removed = 0, non_manifold = 0;
|
size_t loops_removed = 0, non_manifold = 0, duplicate_faces = 0;
|
||||||
|
|
||||||
|
typedef std::array<int, 2> edge_t;
|
||||||
|
typedef std::set<edge_t> edge_set_t;
|
||||||
|
std::set<edge_set_t> edge_sets;
|
||||||
|
|
||||||
for (auto& loop : *loops) {
|
for (auto& loop : *loops) {
|
||||||
auto ps = loop->Polygon();
|
auto ps = loop->Polygon();
|
||||||
|
|
||||||
std::vector<std::pair<int, int> > segments;
|
std::vector<std::pair<int, int> > segments;
|
||||||
|
edge_set_t segment_set;
|
||||||
|
|
||||||
loop_(ps, [&segments](int C, int D, bool) {
|
loop_(ps, [&segments, &segment_set](int C, int D, bool) {
|
||||||
|
segment_set.insert({ C, D });
|
||||||
segments.push_back({ C, D });
|
segments.push_back({ C, D });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (edge_sets.find(segment_set) != edge_sets.end()) {
|
||||||
|
duplicate_faces++;
|
||||||
|
duplicates_.insert(loop);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
edge_sets.insert(segment_set);
|
||||||
|
|
||||||
if (segments.size() >= 3) {
|
if (segments.size() >= 3) {
|
||||||
for (auto& p : segments) {
|
for (auto& p : segments) {
|
||||||
edge_use[p] ++;
|
edge_use[p] ++;
|
||||||
@@ -4206,6 +4223,6 @@ IfcGeom::Kernel::faceset_helper::faceset_helper(Kernel* kernel, const IfcSchema:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (loops_removed || (non_manifold && l->declaration().is(IfcSchema::IfcClosedShell::Class()))) {
|
if (loops_removed || (non_manifold && l->declaration().is(IfcSchema::IfcClosedShell::Class()))) {
|
||||||
Logger::Warning(boost::lexical_cast<std::string>(loops_removed) + " loops removed and " + boost::lexical_cast<std::string>(non_manifold) + " non-manifold edges for:", l);
|
Logger::Warning(boost::lexical_cast<std::string>(duplicate_faces) + " duplicate faces removed, " + boost::lexical_cast<std::string>(loops_removed) + " loops removed and " + boost::lexical_cast<std::string>(non_manifold) + " non-manifold edges for:", l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user