53 #include <boost/lexical_cast.hpp>
54 #include <boost/mpl/fold.hpp>
55 #include <boost/mpl/inherit.hpp>
56 #include <boost/mpl/inherit_linearly.hpp>
57 #include <boost/mpl/joint_view.hpp>
58 #include <boost/mpl/transform.hpp>
59 #include <boost/mpl/vector.hpp>
92 template <
typename ScalarType>
95 using type = std::function<void (ScalarType)>;
98 template <
typename ScalarType>
105 using scalar_types = boost::mpl::vector<int8, int16, int32, uint8, uint16, uint32, float32, float64>;
110 template <
typename T>
111 struct callbacks_element
114 using scalar_type = T;
118 using callbacks = boost::mpl::inherit_linearly<
122 callbacks_element<boost::mpl::_2>
125 callbacks callbacks_;
128 template <
typename ScalarType>
132 return (
static_cast<const callbacks_element<ScalarType>&
> (callbacks_).callback);
135 template <
typename ScalarType>
139 return (
static_cast<callbacks_element<ScalarType>&
> (callbacks_).callback);
142 template <
typename ScalarType>
146 template <
typename ScalarType>
151 template <
typename ScalarType>
static
155 return (scalar_property_definition_callbacks.
get<ScalarType> ());
159 template <
typename ScalarType>
static
160 const typename scalar_property_definition_callback_type<ScalarType>::type&
163 return (scalar_property_definition_callbacks.
get<ScalarType> ());
166 template <
typename SizeType,
typename ScalarType>
169 using type = std::function<void (SizeType)>;
172 template <
typename SizeType,
typename ScalarType>
175 using type = std::function<void (ScalarType)>;
178 template <
typename SizeType,
typename ScalarType>
181 using type = std::function<void ()>;
184 template <
typename SizeType,
typename ScalarType>
190 using type = std::function<std::tuple<
194 > (
const std::string&,
const std::string&)>;
197 using size_types = boost::mpl::vector<uint8, uint16, uint32>;
202 template <
typename T>
struct pair_with : boost::mpl::pair<T,boost::mpl::_> {};
203 template<
typename Sequence1,
typename Sequence2>
205 struct sequence_product :
206 boost::mpl::fold<Sequence1, boost::mpl::vector0<>,
207 boost::mpl::joint_view<
208 boost::mpl::_1,boost::mpl::transform<Sequence2, pair_with<boost::mpl::_2> > > >
211 template <
typename T>
212 struct callbacks_element
214 using size_type =
typename T::first;
215 using scalar_type =
typename T::second;
219 using callbacks = boost::mpl::inherit_linearly<sequence_product<size_types, scalar_types>::type, boost::mpl::inherit<boost::mpl::_1, callbacks_element<boost::mpl::_2> > >::type;
220 callbacks callbacks_;
223 template <
typename SizeType,
typename ScalarType>
227 return (
static_cast<callbacks_element<boost::mpl::pair<SizeType, ScalarType>
>&> (callbacks_).callback);
230 template <
typename SizeType,
typename ScalarType>
234 return (
static_cast<const callbacks_element<boost::mpl::pair<SizeType, ScalarType>
>&> (callbacks_).callback);
237 template <
typename SizeType,
typename ScalarType>
241 template <
typename SizeType,
typename ScalarType>
246 template <
typename SizeType,
typename ScalarType>
static
250 return (list_property_definition_callbacks.
get<SizeType, ScalarType> ());
253 template <
typename SizeType,
typename ScalarType>
static
254 const typename list_property_definition_callback_type<SizeType, ScalarType>::type&
257 return (list_property_definition_callbacks.
get<SizeType, ScalarType> ());
262 info_callback (
const info_callback_type& info_callback);
265 warning_callback (
const warning_callback_type& warning_callback);
268 error_callback (
const error_callback_type& error_callback);
271 magic_callback (
const magic_callback_type& magic_callback);
274 format_callback (
const format_callback_type& format_callback);
277 element_definition_callback (
const element_definition_callback_type& element_definition_callback);
280 scalar_property_definition_callbacks (
const scalar_property_definition_callbacks_type& scalar_property_definition_callbacks);
283 list_property_definition_callbacks (
const list_property_definition_callbacks_type& list_property_definition_callbacks);
286 comment_callback (
const comment_callback_type& comment_callback);
289 obj_info_callback (
const obj_info_callback_type& obj_info_callback);
292 end_header_callback (
const end_header_callback_type& end_header_callback);
299 bool parse (
const std::string& filename);
306 property (
const std::string& name) : name (name) {}
307 virtual ~property () =
default;
312 template <
typename ScalarType>
313 struct scalar_property :
public property
315 using scalar_type = ScalarType;
317 scalar_property (
const std::string& name, callback_type callback)
319 , callback (callback)
321 bool parse (
class ply_parser& ply_parser,
323 std::istream& istream)
override
325 return ply_parser.parse_scalar_property<scalar_type> (
format, istream, callback);
327 callback_type callback;
330 template <
typename SizeType,
typename ScalarType>
331 struct list_property :
public property
333 using size_type = SizeType;
334 using scalar_type = ScalarType;
338 list_property (
const std::string& name,
339 begin_callback_type begin_callback,
340 element_callback_type element_callback,
341 end_callback_type end_callback)
343 , begin_callback (begin_callback)
344 , element_callback (element_callback)
345 , end_callback (end_callback)
347 bool parse (
class ply_parser& ply_parser,
349 std::istream& istream)
override
351 return ply_parser.parse_list_property<size_type, scalar_type> (
format,
357 begin_callback_type begin_callback;
358 element_callback_type element_callback;
359 end_callback_type end_callback;
364 element (
const std::string& name,
366 const begin_element_callback_type& begin_element_callback,
367 const end_element_callback_type& end_element_callback)
370 , begin_element_callback (begin_element_callback)
371 , end_element_callback (end_element_callback)
375 begin_element_callback_type begin_element_callback;
376 end_element_callback_type end_element_callback;
377 std::vector<std::shared_ptr<property>> properties;
380 info_callback_type info_callback_ = [](std::size_t,
const std::string&){};
381 warning_callback_type warning_callback_ = [](std::size_t,
const std::string&){};
382 error_callback_type error_callback_ = [](std::size_t,
const std::string&){};
384 magic_callback_type magic_callback_ = [](){};
385 format_callback_type format_callback_ = [](
format_type,
const std::string&){};
386 comment_callback_type comment_callback_ = [](
const std::string&){};
387 obj_info_callback_type obj_info_callback_ = [](
const std::string&){};
388 end_header_callback_type end_header_callback_ = [](){
return true;};
390 element_definition_callback_type element_definition_callbacks_ =
391 [](
const std::string&, std::size_t)
393 return std::make_tuple([](){}, [](){});
395 scalar_property_definition_callbacks_type scalar_property_definition_callbacks_;
396 list_property_definition_callbacks_type list_property_definition_callbacks_;
398 template <
typename ScalarType>
inline void
399 parse_scalar_property_definition (
const std::string& property_name);
401 template <
typename SizeType,
typename ScalarType>
inline void
402 parse_list_property_definition (
const std::string& property_name);
404 template <
typename ScalarType>
inline bool
406 std::istream& istream,
407 const typename scalar_property_callback_type<ScalarType>::type& scalar_property_callback);
409 template <
typename SizeType,
typename ScalarType>
inline bool
411 std::istream& istream,
412 const typename list_property_begin_callback_type<SizeType, ScalarType>::type& list_property_begin_callback,
413 const typename list_property_element_callback_type<SizeType, ScalarType>::type& list_property_element_callback,
414 const typename list_property_end_callback_type<SizeType, ScalarType>::type& list_property_end_callback);
416 std::size_t line_number_{0};
417 element* current_element_{
nullptr};
436 warning_callback_ = warning_callback;
441 error_callback_ = error_callback;
446 magic_callback_ = magic_callback;
451 format_callback_ = format_callback;
456 element_definition_callbacks_ = element_definition_callback;
461 scalar_property_definition_callbacks_ = scalar_property_definition_callbacks;
466 list_property_definition_callbacks_ = list_property_definition_callbacks;
471 comment_callback_ = comment_callback;
476 obj_info_callback_ = obj_info_callback;
481 end_header_callback_ = end_header_callback;
484 template <
typename ScalarType>
485 inline void pcl::io::ply::ply_parser::parse_scalar_property_definition (
const std::string& property_name)
487 using scalar_type = ScalarType;
489 scalar_property_definition_callbacks_.get<scalar_type> ();
491 if (scalar_property_definition_callback)
493 scalar_property_callback = scalar_property_definition_callback (current_element_->name, property_name);
495 if (!scalar_property_callback)
497 if (warning_callback_)
499 warning_callback_ (line_number_,
500 "property '" + std::string (type_traits<scalar_type>::name ()) +
" " +
501 property_name +
"' of element '" + current_element_->name +
"' is not handled");
504 current_element_->properties.emplace_back (
new scalar_property<scalar_type> (property_name, scalar_property_callback));
507 template <
typename SizeType,
typename ScalarType>
508 inline void pcl::io::ply::ply_parser::parse_list_property_definition (
const std::string& property_name)
510 using size_type = SizeType;
511 using scalar_type = ScalarType;
513 list_property_definition_callback_type& list_property_definition_callback = list_property_definition_callbacks_.get<size_type, scalar_type> ();
517 std::tuple<list_property_begin_callback_type, list_property_element_callback_type, list_property_end_callback_type> list_property_callbacks;
518 if (list_property_definition_callback)
520 list_property_callbacks = list_property_definition_callback (current_element_->name, property_name);
522 if (!std::get<0> (list_property_callbacks) || !std::get<1> (list_property_callbacks) || !std::get<2> (list_property_callbacks))
524 if (warning_callback_)
526 warning_callback_ (line_number_,
527 "property 'list " + std::string (type_traits<size_type>::name ()) +
" " +
528 std::string (type_traits<scalar_type>::name ()) +
" " +
529 property_name +
"' of element '" +
530 current_element_->name +
"' is not handled");
533 current_element_->properties.emplace_back (
new list_property<size_type, scalar_type> (
535 std::get<0> (list_property_callbacks),
536 std::get<1> (list_property_callbacks),
537 std::get<2> (list_property_callbacks)));
540 template <
typename ScalarType>
542 std::istream& istream,
543 const typename scalar_property_callback_type<ScalarType>::type& scalar_property_callback)
545 using namespace io_operators;
546 using scalar_type = ScalarType;
555 value =
static_cast<scalar_type
> (boost::lexical_cast<typename pcl::io::ply::type_traits<scalar_type>::parse_type> (value_s));
557 catch (boost::bad_lexical_cast &)
559 value = std::numeric_limits<scalar_type>::quiet_NaN ();
563 istream >> space >> std::ws;
564 if (!istream || !isspace (space))
567 error_callback_ (line_number_,
"error while parsing scalar property (file format: ascii)");
570 if (scalar_property_callback)
571 scalar_property_callback (value);
574 scalar_type value = std::numeric_limits<scalar_type>::quiet_NaN ();
575 istream.read (
reinterpret_cast<char*
> (&value),
sizeof (scalar_type));
579 error_callback_ (line_number_,
"error while parsing scalar property (file format: binary)");
585 if (scalar_property_callback)
586 scalar_property_callback (value);
590 template <
typename SizeType,
typename ScalarType>
591 inline bool pcl::io::ply::ply_parser::parse_list_property (
format_type format, std::istream& istream,
592 const typename list_property_begin_callback_type<SizeType, ScalarType>::type& list_property_begin_callback,
593 const typename list_property_element_callback_type<SizeType, ScalarType>::type& list_property_element_callback,
594 const typename list_property_end_callback_type<SizeType, ScalarType>::type& list_property_end_callback)
596 using namespace io_operators;
597 using size_type = SizeType;
598 using scalar_type = ScalarType;
601 size_type size = std::numeric_limits<size_type>::infinity ();
606 istream >> space >> std::ws;
608 if (!istream || !isspace (space))
612 error_callback_ (line_number_,
"error while parsing list (file format: ascii)");
616 if (list_property_begin_callback)
618 list_property_begin_callback (size);
620 for (std::size_t index = 0; index < size; ++index)
628 value =
static_cast<scalar_type
> (boost::lexical_cast<typename pcl::io::ply::type_traits<scalar_type>::parse_type> (value_s));
630 catch (boost::bad_lexical_cast &)
632 value = std::numeric_limits<scalar_type>::quiet_NaN ();
637 istream >> space >> std::ws;
639 if (!istream || !isspace (space))
643 error_callback_ (line_number_,
"error while parsing list (file format: ascii)");
647 if (list_property_element_callback)
649 list_property_element_callback (value);
652 if (list_property_end_callback)
654 list_property_end_callback ();
658 size_type size = std::numeric_limits<size_type>::infinity ();
659 istream.read (
reinterpret_cast<char*
> (&size),
sizeof (size_type));
669 error_callback_ (line_number_,
"error while parsing list (file format: binary)");
673 if (list_property_begin_callback)
675 list_property_begin_callback (size);
677 for (std::size_t index = 0; index < size; ++index) {
678 scalar_type value = std::numeric_limits<scalar_type>::quiet_NaN ();
679 istream.read (
reinterpret_cast<char*
> (&value),
sizeof (scalar_type));
681 if (error_callback_) {
682 error_callback_ (line_number_,
"error while parsing list (file format: binary)");
691 if (list_property_element_callback)
693 list_property_element_callback (value);
696 if (list_property_end_callback)
698 list_property_end_callback ();
const list_property_definition_callback_type< SizeType, ScalarType >::type & get() const
friend const list_property_definition_callback_type< SizeType, ScalarType >::type & at(const list_property_definition_callbacks_type &list_property_definition_callbacks)
list_property_definition_callback_type< SizeType, ScalarType >::type & get()
friend list_property_definition_callback_type< SizeType, ScalarType >::type & at(list_property_definition_callbacks_type &list_property_definition_callbacks)
friend const scalar_property_definition_callback_type< ScalarType >::type & at(const scalar_property_definition_callbacks_type &scalar_property_definition_callbacks)
const scalar_property_definition_callback_type< ScalarType >::type & get() const
scalar_property_definition_callback_type< ScalarType >::type & get()
friend scalar_property_definition_callback_type< ScalarType >::type & at(scalar_property_definition_callbacks_type &scalar_property_definition_callbacks)
Class ply_parser parses a PLY file and generates appropriate atomic parsers for the body.
void comment_callback(const comment_callback_type &comment_callback)
void error_callback(const error_callback_type &error_callback)
std::tuple< begin_element_callback_type, end_element_callback_type > element_callbacks_type
std::function< void(const std::string &)> obj_info_callback_type
void obj_info_callback(const obj_info_callback_type &obj_info_callback)
std::function< element_callbacks_type(const std::string &, std::size_t)> element_definition_callback_type
void list_property_definition_callbacks(const list_property_definition_callbacks_type &list_property_definition_callbacks)
std::function< void(const std::string &)> comment_callback_type
std::function< void()> magic_callback_type
std::function< void()> begin_element_callback_type
static list_property_definition_callback_type< SizeType, ScalarType >::type & at(list_property_definition_callbacks_type &list_property_definition_callbacks)
void end_header_callback(const end_header_callback_type &end_header_callback)
void info_callback(const info_callback_type &info_callback)
static scalar_property_definition_callback_type< ScalarType >::type & at(scalar_property_definition_callbacks_type &scalar_property_definition_callbacks)
void magic_callback(const magic_callback_type &magic_callback)
std::function< bool()> end_header_callback_type
static const list_property_definition_callback_type< SizeType, ScalarType >::type & at(const list_property_definition_callbacks_type &list_property_definition_callbacks)
void warning_callback(const warning_callback_type &warning_callback)
void format_callback(const format_callback_type &format_callback)
static const scalar_property_definition_callback_type< ScalarType >::type & at(const scalar_property_definition_callbacks_type &scalar_property_definition_callbacks)
boost::mpl::vector< int8, int16, int32, uint8, uint16, uint32, float32, float64 > scalar_types
std::function< void(std::size_t, const std::string &)> error_callback_type
void scalar_property_definition_callbacks(const scalar_property_definition_callbacks_type &scalar_property_definition_callbacks)
bool parse(const std::string &filename)
boost::mpl::vector< uint8, uint16, uint32 > size_types
std::function< void(std::size_t, const std::string &)> info_callback_type
void element_definition_callback(const element_definition_callback_type &element_definition_callback)
std::function< void()> end_element_callback_type
std::function< void(std::size_t, const std::string &)> warning_callback_type
std::function< void(format_type, const std::string &)> format_callback_type
defines output operators for int8 and uint8
int parse(int argc, const char *const *argv, const char *argument_name, Type &value)
Template version for parsing arguments.
void swap_byte_order(char *bytes)
@ little_endian_byte_order
@ binary_little_endian_format
@ binary_big_endian_format
Defines all the PCL and non-PCL macros used.
contains standard typedefs and generic type traits
std::function< void(SizeType)> type
typename list_property_end_callback_type< SizeType, ScalarType >::type list_property_end_callback_type
typename list_property_element_callback_type< SizeType, ScalarType >::type list_property_element_callback_type
std::function< std::tuple< list_property_begin_callback_type, list_property_element_callback_type, list_property_end_callback_type >(const std::string &, const std::string &)> type
typename list_property_begin_callback_type< SizeType, ScalarType >::type list_property_begin_callback_type
std::function< void(ScalarType)> type
std::function< void()> type
std::function< void(ScalarType)> type
typename scalar_property_callback_type< ScalarType >::type scalar_property_callback_type
std::function< scalar_property_callback_type(const std::string &, const std::string &)> type