如何从 3D 表面网格中删除自相交三角形?

How do I remove self-intersecting triangles from a 3D surface mesh?

我有一个 CGAL surface_mesh 三角形,其中有一些自相交的三角形,我试图将其移除以创建一个连续的 2 流形 shell,最终用于打印。

我尝试使用 remove_self_intersection() and autorefine_and_remove_self_intersections() from this answer。第一个只删除了一些自交,而第二个完全删除了我的网格。

所以,我正在尝试我自己的方法 - 我发现 self-intersections and then attempting to delete them. I've tried using the low level remove_face but the borders are not detectable afterwards so I'm unable to fill the resulting holes. 指的是使用更高级别的 Euler remove_face 但是这种方法和 make_hole 似乎丢弃了完全是我的网格。

这是一个摘录(我正在使用 break 看看我是否可以删除至少一个三角形,我只是尝试删除一对中的第一个):

    vector<pair<face_descriptor, face_descriptor> > intersected_tris;
PMP::self_intersections(mesh, back_inserter(intersected_tris));
for (pair<face_descriptor, face_descriptor> &p : intersected_tris) {
    CGAL::Euler::remove_face(mesh.halfedge(get<0>(p)), mesh);
    break;
}

我删除自相交三角形的方法是积极删除相交的面以及附近的面并填充产​​生的孔。感谢@sloriot 的评论,我意识到 Euler::remove_face 函数失败是因为 self_intersections 和 expand_face_selection 函数返回的集合中有重复的面孔。

从这两个函数的矢量结果中删除重复面孔的快速方法是:

std::set<face_descriptor> s(selected_faces.begin(), selected_faces.end());
selected_faces.assign(s.begin(), s.end());

此代码将人脸向量转换为一个集合(集合不包含重复项),然后再次将集合转换回来。

删除重复项后,Euler::remove_face 函数可以正常工作,包括更新边界,以便可以在结果上使用 triangulate_hole 函数生成没有自相交的最终表面。