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 中补洞大概分了四个步骤:(这些官网的文档里都有写)

  1. triangulate_hole_polyline() : given a sequence of points defining the hole, triangulates the hole.
  2. triangulate_hole() : given a border halfedge on the boundary of the hole on a mesh, triangulates the hole.
  3. triangulate_and_refine_hole() : in addition to triangulate_hole() the generated patch is refined.
  4. 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(补洞)功能的主要内容,如果未能解决你的问题,请参考以下文章

基于CGAL的Delaunay三角网应用

三维网格补洞算法(Poisson Method)

White Hole现场场记(步步实现个人博客社区,Django实战开发一)

CGAL:配置 《一》

(Water Filling)注水算法原理与实现

White Hole 开发实战阶段验收