CGAL实现Hole Filling(补洞)功能
Posted 烨烨烨烨
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CGAL实现Hole Filling(补洞)功能相关的知识,希望对你有一定的参考价值。
CGAL提供强大的算法,支持很多功能,我用的是4.8版本,具体的功能可以上网在手册上查。
这里提供今天用到的这个Hole Filling功能的手册链接:http://doc.cgal.org/latest/Polygon_mesh_processing/group__hole__filling__grp.html
CGAL 中补洞大概分了四个步骤:(这些官网的文档里都有写)
- triangulate_hole_polyline() : given a sequence of points defining the hole, triangulates the hole.
- triangulate_hole() : given a border halfedge on the boundary of the hole on a mesh, triangulates the hole.
- triangulate_and_refine_hole() : in addition to triangulate_hole() the generated patch is refined.
- triangulate_refine_and_fair_hole() : in addition to triangulate_and_refine_hole() the generated patch is also faired.
新建工程之后配置CGAL库,官网上也给了样例去调用这些函数。在你安装CGAL的文件夹中就可以找到这些example。例如我的(C:\\dev\\CGAL-4.8\\examples\\Polygon_mesh_processing)
data文件夹中是样例中输入的各种文件。
我们发现hole_filling的.cpp一共有三个,第一个是基于CGAL的,第二个是基于openmesh和CGAL的。
区别在于,第一个要求输入文件只能是.off文件,而第二个可以运行其他类型的文件。我们这次需要补洞的多边形网格文件是.obj文件,所以用了第二个。
由于基于OpenMesh,所以要配置openmesh:
从www.epenmesh.org下载最新版的安装包或者源代码,注意下载与自己系统匹配的版本。直接打开下一步安装就行。
在工程的包含目录,引用目录和链接器-->输入分别添加:
包含目录:openmesh安装路径\\include
引用目录:openmesh安装路径\\lib
链接器-->输入:
OpenMeshCore.lib
OpenMeshCored.lib
OpenMeshTools.lib
OpenMeshToolsd.lib
在工程中运行这个.cpp,发现编译报错,是因为没有配置EIGEN库。这是一个矩阵算法的库,可以方便的进行矩阵计算。
CGAL4.8支持的是EIGEN3以上的版本,下载的时候要注意。这个库需要自己编译一下。然后再配置到工程中。最后在代码中添加:
#define CGAL_EIGEN3_ENABLED
这个#define必须在代码最开始的地方写。
最后附上代码:
#define CGAL_EIGEN3_ENABLED
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
#include <CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h>
#include <CGAL/Polygon_mesh_processing/triangulate_hole.h>
#include <CGAL/boost/graph/helpers.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <boost/foreach.hpp>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef OpenMesh::PolyMesh_ArrayKernelT< > Mesh;
typedef boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor;
typedef boost::graph_traits<Mesh>::face_descriptor face_descriptor;
int main(int argc, char* argv[])
const char* filename = (argc > 1) ? argv[1] : "data/merge.obj";
Mesh mesh;
OpenMesh::IO::read_mesh(mesh, filename);
// Incrementally fill the holes
unsigned int nb_holes = 0;
BOOST_FOREACH(halfedge_descriptor h, halfedges(mesh))
if(CGAL::is_border(h,mesh))
std::vector<face_descriptor> patch_facets;
std::vector<vertex_descriptor> patch_vertices;
bool success = CGAL::cpp11::get<0>(
CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole(
mesh,
h,
std::back_inserter(patch_facets),
std::back_inserter(patch_vertices),
CGAL::Polygon_mesh_processing::parameters::vertex_point_map(get(CGAL::vertex_point, mesh)).
geom_traits(Kernel())) );
CGAL_assertion(CGAL::is_valid_polygon_mesh(mesh));
std::cout << "* FILL HOLE NUMBER " << ++nb_holes << std::endl;
std::cout << " Number of facets in constructed patch: " << patch_facets.size() << std::endl;
std::cout << " Number of vertices in constructed patch: " << patch_vertices.size() << std::endl;
//std::cout << " Is fairing successful: " << success << std::endl;
CGAL_assertion(CGAL::is_valid_polygon_mesh(mesh));
std::cout << std::endl;
std::cout << nb_holes << " holes have been filled" << std::endl;
OpenMesh::IO::write_mesh(mesh, "merge_done.obj");
return 0;
以上是关于CGAL实现Hole Filling(补洞)功能的主要内容,如果未能解决你的问题,请参考以下文章