Filter duplicate edge indices #3546

This commit is contained in:
Thomas Krijnen
2023-08-06 14:27:31 +08:00
parent c6438933ba
commit ee09f2404b
3 changed files with 18 additions and 12 deletions
+2 -4
View File
@@ -409,11 +409,9 @@ int IfcGeom::Representation::Triangulation::addVertex(int item_id, int material_
return i; return i;
} }
void IfcGeom::Representation::Triangulation::addEdge(int n1, int n2, std::map<std::pair<int, int>, int>& edgecount, std::vector<std::pair<int, int>>& edges_temp) { void IfcGeom::Representation::Triangulation::addEdge(int n1, int n2, std::map<std::pair<int, int>, int>& edgecount) {
const Edge e = Edge((std::min)(n1, n2), (std::max)(n1, n2)); const Edge e = Edge((std::min)(n1, n2), (std::max)(n1, n2));
if (edgecount.find(e) == edgecount.end()) edgecount[e] = 1; edgecount[e] ++;
else edgecount[e] ++;
edges_temp.push_back(e);
} }
const IfcGeom::ConversionResultShape* IfcGeom::Representation::BRep::item(int i) const { const IfcGeom::ConversionResultShape* IfcGeom::Representation::BRep::item(int i) const {
+1 -1
View File
@@ -195,7 +195,7 @@ namespace IfcGeom {
_edges.push_back(i1); _edges.push_back(i1);
} }
void addEdge(int n1, int n2, std::map<std::pair<int, int>, int>& edgecount, std::vector<std::pair<int, int> >& edges_temp); void addEdge(int n1, int n2, std::map<std::pair<int, int>, int>& edgecount);
void resetWelds() { void resetWelds() {
weld_offset_ += welds.size(); weld_offset_ += welds.size();
@@ -48,6 +48,10 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(ifcopenshell::geometr
); );
} }
// When welding vertices, vertex coords will be shared among faces so we need to per-shape set
// to keep track of which edges were already emitted.
std::set<std::pair<int, int>> emitted_edges;
// Triangulate the shape // Triangulate the shape
try { try {
BRepMesh_IncrementalMesh(shape_, settings.get<settings::MesherLinearDeflection>().get(), false, settings.get<settings::MesherAngularDeflection>().get()); BRepMesh_IncrementalMesh(shape_, settings.get<settings::MesherLinearDeflection>().get(), false, settings.get<settings::MesherAngularDeflection>().get());
@@ -70,7 +74,6 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(ifcopenshell::geometr
// Keep track of the number of times an edge is used // Keep track of the number of times an edge is used
// Manifold edges (i.e. edges used twice) are deemed invisible // Manifold edges (i.e. edges used twice) are deemed invisible
std::map<std::pair<int, int>, int> edgecount; std::map<std::pair<int, int>, int> edgecount;
std::vector<std::pair<int, int> > edges_temp;
std::vector<gp_XYZ> coords; std::vector<gp_XYZ> coords;
BRepGProp_Face prop(face); BRepGProp_Face prop(face);
@@ -142,14 +145,19 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(ifcopenshell::geometr
t->addFace(item_id, surface_style_id, dict[n1], dict[n2], dict[n3]); t->addFace(item_id, surface_style_id, dict[n1], dict[n2], dict[n3]);
t->addEdge(dict[n1], dict[n2], edgecount, edges_temp); t->addEdge(dict[n1], dict[n2], edgecount);
t->addEdge(dict[n2], dict[n3], edgecount, edges_temp); t->addEdge(dict[n2], dict[n3], edgecount);
t->addEdge(dict[n3], dict[n1], edgecount, edges_temp); t->addEdge(dict[n3], dict[n1], edgecount);
} }
for (std::vector<std::pair<int, int> >::const_iterator jt = edges_temp.begin(); jt != edges_temp.end(); ++jt) { for (auto& p : edgecount) {
if (edgecount[*jt] == 1) { // @todo should be != 2?
if (p.second == 1 && emitted_edges.find(p.first) == emitted_edges.end()) {
// non manifold edge, face boundary // non manifold edge, face boundary
t->registerEdge(jt->first, jt->second); t->registerEdge(p.first.first, p.first.second);
if (settings.get<settings::WeldVertices>().get()) {
// only relevant while welding, because otherwise vertices are not shared among distinct faces
emitted_edges.insert(p.first);
}
} }
} }
} }