首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当将多面体转换为nef时,CGAL崩溃(访问冲突)

当将多面体转换为nef时,CGAL崩溃(访问冲突)
EN

Stack Overflow用户
提问于 2018-02-16 13:52:08
回答 1查看 577关注 0票数 0

下面是我用来计算两个多面体与cgal的交集的代码。我知道它很大,但我已经尽了最大的努力。

这段代码适用于一个示例,但对于下面包含的示例,它会崩溃。编译运行良好,但当我运行可执行文件时,它会崩溃。当我从Haskell运行它时,我会得到错误消息“读取xxx时生成的代码中的访问冲突”(其中xxx是一个地址)。

该程序首先建立了两个多面体P1P2。这一步没问题。然后,当程序到达这一行时,就会出现问题:

代码语言:javascript
复制
  Nef_polyhedron nef1(P1);

如果能帮我弄清楚发生了什么,我将不胜感激。

代码语言:javascript
复制
#include <vector>
#include <fstream>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Polyhedron_incremental_builder_3.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>
#include <CGAL/Nef_polyhedron_3.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/boost/graph/convert_nef_polyhedron_to_polygon_mesh.h>

typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef CGAL::Polyhedron_3<Kernel>                        Polyhedron;
typedef Polyhedron::HalfedgeDS                            HalfedgeDS;
typedef CGAL::Surface_mesh<Kernel::Point_3>               Surface_mesh;
typedef CGAL::Nef_polyhedron_3<Kernel, CGAL::SNC_indexed_items> Nef_polyhedron;


// helper functions to convert arrays to vectors
std::vector<int> iarray2vector(int* array, size_t n){
  std::vector<int> out;
  for(size_t i=0; i<n; i++){
      out.push_back(array[i]);
  }
  return out;
}
std::vector<double> darray2vector(double* array, size_t n){
  std::vector<double> out;
  for(size_t i=0; i<n; i++){
      out.push_back(array[i]);
  }
  return out;
}


// A modifier creating a polyhedron with the incremental builder.
class polyhedron_builder : public CGAL::Modifier_base<HalfedgeDS> {
public:
  std::vector<double> &coords;
  std::vector<int>    &faces;
  std::vector<int>    &facesizes;
  polyhedron_builder(
    std::vector<double> &_coords,
    std::vector<int> &_faces,
    std::vector<int> &_facesizes
  ) : coords(_coords), faces(_faces), facesizes(_facesizes) {}
  void operator()( HalfedgeDS& hds) {
    typedef typename HalfedgeDS::Vertex   Vertex;
    typedef typename Vertex::Point        Point;
    /* create a cgal incremental builder */
    CGAL::Polyhedron_incremental_builder_3<HalfedgeDS> B( hds, true);
    B.begin_surface( coords.size()/3, faces.size()); 
      /* add the polyhedron vertices */
      for(int i=0; i<(int)coords.size(); i+=3){
        B.add_vertex( Point( coords[i+0], coords[i+1], coords[i+2] ) );
      }
      /* add the polyhedron faces */
      int i=0;
      for(int k=0; k<(int)facesizes.size(); k++){
        int fs = facesizes[k];
        B.begin_facet();
        for(int j=0; j<fs; j++){
          B.add_vertex_to_facet( faces[i+j] );
        }
        B.end_facet();
        i += fs;
      }
    /* finish up the surface */
    B.end_surface();
  }
};


Polyhedron buildPolyhedron(
  double* vertices,
  size_t nvertices,
  int* faces,
  int* facesizes,
  size_t nfaces)
{
  /* calculate length of `faces`*/
  size_t l = 0;
  for(size_t i=0; i < nfaces; i++){
    l += facesizes[i];
  }
  /* make vectors from arrays */
  std::vector<double> vs = darray2vector(vertices, 3*nvertices);
  std::vector<int> fs = iarray2vector(faces, l);
  std::vector<int> fzs = iarray2vector(facesizes, nfaces);
  /* build the polyhedron */
  Polyhedron P;
  polyhedron_builder builder(vs, fs, fzs);
  P.delegate( builder );
  /**/
  return P;
}

void intersectPolyhedra(Polyhedron P1, Polyhedron P2){
  /* convert polyhedra to nefs */
  printf("make nef1\n");
  Nef_polyhedron nef1(P1);
  printf("make nef2\n");
  Nef_polyhedron nef2(P2);
  /* compute the intersection */
  printf("make nefs intersection\n");
  Nef_polyhedron nef = nef1*nef2;
  /* surface mesh */
  Surface_mesh smesh;
  CGAL::convert_nef_polyhedron_to_polygon_mesh(nef, smesh);
  /* write OFF file */
  std::ofstream outfile;
  outfile.open("intersection.off");
  outfile << smesh;
  outfile.close();
}

void intersectionTwoPolyhedra(
  double* vertices1,
  size_t nvertices1,
  int* faces1,
  int* facesizes1,
  size_t nfaces1,
  double* vertices2,
  size_t nvertices2,
  int* faces2,
  int* facesizes2,
  size_t nfaces2)
{
  printf("build P1\n");
  Polyhedron P1 = buildPolyhedron(vertices1, nvertices1, faces1, facesizes1, nfaces1);
  printf("P1 is closed: %u\n", P1.is_closed());
  std::cout << P1;
  printf("build P2\n");
  Polyhedron P2 = buildPolyhedron(vertices2, nvertices2, faces2, facesizes2, nfaces2);
  printf("P2 is closed: %u\n", P2.is_closed());
  std::cout << P2;
  printf("run intersection\n");
  intersectPolyhedra(P1, P2);
}


int main(){
    double x = (1 + sqrt(5))/2;
    double y = x - 1;
    double vertices[60] = { -1, 1, 1,
                            0, y, x,
                            y, x, 0,
                            -y, x, 0,
                            0, y, -x,
                            0, -y, x,
                            1, -1, 1,
                            x, 0, y,
                            1, 1, 1,
                            1, 1, -1,
                            x, 0, -y,
                            y, -x, 0,
                            1, -1, -1,
                            -1, -1, 1,
                            -x, 0, y,
                            -1, 1, -1,
                            -x, 0, -y,
                            -1, -1, -1,
                            -y, -x, 0,
                            0, -y, -x };
    int faces1[24] = { 3,1,7,9,
                       1,3,16,13,
                       9,19,16,3,
                       16,19,11,13,
                       1,13,11,7,
                       9,7,11,19 };
    int faces2[24] = { 2,4,16,0,
                       2,7,12,4,
                       2,0,5,7,
                       4,12,18,16,
                       0,16,18,5,
                       7,5,18,12 };
    int facesizes[6] = { 4, 4, 4, 4, 4, 4};

    intersectionTwoPolyhedra(
        vertices,
        20,
        faces1,
        facesizes,
        6,
        vertices,
        20,
        faces2,
        facesizes,
        6
    );

    return 0;
}
EN

回答 1

Stack Overflow用户

发布于 2018-02-16 15:24:11

两者都调用P1.is_valid()P2.is_valid()返回false。看来你的输入多面体是无效的。

我建议您尝试使用更用户友好的polygon_soup_to_polygon_mesh()函数来创建多面体。

此外,您可能希望直接使用Surface_mesh和多边形网格处理包中可用的布尔操作。见这里

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48828281

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档