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);
298 bool parse (
const std::string& filename);
305 property (
const std::string& name) : name (name) {}
306 virtual ~property () =
default;
311 template <
typename ScalarType>
312 struct scalar_property :
public property
314 using scalar_type = ScalarType;
316 scalar_property (
const std::string& name, callback_type callback)
318 , callback (callback)
320 bool parse (
class ply_parser& ply_parser,
322 std::istream& istream)
override
324 return ply_parser.parse_scalar_property<scalar_type> (
format, istream, callback);
326 callback_type callback;
329 template <
typename SizeType,
typename ScalarType>
330 struct list_property :
public property
332 using size_type = SizeType;
333 using scalar_type = ScalarType;
337 list_property (
const std::string& name,
338 begin_callback_type begin_callback,
339 element_callback_type element_callback,
340 end_callback_type end_callback)
342 , begin_callback (begin_callback)
343 , element_callback (element_callback)
344 , end_callback (end_callback)
346 bool parse (
class ply_parser& ply_parser,
348 std::istream& istream)
override
350 return ply_parser.parse_list_property<size_type, scalar_type> (
format,
356 begin_callback_type begin_callback;
357 element_callback_type element_callback;
358 end_callback_type end_callback;
363 element (
const std::string& name,
365 const begin_element_callback_type& begin_element_callback,
366 const end_element_callback_type& end_element_callback)
369 , begin_element_callback (begin_element_callback)
370 , end_element_callback (end_element_callback)
374 begin_element_callback_type begin_element_callback;
375 end_element_callback_type end_element_callback;
376 std::vector<std::shared_ptr<property>> properties;
379 info_callback_type info_callback_ = [](std::size_t,
const std::string&){};
380 warning_callback_type warning_callback_ = [](std::size_t,
const std::string&){};
381 error_callback_type error_callback_ = [](std::size_t,
const std::string&){};
383 magic_callback_type magic_callback_ = [](){};
384 format_callback_type format_callback_ = [](
format_type,
const std::string&){};
385 comment_callback_type comment_callback_ = [](
const std::string&){};
386 obj_info_callback_type obj_info_callback_ = [](
const std::string&){};
387 end_header_callback_type end_header_callback_ = [](){
return true;};
389 element_definition_callback_type element_definition_callbacks_ =
390 [](
const std::string&, std::size_t)
392 return std::make_tuple([](){}, [](){});
394 scalar_property_definition_callbacks_type scalar_property_definition_callbacks_;
395 list_property_definition_callbacks_type list_property_definition_callbacks_;
397 template <
typename ScalarType>
inline void
398 parse_scalar_property_definition (
const std::string& property_name);
400 template <
typename SizeType,
typename ScalarType>
inline void
401 parse_list_property_definition (
const std::string& property_name);
403 template <
typename ScalarType>
inline bool
405 std::istream& istream,
406 const typename scalar_property_callback_type<ScalarType>::type& scalar_property_callback);
408 template <
typename SizeType,
typename ScalarType>
inline bool
410 std::istream& istream,
411 const typename list_property_begin_callback_type<SizeType, ScalarType>::type& list_property_begin_callback,
412 const typename list_property_element_callback_type<SizeType, ScalarType>::type& list_property_element_callback,
413 const typename list_property_end_callback_type<SizeType, ScalarType>::type& list_property_end_callback);
415 std::size_t line_number_{0};
416 element* current_element_{
nullptr};
435 warning_callback_ = warning_callback;
440 error_callback_ = error_callback;
445 magic_callback_ = magic_callback;
450 format_callback_ = format_callback;
455 element_definition_callbacks_ = element_definition_callback;
460 scalar_property_definition_callbacks_ = scalar_property_definition_callbacks;
465 list_property_definition_callbacks_ = list_property_definition_callbacks;
470 comment_callback_ = comment_callback;
475 obj_info_callback_ = obj_info_callback;
480 end_header_callback_ = end_header_callback;
483 template <
typename ScalarType>
484 inline void pcl::io::ply::ply_parser::parse_scalar_property_definition (
const std::string& property_name)
486 using scalar_type = ScalarType;
488 scalar_property_definition_callbacks_.get<scalar_type> ();
490 if (scalar_property_definition_callback)
492 scalar_property_callback = scalar_property_definition_callback (current_element_->name, property_name);
494 if (!scalar_property_callback)
496 if (warning_callback_)
498 warning_callback_ (line_number_,
499 "property '" + std::string (type_traits<scalar_type>::name ()) +
" " +
500 property_name +
"' of element '" + current_element_->name +
"' is not handled");
503 current_element_->properties.emplace_back (
new scalar_property<scalar_type> (property_name, scalar_property_callback));
506 template <
typename SizeType,
typename ScalarType>
507 inline void pcl::io::ply::ply_parser::parse_list_property_definition (
const std::string& property_name)
509 using size_type = SizeType;
510 using scalar_type = ScalarType;
512 list_property_definition_callback_type& list_property_definition_callback = list_property_definition_callbacks_.get<size_type, scalar_type> ();
516 std::tuple<list_property_begin_callback_type, list_property_element_callback_type, list_property_end_callback_type> list_property_callbacks;
517 if (list_property_definition_callback)
519 list_property_callbacks = list_property_definition_callback (current_element_->name, property_name);
521 if (!std::get<0> (list_property_callbacks) || !std::get<1> (list_property_callbacks) || !std::get<2> (list_property_callbacks))
523 if (warning_callback_)
525 warning_callback_ (line_number_,
526 "property 'list " + std::string (type_traits<size_type>::name ()) +
" " +
527 std::string (type_traits<scalar_type>::name ()) +
" " +
528 property_name +
"' of element '" +
529 current_element_->name +
"' is not handled");
532 current_element_->properties.emplace_back (
new list_property<size_type, scalar_type> (
534 std::get<0> (list_property_callbacks),
535 std::get<1> (list_property_callbacks),
536 std::get<2> (list_property_callbacks)));
539 template <
typename ScalarType>
541 std::istream& istream,
542 const typename scalar_property_callback_type<ScalarType>::type& scalar_property_callback)
544 using namespace io_operators;
545 using scalar_type = ScalarType;
554 value =
static_cast<scalar_type
> (boost::lexical_cast<typename pcl::io::ply::type_traits<scalar_type>::parse_type> (value_s));
556 catch (boost::bad_lexical_cast &)
558 value = std::numeric_limits<scalar_type>::quiet_NaN ();
562 istream >> space >> std::ws;
563 if (!istream || !isspace (space))
566 error_callback_ (line_number_,
"parse error");
569 if (scalar_property_callback)
570 scalar_property_callback (value);
573 scalar_type value = std::numeric_limits<scalar_type>::quiet_NaN ();
574 istream.read (
reinterpret_cast<char*
> (&value),
sizeof (scalar_type));
578 error_callback_ (line_number_,
"parse error");
584 if (scalar_property_callback)
585 scalar_property_callback (value);
589 template <
typename SizeType,
typename ScalarType>
590 inline bool pcl::io::ply::ply_parser::parse_list_property (
format_type format, std::istream& istream,
591 const typename list_property_begin_callback_type<SizeType, ScalarType>::type& list_property_begin_callback,
592 const typename list_property_element_callback_type<SizeType, ScalarType>::type& list_property_element_callback,
593 const typename list_property_end_callback_type<SizeType, ScalarType>::type& list_property_end_callback)
595 using namespace io_operators;
596 using size_type = SizeType;
597 using scalar_type = ScalarType;
600 size_type size = std::numeric_limits<size_type>::infinity ();
605 istream >> space >> std::ws;
607 if (!istream || !isspace (space))
611 error_callback_ (line_number_,
"parse error");
615 if (list_property_begin_callback)
617 list_property_begin_callback (size);
619 for (std::size_t index = 0; index < size; ++index)
627 value =
static_cast<scalar_type
> (boost::lexical_cast<typename pcl::io::ply::type_traits<scalar_type>::parse_type> (value_s));
629 catch (boost::bad_lexical_cast &)
631 value = std::numeric_limits<scalar_type>::quiet_NaN ();
636 istream >> space >> std::ws;
638 if (!istream || !isspace (space))
642 error_callback_ (line_number_,
"parse error");
646 if (list_property_element_callback)
648 list_property_element_callback (value);
651 if (list_property_end_callback)
653 list_property_end_callback ();
657 size_type size = std::numeric_limits<size_type>::infinity ();
658 istream.read (
reinterpret_cast<char*
> (&size),
sizeof (size_type));
668 error_callback_ (line_number_,
"parse error");
672 if (list_property_begin_callback)
674 list_property_begin_callback (size);
676 for (std::size_t index = 0; index < size; ++index) {
677 scalar_type value = std::numeric_limits<scalar_type>::quiet_NaN ();
678 istream.read (
reinterpret_cast<char*
> (&value),
sizeof (scalar_type));
680 if (error_callback_) {
681 error_callback_ (line_number_,
"parse error");
690 if (list_property_element_callback)
692 list_property_element_callback (value);
695 if (list_property_end_callback)
697 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