代码实践篇二 如何提取曲面外边界?
简述思路
借助CGAL几何库,分为以下步骤:
- 曲面为surface mesh类型,因为要polygon processing接口,其他格式可以用copy_face_graph转换;
- 利用extract_boundary_cycles接口检测hole是否等于1,不等于返回;
- 根据border_halfedges接口提取边界半边halfedge_descriptor
- 解析返回的std::vector<halfedge_descriptor>生成polyline3d返回。
问题
- 检测hole等于1是为了简化处理
- 利用map的key和value将每个半边的source和target组织起来,一是为了排序,
另一个是边界可能出现环,自交等异常情况,并没有处理异常,而是根据有序性将原本可能的异常结果返回; - 如果需要处理多孔的情况的内外边界以及处理边界异常自行处理,后续会单独介绍解决方案。
接口原型
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h>
#include <CGAL/Polygon_mesh_processing/border.h>
#include <CGAL/Vector_3.h>
#include <CGAL/Surface_mesh.h>
namespace PMP = CGAL::Polygon_mesh_processing;
using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
using Point_3 = Kernel::Point_3;
using Mesh = CGAL::Surface_mesh<Kernel::Point_3>;
using Polyline3D = std::vector<Point_3>;
bool TriangulateByPolyline(Polyline3D& polyline, Mesh& outmesh);
代码
bool TriangulateByPolyline(Polyline3D& polyline, Mesh& outmesh)
{
using Vertex_index = Mesh::Vertex_index;
typedef CGAL::Triple<int, int, int> Triangle_int;
std::vector<Triangle_int> patch;
PMP::triangulate_hole_polyline(
polyline,
std::back_inserter(patch));
for (auto& p : polyline)
{
outmesh.add_vertex(p);
}
if (patch.size() == 0)
{
return false;
}
for (auto& f : patch)
{
outmesh.add_face(Vertex_index(f.first), Vertex_index(f.second), Vertex_index(f.third));
}
return true;
}