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

Jam*_*mes 3 c++ mesh surface cgal

我有一个三角形的 CGAL 表面网格,其中有一些自相交的三角形,我试图将其删除以创建一个连续的 2 流形壳,最终用于打印。

我尝试使用此答案中的remove_self_intersection()autorefine_and_remove_self_intersections()。第一个仅删除了一些自相交,而第二个则完全删除了我的网格。

所以,我正在尝试自己的方法 - 我正在找到自交点,然后尝试删除它们。我尝试过使用低级别的remove_face,但之后无法检测到边框,因此我无法填补由此产生的漏洞。这个答案是指使用更高级别的欧拉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;
}
Run Code Online (Sandbox Code Playgroud)

Jam*_*mes 5

我删除自相交三角形的方法是积极删除相交的面以及附近的面并填充由此产生的孔。感谢 @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());
Run Code Online (Sandbox Code Playgroud)

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

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