// Copyright (c) 2015 GeometryFactory (France). All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // Author(s) : Andreas Fabri // Mael Rouxel-Labbé #ifndef CGAL_BGL_IO_PLY_H #define CGAL_BGL_IO_PLY_H #include #include #include #include namespace CGAL { /*! Inserts the mesh in an output stream in PLY format. If provided, the `comments` string is included line by line in the header of the PLY stream (each line will be precedeed by "comment "). The `np` is an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below \cgalNamedParamsBegin \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `mesh` . If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` should be available in `FaceGraph` \cgalParamEnd \cgalParamBegin{vertex_index_map} is a property map containing for each vertex of `mesh` a unique index between `0` and `num_vertices(mesh)-1`. \cgalParamEnd \cgalNamedParamsEnd */ template bool write_PLY(std::ostream& out, const FaceGraph& mesh, const std::string& comments, const NamedParameters& np ) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; typedef typename CGAL::GetInitializedVertexIndexMap::const_type VIMap; typedef typename GetVertexPointMap::const_type Vpm; typedef typename boost::property_traits::value_type Point_3; VIMap vim = CGAL::get_initialized_vertex_index_map(mesh, np); Vpm vpm = parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_point), get_const_property_map(boost::vertex_point, mesh)); if(!out.good()) { std::cerr << "Error: cannot open file" << std::endl; return false; } // Write header out << "ply" << std::endl << ((get_mode(out) == IO::BINARY) ? "format binary_little_endian 1.0" : "format ascii 1.0") << std::endl << "comment Generated by the CGAL library" << std::endl; if(comments != std::string()) { std::istringstream iss(comments); std::string line; while(getline(iss, line)) { if(line != "Generated by the CGAL library") // Avoid repeating the line if multiple savings out << "comment " << line << std::endl; } } out << "element vertex " << num_vertices(mesh) << std::endl; IO::internal::output_property_header(out, make_ply_point_writer (CGAL::Identity_property_map())); out << "element face " << num_faces(mesh) << std::endl; IO::internal::output_property_header( out, std::make_pair(CGAL::Identity_property_map >(), PLY_property >("vertex_indices"))); out << "end_header" << std::endl; for(vertex_descriptor vd : vertices(mesh)) { Point_3 p = get(vpm, vd); IO::internal::output_properties(out, &p, make_ply_point_writer (CGAL::Identity_property_map())); } std::vector polygon; for(face_descriptor fd : faces(mesh)) { polygon.clear(); for(halfedge_descriptor hd : halfedges_around_face(halfedge(fd, mesh), mesh)) polygon.push_back(get(vim, target(hd,mesh))); IO::internal::output_properties(out, &polygon, std::make_pair(CGAL::Identity_property_map >(), PLY_property >("vertex_indices"))); } return out.good(); } template bool write_PLY(std::ostream& out, const FaceGraph& mesh, const std::string comments) { return write_PLY(out, mesh, comments, parameters::all_default()); } template bool write_PLY(std::ostream& out, const FaceGraph& mesh, const CGAL_BGL_NP_CLASS& np) { return write_PLY(out, mesh, "", np); } template bool write_PLY(std::ostream& out, const FaceGraph& mesh) { return write_PLY(out, mesh, "", parameters::all_default()); } } // namespace CGAL #endif // CGAL_BGL_IO_PLY_H