Bootstrap

# 代码实践篇二 如何提取曲面外边界?

代码实践篇二 如何提取曲面外边界?

简述思路

借助CGAL几何库,分为以下步骤:

  1. 曲面为surface mesh类型,因为要polygon processing接口,其他格式可以用copy_face_graph转换;
  2. 利用extract_boundary_cycles接口检测hole是否等于1,不等于返回;
  3. 根据border_halfedges接口提取边界半边halfedge_descriptor
  4. 解析返回的std::vector<halfedge_descriptor>生成polyline3d返回。

问题

  1. 检测hole等于1是为了简化处理
  2. 利用map的key和value将每个半边的source和target组织起来,一是为了排序,
    另一个是边界可能出现环,自交等异常情况,并没有处理异常,而是根据有序性将原本可能的异常结果返回;
  3. 如果需要处理多孔的情况的内外边界以及处理边界异常自行处理,后续会单独介绍解决方案。

接口原型

#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;
}
;