如何使用 CGAL 获取多边形网格的顶点和面?

How to get the vertices and the faces of a polygon mesh with CGAL?

使用 CGAL,我可以得到 OFF 格式的多面体网格。例如,下面的程序构建了两个四面体,计算它们的交点,并将结果 returns 保存在 OFF 文件中。 OFF 输出提供顶点坐标和顶点索引给出的面。

但我想获取顶点和面作为 C++ 变量(例如 double 顶点向量和 int 面向量)。这可能吗?如何实现?

当然我可以从 OFF 文件中提取我想要的内容,但可能有更好的方法。

#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Nef_polyhedron_3.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/boost/graph/convert_nef_polyhedron_to_polygon_mesh.h>
#include <iostream>
#include <sstream>
#include <fstream>
typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_kernel;
typedef CGAL::Polyhedron_3<Exact_kernel>                  Polyhedron;
typedef CGAL::Surface_mesh<Exact_kernel::Point_3>         Surface_mesh;
typedef CGAL::Nef_polyhedron_3<Exact_kernel>              Nef_polyhedron;
typedef Exact_kernel::Point_3                             Point_3;

int main() {
    double phi = (1+sqrt(5))/2;
    double a = 1/sqrt(3);
    double b = a/phi;
    double c = a*phi;

    Point_3 p1( 0, b, c);
    Point_3 q1( b, -c, 0);
    Point_3 r1( a, a, -a);
    Point_3 s1( -c, 0, -b);
    Polyhedron P1;
    P1.make_tetrahedron( p1, q1, r1, s1);

    Point_3 p2( a, -a, -a);
    Point_3 q2( a, a, a);
    Point_3 r2( -a, -a, a);
    Point_3 s2( -a, a, -a);
    Polyhedron P2;
    P2.make_tetrahedron( p2, q2, r2, s2);

    Nef_polyhedron nef1(P1);
    Nef_polyhedron nef2(P2);
    /* compute the intersection */
    Nef_polyhedron nef = nef1*nef2;

    Surface_mesh smesh;
    CGAL::convert_nef_polyhedron_to_polygon_mesh(nef, smesh);

    std::ofstream outfile;
    outfile.open("output.off");
    outfile << smesh;
    outfile.close();
}

好吧,我终于成功了。我 post 一个答案,以防对某人有帮助。

顶点

#include <CGAL/Gmpq.h>

typedef Surface_mesh::Vertex_index vertex_descriptor;

double gmpq2double(CGAL::Gmpq r){
  return r.numerator().to_double()/r.denominator().to_double();
}

  printf("Number of vertices: %d\n", smesh.number_of_vertices());
  double** vertices = (double**)malloc(smesh.number_of_vertices() * sizeof(double*));
  std::cout << "Iterate over vertices\n";
  {
    unsigned i_vertex = 0;
    BOOST_FOREACH(vertex_descriptor vd, smesh.vertices()){
      std::cout << smesh.point(vd) << std::endl;
      vertices[i_vertex] = (double*)malloc(3 * sizeof(double));
      for(unsigned k=0; k < 3; k++){
        vertices[i_vertex][k] = gmpq2double(smesh.point(vd)[k].exact());
      }
      i_vertex++;
    } 
  }

面孔

这不完全是我的代码,我还没有测试过这个。无论如何它给出了想法。

typedef Surface_mesh::Face_index face_descriptor;

  printf("Number of faces: %d\n", smesh.number_of_faces());
  std::vector<unsigned>* faces = new std::vector<unsigned>[smesh.number_of_faces()];
  std::cout << "Iterate over faces\n";
  {
    unsigned i_face = 0;
    BOOST_FOREACH(face_descriptor fd, smesh.faces()){
      BOOST_FOREACH(vertex_descriptor vd, vertices_around_face(smesh.halfedge(fd), smesh)){
        printf("vertex: %u\n", vd);
        faces[i_face].push_back(vd);
      }
      i_face++;
    }
  }

奖金:边缘

typedef Surface_mesh::Edge_index edge_descriptor;

  printf("Number of edges: %d\n", smesh.number_of_edges());
  unsigned** edges = (unsigned**)malloc(smesh.number_of_edges() * sizeof(unsigned*));
  std::cout << "Iterate over edges\n";
  {
    unsigned i_edge = 0;
    BOOST_FOREACH(edge_descriptor ed, smesh.edges()){
      edges[i_edge] = (unsigned*)malloc(2 * sizeof(unsigned));
      edges[i_edge][0] = source(ed,smesh);
      edges[i_edge][1] = target(ed,smesh);
      i_edge++;
    }
  }