52 #include <boost/lexical_cast.hpp>
53 #include <boost/mpl/fold.hpp>
54 #include <boost/mpl/inherit.hpp>
55 #include <boost/mpl/inherit_linearly.hpp>
56 #include <boost/mpl/joint_view.hpp>
57 #include <boost/mpl/transform.hpp>
58 #include <boost/mpl/vector.hpp>
91 template <
typename ScalarType>
94 using type = std::function<void (ScalarType)>;
97 template <
typename ScalarType>
104 using scalar_types = boost::mpl::vector<int8, int16, int32, uint8, uint16, uint32, float32, float64>;
109 template <
typename T>
110 struct callbacks_element
113 using scalar_type = T;
117 using callbacks = boost::mpl::inherit_linearly<
121 callbacks_element<boost::mpl::_2>
124 callbacks callbacks_;
127 template <
typename ScalarType>
131 return (
static_cast<const callbacks_element<ScalarType>&
> (callbacks_).callback);
134 template <
typename ScalarType>
138 return (
static_cast<callbacks_element<ScalarType>&
> (callbacks_).callback);
141 template <
typename ScalarType>
145 template <
typename ScalarType>
150 template <
typename ScalarType>
static
154 return (scalar_property_definition_callbacks.
get<ScalarType> ());
158 template <
typename ScalarType>
static
159 const typename scalar_property_definition_callback_type<ScalarType>::type&
162 return (scalar_property_definition_callbacks.
get<ScalarType> ());
165 template <
typename SizeType,
typename ScalarType>
168 using type = std::function<void (SizeType)>;
171 template <
typename SizeType,
typename ScalarType>
174 using type = std::function<void (ScalarType)>;
177 template <
typename SizeType,
typename ScalarType>
180 using type = std::function<void ()>;
183 template <
typename SizeType,
typename ScalarType>
189 using type = std::function<std::tuple<
193 > (
const std::string&,
const std::string&)>;
196 using size_types = boost::mpl::vector<uint8, uint16, uint32>;
201 template <
typename T>
struct pair_with : boost::mpl::pair<T,boost::mpl::_> {};
202 template<
typename Sequence1,
typename Sequence2>
204 struct sequence_product :
205 boost::mpl::fold<Sequence1, boost::mpl::vector0<>,
206 boost::mpl::joint_view<
207 boost::mpl::_1,boost::mpl::transform<Sequence2, pair_with<boost::mpl::_2> > > >
210 template <
typename T>
211 struct callbacks_element
213 using size_type =
typename T::first;
214 using scalar_type =
typename T::second;
218 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;
219 callbacks callbacks_;
222 template <
typename SizeType,
typename ScalarType>
226 return (
static_cast<callbacks_element<boost::mpl::pair<SizeType, ScalarType>
>&> (callbacks_).callback);
229 template <
typename SizeType,
typename ScalarType>
233 return (
static_cast<const callbacks_element<boost::mpl::pair<SizeType, ScalarType>
>&> (callbacks_).callback);
236 template <
typename SizeType,
typename ScalarType>
240 template <
typename SizeType,
typename ScalarType>
245 template <
typename SizeType,
typename ScalarType>
static
249 return (list_property_definition_callbacks.
get<SizeType, ScalarType> ());
252 template <
typename SizeType,
typename ScalarType>
static
253 const typename list_property_definition_callback_type<SizeType, ScalarType>::type&
256 return (list_property_definition_callbacks.
get<SizeType, ScalarType> ());
261 info_callback (
const info_callback_type& info_callback);
264 warning_callback (
const warning_callback_type& warning_callback);
267 error_callback (
const error_callback_type& error_callback);
270 magic_callback (
const magic_callback_type& magic_callback);
273 format_callback (
const format_callback_type& format_callback);
276 element_definition_callback (
const element_definition_callback_type& element_definition_callback);
279 scalar_property_definition_callbacks (
const scalar_property_definition_callbacks_type& scalar_property_definition_callbacks);
282 list_property_definition_callbacks (
const list_property_definition_callbacks_type& list_property_definition_callbacks);
285 comment_callback (
const comment_callback_type& comment_callback);
288 obj_info_callback (
const obj_info_callback_type& obj_info_callback);
291 end_header_callback (
const end_header_callback_type& end_header_callback);
297 line_number_ (0), current_element_ ()
300 bool parse (
const std::string& filename);
307 property (
const std::string& name) : name (name) {}
308 virtual ~property () =
default;
313 template <
typename ScalarType>
314 struct scalar_property :
public property
316 using scalar_type = ScalarType;
318 scalar_property (
const std::string& name, callback_type callback)
320 , callback (callback)
322 bool parse (
class ply_parser& ply_parser,
324 std::istream& istream)
override
326 return ply_parser.parse_scalar_property<scalar_type> (
format, istream, callback);
328 callback_type callback;
331 template <
typename SizeType,
typename ScalarType>
332 struct list_property :
public property
334 using size_type = SizeType;
335 using scalar_type = ScalarType;
339 list_property (
const std::string& name,
340 begin_callback_type begin_callback,
341 element_callback_type element_callback,
342 end_callback_type end_callback)
344 , begin_callback (begin_callback)
345 , element_callback (element_callback)
346 , end_callback (end_callback)
348 bool parse (
class ply_parser& ply_parser,
350 std::istream& istream)
override
352 return ply_parser.parse_list_property<size_type, scalar_type> (
format,
358 begin_callback_type begin_callback;
359 element_callback_type element_callback;
360 end_callback_type end_callback;
365 element (
const std::string& name,
367 const begin_element_callback_type& begin_element_callback,
368 const end_element_callback_type& end_element_callback)
371 , begin_element_callback (begin_element_callback)
372 , end_element_callback (end_element_callback)
376 begin_element_callback_type begin_element_callback;
377 end_element_callback_type end_element_callback;
378 std::vector<std::shared_ptr<property>> properties;
381 info_callback_type info_callback_ = [](std::size_t,
const std::string&){};
382 warning_callback_type warning_callback_ = [](std::size_t,
const std::string&){};
383 error_callback_type error_callback_ = [](std::size_t,
const std::string&){};
385 magic_callback_type magic_callback_ = [](){};
386 format_callback_type format_callback_ = [](
format_type,
const std::string&){};
387 comment_callback_type comment_callback_ = [](
const std::string&){};
388 obj_info_callback_type obj_info_callback_ = [](
const std::string&){};
389 end_header_callback_type end_header_callback_ = [](){
return true;};
391 element_definition_callback_type element_definition_callbacks_ =
392 [](
const std::string&, std::size_t)
394 return std::make_tuple([](){}, [](){});
396 scalar_property_definition_callbacks_type scalar_property_definition_callbacks_;
397 list_property_definition_callbacks_type list_property_definition_callbacks_;
399 template <
typename ScalarType>
inline void
400 parse_scalar_property_definition (
const std::string& property_name);
402 template <
typename SizeType,
typename ScalarType>
inline void
403 parse_list_property_definition (
const std::string& property_name);
405 template <
typename ScalarType>
inline bool
407 std::istream& istream,
408 const typename scalar_property_callback_type<ScalarType>::type& scalar_property_callback);
410 template <
typename SizeType,
typename ScalarType>
inline bool
412 std::istream& istream,
413 const typename list_property_begin_callback_type<SizeType, ScalarType>::type& list_property_begin_callback,
414 const typename list_property_element_callback_type<SizeType, ScalarType>::type& list_property_element_callback,
415 const typename list_property_end_callback_type<SizeType, ScalarType>::type& list_property_end_callback);
417 std::size_t line_number_;
418 element* current_element_;
437 warning_callback_ = warning_callback;
442 error_callback_ = error_callback;
447 magic_callback_ = magic_callback;
452 format_callback_ = format_callback;
457 element_definition_callbacks_ = element_definition_callback;
462 scalar_property_definition_callbacks_ = scalar_property_definition_callbacks;
467 list_property_definition_callbacks_ = list_property_definition_callbacks;
472 comment_callback_ = comment_callback;
477 obj_info_callback_ = obj_info_callback;
482 end_header_callback_ = end_header_callback;
485 template <
typename ScalarType>
486 inline void pcl::io::ply::ply_parser::parse_scalar_property_definition (
const std::string& property_name)
488 using scalar_type = ScalarType;
490 scalar_property_definition_callbacks_.get<scalar_type> ();
492 if (scalar_property_definition_callback)
494 scalar_property_callback = scalar_property_definition_callback (current_element_->name, property_name);
496 if (!scalar_property_callback)
498 if (warning_callback_)
500 warning_callback_ (line_number_,
501 "property '" + std::string (type_traits<scalar_type>::name ()) +
" " +
502 property_name +
"' of element '" + current_element_->name +
"' is not handled");
505 current_element_->properties.emplace_back (
new scalar_property<scalar_type> (property_name, scalar_property_callback));
508 template <
typename SizeType,
typename ScalarType>
509 inline void pcl::io::ply::ply_parser::parse_list_property_definition (
const std::string& property_name)
511 using size_type = SizeType;
512 using scalar_type = ScalarType;
514 list_property_definition_callback_type& list_property_definition_callback = list_property_definition_callbacks_.get<size_type, scalar_type> ();
518 std::tuple<list_property_begin_callback_type, list_property_element_callback_type, list_property_end_callback_type> list_property_callbacks;
519 if (list_property_definition_callback)
521 list_property_callbacks = list_property_definition_callback (current_element_->name, property_name);
523 if (!std::get<0> (list_property_callbacks) || !std::get<1> (list_property_callbacks) || !std::get<2> (list_property_callbacks))
525 if (warning_callback_)
527 warning_callback_ (line_number_,
528 "property 'list " + std::string (type_traits<size_type>::name ()) +
" " +
529 std::string (type_traits<scalar_type>::name ()) +
" " +
530 property_name +
"' of element '" +
531 current_element_->name +
"' is not handled");
534 current_element_->properties.emplace_back (
new list_property<size_type, scalar_type> (
536 std::get<0> (list_property_callbacks),
537 std::get<1> (list_property_callbacks),
538 std::get<2> (list_property_callbacks)));
541 template <
typename ScalarType>
543 std::istream& istream,
544 const typename scalar_property_callback_type<ScalarType>::type& scalar_property_callback)
546 using namespace io_operators;
547 using scalar_type = ScalarType;
556 value =
static_cast<scalar_type
> (boost::lexical_cast<typename pcl::io::ply::type_traits<scalar_type>::parse_type> (value_s));
558 catch (boost::bad_lexical_cast &)
560 value = std::numeric_limits<scalar_type>::quiet_NaN ();
564 istream >> space >> std::ws;
565 if (!istream || !isspace (space))
568 error_callback_ (line_number_,
"parse error");
571 if (scalar_property_callback)
572 scalar_property_callback (value);
575 scalar_type value = std::numeric_limits<scalar_type>::quiet_NaN ();
576 istream.read (
reinterpret_cast<char*
> (&value),
sizeof (scalar_type));
580 error_callback_ (line_number_,
"parse error");
586 if (scalar_property_callback)
587 scalar_property_callback (value);
591 template <
typename SizeType,
typename ScalarType>
592 inline bool pcl::io::ply::ply_parser::parse_list_property (
format_type format, std::istream& istream,
593 const typename list_property_begin_callback_type<SizeType, ScalarType>::type& list_property_begin_callback,
594 const typename list_property_element_callback_type<SizeType, ScalarType>::type& list_property_element_callback,
595 const typename list_property_end_callback_type<SizeType, ScalarType>::type& list_property_end_callback)
597 using namespace io_operators;
598 using size_type = SizeType;
599 using scalar_type = ScalarType;
602 size_type size = std::numeric_limits<size_type>::infinity ();
607 istream >> space >> std::ws;
609 if (!istream || !isspace (space))
613 error_callback_ (line_number_,
"parse error");
617 if (list_property_begin_callback)
619 list_property_begin_callback (size);
621 for (std::size_t index = 0; index < size; ++index)
629 value =
static_cast<scalar_type
> (boost::lexical_cast<typename pcl::io::ply::type_traits<scalar_type>::parse_type> (value_s));
631 catch (boost::bad_lexical_cast &)
633 value = std::numeric_limits<scalar_type>::quiet_NaN ();
638 istream >> space >> std::ws;
640 if (!istream || !isspace (space))
644 error_callback_ (line_number_,
"parse error");
648 if (list_property_element_callback)
650 list_property_element_callback (value);
653 if (list_property_end_callback)
655 list_property_end_callback ();
659 size_type size = std::numeric_limits<size_type>::infinity ();
660 istream.read (
reinterpret_cast<char*
> (&size),
sizeof (size_type));
670 error_callback_ (line_number_,
"parse error");
674 if (list_property_begin_callback)
676 list_property_begin_callback (size);
678 for (std::size_t index = 0; index < size; ++index) {
679 scalar_type value = std::numeric_limits<scalar_type>::quiet_NaN ();
680 istream.read (
reinterpret_cast<char*
> (&value),
sizeof (scalar_type));
682 if (error_callback_) {
683 error_callback_ (line_number_,
"parse error");
692 if (list_property_element_callback)
694 list_property_element_callback (value);
697 if (list_property_end_callback)
699 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