diff --git a/BGL/include/CGAL/boost/graph/IO/PLY.h b/BGL/include/CGAL/boost/graph/IO/PLY.h index cc5592272cd..0a829ca9cd2 100644 --- a/BGL/include/CGAL/boost/graph/IO/PLY.h +++ b/BGL/include/CGAL/boost/graph/IO/PLY.h @@ -50,9 +50,9 @@ public: bool read(std::istream& input, Point_container& points, Face_container& faces, - const NamedParameters&) + const NamedParameters& np) { - return read_PLY(input, points, faces); + return read_PLY(input, points, faces, np); } }; @@ -99,6 +99,7 @@ bool read_PLY(std::istream& in, FaceGraph& g, const CGAL_BGL_NP_CLASS& np) { return IO::internal::read_PLY_BGL(in, g, np); } + /*! Inserts the graph in an output stream in PLY format. @@ -132,9 +133,25 @@ bool write_PLY(std::ostream& os, typedef typename CGAL::GetInitializedVertexIndexMap::const_type VIMap; typedef typename GetVertexPointMap::const_type Vpm; typedef typename boost::property_traits::value_type Point_3; + typedef CGAL::Color Color; + typedef typename internal_np::Lookup_named_param_def< + internal_np::vertex_color_map_t, NamedParameters, + Constant_property_map >::type VCM; + typedef typename internal_np::Lookup_named_param_def< + internal_np::face_color_map_t, NamedParameters, + Constant_property_map >::type FCM; + using parameters::choose_parameter; + using parameters::is_default_parameter; + using parameters::get_parameter; + + VCM vcm = choose_parameter(get_parameter(np, internal_np::vertex_color_map), VCM()); + FCM fcm = choose_parameter(get_parameter(np, internal_np::face_color_map), FCM()); + + bool has_vcolor = !is_default_parameter(get_parameter(np, internal_np::vertex_color_map)); + bool has_fcolor = !is_default_parameter(get_parameter(np, internal_np::face_color_map)); VIMap vim = CGAL::get_initialized_vertex_index_map(g, np); - Vpm vpm = parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_point), + Vpm vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), get_const_property_map(boost::vertex_point, g)); if(!os.good()) @@ -161,18 +178,45 @@ bool write_PLY(std::ostream& os, os << "element vertex " << num_vertices(g) << std::endl; IO::internal::output_property_header(os, make_ply_point_writer (CGAL::Identity_property_map())); + //if vcm is not default add v:color property + if(has_vcolor) + { + os << "property uchar red" << std::endl + << "property uchar green" << std::endl + << "property uchar blue" << std::endl + << "property uchar alpha" << std::endl; + } os << "element face " << num_faces(g) << std::endl; IO::internal::output_property_header( os, std::make_pair(CGAL::Identity_property_map >(), PLY_property >("vertex_indices"))); - + //if fcm is not default add f:color property + if(has_fcolor) + { + os << "property uchar red" << std::endl + << "property uchar green" << std::endl + << "property uchar blue" << std::endl + << "property uchar alpha" << std::endl; + } os << "end_header" << std::endl; for(vertex_descriptor vd : vertices(g)) { Point_3 p = get(vpm, vd); IO::internal::output_properties(os, &p, make_ply_point_writer (CGAL::Identity_property_map())); + if(has_vcolor) + { + CGAL::Color c = get(vcm, vd); + if(get_mode(os) == CGAL::IO::ASCII) + { + os << c << std::endl; + } + else + { + os.write(reinterpret_cast(&c), sizeof(c)); + } + } } std::vector polygon; @@ -184,6 +228,16 @@ bool write_PLY(std::ostream& os, IO::internal::output_properties(os, &polygon, std::make_pair(CGAL::Identity_property_map >(), PLY_property >("vertex_indices"))); + if(has_fcolor) + { + CGAL::Color c = get(fcm, fd); + if(get_mode(os) == CGAL::IO::ASCII) + os << c << std::endl; + else + { + os.write(reinterpret_cast(&c), sizeof(c)); + } + } } return os.good(); diff --git a/BGL/test/BGL/test_bgl_read_write.cpp b/BGL/test/BGL/test_bgl_read_write.cpp index a0fddc2b548..220383310b3 100644 --- a/BGL/test/BGL/test_bgl_read_write.cpp +++ b/BGL/test/BGL/test_bgl_read_write.cpp @@ -200,29 +200,67 @@ bool test_STL() template -bool test_PLY() +bool test_PLY(bool binary = false) { + //! TODO add tests for face colors FaceGraph fg; CGAL::make_tetrahedron(Point(0, 0, 0), Point(1, 1, 0), Point(2, 0, 1), Point(3, 0, 0), fg); + typedef typename boost::property_map >::type VertexColorMap; + typedef typename boost::property_map >::type FaceColorMap; + FaceColorMap fcm = get(CGAL::dynamic_face_property_t(), fg); + VertexColorMap vcm = get(CGAL::dynamic_vertex_property_t(), fg); + + auto fit = faces(fg).begin(); + put(fcm,*fit++,CGAL::Color(155,0,0)); + put(fcm,*fit++,CGAL::Color(0,155,0)); + put(fcm,*fit++,CGAL::Color(0,0,155)); + put(fcm,*fit++,CGAL::Color(155,0,155)); + + auto vit = vertices(fg).begin(); + put(vcm,*vit++,CGAL::Color(255,0,0)); + put(vcm,*vit++,CGAL::Color(0,255,0)); + put(vcm,*vit++,CGAL::Color(0,0,255)); + put(vcm,*vit++,CGAL::Color(255,0,255)); std::ostringstream out; - CGAL::write_PLY(out, fg, "hello"); + + if(binary) + CGAL::set_mode(out, CGAL::IO::BINARY); + + CGAL::write_PLY(out, fg, "hello", CGAL::parameters::vertex_color_map(vcm) + .face_color_map(fcm)); if(out.fail()) { std::cerr<<"Tetrahedron writing failed."< points; - std::vector > polygons; + + if(binary) + CGAL::set_mode(in, CGAL::IO::BINARY); + fg.clear(); - if(!CGAL::read_PLY(in,fg, CGAL::parameters::all_default())){ + + VertexColorMap vcm2 = get(CGAL::dynamic_vertex_property_t(), fg); + FaceColorMap fcm2 = get(CGAL::dynamic_face_property_t(), fg); + if(!CGAL::read_PLY(in,fg, CGAL::parameters::vertex_color_map(vcm2).face_color_map(fcm2))){ std::cerr<<"Tetrahedron reading failed."<1) ? argv[1] : "data/prim.off"; //PLY - test_PLY(); - test_PLY(); + if(!test_PLY()) + return 1; + if(!test_PLY(true)) + return 1; + if(!test_PLY()) + return 1; + if(!test_PLY(true)) + return 1; // OFF test_bgl_read_write(filename); test_bgl_read_write(filename); diff --git a/Stream_support/include/CGAL/IO/PLY.h b/Stream_support/include/CGAL/IO/PLY.h index a47bb924dd3..728fdd7e011 100644 --- a/Stream_support/include/CGAL/IO/PLY.h +++ b/Stream_support/include/CGAL/IO/PLY.h @@ -31,10 +31,10 @@ template ::value @@ -198,7 +198,10 @@ bool read_PLY(std::istream& is, ColorRange& fcolors, ColorRange& vcolors, HUVRange& huvs, - bool /* verbose */ = false) + bool /* verbose */ = false, + typename std::enable_if< + !CGAL::is_iterator::value + >::type* =0) { return read_PLY(is, points, polygons, std::back_inserter(hedges), std::back_inserter(fcolors), std::back_inserter(vcolors), std::back_inserter(huvs)); } @@ -323,12 +326,15 @@ bool read_PLY(std::istream& is, using parameters::choose_parameter; using parameters::get_parameter; + std::vector > dummy_pui; + std::vector > dummy_pf; - return read_PLY(is, points, polygons, - choose_parameter(get_parameter(np, internal_np::vertex_color_output_iterator), - CGAL::Emptyset_iterator()), - choose_parameter(get_parameter(np, internal_np::face_color_output_iterator), - CGAL::Emptyset_iterator())); + return read_PLY(is, points, polygons,std::back_inserter(dummy_pui), + choose_parameter(get_parameter(np, internal_np::face_color_output_iterator), + CGAL::Emptyset_iterator()), + choose_parameter(get_parameter(np, internal_np::vertex_color_output_iterator), + CGAL::Emptyset_iterator()), + std::back_inserter(dummy_pf)); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Stream_support/include/CGAL/IO/PLY/PLY_reader.h b/Stream_support/include/CGAL/IO/PLY/PLY_reader.h index cd73f2b3dc6..4393a313327 100644 --- a/Stream_support/include/CGAL/IO/PLY/PLY_reader.h +++ b/Stream_support/include/CGAL/IO/PLY/PLY_reader.h @@ -745,7 +745,10 @@ bool read_PLY_faces(std::istream& in, PLY_element& element, PolygonRange& polygons, ColorRange& fcolors, - const char* vertex_indices_tag) + const char* vertex_indices_tag, + typename boost::enable_if< + typename boost::has_range_const_iterator::type + >::type* =0) { return read_PLY_faces(in, element, polygons, std::back_inserter(fcolors), vertex_indices_tag); }