43 #include <pcl/io/boost.h>
88 template <
typename ScalarType>
91 using type = std::function<void (ScalarType)>;
94 template <
typename ScalarType>
101 using scalar_types = boost::mpl::vector<int8, int16, int32, uint8, uint16, uint32, float32, float64>;
106 template <
typename T>
107 struct callbacks_element
110 using scalar_type = T;
114 using callbacks = boost::mpl::inherit_linearly<
118 callbacks_element<boost::mpl::_2>
121 callbacks callbacks_;
124 template <
typename ScalarType>
128 return (
static_cast<const callbacks_element<ScalarType>&
> (callbacks_).callback);
131 template <
typename ScalarType>
135 return (
static_cast<callbacks_element<ScalarType>&
> (callbacks_).callback);
138 template <
typename ScalarType>
142 template <
typename ScalarType>
147 template <
typename ScalarType>
static
151 return (scalar_property_definition_callbacks.
get<ScalarType> ());
155 template <
typename ScalarType>
static
156 const typename scalar_property_definition_callback_type<ScalarType>::type&
159 return (scalar_property_definition_callbacks.
get<ScalarType> ());
162 template <
typename SizeType,
typename ScalarType>
165 using type = std::function<void (SizeType)>;
168 template <
typename SizeType,
typename ScalarType>
171 using type = std::function<void (ScalarType)>;
174 template <
typename SizeType,
typename ScalarType>
177 using type = std::function<void ()>;
180 template <
typename SizeType,
typename ScalarType>
186 using type = std::function<std::tuple<
190 > (
const std::string&,
const std::string&)>;
193 using size_types = boost::mpl::vector<uint8, uint16, uint32>;
198 template <
typename T>
struct pair_with : boost::mpl::pair<T,boost::mpl::_> {};
199 template<
typename Sequence1,
typename Sequence2>
201 struct sequence_product :
202 boost::mpl::fold<Sequence1, boost::mpl::vector0<>,
203 boost::mpl::joint_view<
204 boost::mpl::_1,boost::mpl::transform<Sequence2, pair_with<boost::mpl::_2> > > >
207 template <
typename T>
208 struct callbacks_element
210 using size_type =
typename T::first;
211 using scalar_type =
typename T::second;
215 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;
216 callbacks callbacks_;
219 template <
typename SizeType,
typename ScalarType>
223 return (
static_cast<callbacks_element<boost::mpl::pair<SizeType, ScalarType>
>&> (callbacks_).callback);
226 template <
typename SizeType,
typename ScalarType>
230 return (
static_cast<const callbacks_element<boost::mpl::pair<SizeType, ScalarType>
>&> (callbacks_).callback);
233 template <
typename SizeType,
typename ScalarType>
237 template <
typename SizeType,
typename ScalarType>
242 template <
typename SizeType,
typename ScalarType>
static
246 return (list_property_definition_callbacks.
get<SizeType, ScalarType> ());
249 template <
typename SizeType,
typename ScalarType>
static
250 const typename list_property_definition_callback_type<SizeType, ScalarType>::type&
253 return (list_property_definition_callbacks.
get<SizeType, ScalarType> ());
258 info_callback (
const info_callback_type& info_callback);
261 warning_callback (
const warning_callback_type& warning_callback);
264 error_callback (
const error_callback_type& error_callback);
267 magic_callback (
const magic_callback_type& magic_callback);
270 format_callback (
const format_callback_type& format_callback);
273 element_definition_callback (
const element_definition_callback_type& element_definition_callback);
276 scalar_property_definition_callbacks (
const scalar_property_definition_callbacks_type& scalar_property_definition_callbacks);
279 list_property_definition_callbacks (
const list_property_definition_callbacks_type& list_property_definition_callbacks);
282 comment_callback (
const comment_callback_type& comment_callback);
285 obj_info_callback (
const obj_info_callback_type& obj_info_callback);
288 end_header_callback (
const end_header_callback_type& end_header_callback);
294 line_number_ (0), current_element_ ()
297 bool parse (
const std::string& filename);
304 property (
const std::string& name) : name (name) {}
305 virtual ~property () {}
306 virtual bool parse (
class ply_parser& ply_parser,
format_type format, std::istream& istream) = 0;
310 template <
typename ScalarType>
311 struct scalar_property :
public property
313 using scalar_type = ScalarType;
315 scalar_property (
const std::string& name, callback_type callback)
317 , callback (callback)
319 bool parse (
class ply_parser& ply_parser,
321 std::istream& istream)
override
323 return ply_parser.parse_scalar_property<scalar_type> (
format, istream, callback);
325 callback_type callback;
328 template <
typename SizeType,
typename ScalarType>
329 struct list_property :
public property
331 using size_type = SizeType;
332 using scalar_type = ScalarType;
336 list_property (
const std::string& name,
337 begin_callback_type begin_callback,
338 element_callback_type element_callback,
339 end_callback_type end_callback)
341 , begin_callback (begin_callback)
342 , element_callback (element_callback)
343 , end_callback (end_callback)
345 bool parse (
class ply_parser& ply_parser,
347 std::istream& istream)
override
349 return ply_parser.parse_list_property<size_type, scalar_type> (
format,
355 begin_callback_type begin_callback;
356 element_callback_type element_callback;
357 end_callback_type end_callback;
362 element (
const std::string& name,
364 const begin_element_callback_type& begin_element_callback,
365 const end_element_callback_type& end_element_callback)
368 , begin_element_callback (begin_element_callback)
369 , end_element_callback (end_element_callback)
373 begin_element_callback_type begin_element_callback;
374 end_element_callback_type end_element_callback;
375 std::vector<std::shared_ptr<property>> properties;
378 info_callback_type info_callback_ = [](std::size_t,
const std::string&){};
379 warning_callback_type warning_callback_ = [](std::size_t,
const std::string&){};
380 error_callback_type error_callback_ = [](std::size_t,
const std::string&){};
382 magic_callback_type magic_callback_ = [](){};
383 format_callback_type format_callback_ = [](
format_type,
const std::string&){};
384 comment_callback_type comment_callback_ = [](
const std::string&){};
385 obj_info_callback_type obj_info_callback_ = [](
const std::string&){};
386 end_header_callback_type end_header_callback_ = [](){
return true;};
388 element_definition_callback_type element_definition_callbacks_ =
389 [](
const std::string&, std::size_t)
391 return std::make_tuple([](){}, [](){});
393 scalar_property_definition_callbacks_type scalar_property_definition_callbacks_;
394 list_property_definition_callbacks_type list_property_definition_callbacks_;
396 template <
typename ScalarType>
inline void
397 parse_scalar_property_definition (
const std::string& property_name);
399 template <
typename SizeType,
typename ScalarType>
inline void
400 parse_list_property_definition (
const std::string& property_name);
402 template <
typename ScalarType>
inline bool
404 std::istream& istream,
405 const typename scalar_property_callback_type<ScalarType>::type& scalar_property_callback);
407 template <
typename SizeType,
typename ScalarType>
inline bool
409 std::istream& istream,
410 const typename list_property_begin_callback_type<SizeType, ScalarType>::type& list_property_begin_callback,
411 const typename list_property_element_callback_type<SizeType, ScalarType>::type& list_property_element_callback,
412 const typename list_property_end_callback_type<SizeType, ScalarType>::type& list_property_end_callback);
414 std::size_t line_number_;
415 element* current_element_;
434 warning_callback_ = warning_callback;
439 error_callback_ = error_callback;
444 magic_callback_ = magic_callback;
449 format_callback_ = format_callback;
454 element_definition_callbacks_ = element_definition_callback;
459 scalar_property_definition_callbacks_ = scalar_property_definition_callbacks;
464 list_property_definition_callbacks_ = list_property_definition_callbacks;
469 comment_callback_ = comment_callback;
474 obj_info_callback_ = obj_info_callback;
479 end_header_callback_ = end_header_callback;
482 template <
typename ScalarType>
483 inline void pcl::io::ply::ply_parser::parse_scalar_property_definition (
const std::string& property_name)
485 using scalar_type = ScalarType;
487 scalar_property_definition_callbacks_.get<scalar_type> ();
489 if (scalar_property_definition_callback)
491 scalar_property_callback = scalar_property_definition_callback (current_element_->name, property_name);
493 if (!scalar_property_callback)
495 if (warning_callback_)
497 warning_callback_ (line_number_,
498 "property '" + std::string (type_traits<scalar_type>::name ()) +
" " +
499 property_name +
"' of element '" + current_element_->name +
"' is not handled");
502 current_element_->properties.emplace_back (
new scalar_property<scalar_type> (property_name, scalar_property_callback));
505 template <
typename SizeType,
typename ScalarType>
506 inline void pcl::io::ply::ply_parser::parse_list_property_definition (
const std::string& property_name)
508 using size_type = SizeType;
509 using scalar_type = ScalarType;
511 list_property_definition_callback_type& list_property_definition_callback = list_property_definition_callbacks_.get<size_type, scalar_type> ();
515 std::tuple<list_property_begin_callback_type, list_property_element_callback_type, list_property_end_callback_type> list_property_callbacks;
516 if (list_property_definition_callback)
518 list_property_callbacks = list_property_definition_callback (current_element_->name, property_name);
520 if (!std::get<0> (list_property_callbacks) || !std::get<1> (list_property_callbacks) || !std::get<2> (list_property_callbacks))
522 if (warning_callback_)
524 warning_callback_ (line_number_,
525 "property 'list " + std::string (type_traits<size_type>::name ()) +
" " +
526 std::string (type_traits<scalar_type>::name ()) +
" " +
527 property_name +
"' of element '" +
528 current_element_->name +
"' is not handled");
531 current_element_->properties.emplace_back (
new list_property<size_type, scalar_type> (
533 std::get<0> (list_property_callbacks),
534 std::get<1> (list_property_callbacks),
535 std::get<2> (list_property_callbacks)));
538 template <
typename ScalarType>
540 std::istream& istream,
541 const typename scalar_property_callback_type<ScalarType>::type& scalar_property_callback)
543 using namespace io_operators;
544 using scalar_type = ScalarType;
553 value =
static_cast<scalar_type
> (boost::lexical_cast<typename pcl::io::ply::type_traits<scalar_type>::parse_type> (value_s));
555 catch (boost::bad_lexical_cast &)
557 value = std::numeric_limits<scalar_type>::quiet_NaN ();
561 istream >> space >> std::ws;
562 if (!istream || !isspace (space))
565 error_callback_ (line_number_,
"parse error");
568 if (scalar_property_callback)
569 scalar_property_callback (value);
572 scalar_type value = std::numeric_limits<scalar_type>::quiet_NaN ();
573 istream.read (
reinterpret_cast<char*
> (&value),
sizeof (scalar_type));
577 error_callback_ (line_number_,
"parse error");
583 if (scalar_property_callback)
584 scalar_property_callback (value);
588 template <
typename SizeType,
typename ScalarType>
589 inline bool pcl::io::ply::ply_parser::parse_list_property (
format_type format, std::istream& istream,
590 const typename list_property_begin_callback_type<SizeType, ScalarType>::type& list_property_begin_callback,
591 const typename list_property_element_callback_type<SizeType, ScalarType>::type& list_property_element_callback,
592 const typename list_property_end_callback_type<SizeType, ScalarType>::type& list_property_end_callback)
594 using namespace io_operators;
595 using size_type = SizeType;
596 using scalar_type = ScalarType;
599 size_type size = std::numeric_limits<size_type>::infinity ();
604 istream >> space >> std::ws;
606 if (!istream || !isspace (space))
610 error_callback_ (line_number_,
"parse error");
614 if (list_property_begin_callback)
616 list_property_begin_callback (size);
618 for (std::size_t index = 0; index < size; ++index)
626 value =
static_cast<scalar_type
> (boost::lexical_cast<typename pcl::io::ply::type_traits<scalar_type>::parse_type> (value_s));
628 catch (boost::bad_lexical_cast &)
630 value = std::numeric_limits<scalar_type>::quiet_NaN ();
635 istream >> space >> std::ws;
637 if (!istream || !isspace (space))
641 error_callback_ (line_number_,
"parse error");
645 if (list_property_element_callback)
647 list_property_element_callback (value);
650 if (list_property_end_callback)
652 list_property_end_callback ();
656 size_type size = std::numeric_limits<size_type>::infinity ();
657 istream.read (
reinterpret_cast<char*
> (&size),
sizeof (size_type));
667 error_callback_ (line_number_,
"parse error");
671 if (list_property_begin_callback)
673 list_property_begin_callback (size);
675 for (std::size_t index = 0; index < size; ++index) {
676 scalar_type value = std::numeric_limits<scalar_type>::quiet_NaN ();
677 istream.read (
reinterpret_cast<char*
> (&value),
sizeof (scalar_type));
679 if (error_callback_) {
680 error_callback_ (line_number_,
"parse error");
689 if (list_property_element_callback)
691 list_property_element_callback (value);
694 if (list_property_end_callback)
696 list_property_end_callback ();