您的位置:首页 > 编程语言 > C语言/C++

CGAL【1】实现Hole Filling(补洞)功能

2016-06-07 13:21 661 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息