|
Point Cloud Library (PCL)
1.5.1
|
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Point Cloud Library (PCL) - www.pointclouds.org 00005 * Copyright (c) 2010-2012, Willow Garage, Inc. 00006 * 00007 * All rights reserved. 00008 * 00009 * Redistribution and use in source and binary forms, with or without 00010 * modification, are permitted provided that the following conditions 00011 * are met: 00012 * 00013 * * Redistributions of source code must retain the above copyright 00014 * notice, this list of conditions and the following disclaimer. 00015 * * Redistributions in binary form must reproduce the above 00016 * copyright notice, this list of conditions and the following 00017 * disclaimer in the documentation and/or other materials provided 00018 * with the distribution. 00019 * * Neither the name of Willow Garage, Inc. nor the names of its 00020 * contributors may be used to endorse or promote products derived 00021 * from this software without specific prior written permission. 00022 * 00023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00024 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00025 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00026 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00027 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00028 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00029 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00030 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00031 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00032 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00033 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00034 * POSSIBILITY OF SUCH DAMAGE. 00035 * 00036 * $Id: point_cloud.h 4702 2012-02-23 09:39:33Z gedikli $ 00037 * 00038 */ 00039 00040 #ifndef PCL_POINT_CLOUD_H_ 00041 #define PCL_POINT_CLOUD_H_ 00042 00043 #include <Eigen/StdVector> 00044 #include <Eigen/Geometry> 00045 #include <cstddef> 00046 #include <std_msgs/Header.h> 00047 #include <pcl/pcl_macros.h> 00048 #include <pcl/exceptions.h> 00049 #include <pcl/cloud_properties.h> 00050 #include <pcl/channel_properties.h> 00051 #include <pcl/point_traits.h> 00052 #include <pcl/for_each_type.h> 00053 #include <boost/shared_ptr.hpp> 00054 #include <map> 00055 #include <boost/mpl/size.hpp> 00056 00057 namespace pcl 00058 { 00059 namespace detail 00060 { 00061 struct FieldMapping 00062 { 00063 size_t serialized_offset; 00064 size_t struct_offset; 00065 size_t size; 00066 }; 00067 } // namespace detail 00068 00069 // Forward declarations 00070 template <typename PointT> class PointCloud; 00071 typedef std::vector<detail::FieldMapping> MsgFieldMap; 00072 00074 00075 template <typename PointOutT> 00076 struct NdCopyEigenPointFunctor 00077 { 00078 typedef typename traits::POD<PointOutT>::type Pod; 00079 00084 NdCopyEigenPointFunctor (const Eigen::VectorXf &p1, PointOutT &p2) 00085 : p1_ (p1), 00086 p2_ (reinterpret_cast<Pod&>(p2)), 00087 f_idx_ (0) { } 00088 00090 template<typename Key> inline void 00091 operator() () 00092 { 00093 //boost::fusion::at_key<Key> (p2_) = p1_[f_idx_++]; 00094 typedef typename pcl::traits::datatype<PointOutT, Key>::type T; 00095 uint8_t* data_ptr = reinterpret_cast<uint8_t*>(&p2_) + pcl::traits::offset<PointOutT, Key>::value; 00096 *reinterpret_cast<T*>(data_ptr) = p1_[f_idx_++]; 00097 } 00098 00099 private: 00100 const Eigen::VectorXf &p1_; 00101 Pod &p2_; 00102 int f_idx_; 00103 public: 00104 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00105 }; 00106 00108 00109 template <typename PointInT> 00110 struct NdCopyPointEigenFunctor 00111 { 00112 typedef typename traits::POD<PointInT>::type Pod; 00113 00118 NdCopyPointEigenFunctor (const PointInT &p1, Eigen::VectorXf &p2) 00119 : p1_ (reinterpret_cast<const Pod&>(p1)), p2_ (p2), f_idx_ (0) { } 00120 00122 template<typename Key> inline void 00123 operator() () 00124 { 00125 //p2_[f_idx_++] = boost::fusion::at_key<Key> (p1_); 00126 typedef typename pcl::traits::datatype<PointInT, Key>::type T; 00127 const uint8_t* data_ptr = reinterpret_cast<const uint8_t*>(&p1_) + pcl::traits::offset<PointInT, Key>::value; 00128 p2_[f_idx_++] = *reinterpret_cast<const T*>(data_ptr); 00129 } 00130 00131 private: 00132 const Pod &p1_; 00133 Eigen::VectorXf &p2_; 00134 int f_idx_; 00135 public: 00136 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00137 }; 00138 00139 namespace detail 00140 { 00141 template <typename PointT> boost::shared_ptr<pcl::MsgFieldMap>& 00142 getMapping (pcl::PointCloud<PointT>& p); 00143 } // namespace detail 00144 00178 template <typename PointT> 00179 class PointCloud 00180 { 00181 public: 00186 PointCloud () : 00187 header (), width (0), height (0), is_dense (true), 00188 sensor_origin_ (Eigen::Vector4f::Zero ()), sensor_orientation_ (Eigen::Quaternionf::Identity ()), 00189 mapping_ () 00190 {} 00191 00195 PointCloud (PointCloud<PointT> &pc) : 00196 header (), width (0), height (0), is_dense (true), 00197 sensor_origin_ (Eigen::Vector4f::Zero ()), sensor_orientation_ (Eigen::Quaternionf::Identity ()), 00198 mapping_ () 00199 { 00200 *this = pc; 00201 } 00202 00206 PointCloud (const PointCloud<PointT> &pc) : 00207 header (), width (0), height (0), is_dense (true), 00208 sensor_origin_ (Eigen::Vector4f::Zero ()), sensor_orientation_ (Eigen::Quaternionf::Identity ()), 00209 mapping_ () 00210 { 00211 *this = pc; 00212 } 00213 00218 PointCloud (const PointCloud<PointT> &pc, 00219 const std::vector<int> &indices) : 00220 header (pc.header), points (indices.size ()), width (indices.size ()), height (1), is_dense (pc.is_dense), 00221 sensor_origin_ (pc.sensor_origin_), sensor_orientation_ (pc.sensor_orientation_), 00222 mapping_ () 00223 { 00224 // Copy the obvious 00225 assert (indices.size () <= pc.size ()); 00226 for (size_t i = 0; i < indices.size (); i++) 00227 points[i] = pc.points[indices[i]]; 00228 } 00229 00235 PointCloud (uint32_t width_, uint32_t height_, const PointT& value_ = PointT ()) 00236 : header () 00237 , points (width_ * height_, value_) 00238 , width (width_) 00239 , height (height_) 00240 , is_dense (true) 00241 , sensor_origin_ (Eigen::Vector4f::Zero ()) 00242 , sensor_orientation_ (Eigen::Quaternionf::Identity ()) 00243 , mapping_ () 00244 {} 00245 00247 virtual ~PointCloud () {} 00248 00250 00254 inline PointCloud& 00255 operator += (const PointCloud& rhs) 00256 { 00257 // Make the resultant point cloud take the newest stamp 00258 if (rhs.header.stamp > header.stamp) 00259 header.stamp = rhs.header.stamp; 00260 00261 size_t nr_points = points.size (); 00262 points.resize (nr_points + rhs.points.size ()); 00263 for (size_t i = nr_points; i < points.size (); ++i) 00264 points[i] = rhs.points[i - nr_points]; 00265 00266 width = (uint32_t) points.size (); 00267 height = 1; 00268 if (rhs.is_dense && is_dense) 00269 is_dense = true; 00270 else 00271 is_dense = false; 00272 return (*this); 00273 } 00274 00276 00280 inline const PointCloud 00281 operator + (const PointCloud& rhs) 00282 { 00283 return (PointCloud (*this) += rhs); 00284 } 00285 00287 00292 inline const PointT& 00293 at (int column, int row) const 00294 { 00295 if (this->height > 1) 00296 return (points.at (row * this->width + column)); 00297 else 00298 throw IsNotDenseException ("Can't use 2D indexing with a unorganized point cloud"); 00299 } 00300 00306 inline PointT& 00307 at (int column, int row) 00308 { 00309 if (this->height > 1) 00310 return (points.at (row * this->width + column)); 00311 else 00312 throw IsNotDenseException ("Can't use 2D indexing with a unorganized point cloud"); 00313 } 00314 00316 00321 inline const PointT& 00322 operator () (size_t column, size_t row) const 00323 { 00324 return (points[row * this->width + column]); 00325 } 00326 00332 inline PointT& 00333 operator () (size_t column, size_t row) 00334 { 00335 return (points[row * this->width + column]); 00336 } 00337 00339 00342 inline bool 00343 isOrganized () const 00344 { 00345 return (height != 1); 00346 } 00347 00349 00364 inline Eigen::Map<Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> > 00365 getMatrixXfMap (int dim, int stride, int offset) 00366 { 00367 if (Eigen::MatrixXf::Flags & Eigen::RowMajorBit) 00368 return (Eigen::Map<Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >((float*)(&points[0])+offset, points.size (), dim, Eigen::OuterStride<> (stride))); 00369 else 00370 return (Eigen::Map<Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >((float*)(&points[0])+offset, dim, points.size (), Eigen::OuterStride<> (stride))); 00371 } 00372 00388 inline const Eigen::Map<const Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> > 00389 getMatrixXfMap (int dim, int stride, int offset) const 00390 { 00391 if (Eigen::MatrixXf::Flags & Eigen::RowMajorBit) 00392 return (Eigen::Map<const Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >((float*)(&points[0])+offset, points.size (), dim, Eigen::OuterStride<> (stride))); 00393 else 00394 return (Eigen::Map<const Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >((float*)(&points[0])+offset, dim, points.size (), Eigen::OuterStride<> (stride))); 00395 } 00396 00398 00403 inline Eigen::Map<Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> > 00404 getMatrixXfMap () 00405 { 00406 return (getMatrixXfMap (sizeof (PointT) / sizeof (float), sizeof (PointT) / sizeof (float), 0)); 00407 } 00408 00414 inline const Eigen::Map<const Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> > 00415 getMatrixXfMap () const 00416 { 00417 return (getMatrixXfMap (sizeof (PointT) / sizeof (float), sizeof (PointT) / sizeof (float), 0)); 00418 } 00419 00421 std_msgs::Header header; 00422 00424 std::vector<PointT, Eigen::aligned_allocator<PointT> > points; 00425 00427 uint32_t width; 00429 uint32_t height; 00430 00432 bool is_dense; 00433 00435 Eigen::Vector4f sensor_origin_; 00437 Eigen::Quaternionf sensor_orientation_; 00438 00439 typedef PointT PointType; // Make the template class available from the outside 00440 typedef std::vector<PointT, Eigen::aligned_allocator<PointT> > VectorType; 00441 typedef boost::shared_ptr<PointCloud<PointT> > Ptr; 00442 typedef boost::shared_ptr<const PointCloud<PointT> > ConstPtr; 00443 00444 // iterators 00445 typedef typename VectorType::iterator iterator; 00446 typedef typename VectorType::const_iterator const_iterator; 00447 inline iterator begin () { return (points.begin ()); } 00448 inline iterator end () { return (points.end ()); } 00449 inline const_iterator begin () const { return (points.begin ()); } 00450 inline const_iterator end () const { return (points.end ()); } 00451 00452 //capacity 00453 inline size_t size () const { return (points.size ()); } 00454 inline void reserve (size_t n) { points.reserve (n); } 00455 inline void resize (size_t n) { points.resize (n); } 00456 inline bool empty () const { return points.empty (); } 00457 00458 //element access 00459 inline const PointT& operator[] (size_t n) const { return points[n]; } 00460 inline PointT& operator[] (size_t n) { return points[n]; } 00461 inline const PointT& at (size_t n) const { return points.at (n); } 00462 inline PointT& at (size_t n) { return points.at (n); } 00463 inline const PointT& front () const { return points.front (); } 00464 inline PointT& front () { return points.front (); } 00465 inline const PointT& back () const { return points.back (); } 00466 inline PointT& back () { return points.back (); } 00467 00472 inline void 00473 push_back (const PointT& pt) 00474 { 00475 points.push_back (pt); 00476 width = points.size (); 00477 height = 1; 00478 } 00479 00486 inline iterator 00487 insert (iterator position, const PointT& pt) 00488 { 00489 iterator it = points.insert (position, pt); 00490 width = points.size (); 00491 height = 1; 00492 return (it); 00493 } 00494 00501 inline void 00502 insert (iterator position, size_t n, const PointT& pt) 00503 { 00504 points.insert (position, n, pt); 00505 width = points.size (); 00506 height = 1; 00507 } 00508 00515 template <class InputIterator> inline void 00516 insert (iterator position, InputIterator first, InputIterator last) 00517 { 00518 points.insert (position, first, last); 00519 width = points.size (); 00520 height = 1; 00521 } 00522 00528 inline iterator 00529 erase (iterator position) 00530 { 00531 iterator it = points.erase (position); 00532 width = points.size (); 00533 height = 1; 00534 return (it); 00535 } 00536 00543 inline iterator 00544 erase (iterator first, iterator last) 00545 { 00546 iterator it = points.erase (first, last); 00547 width = points.size (); 00548 height = 1; 00549 return (it); 00550 } 00551 00555 inline void 00556 swap (PointCloud<PointT> &rhs) 00557 { 00558 this->points.swap (rhs.points); 00559 std::swap (width, rhs.width); 00560 std::swap (height, rhs.height); 00561 std::swap (is_dense, rhs.is_dense); 00562 std::swap (sensor_origin_, rhs.sensor_origin_); 00563 std::swap (sensor_orientation_, rhs.sensor_orientation_); 00564 } 00565 00567 inline void 00568 clear () 00569 { 00570 points.clear (); 00571 width = 0; 00572 height = 0; 00573 } 00574 00580 inline Ptr 00581 makeShared () const { return Ptr (new PointCloud<PointT> (*this)); } 00582 00583 protected: 00584 // This is motivated by ROS integration. Users should not need to access mapping_. 00585 boost::shared_ptr<MsgFieldMap> mapping_; 00586 00587 friend boost::shared_ptr<MsgFieldMap>& detail::getMapping<PointT>(pcl::PointCloud<PointT> &p); 00588 00589 public: 00590 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00591 }; 00592 00611 template <> 00612 class PointCloud<Eigen::MatrixXf> 00613 { 00614 public: 00618 PointCloud () : 00619 properties (), points (Eigen::MatrixXf (0, 0)), channels (), width (0), height (0), is_dense (true) 00620 {} 00621 00625 PointCloud (PointCloud<Eigen::MatrixXf> &pc) : 00626 properties (), points (Eigen::MatrixXf (0, 0)), channels (), width (0), height (0), is_dense (true) 00627 { 00628 *this = pc; 00629 } 00630 00634 template <typename PointT> 00635 PointCloud (PointCloud<PointT> &pc) : 00636 properties (), points (Eigen::MatrixXf (0, 0)), channels (), 00637 width (pc.width), height (pc.height), is_dense (pc.is_dense) 00638 { 00639 // Copy the obvious 00640 properties.acquisition_time = pc.header.stamp; 00641 properties.sensor_origin = pc.sensor_origin_;//.head<3> (); 00642 properties.sensor_orientation = pc.sensor_orientation_; 00643 00644 typedef typename pcl::traits::fieldList<PointT>::type FieldList; 00645 // Copy the fields 00646 pcl::for_each_type <FieldList> (CopyFieldsChannelProperties <PointT> (channels)); 00647 00648 // Resize the array 00649 points.resize (pc.points.size (), boost::mpl::size<FieldList>::value); 00650 00651 for (size_t cp = 0; cp < pc.points.size (); ++cp) 00652 pcl::for_each_type <FieldList> (NdCopyPointEigenFunctor<PointT, Eigen::MatrixXf::RowXpr> (pc.points[cp], points.row (cp))); 00653 } 00654 00658 PointCloud (const PointCloud<Eigen::MatrixXf> &pc) : 00659 properties (), points (Eigen::MatrixXf (0, 0)), channels (), width (0), height (0), is_dense (true) 00660 { 00661 *this = pc; 00662 } 00663 00667 template <typename PointT> 00668 PointCloud (const PointCloud<PointT> &pc) : 00669 properties (), points (Eigen::MatrixXf (0, 0)), channels (), 00670 width (pc.width), height (pc.height), is_dense (pc.is_dense) 00671 { 00672 // Copy the obvious 00673 properties.acquisition_time = pc.header.stamp; 00674 properties.sensor_origin = pc.sensor_origin_;//.head<3> (); 00675 properties.sensor_orientation = pc.sensor_orientation_; 00676 00677 typedef typename pcl::traits::fieldList<PointT>::type FieldList; 00678 00679 // Copy the fields 00680 pcl::for_each_type <FieldList> (CopyFieldsChannelProperties <PointT> (channels)); 00681 00682 // Resize the array 00683 points.resize (pc.points.size (), boost::mpl::size<FieldList>::value); 00684 00685 for (size_t cp = 0; cp < pc.points.size (); ++cp) 00686 pcl::for_each_type <FieldList> (NdCopyPointEigenFunctor<PointT, Eigen::MatrixXf::RowXpr> (pc.points[cp], points.row (cp))); 00687 } 00688 00693 PointCloud (const PointCloud &pc, 00694 const std::vector<int> &indices) : 00695 properties (pc.properties), 00696 points (Eigen::MatrixXf (indices.size (), pc.points.cols ())), 00697 channels (pc.channels), 00698 width ((uint32_t) indices.size ()), height (1), is_dense (pc.is_dense) 00699 { 00700 // Copy the obvious 00701 assert ((int)indices.size () <= pc.points.rows ()); 00702 for (size_t i = 0; i < indices.size (); i++) 00703 points.row (i) = pc.points.row (indices[i]); 00704 } 00705 00711 inline PointCloud (uint32_t _width, uint32_t _height, uint32_t _dim) 00712 : properties () 00713 , points (Eigen::MatrixXf (_width * _height, _dim)) 00714 , channels () 00715 , width (_width) 00716 , height (_height) 00717 , is_dense (true) 00718 {} 00719 00724 inline PointCloud (uint32_t _num_points, uint32_t _dim) 00725 : properties () 00726 , points (Eigen::MatrixXf (_num_points, _dim)) 00727 , channels () 00728 , width (_num_points) 00729 , height (1) 00730 , is_dense (true) 00731 {} 00732 00734 virtual ~PointCloud () {} 00735 00737 00741 inline PointCloud& 00742 operator += (const PointCloud& rhs) 00743 { 00744 if (rhs.properties.acquisition_time > properties.acquisition_time) 00745 properties.acquisition_time = rhs.properties.acquisition_time; 00746 00747 properties.sensor_origin = Eigen::Vector4f::Zero (); 00748 properties.sensor_orientation = Eigen::Quaternionf::Identity (); 00749 00750 int nr_points = (int) points.rows (); 00751 points.resize (nr_points + rhs.points.rows (), points.cols ()); 00752 for (int i = nr_points; i < points.rows (); ++i) 00753 points.row (i) = rhs.points.row (i - nr_points); 00754 00755 channels = rhs.channels; 00756 width = (uint32_t) points.rows (); 00757 height = 1; 00758 if (rhs.is_dense && is_dense) 00759 is_dense = true; 00760 else 00761 is_dense = false; 00762 return (*this); 00763 } 00764 00766 00770 inline const PointCloud 00771 operator + (const PointCloud& rhs) 00772 { 00773 return (PointCloud (*this) += rhs); 00774 } 00775 00777 00782 inline Eigen::Map<Eigen::VectorXf> 00783 at (int column, int row) 00784 { 00785 if (height > 1) 00786 return (Eigen::VectorXf::Map (&points (row * width + column, 0), points.cols ())); 00787 else 00788 throw IsNotDenseException ("Can't use 2D indexing with a unorganized point cloud"); 00789 } 00790 00792 00797 inline Eigen::Map<Eigen::VectorXf> 00798 operator () (int column, int row) 00799 { 00800 return (Eigen::VectorXf::Map (&points (row * width + column, 0), points.cols ())); 00801 } 00802 00804 00807 inline bool 00808 isOrganized () const 00809 { 00810 return (height != 1); 00811 } 00812 00814 00815 inline bool 00816 empty () const 00817 { 00818 return (points.rows () == 0); 00819 } 00820 00822 pcl::CloudProperties properties; 00823 00825 Eigen::MatrixXf points; 00826 00828 std::map<std::string, pcl::ChannelProperties> channels; 00829 00831 uint32_t width; 00833 uint32_t height; 00834 00836 bool is_dense; 00837 00838 typedef boost::shared_ptr<PointCloud<Eigen::MatrixXf> > Ptr; 00839 typedef boost::shared_ptr<const PointCloud<Eigen::MatrixXf> > ConstPtr; 00840 00841 inline size_t size () const { return (points.rows ()); } 00842 00846 inline void 00847 swap (PointCloud<Eigen::MatrixXf> &rhs) 00848 { 00849 std::swap (points, rhs.points); 00850 std::swap (width, rhs.width); 00851 std::swap (height, rhs.height); 00852 std::swap (is_dense, rhs.is_dense); 00853 std::swap (properties, rhs.properties); 00854 std::swap (channels, rhs.channels); 00855 } 00856 00858 inline void 00859 clear () 00860 { 00861 points.resize (0, 0); 00862 width = 0; 00863 height = 0; 00864 } 00865 00871 inline Ptr 00872 makeShared () { return Ptr (new PointCloud<Eigen::MatrixXf> (*this)); } 00873 00878 inline ConstPtr 00879 makeShared () const { return ConstPtr (new PointCloud<Eigen::MatrixXf> (*this)); } 00880 00881 public: 00882 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00883 00884 private: 00886 00887 template <typename PointOutT, typename PointInT> 00888 struct NdCopyEigenPointFunctor 00889 { 00890 typedef typename traits::POD<PointOutT>::type Pod; 00891 00896 NdCopyEigenPointFunctor (const PointInT p1, PointOutT &p2) 00897 : p1_ (p1), 00898 p2_ (reinterpret_cast<Pod&>(p2)), 00899 f_idx_ (0) { } 00900 00902 template<typename Key> inline void 00903 operator() () 00904 { 00905 //boost::fusion::at_key<Key> (p2_) = p1_[f_idx_++]; 00906 typedef typename pcl::traits::datatype<PointOutT, Key>::type T; 00907 uint8_t* data_ptr = reinterpret_cast<uint8_t*>(&p2_) + pcl::traits::offset<PointOutT, Key>::value; 00908 *reinterpret_cast<T*>(data_ptr) = p1_[f_idx_++]; 00909 } 00910 00911 private: 00912 const PointInT p1_; 00913 Pod &p2_; 00914 int f_idx_; 00915 public: 00916 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00917 }; 00918 00920 00921 template <typename PointInT, typename PointOutT> 00922 struct NdCopyPointEigenFunctor 00923 { 00924 typedef typename traits::POD<PointInT>::type Pod; 00925 00930 NdCopyPointEigenFunctor (const PointInT &p1, PointOutT p2) 00931 : p1_ (reinterpret_cast<const Pod&>(p1)), p2_ (p2), f_idx_ (0) { } 00932 00934 template<typename Key> inline void 00935 operator() () 00936 { 00937 //p2_[f_idx_++] = boost::fusion::at_key<Key> (p1_); 00938 typedef typename pcl::traits::datatype<PointInT, Key>::type T; 00939 const uint8_t* data_ptr = reinterpret_cast<const uint8_t*>(&p1_) + pcl::traits::offset<PointInT, Key>::value; 00940 p2_[f_idx_++] = *reinterpret_cast<const T*>(data_ptr); 00941 } 00942 00943 private: 00944 const Pod &p1_; 00945 PointOutT p2_; 00946 int f_idx_; 00947 public: 00948 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00949 }; 00950 00952 00953 template <typename T> 00954 struct CopyFieldsChannelProperties 00955 { 00959 CopyFieldsChannelProperties (std::map<std::string, pcl::ChannelProperties> &channels) 00960 : channels_ (channels) {} 00961 00963 template<typename U> inline void 00964 operator() () 00965 { 00966 //boost::fusion::at_key<Key> (p2_) = p1_[f_idx_++]; 00967 std::string name = pcl::traits::name<T, U>::value; 00968 channels_[name].name = name; 00969 channels_[name].offset = pcl::traits::offset<T, U>::value; 00970 int datatype = pcl::traits::datatype<T, U>::value; 00971 channels_[name].datatype = datatype; 00972 int count = pcl::traits::datatype<T, U>::size; 00973 channels_[name].count = count; 00974 switch (datatype) 00975 { 00976 case sensor_msgs::PointField::INT8: 00977 case sensor_msgs::PointField::UINT8: 00978 { 00979 channels_[name].size = count; 00980 break; 00981 } 00982 00983 case sensor_msgs::PointField::INT16: 00984 case sensor_msgs::PointField::UINT16: 00985 { 00986 channels_[name].size = count * 2; 00987 break; 00988 } 00989 00990 case sensor_msgs::PointField::INT32: 00991 case sensor_msgs::PointField::UINT32: 00992 case sensor_msgs::PointField::FLOAT32: 00993 { 00994 channels_[name].size = count * 4; 00995 break; 00996 } 00997 00998 case sensor_msgs::PointField::FLOAT64: 00999 { 01000 channels_[name].size = count * 8; 01001 break; 01002 } 01003 } 01004 } 01005 01006 private: 01007 std::map<std::string, pcl::ChannelProperties> &channels_; 01008 }; 01009 }; 01010 01012 namespace detail 01013 { 01014 template <typename PointT> boost::shared_ptr<pcl::MsgFieldMap>& 01015 getMapping (pcl::PointCloud<PointT>& p) 01016 { 01017 return (p.mapping_); 01018 } 01019 } // namespace detail 01020 01021 template <typename PointT> std::ostream& 01022 operator << (std::ostream& s, const pcl::PointCloud<PointT> &p) 01023 { 01024 s << "points[]: " << p.points.size () << std::endl; 01025 s << "width: " << p.width << std::endl; 01026 s << "height: " << p.height << std::endl; 01027 s << "is_dense: " << p.is_dense << std::endl; 01028 return (s); 01029 } 01030 } 01031 01032 #endif //#ifndef PCL_POINT_CLOUD_H_
1.8.0