1818#include < CGAL/boost/graph/IO/Generic_facegraph_builder.h>
1919#include < CGAL/Named_function_parameters.h>
2020#include < CGAL/boost/graph/named_params_helper.h>
21+ #include < CGAL/Exact_predicates_inexact_constructions_kernel.h>
2122
2223#include < fstream>
2324#include < string>
@@ -44,27 +45,30 @@ class PLY_builder
4445 typedef typename Base::Face_container Face_container;
4546
4647public:
47- PLY_builder (std::istream& is) : Base(is) { }
48+ PLY_builder (std::istream& is, std::string& comments ) : Base(is), comments(comments ) { }
4849
4950 template <typename NamedParameters>
5051 bool read (std::istream& is,
5152 Point_container& points,
5253 Face_container& faces,
5354 const NamedParameters& np)
5455 {
55- return read_PLY (is, points, faces, np);
56+ return read_PLY (is, points, faces, comments, np);
5657 }
58+
59+ std::string& comments;
5760};
5861
5962template <typename Graph, typename CGAL_NP_TEMPLATE_PARAMETERS>
6063bool read_PLY_BGL (std::istream& is,
6164 Graph& g,
65+ std::string& comments,
6266 const CGAL_NP_CLASS& np = parameters::default_values())
6367{
6468 typedef typename CGAL::GetVertexPointMap<Graph, CGAL_NP_CLASS>::type VPM;
6569 typedef typename boost::property_traits<VPM>::value_type Point;
6670
67- internal::PLY_builder<Graph, Point> builder (is);
71+ internal::PLY_builder<Graph, Point> builder (is, comments );
6872 return builder (g, np);
6973}
7074
@@ -84,6 +88,7 @@ bool read_PLY_BGL(std::istream& is,
8488
8589 \param is the input stream
8690 \param g the graph to be built from the input data
91+ \param comments a string included line by line in the header of the PLY stream (each line will be precedeed by "comment ")
8792 \param np optional \ref bgl_namedparameters "Named Parameters" described below
8893
8994 \cgalNamedParamsBegin
@@ -128,6 +133,20 @@ bool read_PLY_BGL(std::istream& is,
128133
129134 \sa Overloads of this function for specific models of the concept `FaceGraph`.
130135*/
136+ template <typename Graph,
137+ typename CGAL_NP_TEMPLATE_PARAMETERS>
138+ bool read_PLY (std::istream& is,
139+ Graph& g,
140+ std::string& comments,
141+ const CGAL_NP_CLASS& np = parameters::default_values()
142+ #ifndef DOXYGEN_RUNNING
143+ , std::enable_if_t <!internal::is_Point_set_or_Range_or_Iterator<Graph>::value>* = nullptr
144+ #endif
145+ )
146+ {
147+ return internal::read_PLY_BGL (is, g, comments, np);
148+ }
149+
131150template <typename Graph,
132151 typename CGAL_NP_TEMPLATE_PARAMETERS>
133152bool read_PLY (std::istream& is,
@@ -138,9 +157,11 @@ bool read_PLY(std::istream& is,
138157#endif
139158 )
140159{
141- return internal::read_PLY_BGL (is, g, np);
160+ std::string unused_comments;
161+ return internal::read_PLY_BGL (is, g, unused_comments, np);
142162}
143163
164+
144165/* !
145166 \ingroup PkgBGLIoFuncsPLY
146167
@@ -153,6 +174,7 @@ bool read_PLY(std::istream& is,
153174
154175 \param fname the name of the input file
155176 \param g the graph to be built from the input data
177+ \param comments a string included line by line in the header of the PLY stream (each line will be precedeed by "comment" )
156178 \param np optional \ref bgl_namedparameters "Named Parameters" described below
157179
158180 \cgalNamedParamsBegin
@@ -207,6 +229,7 @@ template <typename Graph,
207229 typename CGAL_NP_TEMPLATE_PARAMETERS>
208230bool read_PLY (const std::string& fname,
209231 Graph& g,
232+ std::string& comments,
210233 const CGAL_NP_CLASS& np = parameters::default_values()
211234#ifndef DOXYGEN_RUNNING
212235 , std::enable_if_t <!internal::is_Point_set_or_Range_or_Iterator<Graph>::value>* = nullptr
@@ -218,16 +241,29 @@ bool read_PLY(const std::string& fname,
218241 {
219242 std::ifstream is (fname, std::ios::binary);
220243 CGAL::IO::set_mode (is, CGAL::IO::BINARY);
221- return internal::read_PLY_BGL (is, g, np);
244+ return read_PLY (is, g, comments , np);
222245 }
223246 else
224247 {
225248 std::ifstream is (fname);
226249 CGAL::IO::set_mode (is, CGAL::IO::ASCII);
227- return internal::read_PLY_BGL (is, g, np);
250+ return read_PLY (is, g, comments , np);
228251 }
229252}
230253
254+ template <typename Graph,
255+ typename CGAL_NP_TEMPLATE_PARAMETERS>
256+ bool read_PLY (const std::string& fname,
257+ Graph& g,
258+ const CGAL_NP_CLASS& np = parameters::default_values()
259+ #ifndef DOXYGEN_RUNNING
260+ , std::enable_if_t <!internal::is_Point_set_or_Range_or_Iterator<Graph>::value>* = nullptr
261+ #endif
262+ )
263+ {
264+ std::string unused_comment;
265+ return read_PLY (fname, g, unused_comment, np);
266+ }
231267// //////////////////////////////////////////////////////////////////////////////////////////////////
232268// //////////////////////////////////////////////////////////////////////////////////////////////////
233269// Write
@@ -259,6 +295,15 @@ bool read_PLY(const std::string& fname,
259295 must be available in `Graph`.}
260296 \cgalParamNEnd
261297
298+ \cgalParamNBegin{vertex_normal_map}
299+ \cgalParamDescription{a property map associating normals to the vertices of `g`}
300+ \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
301+ as key type and `%Vector_3` as value type}
302+ \cgalParamDefault{`boost::get(CGAL::vertex_point, g)`}
303+ \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
304+ must be available in `Graph`.}
305+ \cgalParamNEnd
306+
262307 \cgalParamNBegin{vertex_index_map}
263308 \cgalParamDescription{a property map associating to each vertex of `graph` a unique index}
264309 \cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
@@ -326,6 +371,8 @@ bool write_PLY(std::ostream& os,
326371
327372 bool has_vcolor = !is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_color_map_t >::value;
328373 bool has_fcolor = !is_default_parameter<CGAL_NP_CLASS, internal_np::face_color_map_t >::value;
374+ constexpr bool has_vnormal = !is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_normal_map_t >::value;
375+
329376 VIMap vim = CGAL::get_initialized_vertex_index_map (g, np);
330377 Vpm vpm = choose_parameter (get_parameter (np, internal_np::vertex_point),
331378 get_const_property_map (boost::vertex_point, g));
@@ -351,8 +398,20 @@ bool write_PLY(std::ostream& os,
351398 }
352399 }
353400
401+
354402 os << " element vertex " << vertices (g).size () << std::endl;
355- internal::output_property_header (os, make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
403+ if constexpr (std::is_same<typename Kernel_traits<Point_3>::Kernel::FT, float >::value)
404+ {
405+ internal::output_property_header (os, make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
406+ }
407+ else
408+ {
409+ typedef typename Kernel_traits<Point_3>::Kernel K;
410+ typedef decltype (std::declval<CGAL::Cartesian_converter<K, Epick> >().operator ()(std::declval<Point_3>())) Target_point;
411+ auto fvpm = CGAL::make_cartesian_converter_property_map<Target_point>(vpm);
412+ internal::output_property_header (os, make_ply_point_writer (fvpm));
413+ }
414+
356415 // if vcm is not default add v:color property
357416 if (has_vcolor)
358417 {
@@ -362,10 +421,30 @@ bool write_PLY(std::ostream& os,
362421 << " property uchar alpha" << std::endl;
363422 }
364423
424+ if constexpr (has_vnormal)
425+ {
426+ auto vnm = get_parameter (np, internal_np::vertex_normal_map);
427+ typedef decltype (vnm) Normal_map;
428+ typedef typename Normal_map::value_type Vector_3;
429+ typedef typename Kernel_traits<Vector_3>::Kernel K;
430+ typedef typename K::FT FT;
431+ if constexpr (std::is_same<FT, float >::value)
432+ {
433+ internal::output_property_header (os, make_ply_normal_writer (CGAL::Identity_property_map<Vector_3>()));
434+ }
435+ else
436+ {
437+ typedef decltype (std::declval<CGAL::Cartesian_converter<K, Epick> >().operator ()(std::declval<Vector_3>())) Target_vector;
438+ auto fvnm = CGAL::make_cartesian_converter_property_map<Target_vector>(vnm);
439+ internal::output_property_header (os, make_ply_normal_writer (fvnm));
440+ }
441+ }
442+
365443 os << " element face " << faces (g).size () << std::endl;
366444 internal::output_property_header (
367445 os, std::make_pair (CGAL::Identity_property_map<std::vector<std::size_t > >(),
368446 PLY_property<std::vector<int > >(" vertex_indices" )));
447+
369448 // if fcm is not default add f:color property
370449 if (has_fcolor)
371450 {
@@ -378,8 +457,42 @@ bool write_PLY(std::ostream& os,
378457
379458 for (vertex_descriptor vd : vertices (g))
380459 {
381- const Point_3& p = get (vpm, vd);
382- internal::output_properties (os, &p, make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
460+ if constexpr (std::is_same<typename Kernel_traits<Point_3>::Kernel::FT, float >::value)
461+ {
462+ decltype (auto ) p = get (vpm, vd);
463+ internal::output_properties (os, &p, make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
464+ }
465+ else
466+ {
467+ typedef typename Kernel_traits<Point_3>::Kernel K;
468+ typedef CGAL::cpp20::remove_cvref_t <decltype (std::declval<CGAL::Cartesian_converter<K, Epick> >().operator ()(std::declval<Point_3>()))> Target_point;
469+ CGAL::Cartesian_converter_property_map<Target_point, Vpm> fvpm = CGAL::make_cartesian_converter_property_map<Target_point>(vpm);
470+ decltype (auto ) fp = get (fvpm, vd);
471+ internal::output_properties (os, &fp, make_ply_point_writer (CGAL::Identity_property_map<Target_point>()));
472+ }
473+
474+ std::cout << " using generic writer" << std::endl;
475+
476+ if constexpr (!parameters::is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_normal_map_t >::value)
477+ {
478+ auto vnm = get_parameter (np, internal_np::vertex_normal_map);
479+ typedef decltype (vnm) Normal_map;
480+ typedef typename Normal_map::value_type Vector_3;
481+
482+ if constexpr (std::is_same<typename Kernel_traits<Vector_3>::Kernel::FT, float >::value)
483+ {
484+ decltype (auto ) vec = get (vnm,vd);
485+ internal::output_properties (os, &vec, make_ply_normal_writer (CGAL::Identity_property_map<Vector_3>()));
486+ }
487+ else
488+ {
489+ typedef typename Kernel_traits<Vector_3>::Kernel K;
490+ typedef CGAL::cpp20::remove_cvref_t <decltype (std::declval<CGAL::Cartesian_converter<K, Epick> >().operator ()(std::declval<Vector_3>()))> Target_vector;
491+ auto fvnm = CGAL::make_cartesian_converter_property_map<Target_vector>(vnm);
492+ decltype (auto ) fvec = get (fvnm, vd);
493+ internal::output_properties (os, &fvec, make_ply_normal_writer (CGAL::Identity_property_map<Target_vector>()));
494+ }
495+ }
383496 if (has_vcolor)
384497 {
385498 const CGAL::IO::Color& c = get (vcm, vd);
@@ -455,6 +568,15 @@ bool write_PLY(std::ostream& os, const Graph& g, const CGAL_NP_CLASS& np = param
455568 must be available in `Graph`.}
456569 \cgalParamNEnd
457570
571+ \cgalParamNBegin{vertex_normal_map}
572+ \cgalParamDescription{a property map associating normals to the vertices of `g`}
573+ \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
574+ as key type and `%Vector_3` as value type}
575+ \cgalParamDefault{`boost::get(CGAL::vertex_point, g)`}
576+ \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
577+ must be available in `Graph`.}
578+ \cgalParamNEnd
579+
458580 \cgalParamNBegin{vertex_index_map}
459581 \cgalParamDescription{a property map associating to each vertex of `graph` a unique index between `0` and `num_vertices(graph) - 1`}
460582 \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
0 commit comments