如何通过删除 "free faces" 从非流形中提取底层 2-流形?

How to extract the underlying 2-manifold from a non-manifold by deleting "free faces"?

我正在尝试从非流形网格中提取底层的 2-流形(封闭曲面)。我将 CGAL 用于网格 manipulation.I 想通过删除 'free faces' 来实现。我的意思是,自由面的至少一个边缘是边界 edge.Deleting 自由面最终可能会创建新 'free faces'。我想继续删除它们,除非没有面有边界 edge.For 例如,如果我有一个 2 球体和一个鳍状结构附加到它上面,我想通过删除鳍的所有面来获得 2 球体.

在 CGAL 中,我不断迭代半边,如果我得到一个与 is_border 相反的半边,我删除面部事件(更精确地使用 make_hole(h) ), 到半边。当无法删除时,我会继续迭代。

typedef CGAL::Exact_predicates_inexact_constructions_kernel I;
typedef CGAL::Polyhedron_3<I> Polyhedron;
Polyhedron mesh;

//
int in_this_iter = 0;
    do {
        in_this_iter = 0;
        for (auto h = mesh.halfedges_begin(); h != mesh.halfedges_end(); h++) {
            //cout << e->is_border() << endl;

            if (h->opposite()->is_border() && !h->is_border()) {
                mesh.make_hole(h);
                /*CGAL::Euler::remove_face(h,mesh);
                *gives trouble*/
                in_this_iter++;
            }
            else if (h->is_border() && !h->opposite()->is_border()) {
                mesh.make_hole(h->opposite());

                in_this_iter++;
            }

        }
        //mesh.normalize_border();
        count = count + in_this_iter;
        std::cout << "Face Deleted in this iter: " << in_this_iter<<endl;
    } while (in_this_iter != 0);
    std::cout << "Face Deleted: " << count<<endl;

我正在测试的结构是:

OFF
7 8 0
0.0 0.0 0.0
1.0 0.0 0.0
2.0 0.0 0.0
0.0 1.0 0.0
1.0 1.0 0.0
2.0 1.0 0.0
0.0 0.0 1.0
3 0 1 3
3 3 1 4
3 1 4 2
3 2 4 5
3 1 2 4
3 3 1 6
3 3 4 6
3 1 4 6

我的算法不会删除任何空闲面孔。但理想的应该是捕获四面体的 4 个面并删除其他面。 P.S: 感谢您的帮助!如果我没有遵守礼仪,请原谅我,因为这是我的第一次 post.

您不应修改循环所依据的结构,因为结果可能出乎意料。相反,您可以简单地执行以下操作:

Find all faces that have an halfedge on the border
Put them in a stack
while(stack not empty)
  take the face 'f' top of the stack
  if('f' is already tagged)
    continue
  else
    tag 'f' as "to_be_removed"
    add all neighboring faces that are not already tagged to the stack
done
Remove all faces that were tagged "to_be_removed"

请注意,这大致就是 CGAL::PMP::connected_components functions are doing: they regroup all the faces of your structure in groups such that the faces of one group can all reach each other by walking from one face to another. What you could thus also do is to use these CGAL::PMP::connected_components functions to tag your faces in connected components, and then discard the connected components that do not form a closed mesh. You can find inspiration in the following function,其目标是将给定结构拆分为独立连接的组件。这将是您代码的第一步;然后,您的第二步是查看网格是否已关闭 (CGAL::is_closed())。