使用 CGAL isotropic_remeshing 进行约束细化

Do constrained refinement with CGAL isotropic_remeshing

我想细化例如一个简单的立方体(来自 .off);有几种方法,但适合我接下来要做的事情的方法以 'wrinkles' 结束,即对象形状变形。

下面的这种方式承诺允许保留对象的边界(形状?),允许您期望的细化,只添加更多的边和顶点:​​

http://doc.cgal.org/latest/Polygon_mesh_processing/Polygon_mesh_processing_2isotropic_remeshing_example_8cpp-example.html

我想要一个边约束图(如果这还不够,那么我也想要一个顶点约束图)但是无法很好地理解模板抽象。我尝试了来自不同 CGAL 示例的 OpenMesh Constrained_edge_map,但这太不同了,无法编译。我要的是一个边图,也许还有一个顶点图,我可以将其提供给调用:

PMP::isotropic_remeshing( faces(mesh), target_edge_length, mesh, PMP::parameters::number_of_iterations(nb_iter) .protect_constraints(true)//i.e. protect border, here );

我正在使用 CGAL 4.8.1,这是撰写本文时的最新版本。谢谢

这是重新划分三角立方体网格的最小示例:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/boost/graph/graph_traits_Surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/remesh.h>
#include <CGAL/Mesh_3/dihedral_angle_3.h>
#include <boost/foreach.hpp>

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Surface_mesh<K::Point_3>               Mesh;
typedef boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor;
typedef boost::graph_traits<Mesh>::edge_descriptor edge_descriptor;

namespace PMP=CGAL::Polygon_mesh_processing;

int main(int, char* argv[])
{
  std::ifstream input(argv[1]);
  Mesh tmesh;
  input >> tmesh;

  double target_edge_length = 0.20;
  unsigned int nb_iter = 10;

  // give each vertex a name, the default is empty
  Mesh::Property_map<edge_descriptor,bool> is_constrained =
    tmesh.add_property_map<edge_descriptor,bool>("e:is_constrained",false).first;

  //detect sharp features
  BOOST_FOREACH(edge_descriptor e, edges(tmesh))
  {
    halfedge_descriptor hd = halfedge(e,tmesh);
    if ( !is_border(e,tmesh) ){
      double angle = CGAL::Mesh_3::dihedral_angle(tmesh.point(source(hd,tmesh)),
                                                  tmesh.point(target(hd,tmesh)),
                                                  tmesh.point(target(next(hd,tmesh),tmesh)),
                                                  tmesh.point(target(next(opposite(hd,tmesh),tmesh),tmesh)));
      if ( CGAL::abs(angle)<100 )
        is_constrained[e]=true;
    }
  }

  //remesh
  PMP::isotropic_remeshing(
      faces(tmesh),
      target_edge_length,
      tmesh,
      PMP::parameters::number_of_iterations(nb_iter)
      .edge_is_constrained_map(is_constrained) );

  std::ofstream out("out.off");
  out << tmesh;
  return 0;
}