Search code examples
cgal

Write out a triangulation result to an OBJ file in CGAL


I'm trying to make use of a 2D triangulation using CGAL, and create an obj file. I'm able to create a 2D triangulation. I now want to make the 3rd coordinate 0, ie z=0, and create a obj file out of the result of the triangulation. The samples of CGAL seem quite confusing, and I'm not sure how to go about this.


Solution

  • Here is how I did it. Hope it helps someone.

        // A modifier creating a triangle with the incremental builder.
            template<class HDS>
            class polyhedron_builder : public CGAL::Modifier_base<HDS> {
            public:
                std::vector<Triangulation>& t_;
                polyhedron_builder(std::vector<Triangulation>& t) : t_(t) {}
                void operator()(HDS& hds) {
                    typedef typename HDS::Vertex   Vertex;
                    typedef typename Vertex::Point Point3;
    
                    // create a cgal incremental builder
                    CGAL::Polyhedron_incremental_builder_3<HDS> B(hds, true);
    
                    // calculte total vertices
                    int face_num = 0;
                    int vertice_num = 0;
                    for (auto& tri : t_) {
                        face_num += tri.number_of_faces();
                        vertice_num += tri.number_of_vertices();
                    }
    
                    std::cout << face_num << ", " << vertice_num << ", " <<  t_.size() << "\n";
    
                    B.begin_surface(face_num, vertice_num);
    
                    // add the polyhedron vertices
                    for (auto& tri : t_) {
                        for (auto itr = tri.finite_vertices_begin(); itr != tri.finite_vertices_end(); ++itr) {
                            B.add_vertex(Point3(itr->point().x(), itr->point().y(), 0));
                        }
                    }
    
    
                    // add the polyhedron triangles
                    for (auto& tri : t_) {
                        for (auto itr = tri.finite_faces_begin(); itr != tri.finite_faces_end(); ++itr) {
                            B.begin_facet();
                            B.add_vertex_to_facet(itr->vertex(0)->info());
                            B.add_vertex_to_facet(itr->vertex(1)->info());
                            B.add_vertex_to_facet(itr->vertex(2)->info());
                            B.end_facet();
                        }
                    }
    
                    // finish up the surface
                    B.end_surface();
                }
            };
    
            void OBJfile::write_obj_file(const std::string& filename) {
                CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>> polyhedron;
    
                unsigned index = 0;
                std::vector<Triangulation> t_vector;
    
        // here, contours is an internal object that tracks the polygon outlines
                for (auto& contour : contours_) {
                    Triangulation t;
                    std::vector < std::pair<Point, unsigned> > polygon;
                    for (auto& pt : contour) {
                        Point point(pt.x(), pt.y());
                        polygon.push_back(std::make_pair(point, index++));
                    }
                    triangulate(polygon, t);
                    t_vector.push_back(t);
    
                }
    
                    polyhedron_builder<HalfedgeDS> builder(t_vector);
                    polyhedron.delegate(builder);
    
                // write the polyhedron out as a .OFF file
                    std::ofstream os("test.obj");
                    CGAL::File_writer_wavefront writer;
                    CGAL::generic_print_polyhedron(os, polyhedron, writer);
    
    
                os.close();
    
            }
    
            void OBJfile::triangulate(const std::vector<std::pair<Point, unsigned>>& polygon_points, Triangulation& t) {
    
                auto begin = polygon_points.begin();
                auto end = polygon_points.end();
                //std::istream_iterator<Point> end;
                t.insert(begin, end);
    
            }