void renewAttrs( Polyhedron & poly ) { // assign IDs to vertices for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) { vi->nCuts() = 0; } // assign IDs to faces: the dual vertex and the dual coordinates-the center coordinates for ( Facet_iterator fi = poly.facets_begin(); fi != poly.facets_end(); ++fi ) { fi->piece() = NO_INDEX; Vector3 sum( 0.0, 0.0, 0.0 ); Halfedge_facet_circulator hfc = fi->facet_begin(); do { sum = sum + ( hfc->vertex()->point() - CGAL::ORIGIN ); } while ( ++hfc != fi->facet_begin() ); sum = sum / ( double )CGAL::circulator_size( hfc ); fi->center() = CGAL::ORIGIN + sum; } // assign the same IDs to the identical/ opposite halfedges for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) { hi->label() = DEFAULT_LABEL; hi->match() = DEFAULT_LABEL; hi->cycle() = NO_INDEX; hi->connect() = true; hi->visit() = false; hi->path() = NO_INDEX; hi->orient() = true; // We individually handle hi->fixed } }
int main() { std::vector<Point_3> points; points.push_back(Point_3(2.0f, 3.535533905932738f, 3.535533905932737f)); points.push_back(Point_3(4.0f, 2.0f, 0.0f)); points.push_back(Point_3(0.0f, 2.0f, 0.0f)); points.push_back(Point_3(1.0f, 0.0f, 0.0f)); points.push_back(Point_3(4.0f, 1.414213562373095f, 1.414213562373095f)); points.push_back(Point_3(0.0f, 1.414213562373095f, 1.414213562373095f)); points.push_back(Point_3(3.0f, 0.0f, 0.0f)); points.push_back(Point_3(2.0f, 5.0f, 0.0f)); Polyhedron P; CGAL::convex_hull_3(points.begin(), points.end(), P); std::cout << "- Number of vertices = " << P.size_of_vertices() << std::endl; std::cout << "- Number of edges = " << P.size_of_halfedges()/2 << std::endl; std::cout << "- Number of faces = " << P.size_of_facets() << std::endl; for ( Facet_iterator i = P.facets_begin(); i != P.facets_end(); ++i) { Halfedge_facet_circulator j = i->facet_begin(); CGAL_assertion( CGAL::circulator_size(j) >= 3); std::cout << CGAL::circulator_size(j) << ' '; do{ //std::cout << ' ' << std::distance(P.vertices_begin(), j->vertex()); std::cout << " (" << j->vertex()->point().x() << ' ' << j->vertex()->point().y() << ' ' << j->vertex()->point().z() << ')' << ", "; } while ( ++j != i->facet_begin()); std::cout << std::endl; } return 0; }
//------------------------------------------------------------------------------ // Initialize the dual center //------------------------------------------------------------------------------ void initAttrs( Polyhedron & poly ) { // assign IDs to vertices int vID = 0; for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) { vi->id() = vID++; vi->label() = DEFAULT_LABEL; vi->nCuts() = 0; } cerr << "Total number of vertices = " << vID << endl; // assign IDs to faces: the dual vertex and the dual coordinates-the center coordinates int fID = 0; for ( Facet_iterator fi = poly.facets_begin(); fi != poly.facets_end(); ++fi ) { fi->id() = fID++; // fi->label() = DEFAULT_LABEL; fi->piece() = NO_INDEX; Vector3 sum( 0.0, 0.0, 0.0 ); Halfedge_facet_circulator hfc = fi->facet_begin(); do { sum = sum + ( hfc->vertex()->point() - CGAL::ORIGIN ); } while ( ++hfc != fi->facet_begin() ); sum = sum / ( double )CGAL::circulator_size( hfc ); fi->center() = CGAL::ORIGIN + sum; // cerr << " Barycenter No. " << fid-1 << " : " << bary[ fid-1 ] << endl; } cerr << "Total number of facets = " << fID << endl; // initialize the halfedge IDs for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) { hi->id() = NO_INDEX; } // assign the same IDs to the identical/ opposite halfedges int eID = 0; for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) { if ( hi->id() == NO_INDEX ) { assert( hi->opposite()->id() == NO_INDEX ); hi->id() = eID; hi->opposite()->id() = eID; eID++; hi->label() = hi->opposite()->label() = DEFAULT_LABEL; hi->match() = hi->opposite()->match() = DEFAULT_LABEL; hi->cycle() = hi->opposite()->cycle() = NO_INDEX; hi->weight() = hi->opposite()->weight() = 0.0; hi->connect() = hi->opposite()->connect() = true; hi->visit() = hi->opposite()->visit() = false; // We individually handle hi->fixed } } cerr << "Total number of edges = " << eID << endl; }
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(int argc, const char **argv ) { std::vector<Point> points; CGAL::Random_points_on_sphere_3<Point> g; size_t N = 0; if (argc > 1) N = atof(argv[1]); N = std::max(size_t(100), N); for (size_t i = 0; i < N; ++i) points.push_back(rescale(*g++)); for (size_t n = 0; n < 100; ++n) { std::cerr << "step " << n << ":\n\t"; lloyd_step(points); } Polyhedron P; CGAL::convex_hull_3(points.begin(), points.end(), P); CGAL::set_ascii_mode( std::cout); std::cout << "OFF" << std::endl << P.size_of_vertices() << ' ' << P.size_of_facets() << " 0" << std::endl; std::copy( P.points_begin(), P.points_end(), std::ostream_iterator<Point>( std::cout, "\n")); for ( Facet_iterator i = P.facets_begin(); i != P.facets_end(); ++i) { Halfedge_facet_circulator j = i->facet_begin(); // Facets in polyhedral surfaces are at least triangles. CGAL_assertion( CGAL::circulator_size(j) >= 3); std::cout << CGAL::circulator_size(j) << ' '; do { std::cout << ' ' << std::distance(P.vertices_begin(), j->vertex()); } while ( ++j != i->facet_begin()); std::cout << std::endl; } std::ofstream os ("test.cloud"); std::copy(points.begin(), points.end(), std::ostream_iterator<Point>(os, "\n")); }
int main() { //std::cout<<CGBench::BendBench::Run(CGBench::VMag::M1)<<std::endl; //CGBench::BenchLanuch(CGBench::VMag::M3,CGBench::VMag::M3); /*std::ofstream of("C:\\123.off"); std::vector <Point_3> arr; arr.push_back(Point_3 (2,0,2)); arr.push_back(Point_3 (6,0,3)); arr.push_back(Point_3 (8,0,4)); arr.push_back(Point_3 (3,0,5)); arr.push_back(Point_3 (5,0,6)); arr.push_back(Point_3 (8,0,7)); arr.push_back(Point_3 (0,1.75,8)); arr.push_back(Point_3 (0,1.50,8)); arr.push_back(Point_3 (0,1.25,8)); arr.push_back(Point_3 (0,1,8)); arr.push_back(Point_3 (0,1,7)); arr.push_back(Point_3 (0,1,6)); arr.push_back(Point_3 (0,1,5)); arr.push_back(Point_3 (0,1,4)); arr.push_back(Point_3 (0,1,3)); arr.push_back(Point_3 (0,1.25,3)); arr.push_back(Point_3 (0,1.50,3)); arr.push_back(Point_3 (0,1.75,3)); Point_3* Center = new Point_3(0,0,0);*/ //Arc_2 s(30,270,30,true); //Circle_2 s(4,20); //Ellipse_2 s(6,4,30); //Plane_3 s(30,30,10,10); //Rectangle_2 s(20,10); //Box_3 s(20,20,20,15,15,15); //Capsule_3 s(30,200,10,10); //ChamferCyl_3 s(60,100,30,10,5,5,15); //Cone_3 s(2,5,10,3,3,3); //Cylinder_3 s(3,20,20,9,30); //Lathe_3 s(arr,Center,Z_ax,20,360); //Pyramid_3 s(100,200,200,4,4,4); //Sphere_3 s(20,50); //Spindle_3 s(10,30,20,10,5,15); //Spring_3 s(20,2.5,200,10,10,40); //Torus_3 s(20,5,0,0,30,40); //Tube_3 s(14,13,15,20,20,10); //Polyhedron P; //P = s.Draw(); //Traingulate trg; //P=s.Draw(); //std::transform(P.facets_begin(), P.facets_end(), P.planes_begin(), Normal_vector()); /*Eigen::Transform3d T; Eigen::Vector3d Original(0,0,10); T.setIdentity(); T.pretranslate (-Original); trg.ApplyTransformToPolyhedron(P,T);*/ //Traingulate tr; //tr.Do(P); //Bevel Be(400,-4,1.25); //Be.Do(P); //Bridge Br(18,20); //Br.Do(P); //Extrude Ex(45,15); //Ex.Do(P); //Outline Ou(45,1.5); //Ou.Do(P); //Bend Ben(90,s.Center,Y_ax,false,20,-20); //Ben.Do(P); //Bulge Bu(40,s.Center,Z_ax,BRadial,false,45,-45); //Bu.Do(P); //Cylindrical_Wave CylWa(2,8,12,s.Center,Z_ax); //CylWa.Do(P); //Linear_Wave LiWaX(1,10,0,s.Center,Z_ax,X_ax); //LiWaX.Do(P); //Linear_Wave LiWaY(2,10,0,s.Center,Z_ax,Y_ax); //LiWaY.Do(P); /*ChamferCyl_3 n(1,50,5,10,10,10,40); Spindle_3 p(5,30,5,10,20,40); Polyhedron P; Polyhedron E; E = p.Draw(); P = n.Draw(); Morph Mor(E,50); Mor.Do(P);*/ //Noise No(5,0.3,0,s.Center,Z_ax); //No.Do(P); //Skew Sk(30,s.Center,Z_ax,false,20,-20); //Sk.Do(P); //Smooth Sm(1); //Sm.Do(P); //Spherify Sph(50); //Sph.Do(P); //Squeeze Sq(-30,s.Center,Z_ax,false,10,0); //Sq.Do(P); //Stretch St(-20,s.Center,Z_ax,true,50,-50); //St.Do(P); //Taper Ta(3,s.Center,X_ax,false,20,-20); //Ta.Do(P); //Twist Tw(270,s.Center,Z_ax,true,-5,15); //Tw.Do(P); /*Box_3 B(20, 30, 60, 20, 30, 30); Polyhedron P = B.Draw(); Twist Tw1(270, B.Center, Z_ax, true, 30, 10); Twist Tw2(-270, B.Center, Z_ax, true, -10, -30); Stretch St(30, B.Center, Z_ax, true, 20,-20); Squeeze Sq(15, B.Center, Z_ax); Tw1.Do(P); Tw2.Do(P); Sq.Do(P); St.Do(P);*/ std::ofstream of("C:\\123.off"); Box_3 B(20, 30, 60, 20, 30, 30); Polyhedron P = B.Draw(); Twist Tw1(270, B.Center, Z_ax, true, 30, 10); Twist Tw2(-270, B.Center, Z_ax, true, -10, -30); Stretch St(30, B.Center, Z_ax, true, 20,-20); Squeeze Sq(15, B.Center, Z_ax); Tw1.Do(P); Tw2.Do(P); Sq.Do(P); St.Do(P); //// Write polyhedron in Object File Format (OFF). CGAL::set_ascii_mode( of ); of << "OFF" << std::endl << P.size_of_vertices() << ' ' << P.size_of_facets() << " 0" << std::endl; std::copy( P.points_begin(), P.points_end(), std::ostream_iterator<Point_3>( of, "\n")); for ( Facet_iterator i = P.facets_begin(); i != P.facets_end(); ++i) { Halfedge_facet_circulator j = i->facet_begin(); // Facets in polyhedral surfaces are at least triangles. CGAL_assertion( CGAL::circulator_size(j) >= 3); of << CGAL::circulator_size(j) << ' '; do { of << ' ' << std::distance(P.vertices_begin(), j->vertex()); } while ( ++j != i->facet_begin()); of << std::endl; } /* Write polyhedron in (OBJ). CGAL::set_ascii_mode( oof ); oof << "# " << P.size_of_vertices() << ' ' << std::endl <<"# "<< P.size_of_facets() << std::endl; oof<<"v "; std::copy( P.points_begin(), P.points_end(), std::ostream_iterator<Point_3>( oof, "\nv ")); oof<<"_ _ _\n"; for ( Facet_iterator i = P.facets_begin(); i != P.facets_end(); ++i) { Halfedge_facet_circulator j = i->facet_begin(); // Facets in polyhedral surfaces are at least triangles. //CGAL_assertion( CGAL::circulator_size(j) >= 3); oof << 'f' << ' '; do { oof << ' ' << std::distance(P.vertices_begin(), j->vertex())+1; } while ( ++j != i->facet_begin()); oof << std::endl; } */ return 0; }
void simplifyMesh(TriangleMesh &src, TriangleMesh &dst){ namespace SMS = CGAL::Surface_mesh_simplification; Surface surface; PolyhedronBuilder<HalfedgeDS> builder(src.points, src.facets); surface.delegate(builder); // --- before mesh simplification, to maintain mesh quality high poisson surface reconstruction is applied --- // This is a stop predicate (defines when the algorithm terminates). // In this example, the simplification stops when the number of undirected edges // left in the surface drops below the specified number (1000) // SMS::Count_stop_predicate<Surface> stop(3000); //SMS::Count_ratio_stop_predicate<Surface> stop(0.1); SMS::Count_stop_predicate<Surface> stop(100); // This the actual call to the simplification algorithm. // The surface and stop conditions are mandatory arguments. // The index maps are needed because the vertices and edges // of this surface lack an "id()" field. int r = SMS::edge_collapse (surface ,stop ,CGAL::vertex_index_map(boost::get(CGAL::vertex_external_index, surface)) .edge_index_map(boost::get(CGAL::edge_external_index, surface)) .get_cost(CGAL::Surface_mesh_simplification::Edge_length_cost<Polyhedron>()) .get_placement(CGAL::Surface_mesh_simplification::Midpoint_placement<Polyhedron>()) //.get_cost(CGAL::Surface_mesh_simplification::LindstromTurk_cost<Polyhedron>()) //.get_placement(CGAL::Surface_mesh_simplification::LindstromTurk_placement<Polyhedron>()) ); std::cout << "\nFinished...\n" << r << " edges removed.\n" << (surface.size_of_halfedges()/2) << " final edges.\n" ; std::vector<Eigen::Vector3d> points; std::vector<std::vector<int> > faces; points.resize(surface.size_of_vertices()); faces.resize(surface.size_of_facets()); Polyhedron::Point_iterator pit; int index = 0; for(pit=surface.points_begin(); pit!=surface.points_end(); ++pit){ points[index][0] = pit->x(); points[index][1] = pit->y(); points[index][2] = pit->z(); index ++; } index = 0; Polyhedron::Face_iterator fit; for(fit=surface.facets_begin(); fit!=surface.facets_end(); ++fit){ std::vector<int > face(3); Halfedge_facet_circulator j = fit->facet_begin(); int f_index = 0; do { face[f_index] = std::distance(surface.vertices_begin(), j->vertex()); f_index++; } while ( ++j != fit->facet_begin()); faces[index] = face; index++; } dst.createFromFaceVertex(points, faces); }
void PoissonSurfaceReconstruction::reconstruct(std::vector<Eigen::Vector3d> &points, std::vector<Eigen::Vector3d> &normals, TriangleMesh &mesh){ assert(points.size() == normals.size()); std::cout << "creating points with normal..." << std::endl; std::vector<Point_with_normal> points_with_normal; points_with_normal.resize((int)points.size()); for(int i=0; i<(int)points.size(); i++){ Vector vec(normals[i][0], normals[i][1], normals[i][2]); //Point_with_normal pwn(points[i][0], points[i][1], points[i][2], vec); //points_with_normal[i] = pwn; points_with_normal[i] = Point_with_normal(points[i][0], points[i][1], points[i][2], vec); } std::cout << "constructing poisson reconstruction function..." << std::endl; Poisson_reconstruction_function function(points_with_normal.begin(), points_with_normal.end(), CGAL::make_normal_of_point_with_normal_pmap(PointList::value_type())); std::cout << "computing implicit function..." << std::endl; if( ! function.compute_implicit_function() ) { std::cout << "compute implicit function is failure" << std::endl; return; } //return EXIT_FAILURE; // Computes average spacing std::cout << "compute average spacing..." << std::endl; FT average_spacing = CGAL::compute_average_spacing(points_with_normal.begin(), points_with_normal.end(), 6 /* knn = 1 ring */); // Gets one point inside the implicit surface // and computes implicit function bounding sphere radius. Point inner_point = function.get_inner_point(); Sphere bsphere = function.bounding_sphere(); FT radius = std::sqrt(bsphere.squared_radius()); // Defines the implicit surface: requires defining a // conservative bounding sphere centered at inner point. FT sm_sphere_radius = 5.0 * radius; FT sm_dichotomy_error = distance_criteria*average_spacing/1000.0; // Dichotomy error must be << sm_distance //FT sm_dichotomy_error = distance_criteria*average_spacing/10.0; // Dichotomy error must be << sm_distance std::cout << "reconstructed surface" << std::endl; Surface_3 reconstructed_surface(function, Sphere(inner_point,sm_sphere_radius*sm_sphere_radius), sm_dichotomy_error/sm_sphere_radius); // Defines surface mesh generation criteria CGAL::Surface_mesh_default_criteria_3<STr> criteria(angle_criteria, // Min triangle angle (degrees) radius_criteria*average_spacing, // Max triangle size distance_criteria*average_spacing); // Approximation error std::cout << "generating surface mesh..." << std::endl; // Generates surface mesh with manifold option STr tr; // 3D Delaunay triangulation for surface mesh generation C2t3 c2t3(tr); // 2D complex in 3D Delaunay triangulation CGAL::make_surface_mesh(c2t3, // reconstructed mesh reconstructed_surface, // implicit surface criteria, // meshing criteria CGAL::Manifold_tag()); // require manifold mesh if(tr.number_of_vertices() == 0){ std::cout << "surface mesh generation is failed" << std::endl; return; } Polyhedron surface; CGAL::output_surface_facets_to_polyhedron(c2t3, surface); // convert CGAL::surface to TriangleMesh // std::cout << "converting CGA::surface to TriangleMesh..." << std::endl; std::vector<Eigen::Vector3d> pts; std::vector<std::vector<int> > faces; pts.resize(surface.size_of_vertices()); faces.resize(surface.size_of_facets()); Polyhedron::Point_iterator pit; int index = 0; for(pit=surface.points_begin(); pit!=surface.points_end(); ++pit){ pts[index][0] = pit->x(); pts[index][1] = pit->y(); pts[index][2] = pit->z(); index ++; } index = 0; Polyhedron::Face_iterator fit; for(fit=surface.facets_begin(); fit!=surface.facets_end(); ++fit){ std::vector<int > face(3); Halfedge_facet_circulator j = fit->facet_begin(); int f_index = 0; do { face[f_index] = std::distance(surface.vertices_begin(), j->vertex()); f_index++; } while ( ++j != fit->facet_begin()); faces[index] = face; index++; } mesh.createFromFaceVertex(pts, faces); }