下面是我用来计算两个多面体与cgal的交集的代码。我知道它很大,但我已经尽了最大的努力。
这段代码适用于一个示例,但对于下面包含的示例,它会崩溃。编译运行良好,但当我运行可执行文件时,它会崩溃。当我从Haskell运行它时,我会得到错误消息“读取xxx时生成的代码中的访问冲突”(其中xxx是一个地址)。
该程序首先建立了两个多面体P1和P2。这一步没问题。然后,当程序到达这一行时,就会出现问题:
Nef_polyhedron nef1(P1);如果能帮我弄清楚发生了什么,我将不胜感激。
#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;
}发布于 2018-02-16 15:24:11
两者都调用P1.is_valid()和P2.is_valid()返回false。看来你的输入多面体是无效的。
我建议您尝试使用更用户友好的polygon_soup_to_polygon_mesh()函数来创建多面体。
此外,您可能希望直接使用Surface_mesh和多边形网格处理包中可用的布尔操作。见这里。
https://stackoverflow.com/questions/48828281
复制相似问题