|
Point Cloud Library (PCL)
1.6.0
|
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 6126 2012-07-03 20:19:58Z aichim $ 00037 * 00038 */ 00039 00040 #ifndef PCL_POINT_CLOUD_H_ 00041 #define PCL_POINT_CLOUD_H_ 00042 00043 #include <pcl/common/eigen.h> 00044 #include <cstddef> 00045 #include <std_msgs/Header.h> 00046 #include <pcl/pcl_macros.h> 00047 #include <pcl/exceptions.h> 00048 #include <pcl/cloud_properties.h> 00049 #include <pcl/channel_properties.h> 00050 #include <pcl/point_traits.h> 00051 #include <pcl/for_each_type.h> 00052 #include <boost/shared_ptr.hpp> 00053 #include <map> 00054 #include <boost/mpl/size.hpp> 00055 00056 namespace pcl 00057 { 00058 namespace detail 00059 { 00060 struct FieldMapping 00061 { 00062 size_t serialized_offset; 00063 size_t struct_offset; 00064 size_t size; 00065 }; 00066 } // namespace detail 00067 00068 // Forward declarations 00069 template <typename PointT> class PointCloud; 00070 typedef std::vector<detail::FieldMapping> MsgFieldMap; 00071 00073 00074 template <typename PointOutT> 00075 struct NdCopyEigenPointFunctor 00076 { 00077 typedef typename traits::POD<PointOutT>::type Pod; 00078 00083 NdCopyEigenPointFunctor (const Eigen::VectorXf &p1, PointOutT &p2) 00084 : p1_ (p1), 00085 p2_ (reinterpret_cast<Pod&>(p2)), 00086 f_idx_ (0) { } 00087 00089 template<typename Key> inline void 00090 operator() () 00091 { 00092 //boost::fusion::at_key<Key> (p2_) = p1_[f_idx_++]; 00093 typedef typename pcl::traits::datatype<PointOutT, Key>::type T; 00094 uint8_t* data_ptr = reinterpret_cast<uint8_t*>(&p2_) + pcl::traits::offset<PointOutT, Key>::value; 00095 *reinterpret_cast<T*>(data_ptr) = static_cast<T> (p1_[f_idx_++]); 00096 } 00097 00098 private: 00099 const Eigen::VectorXf &p1_; 00100 Pod &p2_; 00101 int f_idx_; 00102 public: 00103 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00104 }; 00105 00107 00108 template <typename PointInT> 00109 struct NdCopyPointEigenFunctor 00110 { 00111 typedef typename traits::POD<PointInT>::type Pod; 00112 00117 NdCopyPointEigenFunctor (const PointInT &p1, Eigen::VectorXf &p2) 00118 : p1_ (reinterpret_cast<const Pod&>(p1)), p2_ (p2), f_idx_ (0) { } 00119 00121 template<typename Key> inline void 00122 operator() () 00123 { 00124 //p2_[f_idx_++] = boost::fusion::at_key<Key> (p1_); 00125 typedef typename pcl::traits::datatype<PointInT, Key>::type T; 00126 const uint8_t* data_ptr = reinterpret_cast<const uint8_t*>(&p1_) + pcl::traits::offset<PointInT, Key>::value; 00127 p2_[f_idx_++] = static_cast<float> (*reinterpret_cast<const T*>(data_ptr)); 00128 } 00129 00130 private: 00131 const Pod &p1_; 00132 Eigen::VectorXf &p2_; 00133 int f_idx_; 00134 public: 00135 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00136 }; 00137 00138 namespace detail 00139 { 00140 template <typename PointT> boost::shared_ptr<pcl::MsgFieldMap>& 00141 getMapping (pcl::PointCloud<PointT>& p); 00142 } // namespace detail 00143 00177 template <typename PointT> 00178 class PointCloud 00179 { 00180 public: 00185 PointCloud () : 00186 header (), points (), width (0), height (0), is_dense (true), 00187 sensor_origin_ (Eigen::Vector4f::Zero ()), sensor_orientation_ (Eigen::Quaternionf::Identity ()), 00188 mapping_ () 00189 {} 00190 00194 PointCloud (PointCloud<PointT> &pc) : 00195 header (), points (), width (0), height (0), is_dense (true), 00196 sensor_origin_ (Eigen::Vector4f::Zero ()), sensor_orientation_ (Eigen::Quaternionf::Identity ()), 00197 mapping_ () 00198 { 00199 *this = pc; 00200 } 00201 00205 PointCloud (const PointCloud<PointT> &pc) : 00206 header (), points (), width (0), height (0), is_dense (true), 00207 sensor_origin_ (Eigen::Vector4f::Zero ()), sensor_orientation_ (Eigen::Quaternionf::Identity ()), 00208 mapping_ () 00209 { 00210 *this = pc; 00211 } 00212 00217 PointCloud (const PointCloud<PointT> &pc, 00218 const std::vector<int> &indices) : 00219 header (pc.header), points (indices.size ()), width (indices.size ()), height (1), is_dense (pc.is_dense), 00220 sensor_origin_ (pc.sensor_origin_), sensor_orientation_ (pc.sensor_orientation_), 00221 mapping_ () 00222 { 00223 // Copy the obvious 00224 assert (indices.size () <= pc.size ()); 00225 for (size_t i = 0; i < indices.size (); i++) 00226 points[i] = pc.points[indices[i]]; 00227 } 00228 00234 PointCloud (uint32_t width_, uint32_t height_, const PointT& value_ = PointT ()) 00235 : header () 00236 , points (width_ * height_, value_) 00237 , width (width_) 00238 , height (height_) 00239 , is_dense (true) 00240 , sensor_origin_ (Eigen::Vector4f::Zero ()) 00241 , sensor_orientation_ (Eigen::Quaternionf::Identity ()) 00242 , mapping_ () 00243 {} 00244 00246 virtual ~PointCloud () {} 00247 00249 00253 inline PointCloud& 00254 operator += (const PointCloud& rhs) 00255 { 00256 // Make the resultant point cloud take the newest stamp 00257 if (rhs.header.stamp > header.stamp) 00258 header.stamp = rhs.header.stamp; 00259 00260 size_t nr_points = points.size (); 00261 points.resize (nr_points + rhs.points.size ()); 00262 for (size_t i = nr_points; i < points.size (); ++i) 00263 points[i] = rhs.points[i - nr_points]; 00264 00265 width = static_cast<uint32_t>(points.size ()); 00266 height = 1; 00267 if (rhs.is_dense && is_dense) 00268 is_dense = true; 00269 else 00270 is_dense = false; 00271 return (*this); 00272 } 00273 00275 00279 inline const PointCloud 00280 operator + (const PointCloud& rhs) 00281 { 00282 return (PointCloud (*this) += rhs); 00283 } 00284 00286 00291 inline const PointT& 00292 at (int column, int row) const 00293 { 00294 if (this->height > 1) 00295 return (points.at (row * this->width + column)); 00296 else 00297 throw IsNotDenseException ("Can't use 2D indexing with a unorganized point cloud"); 00298 } 00299 00305 inline PointT& 00306 at (int column, int row) 00307 { 00308 if (this->height > 1) 00309 return (points.at (row * this->width + column)); 00310 else 00311 throw IsNotDenseException ("Can't use 2D indexing with a unorganized point cloud"); 00312 } 00313 00315 00320 inline const PointT& 00321 operator () (size_t column, size_t row) const 00322 { 00323 return (points[row * this->width + column]); 00324 } 00325 00331 inline PointT& 00332 operator () (size_t column, size_t row) 00333 { 00334 return (points[row * this->width + column]); 00335 } 00336 00338 00341 inline bool 00342 isOrganized () const 00343 { 00344 return (height != 1); 00345 } 00346 00348 00363 inline Eigen::Map<Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> > 00364 getMatrixXfMap (int dim, int stride, int offset) 00365 { 00366 if (Eigen::MatrixXf::Flags & Eigen::RowMajorBit) 00367 return (Eigen::Map<Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >(reinterpret_cast<float*>(&points[0])+offset, points.size (), dim, Eigen::OuterStride<> (stride))); 00368 else 00369 return (Eigen::Map<Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >(reinterpret_cast<float*>(&points[0])+offset, dim, points.size (), Eigen::OuterStride<> (stride))); 00370 } 00371 00387 inline const Eigen::Map<const Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> > 00388 getMatrixXfMap (int dim, int stride, int offset) const 00389 { 00390 if (Eigen::MatrixXf::Flags & Eigen::RowMajorBit) 00391 return (Eigen::Map<const Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >(reinterpret_cast<float*>(&points[0])+offset, points.size (), dim, Eigen::OuterStride<> (stride))); 00392 else 00393 return (Eigen::Map<const Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >(reinterpret_cast<float*>(&points[0])+offset, dim, points.size (), Eigen::OuterStride<> (stride))); 00394 } 00395 00397 00402 inline Eigen::Map<Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> > 00403 getMatrixXfMap () 00404 { 00405 return (getMatrixXfMap (sizeof (PointT) / sizeof (float), sizeof (PointT) / sizeof (float), 0)); 00406 } 00407 00413 inline const Eigen::Map<const Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> > 00414 getMatrixXfMap () const 00415 { 00416 return (getMatrixXfMap (sizeof (PointT) / sizeof (float), sizeof (PointT) / sizeof (float), 0)); 00417 } 00418 00420 std_msgs::Header header; 00421 00423 std::vector<PointT, Eigen::aligned_allocator<PointT> > points; 00424 00426 uint32_t width; 00428 uint32_t height; 00429 00431 bool is_dense; 00432 00434 Eigen::Vector4f sensor_origin_; 00436 Eigen::Quaternionf sensor_orientation_; 00437 00438 typedef PointT PointType; // Make the template class available from the outside 00439 typedef std::vector<PointT, Eigen::aligned_allocator<PointT> > VectorType; 00440 typedef std::vector<PointCloud<PointT>, Eigen::aligned_allocator<PointCloud<PointT> > > CloudVectorType; 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 bool empty () const { return points.empty (); } 00456 00460 inline void resize (size_t n) 00461 { 00462 points.resize (n); 00463 if (width * height != n) 00464 { 00465 width = static_cast<uint32_t> (n); 00466 height = 1; 00467 } 00468 } 00469 00470 //element access 00471 inline const PointT& operator[] (size_t n) const { return (points[n]); } 00472 inline PointT& operator[] (size_t n) { return (points[n]); } 00473 inline const PointT& at (size_t n) const { return (points.at (n)); } 00474 inline PointT& at (size_t n) { return (points.at (n)); } 00475 inline const PointT& front () const { return (points.front ()); } 00476 inline PointT& front () { return (points.front ()); } 00477 inline const PointT& back () const { return (points.back ()); } 00478 inline PointT& back () { return (points.back ()); } 00479 00484 inline void 00485 push_back (const PointT& pt) 00486 { 00487 points.push_back (pt); 00488 width = static_cast<uint32_t> (points.size ()); 00489 height = 1; 00490 } 00491 00498 inline iterator 00499 insert (iterator position, const PointT& pt) 00500 { 00501 iterator it = points.insert (position, pt); 00502 width = static_cast<uint32_t> (points.size ()); 00503 height = 1; 00504 return (it); 00505 } 00506 00513 inline void 00514 insert (iterator position, size_t n, const PointT& pt) 00515 { 00516 points.insert (position, n, pt); 00517 width = static_cast<uint32_t> (points.size ()); 00518 height = 1; 00519 } 00520 00527 template <class InputIterator> inline void 00528 insert (iterator position, InputIterator first, InputIterator last) 00529 { 00530 points.insert (position, first, last); 00531 width = static_cast<uint32_t> (points.size ()); 00532 height = 1; 00533 } 00534 00540 inline iterator 00541 erase (iterator position) 00542 { 00543 iterator it = points.erase (position); 00544 width = static_cast<uint32_t> (points.size ()); 00545 height = 1; 00546 return (it); 00547 } 00548 00555 inline iterator 00556 erase (iterator first, iterator last) 00557 { 00558 iterator it = points.erase (first, last); 00559 width = static_cast<uint32_t> (points.size ()); 00560 height = 1; 00561 return (it); 00562 } 00563 00567 inline void 00568 swap (PointCloud<PointT> &rhs) 00569 { 00570 this->points.swap (rhs.points); 00571 std::swap (width, rhs.width); 00572 std::swap (height, rhs.height); 00573 std::swap (is_dense, rhs.is_dense); 00574 std::swap (sensor_origin_, rhs.sensor_origin_); 00575 std::swap (sensor_orientation_, rhs.sensor_orientation_); 00576 } 00577 00579 inline void 00580 clear () 00581 { 00582 points.clear (); 00583 width = 0; 00584 height = 0; 00585 } 00586 00592 inline Ptr 00593 makeShared () const { return Ptr (new PointCloud<PointT> (*this)); } 00594 00595 protected: 00596 // This is motivated by ROS integration. Users should not need to access mapping_. 00597 boost::shared_ptr<MsgFieldMap> mapping_; 00598 00599 friend boost::shared_ptr<MsgFieldMap>& detail::getMapping<PointT>(pcl::PointCloud<PointT> &p); 00600 00601 public: 00602 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00603 }; 00604 00623 template <> 00624 class PointCloud<Eigen::MatrixXf> 00625 { 00626 public: 00630 PointCloud () : 00631 properties (), points (Eigen::MatrixXf (0, 0)), channels (), width (0), height (0), is_dense (true) 00632 {} 00633 00637 PointCloud (PointCloud<Eigen::MatrixXf> &pc) : 00638 properties (), points (Eigen::MatrixXf (0, 0)), channels (), width (0), height (0), is_dense (true) 00639 { 00640 *this = pc; 00641 } 00642 00646 template <typename PointT> 00647 PointCloud (PointCloud<PointT> &pc) : 00648 properties (), points (Eigen::MatrixXf (0, 0)), channels (), 00649 width (pc.width), height (pc.height), is_dense (pc.is_dense) 00650 { 00651 // Copy the obvious 00652 properties.acquisition_time = pc.header.stamp; 00653 properties.sensor_origin = pc.sensor_origin_;//.head<3> (); 00654 properties.sensor_orientation = pc.sensor_orientation_; 00655 00656 typedef typename pcl::traits::fieldList<PointT>::type FieldList; 00657 // Copy the fields 00658 pcl::for_each_type <FieldList> (CopyFieldsChannelProperties <PointT> (channels)); 00659 00660 // Resize the array 00661 points.resize (pc.points.size (), boost::mpl::size<FieldList>::value); 00662 00663 for (size_t cp = 0; cp < pc.points.size (); ++cp) 00664 pcl::for_each_type <FieldList> (NdCopyPointEigenFunctor<PointT, Eigen::MatrixXf::RowXpr> (pc.points[cp], points.row (cp))); 00665 } 00666 00670 PointCloud (const PointCloud<Eigen::MatrixXf> &pc) : 00671 properties (), points (Eigen::MatrixXf (0, 0)), channels (), width (0), height (0), is_dense (true) 00672 { 00673 *this = pc; 00674 } 00675 00679 template <typename PointT> 00680 PointCloud (const PointCloud<PointT> &pc) : 00681 properties (), points (Eigen::MatrixXf (0, 0)), channels (), 00682 width (pc.width), height (pc.height), is_dense (pc.is_dense) 00683 { 00684 // Copy the obvious 00685 properties.acquisition_time = pc.header.stamp; 00686 properties.sensor_origin = pc.sensor_origin_;//.head<3> (); 00687 properties.sensor_orientation = pc.sensor_orientation_; 00688 00689 typedef typename pcl::traits::fieldList<PointT>::type FieldList; 00690 00691 // Copy the fields 00692 pcl::for_each_type <FieldList> (CopyFieldsChannelProperties <PointT> (channels)); 00693 00694 // Resize the array 00695 points.resize (pc.points.size (), boost::mpl::size<FieldList>::value); 00696 00697 for (size_t cp = 0; cp < pc.points.size (); ++cp) 00698 pcl::for_each_type <FieldList> (NdCopyPointEigenFunctor<PointT, Eigen::MatrixXf::RowXpr> (pc.points[cp], points.row (cp))); 00699 } 00700 00705 PointCloud (const PointCloud &pc, 00706 const std::vector<int> &indices) : 00707 properties (pc.properties), 00708 points (Eigen::MatrixXf (indices.size (), pc.points.cols ())), 00709 channels (pc.channels), 00710 width (static_cast<uint32_t> (indices.size ())), height (1), is_dense (pc.is_dense) 00711 { 00712 // Copy the obvious 00713 assert (static_cast<int>(indices.size ()) <= pc.points.rows ()); 00714 for (size_t i = 0; i < indices.size (); i++) 00715 points.row (i) = pc.points.row (indices[i]); 00716 } 00717 00723 inline PointCloud (uint32_t _width, uint32_t _height, uint32_t _dim) 00724 : properties () 00725 , points (Eigen::MatrixXf (_width * _height, _dim)) 00726 , channels () 00727 , width (_width) 00728 , height (_height) 00729 , is_dense (true) 00730 {} 00731 00736 inline PointCloud (uint32_t _num_points, uint32_t _dim) 00737 : properties () 00738 , points (Eigen::MatrixXf (_num_points, _dim)) 00739 , channels () 00740 , width (_num_points) 00741 , height (1) 00742 , is_dense (true) 00743 {} 00744 00746 virtual ~PointCloud () {} 00747 00749 00753 inline PointCloud& 00754 operator += (const PointCloud& rhs) 00755 { 00756 if (rhs.properties.acquisition_time > properties.acquisition_time) 00757 properties.acquisition_time = rhs.properties.acquisition_time; 00758 00759 properties.sensor_origin = Eigen::Vector4f::Zero (); 00760 properties.sensor_orientation = Eigen::Quaternionf::Identity (); 00761 00762 int nr_points = static_cast<int>(points.rows ()); 00763 points.resize (nr_points + rhs.points.rows (), points.cols ()); 00764 for (int i = nr_points; i < points.rows (); ++i) 00765 points.row (i) = rhs.points.row (i - nr_points); 00766 00767 channels = rhs.channels; 00768 width = static_cast<uint32_t>(points.rows ()); 00769 height = 1; 00770 if (rhs.is_dense && is_dense) 00771 is_dense = true; 00772 else 00773 is_dense = false; 00774 return (*this); 00775 } 00776 00778 00782 inline const PointCloud 00783 operator + (const PointCloud& rhs) 00784 { 00785 return (PointCloud (*this) += rhs); 00786 } 00787 00789 00794 inline Eigen::Map<Eigen::VectorXf> 00795 at (int column, int row) 00796 { 00797 if (height > 1) 00798 return (Eigen::VectorXf::Map (&points (row * width + column, 0), points.cols ())); 00799 else 00800 throw IsNotDenseException ("Can't use 2D indexing with a unorganized point cloud"); 00801 } 00802 00804 00809 inline Eigen::Map<Eigen::VectorXf> 00810 operator () (int column, int row) 00811 { 00812 return (Eigen::VectorXf::Map (&points (row * width + column, 0), points.cols ())); 00813 } 00814 00816 00819 inline bool 00820 isOrganized () const 00821 { 00822 return (height != 1); 00823 } 00824 00826 00827 inline bool 00828 empty () const 00829 { 00830 return (points.rows () == 0); 00831 } 00832 00834 pcl::CloudProperties properties; 00835 00837 Eigen::MatrixXf points; 00838 00840 std::map<std::string, pcl::ChannelProperties> channels; 00841 00843 uint32_t width; 00845 uint32_t height; 00846 00848 bool is_dense; 00849 00850 typedef boost::shared_ptr<PointCloud<Eigen::MatrixXf> > Ptr; 00851 typedef boost::shared_ptr<const PointCloud<Eigen::MatrixXf> > ConstPtr; 00852 00853 inline size_t size () const { return (points.rows ()); } 00854 00858 inline void 00859 swap (PointCloud<Eigen::MatrixXf> &rhs) 00860 { 00861 std::swap (points, rhs.points); 00862 std::swap (width, rhs.width); 00863 std::swap (height, rhs.height); 00864 std::swap (is_dense, rhs.is_dense); 00865 std::swap (properties, rhs.properties); 00866 std::swap (channels, rhs.channels); 00867 } 00868 00870 inline void 00871 clear () 00872 { 00873 points.resize (0, 0); 00874 width = 0; 00875 height = 0; 00876 } 00877 00883 inline Ptr 00884 makeShared () { return Ptr (new PointCloud<Eigen::MatrixXf> (*this)); } 00885 00890 inline ConstPtr 00891 makeShared () const { return ConstPtr (new PointCloud<Eigen::MatrixXf> (*this)); } 00892 00893 public: 00894 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00895 00896 private: 00898 00899 template <typename PointOutT, typename PointInT> 00900 struct NdCopyEigenPointFunctor 00901 { 00902 typedef typename traits::POD<PointOutT>::type Pod; 00903 00908 NdCopyEigenPointFunctor (const PointInT p1, PointOutT &p2) 00909 : p1_ (p1), 00910 p2_ (reinterpret_cast<Pod&>(p2)), 00911 f_idx_ (0) { } 00912 00914 template<typename Key> inline void 00915 operator() () 00916 { 00917 //boost::fusion::at_key<Key> (p2_) = p1_[f_idx_++]; 00918 typedef typename pcl::traits::datatype<PointOutT, Key>::type T; 00919 uint8_t* data_ptr = reinterpret_cast<uint8_t*>(&p2_) + pcl::traits::offset<PointOutT, Key>::value; 00920 *reinterpret_cast<T*>(data_ptr) = p1_[f_idx_++]; 00921 } 00922 00923 private: 00924 const PointInT p1_; 00925 Pod &p2_; 00926 int f_idx_; 00927 public: 00928 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00929 }; 00930 00932 00933 template <typename PointInT, typename PointOutT> 00934 struct NdCopyPointEigenFunctor 00935 { 00936 typedef typename traits::POD<PointInT>::type Pod; 00937 00942 NdCopyPointEigenFunctor (const PointInT &p1, PointOutT p2) 00943 : p1_ (reinterpret_cast<const Pod&>(p1)), p2_ (p2), f_idx_ (0) { } 00944 00946 template<typename Key> inline void 00947 operator() () 00948 { 00949 //p2_[f_idx_++] = boost::fusion::at_key<Key> (p1_); 00950 typedef typename pcl::traits::datatype<PointInT, Key>::type T; 00951 const uint8_t* data_ptr = reinterpret_cast<const uint8_t*>(&p1_) + pcl::traits::offset<PointInT, Key>::value; 00952 p2_[f_idx_++] = *reinterpret_cast<const T*>(data_ptr); 00953 } 00954 00955 private: 00956 const Pod &p1_; 00957 PointOutT p2_; 00958 int f_idx_; 00959 public: 00960 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00961 }; 00962 00964 00965 template <typename T> 00966 struct CopyFieldsChannelProperties 00967 { 00971 CopyFieldsChannelProperties (std::map<std::string, pcl::ChannelProperties> &channels) 00972 : channels_ (channels) {} 00973 00975 template<typename U> inline void 00976 operator() () 00977 { 00978 //boost::fusion::at_key<Key> (p2_) = p1_[f_idx_++]; 00979 std::string name = pcl::traits::name<T, U>::value; 00980 channels_[name].name = name; 00981 channels_[name].offset = pcl::traits::offset<T, U>::value; 00982 uint8_t datatype = pcl::traits::datatype<T, U>::value; 00983 channels_[name].datatype = datatype; 00984 int count = pcl::traits::datatype<T, U>::size; 00985 channels_[name].count = count; 00986 switch (datatype) 00987 { 00988 case sensor_msgs::PointField::INT8: 00989 case sensor_msgs::PointField::UINT8: 00990 { 00991 channels_[name].size = count; 00992 break; 00993 } 00994 00995 case sensor_msgs::PointField::INT16: 00996 case sensor_msgs::PointField::UINT16: 00997 { 00998 channels_[name].size = count * 2; 00999 break; 01000 } 01001 01002 case sensor_msgs::PointField::INT32: 01003 case sensor_msgs::PointField::UINT32: 01004 case sensor_msgs::PointField::FLOAT32: 01005 { 01006 channels_[name].size = count * 4; 01007 break; 01008 } 01009 01010 case sensor_msgs::PointField::FLOAT64: 01011 { 01012 channels_[name].size = count * 8; 01013 break; 01014 } 01015 } 01016 } 01017 01018 private: 01019 std::map<std::string, pcl::ChannelProperties> &channels_; 01020 }; 01021 }; 01022 01024 namespace detail 01025 { 01026 template <typename PointT> boost::shared_ptr<pcl::MsgFieldMap>& 01027 getMapping (pcl::PointCloud<PointT>& p) 01028 { 01029 return (p.mapping_); 01030 } 01031 } // namespace detail 01032 01033 template <typename PointT> std::ostream& 01034 operator << (std::ostream& s, const pcl::PointCloud<PointT> &p) 01035 { 01036 s << "points[]: " << p.points.size () << std::endl; 01037 s << "width: " << p.width << std::endl; 01038 s << "height: " << p.height << std::endl; 01039 s << "is_dense: " << p.is_dense << std::endl; 01040 return (s); 01041 } 01042 } 01043 01044 #endif //#ifndef PCL_POINT_CLOUD_H_
1.7.6.1