如何在CGAL中获取尖锐边关联面并进行细化处理
从CGAL尖锐边获取关联面并计算连通分量
步骤1:收集尖锐边关联的所有面
遍历detect_sharp_edges返回的边映射/集合,提取每条尖锐边关联的有效面,用集合存储以避免重复(同一个面可能被多条尖锐边关联)。
假设你使用的是CGAL::Surface_mesh或类似支持半边结构的网格类型,代码示例如下:
#include <CGAL/Surface_mesh.h> #include <unordered_set> typedef CGAL::Surface_mesh<CGAL::Point_3<CGAL::Simple_cartesian<double>>> Mesh; typedef typename Mesh::edge_descriptor edge_descriptor; typedef typename Mesh::face_descriptor face_descriptor; typedef typename Mesh::halfedge_descriptor halfedge_descriptor; // 假设sharp_edges是detect_sharp_edges返回的结果:键为边描述符,值为是否是尖锐边 std::unordered_map<edge_descriptor, bool> sharp_edges = ...; Mesh mesh = ...; std::unordered_set<face_descriptor> sharp_associated_faces; for (const auto& edge_entry : sharp_edges) { const edge_descriptor e = edge_entry.first; const bool is_sharp = edge_entry.second; if (!is_sharp) continue; // 获取边对应的半边 halfedge_descriptor h = mesh.halfedge(e); // 添加半边关联的面(非边界边有效) if (face_descriptor f = mesh.face(h)) { sharp_associated_faces.insert(f); } // 获取对面的半边,添加其关联的面(非边界边有效) halfedge_descriptor opp_h = mesh.opposite(h); if (face_descriptor opp_f = mesh.face(opp_h)) { sharp_associated_faces.insert(opp_f); } }
步骤2:计算关联面的连通分量
如果需要类似connected_component的功能,可使用CGAL::Polygon_mesh_processing::connected_components,根据需求自定义连通性规则:
规则A:通过任意相邻边连通(常规面连通)
只要两个关联面共享一条边(无论是否为尖锐边),就归为同一分量:
#include <CGAL/Polygon_mesh_processing/connected_components.h> #include <vector> std::vector<std::vector<face_descriptor>> face_components; // 定义连通性谓词:检查两个面是否相邻 auto are_adjacent = [&mesh](face_descriptor f1, face_descriptor f2) { for (halfedge_descriptor h : mesh.halfedges_around_face(mesh.halfedge(f1))) { if (mesh.face(mesh.opposite(h)) == f2) { return true; } } return false; }; // 计算连通分量 CGAL::Polygon_mesh_processing::connected_components( sharp_associated_faces.begin(), sharp_associated_faces.end(), std::back_inserter(face_components), mesh, are_adjacent );
规则B:仅通过尖锐边连通
只有当两个关联面共享一条尖锐边时,才归为同一分量:
auto are_connected_via_sharp = [&mesh, &sharp_edges](face_descriptor f1, face_descriptor f2) { for (halfedge_descriptor h : mesh.halfedges_around_face(mesh.halfedge(f1))) { edge_descriptor e = mesh.edge(h); // 检查共享边是否为尖锐边,且对面是f2 if (sharp_edges.count(e) && sharp_edges.at(e) && mesh.face(mesh.opposite(h)) == f2) { return true; } } return false; }; CGAL::Polygon_mesh_processing::connected_components( sharp_associated_faces.begin(), sharp_associated_faces.end(), std::back_inserter(face_components), mesh, are_connected_via_sharp );
注意事项
- 确保你的网格类型支持半边、面的访问(如
CGAL::Polyhedron_3或CGAL::Surface_mesh),不同网格类型的API可能略有差异。 - 边界边仅关联一个面,代码中通过
mesh.face(h)的有效性判断过滤了无效的面描述符。 - 如果
sharp_edges是std::set<edge_descriptor>类型(仅存储尖锐边),遍历直接取每个edge_descriptor即可,无需判断is_sharp。
内容的提问来源于stack exchange,提问作者wagnifico
相关产品推荐
相关产品推荐

