43 #include <pcl/io/boost.h>
85 template <
typename ScalarType>
88 using type = std::function<void (ScalarType)>;
91 template <
typename ScalarType>
98 using scalar_types = boost::mpl::vector<int8, int16, int32, uint8, uint16, uint32, float32, float64>;
103 template <
typename T>
104 struct callbacks_element
107 using scalar_type = T;
111 using callbacks = boost::mpl::inherit_linearly<
115 callbacks_element<boost::mpl::_2>
118 callbacks callbacks_;
121 template <
typename ScalarType>
125 return (
static_cast<const callbacks_element<ScalarType>&
> (callbacks_).callback);
128 template <
typename ScalarType>
132 return (
static_cast<callbacks_element<ScalarType>&
> (callbacks_).callback);
135 template <
typename ScalarType>
139 template <
typename ScalarType>
144 template <
typename ScalarType>
static
145 typename scalar_property_definition_callback_type<ScalarType>::type&
148 return (scalar_property_definition_callbacks.
get<ScalarType> ());
152 template <
typename ScalarType>
static
153 const typename scalar_property_definition_callback_type<ScalarType>::type&
156 return (scalar_property_definition_callbacks.
get<ScalarType> ());
159 template <
typename SizeType,
typename ScalarType>
162 using type = std::function<void (SizeType)>;
165 template <
typename SizeType,
typename ScalarType>
168 using type = std::function<void (ScalarType)>;
171 template <
typename SizeType,
typename ScalarType>
174 using type = std::function<void ()>;
177 template <
typename SizeType,
typename ScalarType>
183 using type = std::function<std::tuple<
187 > (
const std::string&,
const std::string&)>;
190 using size_types = boost::mpl::vector<uint8, uint16, uint32>;
195 template <
typename T>
struct pair_with : boost::mpl::pair<T,boost::mpl::_> {};
196 template<
typename Sequence1,
typename Sequence2>
198 struct sequence_product :
199 boost::mpl::fold<Sequence1, boost::mpl::vector0<>,
200 boost::mpl::joint_view<
201 boost::mpl::_1,boost::mpl::transform<Sequence2, pair_with<boost::mpl::_2> > > >
204 template <
typename T>
205 struct callbacks_element
207 using size_type =
typename T::first;
208 using scalar_type =
typename T::second;
212 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;
213 callbacks callbacks_;
216 template <
typename SizeType,
typename ScalarType>
220 return (
static_cast<callbacks_element<boost::mpl::pair<SizeType, ScalarType>
>&> (callbacks_).callback);
223 template <
typename SizeType,
typename ScalarType>
227 return (
static_cast<const callbacks_element<boost::mpl::pair<SizeType, ScalarType>
>&> (callbacks_).callback);
230 template <
typename SizeType,
typename ScalarType>
234 template <
typename SizeType,
typename ScalarType>
239 template <
typename SizeType,
typename ScalarType>
static
240 typename list_property_definition_callback_type<SizeType, ScalarType>::type&
243 return (list_property_definition_callbacks.
get<SizeType, ScalarType> ());
246 template <
typename SizeType,
typename ScalarType>
static
247 const typename list_property_definition_callback_type<SizeType, ScalarType>::type&
250 return (list_property_definition_callbacks.
get<SizeType, ScalarType> ());
255 info_callback (
const info_callback_type& info_callback);
258 warning_callback (
const warning_callback_type& warning_callback);
261 error_callback (
const error_callback_type& error_callback);
264 magic_callback (
const magic_callback_type& magic_callback);
267 format_callback (
const format_callback_type& format_callback);
270 element_definition_callback (
const element_definition_callback_type& element_definition_callback);
273 scalar_property_definition_callbacks (
const scalar_property_definition_callbacks_type& scalar_property_definition_callbacks);
276 list_property_definition_callbacks (
const list_property_definition_callbacks_type& list_property_definition_callbacks);
279 comment_callback (
const comment_callback_type& comment_callback);
282 obj_info_callback (
const obj_info_callback_type& obj_info_callback);
285 end_header_callback (
const end_header_callback_type& end_header_callback);
291 line_number_ (0), current_element_ ()
294 bool parse (
const std::string& filename);
301 property (
const std::string& name) : name (name) {}
302 virtual ~property () {}
303 virtual bool parse (
class ply_parser& ply_parser,
format_type format, std::istream& istream) = 0;
307 template <
typename ScalarType>
308 struct scalar_property :
public property
310 using scalar_type = ScalarType;
312 scalar_property (
const std::string& name, callback_type callback)
314 , callback (callback)
316 bool parse (
class ply_parser& ply_parser,
318 std::istream& istream)
override
320 return ply_parser.parse_scalar_property<scalar_type> (
format, istream, callback);
322 callback_type callback;
325 template <
typename SizeType,
typename ScalarType>
326 struct list_property :
public property
328 using size_type = SizeType;
329 using scalar_type = ScalarType;
333 list_property (
const std::string& name,
334 begin_callback_type begin_callback,
335 element_callback_type element_callback,
336 end_callback_type end_callback)
338 , begin_callback (begin_callback)
339 , element_callback (element_callback)
340 , end_callback (end_callback)
342 bool parse (
class ply_parser& ply_parser,
344 std::istream& istream)
override
346 return ply_parser.parse_list_property<size_type, scalar_type> (
format,
352 begin_callback_type begin_callback;
353 element_callback_type element_callback;
354 end_callback_type end_callback;
359 element (
const std::string& name,
361 const begin_element_callback_type& begin_element_callback,
362 const end_element_callback_type& end_element_callback)
365 , begin_element_callback (begin_element_callback)
366 , end_element_callback (end_element_callback)
370 begin_element_callback_type begin_element_callback;
371 end_element_callback_type end_element_callback;
372 std::vector<std::shared_ptr<property>> properties;
375 info_callback_type info_callback_ = [](std::size_t,
const std::string&){};
376 warning_callback_type warning_callback_ = [](std::size_t,
const std::string&){};
377 error_callback_type error_callback_ = [](std::size_t,
const std::string&){};
379 magic_callback_type magic_callback_ = [](){};
380 format_callback_type format_callback_ = [](
format_type,
const std::string&){};
381 comment_callback_type comment_callback_ = [](
const std::string&){};
382 obj_info_callback_type obj_info_callback_ = [](
const std::string&){};
383 end_header_callback_type end_header_callback_ = [](){
return true;};
385 element_definition_callback_type element_definition_callbacks_ =
386 [](
const std::string&, std::size_t)
388 return std::make_tuple([](){}, [](){});
390 scalar_property_definition_callbacks_type scalar_property_definition_callbacks_;
391 list_property_definition_callbacks_type list_property_definition_callbacks_;
393 template <
typename ScalarType>
inline void
394 parse_scalar_property_definition (
const std::string& property_name);
396 template <
typename SizeType,
typename ScalarType>
inline void
397 parse_list_property_definition (
const std::string& property_name);
399 template <
typename ScalarType>
inline bool
401 std::istream& istream,
402 const typename scalar_property_callback_type<ScalarType>::type& scalar_property_callback);
404 template <
typename SizeType,
typename ScalarType>
inline bool
406 std::istream& istream,
407 const typename list_property_begin_callback_type<SizeType, ScalarType>::type& list_property_begin_callback,
408 const typename list_property_element_callback_type<SizeType, ScalarType>::type& list_property_element_callback,
409 const typename list_property_end_callback_type<SizeType, ScalarType>::type& list_property_end_callback);
411 std::size_t line_number_;
412 element* current_element_;
431 warning_callback_ = warning_callback;
436 error_callback_ = error_callback;
441 magic_callback_ = magic_callback;
446 format_callback_ = format_callback;
451 element_definition_callbacks_ = element_definition_callback;
456 scalar_property_definition_callbacks_ = scalar_property_definition_callbacks;
461 list_property_definition_callbacks_ = list_property_definition_callbacks;
466 comment_callback_ = comment_callback;
471 obj_info_callback_ = obj_info_callback;
476 end_header_callback_ = end_header_callback;
479 template <
typename ScalarType>
480 inline void pcl::io::ply::ply_parser::parse_scalar_property_definition (
const std::string& property_name)
482 using scalar_type = ScalarType;
484 scalar_property_definition_callbacks_.get<scalar_type> ();
486 if (scalar_property_definition_callback)
488 scalar_property_callback = scalar_property_definition_callback (current_element_->name, property_name);
490 if (!scalar_property_callback)
492 if (warning_callback_)
494 warning_callback_ (line_number_,
495 "property '" + std::string (type_traits<scalar_type>::name ()) +
" " +
496 property_name +
"' of element '" + current_element_->name +
"' is not handled");
499 current_element_->properties.emplace_back (
new scalar_property<scalar_type> (property_name, scalar_property_callback));
502 template <
typename SizeType,
typename ScalarType>
503 inline void pcl::io::ply::ply_parser::parse_list_property_definition (
const std::string& property_name)
505 using size_type = SizeType;
506 using scalar_type = ScalarType;
508 list_property_definition_callback_type& list_property_definition_callback = list_property_definition_callbacks_.get<size_type, scalar_type> ();
512 std::tuple<list_property_begin_callback_type, list_property_element_callback_type, list_property_end_callback_type> list_property_callbacks;
513 if (list_property_definition_callback)
515 list_property_callbacks = list_property_definition_callback (current_element_->name, property_name);
517 if (!std::get<0> (list_property_callbacks) || !std::get<1> (list_property_callbacks) || !std::get<2> (list_property_callbacks))
519 if (warning_callback_)
521 warning_callback_ (line_number_,
522 "property 'list " + std::string (type_traits<size_type>::name ()) +
" " +
523 std::string (type_traits<scalar_type>::name ()) +
" " +
524 property_name +
"' of element '" +
525 current_element_->name +
"' is not handled");
528 current_element_->properties.emplace_back (
new list_property<size_type, scalar_type> (
530 std::get<0> (list_property_callbacks),
531 std::get<1> (list_property_callbacks),
532 std::get<2> (list_property_callbacks)));
535 template <
typename ScalarType>
537 std::istream& istream,
538 const typename scalar_property_callback_type<ScalarType>::type& scalar_property_callback)
540 using namespace io_operators;
541 using scalar_type = ScalarType;
550 value =
static_cast<scalar_type
> (boost::lexical_cast<typename pcl::io::ply::type_traits<scalar_type>::parse_type> (value_s));
552 catch (boost::bad_lexical_cast &)
554 value = std::numeric_limits<scalar_type>::quiet_NaN ();
558 istream >> space >> std::ws;
559 if (!istream || !isspace (space))
562 error_callback_ (line_number_,
"parse error");
565 if (scalar_property_callback)
566 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);
585 template <
typename SizeType,
typename ScalarType>
586 inline bool pcl::io::ply::ply_parser::parse_list_property (
format_type format, std::istream& istream,
587 const typename list_property_begin_callback_type<SizeType, ScalarType>::type& list_property_begin_callback,
588 const typename list_property_element_callback_type<SizeType, ScalarType>::type& list_property_element_callback,
589 const typename list_property_end_callback_type<SizeType, ScalarType>::type& list_property_end_callback)
591 using namespace io_operators;
592 using size_type = SizeType;
593 using scalar_type = ScalarType;
596 size_type size = std::numeric_limits<size_type>::infinity ();
601 istream >> space >> std::ws;
603 if (!istream || !isspace (space))
607 error_callback_ (line_number_,
"parse error");
611 if (list_property_begin_callback)
613 list_property_begin_callback (size);
615 for (std::size_t index = 0; index < size; ++index)
623 value =
static_cast<scalar_type
> (boost::lexical_cast<typename pcl::io::ply::type_traits<scalar_type>::parse_type> (value_s));
625 catch (boost::bad_lexical_cast &)
627 value = std::numeric_limits<scalar_type>::quiet_NaN ();
632 istream >> space >> std::ws;
634 if (!istream || !isspace (space))
638 error_callback_ (line_number_,
"parse error");
642 if (list_property_element_callback)
644 list_property_element_callback (value);
647 if (list_property_end_callback)
649 list_property_end_callback ();
653 size_type size = std::numeric_limits<size_type>::infinity ();
654 istream.read (
reinterpret_cast<char*
> (&size),
sizeof (size_type));
664 error_callback_ (line_number_,
"parse error");
668 if (list_property_begin_callback)
670 list_property_begin_callback (size);
672 for (std::size_t index = 0; index < size; ++index) {
673 scalar_type value = std::numeric_limits<scalar_type>::quiet_NaN ();
674 istream.read (
reinterpret_cast<char*
> (&value),
sizeof (scalar_type));
676 if (error_callback_) {
677 error_callback_ (line_number_,
"parse error");
686 if (list_property_element_callback)
688 list_property_element_callback (value);
691 if (list_property_end_callback)
693 list_property_end_callback ();