mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 14:41:25 +00:00
Improvements to faceset_helper in case of nearby verts
This commit is contained in:
@@ -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;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user