Polyhedra generate_polyhedra_from_points(const std::vector<std::array<double,3> >& vertices) { std::vector<Point_3> points(vertices.size()); for(int i=0;i<(int)vertices.size();i++) points[i] = Point_3(vertices[i][0],vertices[i][1],vertices[i][2]); Polyhedron_3 poly; CGAL::convex_hull_3(points.begin(), points.end(), poly); std::transform(poly.facets_begin(), poly.facets_end(), poly.planes_begin(), Plane_from_facet()); for(Halfedge_iterator half=poly.halfedges_begin();half!=poly.halfedges_end();++half) { Point_3 v1 = half->vertex()->point(); Point_3 v2 = half->next()->vertex()->point(); Point_3 v3 = half->next()->next()->vertex()->point(); Point_3 v4 = half->opposite()->vertex()->point(); Point_3 v5 = half->opposite()->next()->vertex()->point(); Point_3 v6 = half->opposite()->next()->next()->vertex()->point(); if(coplanar_handmade(v1,v2,v3,v4)&&coplanar_handmade(v1,v2,v3,v5)&&coplanar_handmade(v1,v2,v3,v6)&& coplanar_handmade(v1,v2,v4,v5)&&coplanar_handmade(v1,v2,v4,v6)&&coplanar_handmade(v1,v2,v5,v6)&& coplanar_handmade(v1,v3,v4,v5)&&coplanar_handmade(v1,v3,v4,v6)&&coplanar_handmade(v1,v4,v5,v6)&& coplanar_handmade(v2,v3,v4,v5)&&coplanar_handmade(v2,v3,v4,v6)&&coplanar_handmade(v2,v3,v5,v6)&& coplanar_handmade(v2,v4,v5,v6)&&coplanar_handmade(v1,v3,v5,v6)&&coplanar_handmade(v3,v4,v5,v6)) { poly.join_facet(half); half=poly.halfedges_begin(); } } int cur = 0; for(auto it=poly.points_begin(); it!=poly.points_end(); it++, cur++) points[cur] = *it; cur = 0; std::vector<std::vector<int> > faces; for(Facet_iterator i=poly.facets_begin(); i!=poly.facets_end(); i++) { faces.push_back(std::vector<int>()); Halfedge_facet_circulator j = i->facet_begin(); do {faces[cur].push_back(std::distance(poly.vertices_begin(), j->vertex()));} while (++j != i->facet_begin()); cur++; } return Polyhedra{points,faces}; }
int main() { CGAL::Random_points_in_sphere_3<Point_3, PointCreator> gen(100.0); // generate 250 points randomly on a sphere of radius 100.0 // and copy them to a vector std::vector<Point_3> points; CGAL::cpp11::copy_n( gen, 250, std::back_inserter(points) ); // define polyhedron to hold convex hull Polyhedron_3 poly; // compute convex hull of non-collinear points CGAL::convex_hull_3(points.begin(), points.end(), poly); std::cout << "The convex hull contains " << poly.size_of_vertices() << " vertices" << std::endl; // assign a plane equation to each polyhedron facet using functor Plane_from_facet std::transform( poly.facets_begin(), poly.facets_end(), poly.planes_begin(),Plane_from_facet()); return 0; }
/* FIXME: Copied from Polyhedron_io.cpp with slight modifications. */ static std::shared_ptr<Polyhedron> convertWithAssociation(Polyhedron_3 p, const Point_3 &C, const std::vector<Plane_3> &initPlanes) { /* Check for non-emptiness. */ ASSERT(p.size_of_vertices()); ASSERT(p.size_of_facets()); int numVertices = p.size_of_vertices(); int numFacets = p.size_of_facets(); /* Allocate memory for arrays. */ Vector3d *vertices = new Vector3d[numVertices]; Facet *facets = new Facet[numFacets]; /* Transform vertexes. */ int iVertex = 0; for (auto vertex = p.vertices_begin(); vertex != p.vertices_end(); ++vertex) { Point_3 point = C + vertex->point(); vertices[iVertex++] = Vector3d(point.x(), point.y(), point.z()); } /* * Transform facets. * This algorithm is based on example kindly provided at CGAL online user * manual. See example Polyhedron/polyhedron_prog_off.cpp */ int iFacet = 0; auto plane = p.planes_begin(); auto facet = p.facets_begin(); /* Iterate through the std::lists of planes and facets. */ do { int id = p.indexPlanes_[iFacet]; facets[id].id = id; /* Transform current plane. */ Plane_3 pi = centerizePlane(*plane, Point_3(-C.x(), -C.y(), -C.z()), signedDist(initPlanes[id], C)); facets[id].plane = Plane(Vector3d(pi.a(), pi.b(), pi.c()), pi.d()); /* * Iterate through the std::list of halfedges incident to the curent CGAL * facet. */ auto halfedge = facet->facet_begin(); /* Facets in polyhedral surfaces are at least triangles. */ CGAL_assertion(CGAL::circulator_size(halfedge) >= 3); facets[id].numVertices = CGAL::circulator_size(halfedge); facets[id].indVertices = new int[3 * facets[id].numVertices + 1]; /* * TODO: It's too unsafe architecture if we do such things as setting * the size of internal array outside the API functions. Moreover, it * can cause us to write memory leaks. * indFacets and numFacets should no be public members. */ int iFacetVertex = 0; do { facets[id].indVertices[iFacetVertex++] = std::distance(p.vertices_begin(), halfedge->vertex()); } while (++halfedge != facet->facet_begin()); /* Add cycling vertex to avoid assertion during printing. */ facets[id].indVertices[facets[id].numVertices] = facets[id].indVertices[0]; ASSERT(facets[id].correctPlane()); /* Increment the ID of facet. */ ++iFacet; } while (++plane != p.planes_end() && ++facet != p.facets_end()); return std::make_shared<Polyhedron>(numVertices, numFacets, vertices, facets); }