41 #ifndef PCL_IO_PLY_PLY_PARSER_H
42 #define PCL_IO_PLY_PLY_PARSER_H
51 #include <boost/function.hpp>
52 #include <boost/tuple/tuple.hpp>
53 #include <boost/shared_ptr.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>
65 #ifdef BUILD_Maintainer
67 # if __GNUC__ == 4 && __GNUC_MINOR__ > 3
68 # pragma GCC diagnostic ignored "-Weffc++"
69 # pragma GCC diagnostic ignored "-pedantic"
71 # pragma GCC system_header
73 # elif defined _MSC_VER
74 # pragma warning(push, 1)
109 template <
typename ScalarType>
112 typedef boost::function<void (ScalarType)>
type;
115 template <
typename ScalarType>
119 typedef boost::function<scalar_property_callback_type (const std::string&, const std::string&)>
type;
122 typedef boost::mpl::vector<int8, int16, int32, uint8, uint16, uint32, float32, float64>
scalar_types;
127 template <
typename T>
128 struct callbacks_element
131 typedef T scalar_type;
135 typedef boost::mpl::inherit_linearly<
139 callbacks_element<boost::mpl::_2>
142 callbacks callbacks_;
145 template <
typename ScalarType>
149 return (
static_cast<const callbacks_element<ScalarType>&
> (callbacks_).callback);
152 template <
typename ScalarType>
156 return (
static_cast<callbacks_element<ScalarType>&
> (callbacks_).callback);
159 template <
typename ScalarType>
163 return (scalar_property_definition_callbacks.
get<ScalarType> ());
166 template <
typename ScalarType>
170 return (scalar_property_definition_callbacks.
get<ScalarType> ());
174 template <
typename SizeType,
typename ScalarType>
177 typedef boost::function<void (SizeType)>
type;
180 template <
typename SizeType,
typename ScalarType>
183 typedef boost::function<void (ScalarType)>
type;
186 template <
typename SizeType,
typename ScalarType>
189 typedef boost::function<void ()>
type;
192 template <
typename SizeType,
typename ScalarType>
198 typedef boost::function<
203 > (
const std::string&,
const std::string&)>
type;
206 typedef boost::mpl::vector<uint8, uint16, uint32>
size_types;
211 template <
typename T>
struct pair_with : boost::mpl::pair<T,boost::mpl::_> {};
212 template<
typename Sequence1,
typename Sequence2>
214 struct sequence_product :
215 boost::mpl::fold<Sequence1, boost::mpl::vector0<>,
216 boost::mpl::joint_view<
217 boost::mpl::_1,boost::mpl::transform<Sequence2, pair_with<boost::mpl::_2> > > >
220 template <
typename T>
221 struct callbacks_element
223 typedef typename T::first size_type;
224 typedef typename T::second scalar_type;
228 typedef boost::mpl::inherit_linearly<sequence_product<size_types, scalar_types>::type, boost::mpl::inherit<boost::mpl::_1, callbacks_element<boost::mpl::_2> > >::type callbacks;
229 callbacks callbacks_;
232 template <
typename SizeType,
typename ScalarType>
236 return (
static_cast<callbacks_element<boost::mpl::pair<SizeType, ScalarType>
>&> (callbacks_).callback);
239 template <
typename SizeType,
typename ScalarType>
243 return (
static_cast<const callbacks_element<boost::mpl::pair<SizeType, ScalarType>
>&> (callbacks_).callback);
246 template <
typename SizeType,
typename ScalarType>
250 return (list_property_definition_callbacks.
get<SizeType, ScalarType> ());
253 template <
typename SizeType,
typename ScalarType>
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 comment_callback_ (), obj_info_callback_ (), end_header_callback_ (),
300 line_number_ (0), current_element_ ()
303 bool parse (
const std::string& filename);
310 property (
const std::string& name) : name (name) {}
311 virtual ~property () {}
316 template <
typename ScalarType>
317 struct scalar_property :
public property
319 typedef ScalarType scalar_type;
320 typedef typename scalar_property_callback_type<scalar_type>::type callback_type;
321 scalar_property (
const std::string& name, callback_type callback)
323 , callback (callback)
325 bool parse (
class ply_parser& ply_parser,
327 std::istream& istream)
329 return ply_parser.parse_scalar_property<scalar_type> (
format, istream, callback);
331 callback_type callback;
334 template <
typename SizeType,
typename ScalarType>
335 struct list_property :
public property
337 typedef SizeType size_type;
338 typedef ScalarType scalar_type;
339 typedef typename list_property_begin_callback_type<size_type, scalar_type>::type begin_callback_type;
340 typedef typename list_property_element_callback_type<size_type, scalar_type>::type element_callback_type;
341 typedef typename list_property_end_callback_type<size_type, scalar_type>::type end_callback_type;
342 list_property (
const std::string& name,
343 begin_callback_type begin_callback,
344 element_callback_type element_callback,
345 end_callback_type end_callback)
347 , begin_callback (begin_callback)
348 , element_callback (element_callback)
349 , end_callback (end_callback)
351 bool parse (
class ply_parser& ply_parser,
353 std::istream& istream)
355 return ply_parser.parse_list_property<size_type, scalar_type> (
format,
361 begin_callback_type begin_callback;
362 element_callback_type element_callback;
363 end_callback_type end_callback;
368 element (
const std::string& name,
370 const begin_element_callback_type& begin_element_callback,
371 const end_element_callback_type& end_element_callback)
374 , begin_element_callback (begin_element_callback)
375 , end_element_callback (end_element_callback)
380 begin_element_callback_type begin_element_callback;
381 end_element_callback_type end_element_callback;
382 std::vector<boost::shared_ptr<property> > properties;
387 info_callback_type info_callback_;
388 warning_callback_type warning_callback_;
389 error_callback_type error_callback_;
391 magic_callback_type magic_callback_;
392 format_callback_type format_callback_;
393 element_definition_callback_type element_definition_callbacks_;
394 scalar_property_definition_callbacks_type scalar_property_definition_callbacks_;
395 list_property_definition_callbacks_type list_property_definition_callbacks_;
396 comment_callback_type comment_callback_;
397 obj_info_callback_type obj_info_callback_;
398 end_header_callback_type end_header_callback_;
400 template <
typename ScalarType>
inline void
401 parse_scalar_property_definition (
const std::string& property_name);
403 template <
typename SizeType,
typename ScalarType>
inline void
404 parse_list_property_definition (
const std::string& property_name);
406 template <
typename ScalarType>
inline bool
408 std::istream& istream,
409 const typename scalar_property_callback_type<ScalarType>::type& scalar_property_callback);
411 template <
typename SizeType,
typename ScalarType>
inline bool
413 std::istream& istream,
414 const typename list_property_begin_callback_type<SizeType, ScalarType>::type& list_property_begin_callback,
415 const typename list_property_element_callback_type<SizeType, ScalarType>::type& list_property_element_callback,
416 const typename list_property_end_callback_type<SizeType, ScalarType>::type& list_property_end_callback);
418 std::size_t line_number_;
419 element* current_element_;
438 warning_callback_ = warning_callback;
443 error_callback_ = error_callback;
448 magic_callback_ = magic_callback;
453 format_callback_ = format_callback;
458 element_definition_callbacks_ = element_definition_callback;
463 scalar_property_definition_callbacks_ = scalar_property_definition_callbacks;
468 list_property_definition_callbacks_ = list_property_definition_callbacks;
473 comment_callback_ = comment_callback;
478 obj_info_callback_ = obj_info_callback;
483 end_header_callback_ = end_header_callback;
486 template <
typename ScalarType>
487 inline void pcl::io::ply::ply_parser::parse_scalar_property_definition (
const std::string& property_name)
489 typedef ScalarType scalar_type;
490 typename scalar_property_definition_callback_type<scalar_type>::type& scalar_property_definition_callback =
491 scalar_property_definition_callbacks_.get<scalar_type> ();
492 typename scalar_property_callback_type<scalar_type>::type scalar_property_callback;
493 if (scalar_property_definition_callback)
495 scalar_property_callback = scalar_property_definition_callback (current_element_->name, property_name);
497 if (!scalar_property_callback)
499 if (warning_callback_)
501 warning_callback_ (line_number_,
502 "property '" + std::string (type_traits<scalar_type>::name ()) +
" " +
503 property_name +
"' of element '" + current_element_->name +
"' is not handled");
506 current_element_->properties.push_back (boost::shared_ptr<property> (
new scalar_property<scalar_type> (property_name, scalar_property_callback)));
509 template <
typename SizeType,
typename ScalarType>
510 inline void pcl::io::ply::ply_parser::parse_list_property_definition (
const std::string& property_name)
512 typedef SizeType size_type;
513 typedef ScalarType scalar_type;
514 typename list_property_definition_callback_type<size_type, scalar_type>::type& list_property_definition_callback =
515 list_property_definition_callbacks_.get<size_type, scalar_type> ();
516 typedef typename list_property_begin_callback_type<size_type, scalar_type>::type list_property_begin_callback_type;
517 typedef typename list_property_element_callback_type<size_type, scalar_type>::type list_property_element_callback_type;
518 typedef typename list_property_end_callback_type<size_type, scalar_type>::type list_property_end_callback_type;
519 boost::tuple<list_property_begin_callback_type, list_property_element_callback_type, list_property_end_callback_type> list_property_callbacks;
520 if (list_property_definition_callback)
522 list_property_callbacks = list_property_definition_callback (current_element_->name, property_name);
524 if (!boost::get<0> (list_property_callbacks) || !boost::get<1> (list_property_callbacks) || !boost::get<2> (list_property_callbacks))
526 if (warning_callback_)
528 warning_callback_ (line_number_,
529 "property 'list " + std::string (type_traits<size_type>::name ()) +
" " +
530 std::string (type_traits<scalar_type>::name ()) +
" " +
531 property_name +
"' of element '" +
532 current_element_->name +
"' is not handled");
535 current_element_->properties.push_back (boost::shared_ptr<property> (
536 new list_property<size_type, scalar_type> (
538 boost::get<0> (list_property_callbacks),
539 boost::get<1> (list_property_callbacks),
540 boost::get<2> (list_property_callbacks))));
543 template <
typename ScalarType>
545 std::istream& istream,
546 const typename scalar_property_callback_type<ScalarType>::type& scalar_property_callback)
548 using namespace io_operators;
549 typedef ScalarType scalar_type;
552 scalar_type value = std::numeric_limits<scalar_type>::quiet_NaN ();
556 istream >> space >> std::ws;
557 if (!istream || !isspace (space))
560 error_callback_ (line_number_,
"parse error");
563 if (scalar_property_callback)
564 scalar_property_callback (value);
569 scalar_type value = std::numeric_limits<scalar_type>::quiet_NaN ();
570 istream.read (reinterpret_cast<char*> (&value),
sizeof (scalar_type));
574 error_callback_ (line_number_,
"parse error");
580 if (scalar_property_callback)
581 scalar_property_callback (value);
586 template <
typename SizeType,
typename ScalarType>
587 inline bool pcl::io::ply::ply_parser::parse_list_property (
format_type format, std::istream& istream,
588 const typename list_property_begin_callback_type<SizeType, ScalarType>::type& list_property_begin_callback,
589 const typename list_property_element_callback_type<SizeType, ScalarType>::type& list_property_element_callback,
590 const typename list_property_end_callback_type<SizeType, ScalarType>::type& list_property_end_callback)
592 using namespace io_operators;
593 typedef SizeType size_type;
594 typedef ScalarType scalar_type;
597 size_type size = std::numeric_limits<size_type>::infinity ();
602 istream >> space >> std::ws;
604 if (!istream || !isspace (space))
608 error_callback_ (line_number_,
"parse error");
612 if (list_property_begin_callback)
614 list_property_begin_callback (size);
616 for (std::size_t index = 0; index < size; ++index)
618 scalar_type value = std::numeric_limits<scalar_type>::quiet_NaN ();
623 istream >> space >> std::ws;
625 if (!istream || !isspace (space))
629 error_callback_ (line_number_,
"parse error");
633 if (list_property_element_callback)
635 list_property_element_callback (value);
638 if (list_property_end_callback)
640 list_property_end_callback ();
646 size_type size = std::numeric_limits<size_type>::infinity ();
647 istream.read (reinterpret_cast<char*> (&size),
sizeof (size_type));
657 error_callback_ (line_number_,
"parse error");
661 if (list_property_begin_callback)
663 list_property_begin_callback (size);
665 for (std::size_t index = 0; index < size; ++index) {
666 scalar_type value = std::numeric_limits<scalar_type>::quiet_NaN ();
667 istream.read (reinterpret_cast<char*> (&value),
sizeof (scalar_type));
669 if (error_callback_) {
670 error_callback_ (line_number_,
"parse error");
679 if (list_property_element_callback)
681 list_property_element_callback (value);
684 if (list_property_end_callback)
686 list_property_end_callback ();
692 #ifdef BUILD_Maintainer
693 # if defined __GNUC__
694 # if __GNUC__ == 4 && __GNUC_MINOR__ > 3
695 # pragma GCC diagnostic warning "-Weffc++"
696 # pragma GCC diagnostic warning "-pedantic"
698 # elif defined _MSC_VER
699 # pragma warning(pop)
703 #endif // PCL_IO_PLY_PLY_PARSER_H