我正在尝试从非流形网格中提取底层的2流形(闭合表面)。我正在使用CGAL进行网格处理,我想通过删除``自由面''来实现这一目的,我的意思是指至少一个边为边界边的面,最终删除一个自由面可能会创建新的``自由面'' 。我想一直删除它们,除非没有面有边界边缘。例如,如果我有一个2球体和一个类似鳍的结构,我想通过删除鳍的所有面来获得2球体。 / p>
在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
我的算法不会删除任何自由面孔。但是理想的一个应该捕获四面体的四个面,而删除其他面。 附注:感谢您的帮助!如果我不遵守礼节,请原谅我,因为这是我的第一篇文章。
答案 0 :(得分:0)
您不应该修改循环的结构,因为结果可能是意外的。相反,您可以简单地执行以下操作:
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()
)。