00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifndef PCL_IO_PLY_PLY_PARSER_H
00042 #define PCL_IO_PLY_PLY_PARSER_H
00043
00044 #include <fstream>
00045 #include <iostream>
00046 #include <istream>
00047 #include <sstream>
00048 #include <string>
00049 #include <vector>
00050
00051 #ifdef BUILD_Maintainer
00052 # if defined __GNUC__
00053 # if __GNUC__ == 4 && __GNUC_MINOR__ > 3
00054 # pragma GCC diagnostic ignored "-Weffc++"
00055 # pragma GCC diagnostic ignored "-pedantic"
00056 # else
00057 # pragma GCC system_header
00058 # endif
00059 # elif defined _MSC_VER
00060 # pragma warning(push, 1)
00061 # endif
00062 #endif
00063
00064 #include <pcl/io/boost.h>
00065
00066 #include <pcl/io/ply/ply.h>
00067 #include <pcl/io/ply/io_operators.h>
00068 #include <pcl/pcl_macros.h>
00069
00070 namespace pcl
00071 {
00072 namespace io
00073 {
00074 namespace ply
00075 {
00082 class PCL_EXPORTS ply_parser
00083 {
00084 public:
00085
00086 typedef boost::function<void (std::size_t, const std::string&)> info_callback_type;
00087 typedef boost::function<void (std::size_t, const std::string&)> warning_callback_type;
00088 typedef boost::function<void (std::size_t, const std::string&)> error_callback_type;
00089
00090 typedef boost::function<void ()> magic_callback_type;
00091 typedef boost::function<void (format_type, const std::string&)> format_callback_type;
00092 typedef boost::function<void (const std::string&)> comment_callback_type;
00093 typedef boost::function<void (const std::string&)> obj_info_callback_type;
00094 typedef boost::function<bool ()> end_header_callback_type;
00095
00096 typedef boost::function<void ()> begin_element_callback_type;
00097 typedef boost::function<void ()> end_element_callback_type;
00098 typedef boost::tuple<begin_element_callback_type, end_element_callback_type> element_callbacks_type;
00099 typedef boost::function<element_callbacks_type (const std::string&, std::size_t)> element_definition_callback_type;
00100
00101 template <typename ScalarType>
00102 struct scalar_property_callback_type
00103 {
00104 typedef boost::function<void (ScalarType)> type;
00105 };
00106
00107 template <typename ScalarType>
00108 struct scalar_property_definition_callback_type
00109 {
00110 typedef typename scalar_property_callback_type<ScalarType>::type scalar_property_callback_type;
00111 typedef boost::function<scalar_property_callback_type (const std::string&, const std::string&)> type;
00112 };
00113
00114 typedef boost::mpl::vector<int8, int16, int32, uint8, uint16, uint32, float32, float64> scalar_types;
00115
00116 class scalar_property_definition_callbacks_type
00117 {
00118 private:
00119 template <typename T>
00120 struct callbacks_element
00121 {
00122
00123 typedef T scalar_type;
00124 typename scalar_property_definition_callback_type<scalar_type>::type callback;
00125 };
00126
00127 typedef boost::mpl::inherit_linearly<
00128 scalar_types,
00129 boost::mpl::inherit<
00130 boost::mpl::_1,
00131 callbacks_element<boost::mpl::_2>
00132 >
00133 >::type callbacks;
00134 callbacks callbacks_;
00135
00136 public:
00137 template <typename ScalarType>
00138 const typename scalar_property_definition_callback_type<ScalarType>::type&
00139 get () const
00140 {
00141 return (static_cast<const callbacks_element<ScalarType>&> (callbacks_).callback);
00142 }
00143
00144 template <typename ScalarType>
00145 typename scalar_property_definition_callback_type<ScalarType>::type&
00146 get ()
00147 {
00148 return (static_cast<callbacks_element<ScalarType>&> (callbacks_).callback);
00149 }
00150
00151 template <typename ScalarType>
00152 friend typename scalar_property_definition_callback_type<ScalarType>::type&
00153 at (scalar_property_definition_callbacks_type& scalar_property_definition_callbacks);
00154
00155 template <typename ScalarType>
00156 friend const typename scalar_property_definition_callback_type<ScalarType>::type&
00157 at (const scalar_property_definition_callbacks_type& scalar_property_definition_callbacks);
00158 };
00159
00160 template <typename ScalarType>
00161 friend typename scalar_property_definition_callback_type<ScalarType>::type&
00162 at (scalar_property_definition_callbacks_type& scalar_property_definition_callbacks)
00163 {
00164 return (scalar_property_definition_callbacks.get<ScalarType> ());
00165 }
00166
00167
00168 template <typename ScalarType>
00169 friend const typename scalar_property_definition_callback_type<ScalarType>::type&
00170 at (const scalar_property_definition_callbacks_type& scalar_property_definition_callbacks)
00171 {
00172 return (scalar_property_definition_callbacks.get<ScalarType> ());
00173 }
00174
00175 template <typename SizeType, typename ScalarType>
00176 struct list_property_begin_callback_type
00177 {
00178 typedef boost::function<void (SizeType)> type;
00179 };
00180
00181 template <typename SizeType, typename ScalarType>
00182 struct list_property_element_callback_type
00183 {
00184 typedef boost::function<void (ScalarType)> type;
00185 };
00186
00187 template <typename SizeType, typename ScalarType>
00188 struct list_property_end_callback_type
00189 {
00190 typedef boost::function<void ()> type;
00191 };
00192
00193 template <typename SizeType, typename ScalarType>
00194 struct list_property_definition_callback_type
00195 {
00196 typedef typename list_property_begin_callback_type<SizeType, ScalarType>::type list_property_begin_callback_type;
00197 typedef typename list_property_element_callback_type<SizeType, ScalarType>::type list_property_element_callback_type;
00198 typedef typename list_property_end_callback_type<SizeType, ScalarType>::type list_property_end_callback_type;
00199 typedef boost::function<
00200 boost::tuple<
00201 list_property_begin_callback_type,
00202 list_property_element_callback_type,
00203 list_property_end_callback_type
00204 > (const std::string&, const std::string&)> type;
00205 };
00206
00207 typedef boost::mpl::vector<uint8, uint16, uint32> size_types;
00208
00209 class list_property_definition_callbacks_type
00210 {
00211 private:
00212 template <typename T> struct pair_with : boost::mpl::pair<T,boost::mpl::_> {};
00213 template<typename Sequence1, typename Sequence2>
00214
00215 struct sequence_product :
00216 boost::mpl::fold<Sequence1, boost::mpl::vector0<>,
00217 boost::mpl::joint_view<
00218 boost::mpl::_1,boost::mpl::transform<Sequence2, pair_with<boost::mpl::_2> > > >
00219 {};
00220
00221 template <typename T>
00222 struct callbacks_element
00223 {
00224 typedef typename T::first size_type;
00225 typedef typename T::second scalar_type;
00226 typename list_property_definition_callback_type<size_type, scalar_type>::type callback;
00227 };
00228
00229 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;
00230 callbacks callbacks_;
00231
00232 public:
00233 template <typename SizeType, typename ScalarType>
00234 typename list_property_definition_callback_type<SizeType, ScalarType>::type&
00235 get ()
00236 {
00237 return (static_cast<callbacks_element<boost::mpl::pair<SizeType, ScalarType> >&> (callbacks_).callback);
00238 }
00239
00240 template <typename SizeType, typename ScalarType>
00241 const typename list_property_definition_callback_type<SizeType, ScalarType>::type&
00242 get () const
00243 {
00244 return (static_cast<const callbacks_element<boost::mpl::pair<SizeType, ScalarType> >&> (callbacks_).callback);
00245 }
00246
00247 template <typename SizeType, typename ScalarType>
00248 friend typename list_property_definition_callback_type<SizeType, ScalarType>::type&
00249 at (list_property_definition_callbacks_type& list_property_definition_callbacks);
00250
00251 template <typename SizeType, typename ScalarType>
00252 friend const typename list_property_definition_callback_type<SizeType, ScalarType>::type&
00253 at (const list_property_definition_callbacks_type& list_property_definition_callbacks);
00254 };
00255
00256 template <typename SizeType, typename ScalarType>
00257 friend typename list_property_definition_callback_type<SizeType, ScalarType>::type&
00258 at (list_property_definition_callbacks_type& list_property_definition_callbacks)
00259 {
00260 return (list_property_definition_callbacks.get<SizeType, ScalarType> ());
00261 }
00262
00263 template <typename SizeType, typename ScalarType>
00264 friend const typename list_property_definition_callback_type<SizeType, ScalarType>::type&
00265 at (const list_property_definition_callbacks_type& list_property_definition_callbacks)
00266 {
00267 return (list_property_definition_callbacks.get<SizeType, ScalarType> ());
00268 }
00269
00270
00271 inline void
00272 info_callback (const info_callback_type& info_callback);
00273
00274 inline void
00275 warning_callback (const warning_callback_type& warning_callback);
00276
00277 inline void
00278 error_callback (const error_callback_type& error_callback);
00279
00280 inline void
00281 magic_callback (const magic_callback_type& magic_callback);
00282
00283 inline void
00284 format_callback (const format_callback_type& format_callback);
00285
00286 inline void
00287 element_definition_callback (const element_definition_callback_type& element_definition_callback);
00288
00289 inline void
00290 scalar_property_definition_callbacks (const scalar_property_definition_callbacks_type& scalar_property_definition_callbacks);
00291
00292 inline void
00293 list_property_definition_callbacks (const list_property_definition_callbacks_type& list_property_definition_callbacks);
00294
00295 inline void
00296 comment_callback (const comment_callback_type& comment_callback);
00297
00298 inline void
00299 obj_info_callback (const obj_info_callback_type& obj_info_callback);
00300
00301 inline void
00302 end_header_callback (const end_header_callback_type& end_header_callback);
00303
00304 typedef int flags_type;
00305 enum flags { };
00306
00307 ply_parser (flags_type flags = 0) :
00308 flags_ (flags),
00309 comment_callback_ (), obj_info_callback_ (), end_header_callback_ (),
00310 line_number_ (0), current_element_ ()
00311 {}
00312
00313 bool parse (const std::string& filename);
00314
00315
00316 private:
00317
00318 struct property
00319 {
00320 property (const std::string& name) : name (name) {}
00321 virtual ~property () {}
00322 virtual bool parse (class ply_parser& ply_parser, format_type format, std::istream& istream) = 0;
00323 std::string name;
00324 };
00325
00326 template <typename ScalarType>
00327 struct scalar_property : public property
00328 {
00329 typedef ScalarType scalar_type;
00330 typedef typename scalar_property_callback_type<scalar_type>::type callback_type;
00331 scalar_property (const std::string& name, callback_type callback)
00332 : property (name)
00333 , callback (callback)
00334 {}
00335 bool parse (class ply_parser& ply_parser,
00336 format_type format,
00337 std::istream& istream)
00338 {
00339 return ply_parser.parse_scalar_property<scalar_type> (format, istream, callback);
00340 }
00341 callback_type callback;
00342 };
00343
00344 template <typename SizeType, typename ScalarType>
00345 struct list_property : public property
00346 {
00347 typedef SizeType size_type;
00348 typedef ScalarType scalar_type;
00349 typedef typename list_property_begin_callback_type<size_type, scalar_type>::type begin_callback_type;
00350 typedef typename list_property_element_callback_type<size_type, scalar_type>::type element_callback_type;
00351 typedef typename list_property_end_callback_type<size_type, scalar_type>::type end_callback_type;
00352 list_property (const std::string& name,
00353 begin_callback_type begin_callback,
00354 element_callback_type element_callback,
00355 end_callback_type end_callback)
00356 : property (name)
00357 , begin_callback (begin_callback)
00358 , element_callback (element_callback)
00359 , end_callback (end_callback)
00360 {}
00361 bool parse (class ply_parser& ply_parser,
00362 format_type format,
00363 std::istream& istream)
00364 {
00365 return ply_parser.parse_list_property<size_type, scalar_type> (format,
00366 istream,
00367 begin_callback,
00368 element_callback,
00369 end_callback);
00370 }
00371 begin_callback_type begin_callback;
00372 element_callback_type element_callback;
00373 end_callback_type end_callback;
00374 };
00375
00376 struct element
00377 {
00378 element (const std::string& name,
00379 std::size_t count,
00380 const begin_element_callback_type& begin_element_callback,
00381 const end_element_callback_type& end_element_callback)
00382 : name (name)
00383 , count (count)
00384 , begin_element_callback (begin_element_callback)
00385 , end_element_callback (end_element_callback)
00386 , properties ()
00387 {}
00388 std::string name;
00389 std::size_t count;
00390 begin_element_callback_type begin_element_callback;
00391 end_element_callback_type end_element_callback;
00392 std::vector<boost::shared_ptr<property> > properties;
00393 };
00394
00395 flags_type flags_;
00396
00397 info_callback_type info_callback_;
00398 warning_callback_type warning_callback_;
00399 error_callback_type error_callback_;
00400
00401 magic_callback_type magic_callback_;
00402 format_callback_type format_callback_;
00403 element_definition_callback_type element_definition_callbacks_;
00404 scalar_property_definition_callbacks_type scalar_property_definition_callbacks_;
00405 list_property_definition_callbacks_type list_property_definition_callbacks_;
00406 comment_callback_type comment_callback_;
00407 obj_info_callback_type obj_info_callback_;
00408 end_header_callback_type end_header_callback_;
00409
00410 template <typename ScalarType> inline void
00411 parse_scalar_property_definition (const std::string& property_name);
00412
00413 template <typename SizeType, typename ScalarType> inline void
00414 parse_list_property_definition (const std::string& property_name);
00415
00416 template <typename ScalarType> inline bool
00417 parse_scalar_property (format_type format,
00418 std::istream& istream,
00419 const typename scalar_property_callback_type<ScalarType>::type& scalar_property_callback);
00420
00421 template <typename SizeType, typename ScalarType> inline bool
00422 parse_list_property (format_type format,
00423 std::istream& istream,
00424 const typename list_property_begin_callback_type<SizeType, ScalarType>::type& list_property_begin_callback,
00425 const typename list_property_element_callback_type<SizeType, ScalarType>::type& list_property_element_callback,
00426 const typename list_property_end_callback_type<SizeType, ScalarType>::type& list_property_end_callback);
00427
00428 std::size_t line_number_;
00429 element* current_element_;
00430 };
00431 }
00432 }
00433 }
00434
00435
00436
00437
00438
00439
00440
00441 inline void pcl::io::ply::ply_parser::info_callback (const info_callback_type& info_callback)
00442 {
00443 info_callback_ = info_callback;
00444 }
00445
00446 inline void pcl::io::ply::ply_parser::warning_callback (const warning_callback_type& warning_callback)
00447 {
00448 warning_callback_ = warning_callback;
00449 }
00450
00451 inline void pcl::io::ply::ply_parser::error_callback (const error_callback_type& error_callback)
00452 {
00453 error_callback_ = error_callback;
00454 }
00455
00456 inline void pcl::io::ply::ply_parser::magic_callback (const magic_callback_type& magic_callback)
00457 {
00458 magic_callback_ = magic_callback;
00459 }
00460
00461 inline void pcl::io::ply::ply_parser::format_callback (const format_callback_type& format_callback)
00462 {
00463 format_callback_ = format_callback;
00464 }
00465
00466 inline void pcl::io::ply::ply_parser::element_definition_callback (const element_definition_callback_type& element_definition_callback)
00467 {
00468 element_definition_callbacks_ = element_definition_callback;
00469 }
00470
00471 inline void pcl::io::ply::ply_parser::scalar_property_definition_callbacks (const scalar_property_definition_callbacks_type& scalar_property_definition_callbacks)
00472 {
00473 scalar_property_definition_callbacks_ = scalar_property_definition_callbacks;
00474 }
00475
00476 inline void pcl::io::ply::ply_parser::list_property_definition_callbacks (const list_property_definition_callbacks_type& list_property_definition_callbacks)
00477 {
00478 list_property_definition_callbacks_ = list_property_definition_callbacks;
00479 }
00480
00481 inline void pcl::io::ply::ply_parser::comment_callback (const comment_callback_type& comment_callback)
00482 {
00483 comment_callback_ = comment_callback;
00484 }
00485
00486 inline void pcl::io::ply::ply_parser::obj_info_callback (const obj_info_callback_type& obj_info_callback)
00487 {
00488 obj_info_callback_ = obj_info_callback;
00489 }
00490
00491 inline void pcl::io::ply::ply_parser::end_header_callback (const end_header_callback_type& end_header_callback)
00492 {
00493 end_header_callback_ = end_header_callback;
00494 }
00495
00496 template <typename ScalarType>
00497 inline void pcl::io::ply::ply_parser::parse_scalar_property_definition (const std::string& property_name)
00498 {
00499 typedef ScalarType scalar_type;
00500 typename scalar_property_definition_callback_type<scalar_type>::type& scalar_property_definition_callback =
00501 scalar_property_definition_callbacks_.get<scalar_type> ();
00502 typename scalar_property_callback_type<scalar_type>::type scalar_property_callback;
00503 if (scalar_property_definition_callback)
00504 {
00505 scalar_property_callback = scalar_property_definition_callback (current_element_->name, property_name);
00506 }
00507 if (!scalar_property_callback)
00508 {
00509 if (warning_callback_)
00510 {
00511 warning_callback_ (line_number_,
00512 "property '" + std::string (type_traits<scalar_type>::name ()) + " " +
00513 property_name + "' of element '" + current_element_->name + "' is not handled");
00514 }
00515 }
00516 current_element_->properties.push_back (boost::shared_ptr<property> (new scalar_property<scalar_type> (property_name, scalar_property_callback)));
00517 }
00518
00519 template <typename SizeType, typename ScalarType>
00520 inline void pcl::io::ply::ply_parser::parse_list_property_definition (const std::string& property_name)
00521 {
00522 typedef SizeType size_type;
00523 typedef ScalarType scalar_type;
00524 typename list_property_definition_callback_type<size_type, scalar_type>::type& list_property_definition_callback =
00525 list_property_definition_callbacks_.get<size_type, scalar_type> ();
00526 typedef typename list_property_begin_callback_type<size_type, scalar_type>::type list_property_begin_callback_type;
00527 typedef typename list_property_element_callback_type<size_type, scalar_type>::type list_property_element_callback_type;
00528 typedef typename list_property_end_callback_type<size_type, scalar_type>::type list_property_end_callback_type;
00529 boost::tuple<list_property_begin_callback_type, list_property_element_callback_type, list_property_end_callback_type> list_property_callbacks;
00530 if (list_property_definition_callback)
00531 {
00532 list_property_callbacks = list_property_definition_callback (current_element_->name, property_name);
00533 }
00534 if (!boost::get<0> (list_property_callbacks) || !boost::get<1> (list_property_callbacks) || !boost::get<2> (list_property_callbacks))
00535 {
00536 if (warning_callback_)
00537 {
00538 warning_callback_ (line_number_,
00539 "property 'list " + std::string (type_traits<size_type>::name ()) + " " +
00540 std::string (type_traits<scalar_type>::name ()) + " " +
00541 property_name + "' of element '" +
00542 current_element_->name + "' is not handled");
00543 }
00544 }
00545 current_element_->properties.push_back (boost::shared_ptr<property> (
00546 new list_property<size_type, scalar_type> (
00547 property_name,
00548 boost::get<0> (list_property_callbacks),
00549 boost::get<1> (list_property_callbacks),
00550 boost::get<2> (list_property_callbacks))));
00551 }
00552
00553 template <typename ScalarType>
00554 inline bool pcl::io::ply::ply_parser::parse_scalar_property (format_type format,
00555 std::istream& istream,
00556 const typename scalar_property_callback_type<ScalarType>::type& scalar_property_callback)
00557 {
00558 using namespace io_operators;
00559 typedef ScalarType scalar_type;
00560 if (format == ascii_format)
00561 {
00562 scalar_type value = std::numeric_limits<scalar_type>::quiet_NaN ();
00563 char space = ' ';
00564 istream >> value;
00565 if (!istream.eof ())
00566 istream >> space >> std::ws;
00567 if (!istream || !isspace (space))
00568 {
00569 if (error_callback_)
00570 error_callback_ (line_number_, "parse error");
00571 return (false);
00572 }
00573 if (scalar_property_callback)
00574 scalar_property_callback (value);
00575 return (true);
00576 }
00577 else
00578 {
00579 scalar_type value = std::numeric_limits<scalar_type>::quiet_NaN ();
00580 istream.read (reinterpret_cast<char*> (&value), sizeof (scalar_type));
00581 if (!istream)
00582 {
00583 if (error_callback_)
00584 error_callback_ (line_number_, "parse error");
00585 return (false);
00586 }
00587 if (((format == binary_big_endian_format) && (host_byte_order == little_endian_byte_order)) ||
00588 ((format == binary_little_endian_format) && (host_byte_order == big_endian_byte_order)))
00589 swap_byte_order (value);
00590 if (scalar_property_callback)
00591 scalar_property_callback (value);
00592 return (true);
00593 }
00594 }
00595
00596 template <typename SizeType, typename ScalarType>
00597 inline bool pcl::io::ply::ply_parser::parse_list_property (format_type format, std::istream& istream,
00598 const typename list_property_begin_callback_type<SizeType, ScalarType>::type& list_property_begin_callback,
00599 const typename list_property_element_callback_type<SizeType, ScalarType>::type& list_property_element_callback,
00600 const typename list_property_end_callback_type<SizeType, ScalarType>::type& list_property_end_callback)
00601 {
00602 using namespace io_operators;
00603 typedef SizeType size_type;
00604 typedef ScalarType scalar_type;
00605 if (format == ascii_format)
00606 {
00607 size_type size = std::numeric_limits<size_type>::infinity ();
00608 char space = ' ';
00609 istream >> size;
00610 if (!istream.eof ())
00611 {
00612 istream >> space >> std::ws;
00613 }
00614 if (!istream || !isspace (space))
00615 {
00616 if (error_callback_)
00617 {
00618 error_callback_ (line_number_, "parse error");
00619 }
00620 return (false);
00621 }
00622 if (list_property_begin_callback)
00623 {
00624 list_property_begin_callback (size);
00625 }
00626 for (std::size_t index = 0; index < size; ++index)
00627 {
00628 scalar_type value = std::numeric_limits<scalar_type>::quiet_NaN ();
00629 char space = ' ';
00630 istream >> value;
00631 if (!istream.eof ())
00632 {
00633 istream >> space >> std::ws;
00634 }
00635 if (!istream || !isspace (space))
00636 {
00637 if (error_callback_)
00638 {
00639 error_callback_ (line_number_, "parse error");
00640 }
00641 return (false);
00642 }
00643 if (list_property_element_callback)
00644 {
00645 list_property_element_callback (value);
00646 }
00647 }
00648 if (list_property_end_callback)
00649 {
00650 list_property_end_callback ();
00651 }
00652 return (true);
00653 }
00654 else
00655 {
00656 size_type size = std::numeric_limits<size_type>::infinity ();
00657 istream.read (reinterpret_cast<char*> (&size), sizeof (size_type));
00658 if (((format == binary_big_endian_format) && (host_byte_order == little_endian_byte_order)) ||
00659 ((format == binary_little_endian_format) && (host_byte_order == big_endian_byte_order)))
00660 {
00661 swap_byte_order (size);
00662 }
00663 if (!istream)
00664 {
00665 if (error_callback_)
00666 {
00667 error_callback_ (line_number_, "parse error");
00668 }
00669 return (false);
00670 }
00671 if (list_property_begin_callback)
00672 {
00673 list_property_begin_callback (size);
00674 }
00675 for (std::size_t index = 0; index < size; ++index) {
00676 scalar_type value = std::numeric_limits<scalar_type>::quiet_NaN ();
00677 istream.read (reinterpret_cast<char*> (&value), sizeof (scalar_type));
00678 if (!istream) {
00679 if (error_callback_) {
00680 error_callback_ (line_number_, "parse error");
00681 }
00682 return (false);
00683 }
00684 if (((format == binary_big_endian_format) && (host_byte_order == little_endian_byte_order)) ||
00685 ((format == binary_little_endian_format) && (host_byte_order == big_endian_byte_order)))
00686 {
00687 swap_byte_order (value);
00688 }
00689 if (list_property_element_callback)
00690 {
00691 list_property_element_callback (value);
00692 }
00693 }
00694 if (list_property_end_callback)
00695 {
00696 list_property_end_callback ();
00697 }
00698 return (true);
00699 }
00700 }
00701
00702 #ifdef BUILD_Maintainer
00703 # if defined __GNUC__
00704 # if __GNUC__ == 4 && __GNUC_MINOR__ > 3
00705 # pragma GCC diagnostic warning "-Weffc++"
00706 # pragma GCC diagnostic warning "-pedantic"
00707 # endif
00708 # elif defined _MSC_VER
00709 # pragma warning(pop)
00710 # endif
00711 #endif
00712
00713 #endif // PCL_IO_PLY_PLY_PARSER_H