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

标签 c++ mesh cgal surface 3d-reconstruction

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

在 CGAL 中,我不断迭代半边,如果我得到一个半边,其对面是_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:感谢您的帮助!如果我没有遵守礼仪,请原谅我,因为这是我的第一篇文章。

最佳答案

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

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 的内容功能正在做:它们将结构的所有面重新组合成组,这样一组的面都可以通过从一张面走到另一面来相互接触。因此,您还可以做的是使用这些 CGAL::PMP::connected_components 函数在连接的组件中标记您的面孔,然后丢弃未形成闭合网格的连接组件。您可以在 the following function 中找到灵感,其目标是将给定结构拆分为独立的连接组件。这将是您代码的第一步;然后,您的第二步是查看网格是否已关闭 (CGAL::is_closed())。

关于c++ - 如何通过删除 "free faces"从非流形中提取底层 2-流形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56214403/

相关文章:

3d - 表面网格到体积网格

python - CGAL 的 python 绑定(bind)发生了什么?

c++ - "error: expected constructor, destructor, or type conversion before ' ( ' token"在 memset 调用的位置

c++ - 链接到 gcc 中的 boost 正则表达式

algorithm - 如何合并网格上相邻的共面面

rotation - CGAL:如何将一个 3D 矢量旋转到另一个矢量上?

c++ - CGAL - 如何使用 CGAL::Polygon_mesh_processing::connected_components 将一个 CGAL::Surface_mesh 转换为多个?

c++ - Lubuntu 中的 QT 控制台应用程序

c++ - 在OpenCV中调用stereoRectify会导致异常: invalid frame pointer

在网格上存储粒子位置的算法(链接网格)