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

时间:2018-02-15 14:33:21

标签: c++ computational-geometry cgal

使用CGAL,我能够以OFF格式获得多面体网格。例如,下面的程序构建两个四面体,计算它们的交集,并将结果返回到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();
}

1 个答案:

答案 0 :(得分:0)

好吧,我终于成功了。我发布了一个答案,以防它可以帮助某人。

顶点

#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++;
    }
  }