You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 14:24:50