*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.

#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; }

## 8 comments:

good example code

I got a assertion error on

CGAL_assertion( check_protocoll == 0);

on Polyhedron_incremental_builder_3.h

Did you know why this error occur??

* I made a code like yours.

I'm not sure, the code above compiled and ran fine for me.

Perhaps your polyhedron is not manifold (two triangles adjacent to each mesh edge)?

Typo: barebones .OFF file reader should be barebones .OBJ file reader

Nice source code!

It is so much more helpful for real life scenarios than CGAL's own samples.

Thanks for taking the time to share your code snippets!

Thank you for posting this; it was very helpful.

Do the coordinates and triangles need to represent a closed surface?

how to get vertices and faces from polyhedron

Post a Comment