Improvements to faceset_helper in case of nearby verts

This commit is contained in:
Thomas Krijnen
2018-11-30 11:08:19 +01:00
parent b48d17c690
commit 4f8b430040
3 changed files with 39 additions and 10 deletions
+7 -5
View File
@@ -166,22 +166,24 @@ private:
bool wire(const IfcSchema::IfcPolyLoop* loop, TopoDS_Wire& wire) { bool wire(const IfcSchema::IfcPolyLoop* loop, TopoDS_Wire& wire) {
BRep_Builder builder; BRep_Builder builder;
builder.MakeWire(wire); builder.MakeWire(wire);
bool valid; int count = 0;
auto ps = loop->Polygon(); auto ps = loop->Polygon();
loop_(ps, [this, &builder, &wire, &valid](int A, int B, bool fwd) { loop_(ps, [this, &builder, &wire, &count](int A, int B, bool fwd) {
TopoDS_Edge e; TopoDS_Edge e;
if (edge(A, B, e)) { if (edge(A, B, e)) {
if (!fwd) { if (!fwd) {
e.Reverse(); e.Reverse();
} }
builder.Add(wire, e); builder.Add(wire, e);
valid = true; count += 1;
} }
}); });
if (valid) { if (count >= 3) {
wire.Closed(true); wire.Closed(true);
return true;
} else {
return false;
} }
return valid;
} }
}; };
+5 -1
View File
@@ -179,7 +179,11 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) {
TopoDS_Wire wire; TopoDS_Wire wire;
if (faceset_helper_ && loop->as<IfcSchema::IfcPolyLoop>()) { if (faceset_helper_ && loop->as<IfcSchema::IfcPolyLoop>()) {
faceset_helper_->wire(loop->as<IfcSchema::IfcPolyLoop>(), wire); if (!faceset_helper_->wire(loop->as<IfcSchema::IfcPolyLoop>(), wire)) {
Logger::Message(Logger::LOG_WARNING, "Face boundary loop not included", loop);
delete mf;
return false;
}
} else if (!convert_wire(loop, wire)) { } else if (!convert_wire(loop, wire)) {
Logger::Message(Logger::LOG_ERROR, "Failed to process face boundary loop", loop); Logger::Message(Logger::LOG_ERROR, "Failed to process face boundary loop", loop);
delete mf; delete mf;
+27 -4
View File
@@ -3506,6 +3506,8 @@ namespace {
std::vector<int> js = tree.select_box(b, false); std::vector<int> js = tree.select_box(b, false);
for (int j : js) { for (int j : js) {
if (visited.find(j) == visited.end()) { if (visited.find(j) == visited.end()) {
// @todo, making this recursive removes the dependence on the initial ordering, but will
// likely result in empty results when all vertices are within 1 eps from another point.
find_neighbours(tree, pnts, visited, j, eps); find_neighbours(tree, pnts, visited, j, eps);
} }
} }
@@ -3527,7 +3529,7 @@ IfcGeom::Kernel::faceset_helper::faceset_helper(Kernel* kernel, const IfcSchema:
BRep_Builder B; BRep_Builder B;
const double eps = kernel->getValue(GV_PRECISION); const double eps = kernel->getValue(GV_PRECISION) * 10.;
IfcGeom::impl::tree<int> tree; IfcGeom::impl::tree<int> tree;
{ {
int i = 0; int i = 0;
@@ -3549,23 +3551,44 @@ IfcGeom::Kernel::faceset_helper::faceset_helper(Kernel* kernel, const IfcSchema:
for (int v : vs) { for (int v : vs) {
if (v <= i) { if (v <= i) {
auto pt = *(points->begin() + v); auto pt = *(points->begin() + v);
vertex_mapping_.insert({pt->data().id(), i}); vertex_mapping_[pt->data().id()] = i;
} }
} }
} }
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;
for (auto& loop : *loops) { for (auto& loop : *loops) {
auto ps = loop->Polygon(); auto ps = loop->Polygon();
loop_(ps, [&edge_use](int C, int D, bool) {
edge_use[{C, D}] ++; std::vector<std::pair<int, int> > segments;
loop_(ps, [&segments](int C, int D, bool) {
segments.push_back({ C, D });
}); });
if (segments.size() >= 3) {
for (auto& p : segments) {
edge_use[p] ++;
}
} else {
loops_removed += 1;
}
} }
for (auto& p : edge_use) { for (auto& p : edge_use) {
int a, b; int a, b;
std::tie(a, b) = p.first; std::tie(a, b) = p.first;
edges_[p.first] = BRepBuilderAPI_MakeEdge(vertices[a], vertices[b]); edges_[p.first] = BRepBuilderAPI_MakeEdge(vertices[a], vertices[b]);
if (p.second != 2) {
non_manifold += 1;
}
}
if (loops_removed || non_manifold) {
Logger::Error(boost::lexical_cast<std::string>(loops_removed) + " loops removed and " + boost::lexical_cast<std::string>(non_manifold) + " non-manifold edges for:", l);
} }
} }