1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
#include<fstream> #include<vector> #include<string> #include<algorithm> #include<CGAL/Simple_cartesian.h> #include<CGAL/Polyhedron_incremental_builder_3.h> #include<CGAL/Polyhedron_3.h> #include<CGAL/IO/Polyhedron_iostream.h> typedef CGAL::Simple_cartesian< double > Kernel; typedef CGAL::Polyhedron_3<Kernel> Polyhedron; typedef Polyhedron::HalfedgeDS HalfedgeDS; // A modifier creating a triangle with the incremental builder. template < class HDS> class polyhedron_builder : public CGAL::Modifier_base<HDS> { public : std::vector< double > &coords; std::vector< int > &tris; polyhedron_builder( std::vector< double > &_coords, std::vector< int > &_tris ) : coords(_coords), tris(_tris) {} void operator()( HDS& hds) { typedef typename HDS::Vertex Vertex; typedef typename Vertex::Point Point; // create a cgal incremental builder CGAL::Polyhedron_incremental_builder_3<HDS> B( hds, true ); B.begin_surface( coords.size()/3, tris.size()/3 ); // 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 triangles for ( int i=0; i<( int )tris.size(); i+=3 ){ B.begin_facet(); B.add_vertex_to_facet( tris[i+0] ); B.add_vertex_to_facet( tris[i+1] ); B.add_vertex_to_facet( tris[i+2] ); B.end_facet(); } // finish up the surface B.end_surface(); } }; // reads the first integer from a string in the form // "334/455/234" by stripping forward slashes and // scanning the result int get_first_integer( const char *v ){ int ival; std::string s( v ); std::replace( s.begin(), s.end(), '/' , ' ' ); sscanf ( s.c_str(), "%d" , &ival ); return ival; } // barebones .OFF file reader, throws away texture coordinates, normals, etc. // stores results in input coords array, packed [x0,y0,z0,x1,y1,z1,...] and // tris array packed [T0a,T0b,T0c,T1a,T1b,T1c,...] void load_obj( const char *filename, std::vector< double > &coords, std::vector< int > &tris ){ double x, y, z; char line[1024], v0[1024], v1[1024], v2[1024]; // open the file, return if open fails FILE *fp = fopen (filename, "r" ); if ( !fp ) return ; // read lines from the file, if the first character of the // line is 'v', we are reading a vertex, otherwise, if the // first character is a 'f' we are reading a facet while ( fgets ( line, 1024, fp ) ){ if ( line[0] == 'v' ){ sscanf ( line, "%*s%lf%lf%lf" , &x, &y, &z ); coords.push_back( x ); coords.push_back( y ); coords.push_back( z ); } else if ( line[0] == 'f' ){ sscanf ( line, "%*s%s%s%s" , v0, v1, v2 ); tris.push_back( get_first_integer( v0 )-1 ); tris.push_back( get_first_integer( v1 )-1 ); tris.push_back( get_first_integer( v2 )-1 ); } } fclose (fp); } int main() { // two vectors to hold point coordinates and // triangle vertex indices std::vector< double > coords; std::vector< int > tris; // load the input file load_obj( "input.obj" , coords, tris ); if ( coords.size() == 0 ) return 1; // build a polyhedron from the loaded arrays Polyhedron P; polyhedron_builder<HalfedgeDS> builder( coords, tris ); P.delegate( builder ); // write the polyhedron out as a .OFF file std::ofstream os( "dump.off" ); os << P; os.close(); return 0; } |
반응형
원본
http://jamesgregson.blogspot.kr/2012/05/example-code-for-building.html
Example code for building CGAL::Polyhedron_3
I've found myself redoing this code relatively frequently, so I thought I would post it. Nothing special, just a snippet that loads the file input.obj, builds a CGAL::Polyhedron_3 from it, and writes it out as dump.off. The code also includes a rudimentary Wavefront OBJ loader.
반응형