如何在CGAL的SurfaceMesh中获取最长边界的全部顶点与半边边
获取CGAL SurfaceMesh最长边界的完整顶点/半边链
嘿,这个问题我之前处理网格边界的时候也踩过坑!CGAL::Polygon_mesh_processing::longest_border确实只返回边界链的起始半边,但要拿到完整的边界,只需要顺着CGAL的边界半边循环遍历就行——因为边界在CGAL里是一个闭合的半边序列,从起始半边出发,不断取下一个半边,就能绕完整条边界。
步骤1:获取最长边界的起始半边
首先调用longest_border拿到起始半边,记得先判断网格是否存在边界(比如封闭网格就没有边界):
#include <CGAL/Polygon_mesh_processing/border.h> #include <CGAL/Surface_mesh.h> #include <vector> #include <iostream> // 定义你的网格类型 typedef CGAL::Surface_mesh<CGAL::Simple_cartesian<double>::Point_3> Mesh; typedef boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor; typedef Mesh::Vertex_index Vertex_index; int main() { Mesh mesh; // 这里加载你的网格数据,比如从OBJ文件读取: // CGAL::IO::read_obj("your_mesh.obj", mesh); // 获取最长边界的起始半边 halfedge_descriptor longest_he = CGAL::Polygon_mesh_processing::longest_border(mesh); // 检查是否存在边界(封闭网格会返回null_halfedge) if (longest_he == boost::graph_traits<Mesh>::null_halfedge()) { std::cerr << "Mesh has no borders!" << std::endl; return 1; }
步骤2:收集完整的边界半边链
从起始半边开始,不断调用next()方法,直到回到起始半边,就能收集到整条边界的所有半边:
std::vector<halfedge_descriptor> border_halfedges; halfedge_descriptor current_he = longest_he; do { border_halfedges.push_back(current_he); current_he = next(current_he, mesh); } while (current_he != longest_he);
步骤3:转换为边界顶点列表
如果需要顶点,只需要从每个半边中提取source()顶点即可。注意闭合边界的首尾顶点会重复,你可以选择去掉最后一个:
std::vector<Vertex_index> border_vertices; for (auto he : border_halfedges) { border_vertices.push_back(source(he, mesh)); } // 移除重复的首尾顶点(如果是闭合边界) if (!border_vertices.empty() && border_vertices.front() == border_vertices.back()) { border_vertices.pop_back(); } // 现在border_halfedges和border_vertices就是最长边界的全部半边和顶点了 return 0; }
小提示
- 如果你需要按反向顺序获取顶点,也可以替换
source()为target(),半边的方向决定了顶点的遍历顺序。 - 不管网格是开口还是封闭的边界,这种遍历方式都能正常工作——CGAL会把边界处理成闭合的半边环。
内容的提问来源于stack exchange,提问作者Hardik Jain
相关产品推荐
相关产品推荐

