41 #ifndef PCL_IO_PLY_PLY_PARSER_H
42 #define PCL_IO_PLY_PLY_PARSER_H
51 #ifdef BUILD_Maintainer
53 # if __GNUC__ == 4 && __GNUC_MINOR__ > 3
54 # pragma GCC diagnostic ignored "-Weffc++"
55 # pragma GCC diagnostic ignored "-pedantic"
57 # pragma GCC system_header
59 # elif defined _MSC_VER
60 # pragma warning(push, 1)
64 #include <pcl/io/boost.h>
68 #include <pcl/pcl_macros.h>
101 template <
typename ScalarType>
104 typedef boost::function<void (ScalarType)>
type;
107 template <
typename ScalarType>
114 typedef boost::mpl::vector<int8, int16, int32, uint8, uint16, uint32, float32, float64>
scalar_types;
119 template <
typename T>
120 struct callbacks_element
123 typedef T scalar_type;
127 typedef boost::mpl::inherit_linearly<
131 callbacks_element<boost::mpl::_2>
134 callbacks callbacks_;
137 template <
typename ScalarType>
141 return (
static_cast<const callbacks_element<ScalarType>&
> (callbacks_).callback);
144 template <
typename ScalarType>
148 return (
static_cast<callbacks_element<ScalarType>&
> (callbacks_).callback);
151 template <
typename ScalarType>
155 template <
typename ScalarType>
160 template <
typename ScalarType>
static
161 typename scalar_property_definition_callback_type<ScalarType>::type&
164 return (scalar_property_definition_callbacks.
get<ScalarType> ());
168 template <
typename ScalarType>
static
169 const typename scalar_property_definition_callback_type<ScalarType>::type&
172 return (scalar_property_definition_callbacks.
get<ScalarType> ());
175 template <
typename SizeType,
typename ScalarType>
178 typedef boost::function<void (SizeType)>
type;
181 template <
typename SizeType,
typename ScalarType>
184 typedef boost::function<void (ScalarType)>
type;
187 template <
typename SizeType,
typename ScalarType>
190 typedef boost::function<void ()>
type;
193 template <
typename SizeType,
typename ScalarType>
199 typedef boost::function<
204 > (
const std::string&,
const std::string&)>
type;
207 typedef boost::mpl::vector<uint8, uint16, uint32>
size_types;
212 template <
typename T>
struct pair_with : boost::mpl::pair<T,boost::mpl::_> {};
213 template<
typename Sequence1,
typename Sequence2>
215 struct sequence_product :
216 boost::mpl::fold<Sequence1, boost::mpl::vector0<>,
217 boost::mpl::joint_view<
218 boost::mpl::_1,boost::mpl::transform<Sequence2, pair_with<boost::mpl::_2> > > >
221 template <
typename T>
222 struct callbacks_element
224 typedef typename T::first size_type;
225 typedef typename T::second scalar_type;
229 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;
230 callbacks callbacks_;
233 template <
typename SizeType,
typename ScalarType>
237 return (
static_cast<callbacks_element<boost::mpl::pair<SizeType, ScalarType>
>&> (callbacks_).callback);
240 template <
typename SizeType,
typename ScalarType>
244 return (
static_cast<const callbacks_element<boost::mpl::pair<SizeType, ScalarType>
>&> (callbacks_).callback);
247 template <
typename SizeType,
typename ScalarType>
251 template <
typename SizeType,
typename ScalarType>
256 template <
typename SizeType,
typename ScalarType>
static
257 typename list_property_definition_callback_type<SizeType, ScalarType>::type&
260 return (list_property_definition_callbacks.
get<SizeType, ScalarType> ());
263 template <
typename SizeType,
typename ScalarType>
static
264 const typename list_property_definition_callback_type<SizeType, ScalarType>::type&
267 return (list_property_definition_callbacks.
get<SizeType, ScalarType> ());
272 info_callback (
const info_callback_type& info_callback);
275 warning_callback (
const warning_callback_type& warning_callback);
278 error_callback (
const error_callback_type& error_callback);
281 magic_callback (
const magic_callback_type& magic_callback);
284 format_callback (
const format_callback_type& format_callback);
287 element_definition_callback (
const element_definition_callback_type& element_definition_callback);
290 scalar_property_definition_callbacks (
const scalar_property_definition_callbacks_type& scalar_property_definition_callbacks);
293 list_property_definition_callbacks (
const list_property_definition_callbacks_type& list_property_definition_callbacks);
296 comment_callback (
const comment_callback_type& comment_callback);
299 obj_info_callback (
const obj_info_callback_type& obj_info_callback);
302 end_header_callback (
const end_header_callback_type& end_header_callback);
308 comment_callback_ (), obj_info_callback_ (), end_header_callback_ (),
309 line_number_ (0), current_element_ ()
312 bool parse (
const std::string& filename);
319 property (
const std::string& name) : name (name) {}
320 virtual ~property () {}
321 virtual bool parse (
class ply_parser& ply_parser,
format_type format, std::istream& istream) = 0;
325 template <
typename ScalarType>
326 struct scalar_property :
public property
328 typedef ScalarType scalar_type;
330 scalar_property (
const std::string& name, callback_type callback)
332 , callback (callback)
334 bool parse (
class ply_parser& ply_parser,
336 std::istream& istream)
338 return ply_parser.parse_scalar_property<scalar_type> (
format, istream, callback);
340 callback_type callback;
343 template <
typename SizeType,
typename ScalarType>
344 struct list_property :
public property
346 typedef SizeType size_type;
347 typedef ScalarType scalar_type;
351 list_property (
const std::string& name,
352 begin_callback_type begin_callback,
353 element_callback_type element_callback,
354 end_callback_type end_callback)
356 , begin_callback (begin_callback)
357 , element_callback (element_callback)
358 , end_callback (end_callback)
360 bool parse (
class ply_parser& ply_parser,
362 std::istream& istream)
364 return ply_parser.parse_list_property<size_type, scalar_type> (
format,
370 begin_callback_type begin_callback;
371 element_callback_type element_callback;
372 end_callback_type end_callback;
377 element (
const std::string& name,
379 const begin_element_callback_type& begin_element_callback,
380 const end_element_callback_type& end_element_callback)
383 , begin_element_callback (begin_element_callback)
384 , end_element_callback (end_element_callback)
389 begin_element_callback_type begin_element_callback;
390 end_element_callback_type end_element_callback;
391 std::vector<boost::shared_ptr<property> > properties;
394 info_callback_type info_callback_;
395 warning_callback_type warning_callback_;
396 error_callback_type error_callback_;
398 magic_callback_type magic_callback_;
399 format_callback_type format_callback_;
400 element_definition_callback_type element_definition_callbacks_;
401 scalar_property_definition_callbacks_type scalar_property_definition_callbacks_;
402 list_property_definition_callbacks_type list_property_definition_callbacks_;
403 comment_callback_type comment_callback_;
404 obj_info_callback_type obj_info_callback_;
405 end_header_callback_type end_header_callback_;
407 template <
typename ScalarType>
inline void
408 parse_scalar_property_definition (
const std::string& property_name);
410 template <
typename SizeType,
typename ScalarType>
inline void
411 parse_list_property_definition (
const std::string& property_name);
413 template <
typename ScalarType>
inline bool
415 std::istream& istream,
416 const typename scalar_property_callback_type<ScalarType>::type& scalar_property_callback);
418 template <
typename SizeType,
typename ScalarType>
inline bool
420 std::istream& istream,
421 const typename list_property_begin_callback_type<SizeType, ScalarType>::type& list_property_begin_callback,
422 const typename list_property_element_callback_type<SizeType, ScalarType>::type& list_property_element_callback,
423 const typename list_property_end_callback_type<SizeType, ScalarType>::type& list_property_end_callback);
425 std::size_t line_number_;
426 element* current_element_;
445 warning_callback_ = warning_callback;
450 error_callback_ = error_callback;
455 magic_callback_ = magic_callback;
460 format_callback_ = format_callback;
465 element_definition_callbacks_ = element_definition_callback;
470 scalar_property_definition_callbacks_ = scalar_property_definition_callbacks;
475 list_property_definition_callbacks_ = list_property_definition_callbacks;
480 comment_callback_ = comment_callback;
485 obj_info_callback_ = obj_info_callback;
490 end_header_callback_ = end_header_callback;
493 template <
typename ScalarType>
494 inline void pcl::io::ply::ply_parser::parse_scalar_property_definition (
const std::string& property_name)
496 typedef ScalarType scalar_type;
498 scalar_property_definition_callbacks_.get<scalar_type> ();
500 if (scalar_property_definition_callback)
502 scalar_property_callback = scalar_property_definition_callback (current_element_->name, property_name);
504 if (!scalar_property_callback)
506 if (warning_callback_)
508 warning_callback_ (line_number_,
509 "property '" + std::string (type_traits<scalar_type>::name ()) +
" " +
510 property_name +
"' of element '" + current_element_->name +
"' is not handled");
513 current_element_->properties.push_back (boost::shared_ptr<property> (
new scalar_property<scalar_type> (property_name, scalar_property_callback)));
516 template <
typename SizeType,
typename ScalarType>
517 inline void pcl::io::ply::ply_parser::parse_list_property_definition (
const std::string& property_name)
519 typedef SizeType size_type;
520 typedef ScalarType scalar_type;
522 list_property_definition_callback_type& list_property_definition_callback = list_property_definition_callbacks_.get<size_type, scalar_type> ();
526 boost::tuple<list_property_begin_callback_type, list_property_element_callback_type, list_property_end_callback_type> list_property_callbacks;
527 if (list_property_definition_callback)
529 list_property_callbacks = list_property_definition_callback (current_element_->name, property_name);
531 if (!boost::get<0> (list_property_callbacks) || !boost::get<1> (list_property_callbacks) || !boost::get<2> (list_property_callbacks))
533 if (warning_callback_)
535 warning_callback_ (line_number_,
536 "property 'list " + std::string (type_traits<size_type>::name ()) +
" " +
537 std::string (type_traits<scalar_type>::name ()) +
" " +
538 property_name +
"' of element '" +
539 current_element_->name +
"' is not handled");
542 current_element_->properties.push_back (boost::shared_ptr<property> (
543 new list_property<size_type, scalar_type> (
545 boost::get<0> (list_property_callbacks),
546 boost::get<1> (list_property_callbacks),
547 boost::get<2> (list_property_callbacks))));
550 template <
typename ScalarType>
552 std::istream& istream,
553 const typename scalar_property_callback_type<ScalarType>::type& scalar_property_callback)
555 using namespace io_operators;
556 typedef ScalarType scalar_type;
565 value =
static_cast<scalar_type
> (boost::lexical_cast<typename pcl::io::ply::type_traits<scalar_type>::parse_type> (value_s));
567 catch (boost::bad_lexical_cast &)
569 value = std::numeric_limits<scalar_type>::quiet_NaN ();
573 istream >> space >> std::ws;
574 if (!istream || !isspace (space))
577 error_callback_ (line_number_,
"parse error");
580 if (scalar_property_callback)
581 scalar_property_callback (value);
586 scalar_type value = std::numeric_limits<scalar_type>::quiet_NaN ();
587 istream.read (
reinterpret_cast<char*
> (&value),
sizeof (scalar_type));
591 error_callback_ (line_number_,
"parse error");
597 if (scalar_property_callback)
598 scalar_property_callback (value);
603 template <
typename SizeType,
typename ScalarType>
604 inline bool pcl::io::ply::ply_parser::parse_list_property (
format_type format, std::istream& istream,
605 const typename list_property_begin_callback_type<SizeType, ScalarType>::type& list_property_begin_callback,
606 const typename list_property_element_callback_type<SizeType, ScalarType>::type& list_property_element_callback,
607 const typename list_property_end_callback_type<SizeType, ScalarType>::type& list_property_end_callback)
609 using namespace io_operators;
610 typedef SizeType size_type;
611 typedef ScalarType scalar_type;
614 size_type size = std::numeric_limits<size_type>::infinity ();
619 istream >> space >> std::ws;
621 if (!istream || !isspace (space))
625 error_callback_ (line_number_,
"parse error");
629 if (list_property_begin_callback)
631 list_property_begin_callback (size);
633 for (std::size_t index = 0; index < size; ++index)
641 value =
static_cast<scalar_type
> (boost::lexical_cast<typename pcl::io::ply::type_traits<scalar_type>::parse_type> (value_s));
643 catch (boost::bad_lexical_cast &)
645 value = std::numeric_limits<scalar_type>::quiet_NaN ();
650 istream >> space >> std::ws;
652 if (!istream || !isspace (space))
656 error_callback_ (line_number_,
"parse error");
660 if (list_property_element_callback)
662 list_property_element_callback (value);
665 if (list_property_end_callback)
667 list_property_end_callback ();
673 size_type size = std::numeric_limits<size_type>::infinity ();
674 istream.read (
reinterpret_cast<char*
> (&size),
sizeof (size_type));
684 error_callback_ (line_number_,
"parse error");
688 if (list_property_begin_callback)
690 list_property_begin_callback (size);
692 for (std::size_t index = 0; index < size; ++index) {
693 scalar_type value = std::numeric_limits<scalar_type>::quiet_NaN ();
694 istream.read (
reinterpret_cast<char*
> (&value),
sizeof (scalar_type));
696 if (error_callback_) {
697 error_callback_ (line_number_,
"parse error");
706 if (list_property_element_callback)
708 list_property_element_callback (value);
711 if (list_property_end_callback)
713 list_property_end_callback ();
719 #ifdef BUILD_Maintainer
720 # if defined __GNUC__
721 # if __GNUC__ == 4 && __GNUC_MINOR__ > 3
722 # pragma GCC diagnostic warning "-Weffc++"
723 # pragma GCC diagnostic warning "-pedantic"
725 # elif defined _MSC_VER
726 # pragma warning(pop)
730 #endif // PCL_IO_PLY_PLY_PARSER_H