From ab0e622e8bc1e6d29b121b3236e6f4d0206192b5 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 14 Aug 2018 12:20:27 +0200 Subject: [PATCH] Fix several bugs/badly done stuff in PLY IO --- .../include/CGAL/IO/read_ply_points.h | 55 ++++++++++++++--- .../include/CGAL/IO/write_ply_points.h | 59 +++++++++++++++---- 2 files changed, 92 insertions(+), 22 deletions(-) diff --git a/Point_set_processing_3/include/CGAL/IO/read_ply_points.h b/Point_set_processing_3/include/CGAL/IO/read_ply_points.h index f6322ceef2a..d96d61c76b1 100644 --- a/Point_set_processing_3/include/CGAL/IO/read_ply_points.h +++ b/Point_set_processing_3/include/CGAL/IO/read_ply_points.h @@ -91,25 +91,44 @@ namespace CGAL { PLY_property (const char* name) : name (name) { } }; + /// \cond SKIP_IN_MANUAL + template + struct GetFTFromMap + { + typedef typename Kernel_traits::value_type>::Kernel::FT type; + }; + /// \endcond + /** \ingroup PkgPointSetProcessingIOPly Generates a %PLY property handler to read 3D points. Points are - constructed from the input using 3 %PLY properties of type - `double` and named `x`, `y` and `z`. + constructed from the input using 3 %PLY properties of type `FT` + and named `x`, `y` and `z`. `FT` is `float` if the points use + `CGAL::Simple_cartesian` and `double` otherwise. \sa `read_ply_points_with_properties()` \tparam PointMap the property map used to store points. */ template +#ifdef DOXYGEN_RUNNING std::tuple::Kernel::Construct_point_3, - PLY_property, PLY_property, PLY_property > + PLY_property, PLY_property, PLY_property > +#else + std::tuple::Kernel::Construct_point_3, + PLY_property::type>, + PLY_property::type>, + PLY_property::type> > +#endif make_ply_point_reader(PointMap point_map) { return std::make_tuple (point_map, typename Kernel_traits::Kernel::Construct_point_3(), - PLY_property("x"), PLY_property("y"), PLY_property("z")); + PLY_property::type>("x"), + PLY_property::type>("y"), + PLY_property::type>("z")); } /** @@ -117,20 +136,32 @@ namespace CGAL { Generates a %PLY property handler to read 3D normal vectors. Vectors are constructed from the input using 3 PLY - properties of type `double` and named `nx`, `ny` and `nz`. + properties of type `FT` and named `nx`, `ny` and `nz`. `FT` + is `float` if the points use `CGAL::Simple_cartesian` and + `double` otherwise. \sa `read_ply_points_with_properties()` \tparam VectorMap the property map used to store vectors. */ template +#ifdef DOXYGEN_RUNNING std::tuple::Kernel::Construct_vector_3, - PLY_property, PLY_property, PLY_property > + PLY_property, PLY_property, PLY_property > +#else + std::tuple::Kernel::Construct_vector_3, + PLY_property::type>, + PLY_property::type>, + PLY_property::type> > +#endif make_ply_normal_reader(VectorMap normal_map) { return std::make_tuple (normal_map, typename Kernel_traits::Kernel::Construct_vector_3(), - PLY_property("nx"), PLY_property("ny"), PLY_property("nz")); + PLY_property::type>("nx"), + PLY_property::type>("ny"), + PLY_property::type>("nz")); } /// \cond SKIP_IN_MANUAL @@ -157,13 +188,19 @@ namespace internal { // The two following functions prevent the stream to only extract // ONE character (= what the types char imply) by requiring // explicitely an integer object when reading the stream - void read_ascii (std::istream& stream, boost::int8_t& c) const + void read_ascii (std::istream& stream, char& c) const { short s; stream >> s; c = static_cast(s); } - void read_ascii (std::istream& stream, boost::uint8_t& c) const + void read_ascii (std::istream& stream, signed char& c) const + { + short s; + stream >> s; + c = static_cast(s); + } + void read_ascii (std::istream& stream, unsigned char& c) const { unsigned short s; stream >> s; diff --git a/Point_set_processing_3/include/CGAL/IO/write_ply_points.h b/Point_set_processing_3/include/CGAL/IO/write_ply_points.h index c2b60e4f337..6da878abb1b 100644 --- a/Point_set_processing_3/include/CGAL/IO/write_ply_points.h +++ b/Point_set_processing_3/include/CGAL/IO/write_ply_points.h @@ -49,36 +49,58 @@ namespace CGAL { \ingroup PkgPointSetProcessingIOPly Generates a %PLY property handler to write 3D points. Points are - written as 3 %PLY properties of type `double` and named `x`, `y` - and `z`. + written as 3 %PLY properties of type `FT` and named `x`, `y` and + `z`. `FT` is `float` if the points use + `CGAL::Simple_cartesian` and `double` otherwise. \sa `write_ply_points_with_properties()` \tparam PointMap the property map used to store points. */ template - std::tuple, PLY_property, PLY_property > +#ifdef DOXYGEN_RUNNING + std::tuple, PLY_property, PLY_property > +#else + std::tuple::type>, + PLY_property::type>, + PLY_property::type> > +#endif make_ply_point_writer(PointMap point_map) { - return std::make_tuple (point_map, PLY_property("x"), PLY_property("y"), PLY_property("z")); + return std::make_tuple (point_map, + PLY_property::type>("x"), + PLY_property::type>("y"), + PLY_property::type>("z")); } /** \ingroup PkgPointSetProcessingIOPly Generates a %PLY property handler to write 3D normal - vectors. Vectors are written as 3 %PLY properties of type `double` - and named `nx`, `ny` and `nz`. + vectors. Vectors are written as 3 %PLY properties of type `FT` + and named `nx`, `ny` and `nz`. `FT` is `float` if the vectors use + `CGAL::Simple_cartesian` and `double` otherwise. \sa `write_ply_points_with_properties()` \tparam VectorMap the property map used to store vectors. */ template - std::tuple, PLY_property, PLY_property > +#ifdef DOXYGEN_RUNNING + std::tuple, PLY_property, PLY_property > +#else + std::tuple::type>, + PLY_property::type>, + PLY_property::type> > +#endif make_ply_normal_writer(VectorMap normal_map) { - return std::make_tuple (normal_map, PLY_property("nx"), PLY_property("ny"), PLY_property("nz")); + return std::make_tuple (normal_map, + PLY_property::type>("nx"), + PLY_property::type>("ny"), + PLY_property::type>("nz")); } /// \cond SKIP_IN_MANUAL @@ -87,9 +109,14 @@ namespace internal { namespace PLY { - template void property_header_type (std::ostream& stream) { stream << "undefined_type"; } + template void property_header_type (std::ostream& stream) + { + CGAL_assertion_msg (false, "Unknown PLY type"); + stream << "undefined_type"; + } template <> void property_header_type (std::ostream& stream) { stream << "char"; } + template <> void property_header_type (std::ostream& stream) { stream << "char"; } template <> void property_header_type (std::ostream& stream) { stream << "uchar"; } template <> void property_header_type (std::ostream& stream) { stream << "short"; } template <> void property_header_type (std::ostream& stream) { stream << "ushort"; } @@ -187,14 +214,20 @@ namespace internal { stream << CGAL::oformat(get (map, *it)); } + template + T no_char_character (const T& t) { return t; } + int no_char_character (const char& t) { return int(t); } + int no_char_character (const signed char& t) { return int(t); } + int no_char_character (const unsigned char& t) { return int(t); } + template void simple_property_write (std::ostream& stream, ForwardIterator it, - std::pair >&& map) + std::pair > map) { if (CGAL::get_mode(stream) == IO::ASCII) - stream << get (map.first, *it); + stream << no_char_character(get (map.first, *it)); else { typename PropertyMap::value_type value = get(map.first, *it); @@ -214,7 +247,7 @@ namespace internal { { stream << value.size(); for (std::size_t i = 0; i < value.size(); ++ i) - stream << " " << value[i]; + stream << " " << no_char_character(value[i]); } else { @@ -262,7 +295,7 @@ namespace internal { void output_properties (std::ostream& stream, ForwardIterator it, std::pair >&& current, - NextPropertyHandler& next, + NextPropertyHandler&& next, PropertyHandler&& ... properties) { simple_property_write (stream, it, current);