Point Cloud Library (PCL)  1.11.1-dev
point_cloud.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2012, Willow Garage, Inc.
6  * Copyright (c) 2012-, Open Perception, Inc.
7  *
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * * Redistributions of source code must retain the above copyright
15  * notice, this list of conditions and the following disclaimer.
16  * * Redistributions in binary form must reproduce the above
17  * copyright notice, this list of conditions and the following
18  * disclaimer in the documentation and/or other materials provided
19  * with the distribution.
20  * * Neither the name of the copyright holder(s) nor the names of its
21  * contributors may be used to endorse or promote products derived
22  * from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  *
37  */
38 
39 #pragma once
40 
41 #ifdef __GNUC__
42 #pragma GCC system_header
43 #endif
44 
45 #include <Eigen/StdVector>
46 #include <Eigen/Geometry>
47 #include <pcl/PCLHeader.h>
48 #include <pcl/exceptions.h>
49 #include <pcl/memory.h>
50 #include <pcl/pcl_macros.h>
51 #include <pcl/type_traits.h>
52 #include <pcl/types.h>
53 
54 #include <utility>
55 #include <vector>
56 
57 namespace pcl
58 {
59  namespace detail
60  {
61  struct FieldMapping
62  {
63  std::size_t serialized_offset;
64  std::size_t struct_offset;
65  std::size_t size;
66  };
67  } // namespace detail
68 
69  // Forward declarations
70  template <typename PointT> class PointCloud;
71  using MsgFieldMap = std::vector<detail::FieldMapping>;
72 
73  /** \brief Helper functor structure for copying data between an Eigen type and a PointT. */
74  template <typename PointOutT>
76  {
77  using Pod = typename traits::POD<PointOutT>::type;
78 
79  /** \brief Constructor
80  * \param[in] p1 the input Eigen type
81  * \param[out] p2 the output Point type
82  */
83  NdCopyEigenPointFunctor (const Eigen::VectorXf &p1, PointOutT &p2)
84  : p1_ (p1),
85  p2_ (reinterpret_cast<Pod&>(p2)),
86  f_idx_ (0) { }
87 
88  /** \brief Operator. Data copy happens here. */
89  template<typename Key> inline void
91  {
92  //boost::fusion::at_key<Key> (p2_) = p1_[f_idx_++];
93  using T = typename pcl::traits::datatype<PointOutT, Key>::type;
94  std::uint8_t* data_ptr = reinterpret_cast<std::uint8_t*>(&p2_) + pcl::traits::offset<PointOutT, Key>::value;
95  *reinterpret_cast<T*>(data_ptr) = static_cast<T> (p1_[f_idx_++]);
96  }
97 
98  private:
99  const Eigen::VectorXf &p1_;
100  Pod &p2_;
101  int f_idx_;
102  public:
104  };
105 
106  /** \brief Helper functor structure for copying data between an Eigen type and a PointT. */
107  template <typename PointInT>
109  {
110  using Pod = typename traits::POD<PointInT>::type;
111 
112  /** \brief Constructor
113  * \param[in] p1 the input Point type
114  * \param[out] p2 the output Eigen type
115  */
116  NdCopyPointEigenFunctor (const PointInT &p1, Eigen::VectorXf &p2)
117  : p1_ (reinterpret_cast<const Pod&>(p1)), p2_ (p2), f_idx_ (0) { }
118 
119  /** \brief Operator. Data copy happens here. */
120  template<typename Key> inline void
122  {
123  //p2_[f_idx_++] = boost::fusion::at_key<Key> (p1_);
124  using T = typename pcl::traits::datatype<PointInT, Key>::type;
125  const std::uint8_t* data_ptr = reinterpret_cast<const std::uint8_t*>(&p1_) + pcl::traits::offset<PointInT, Key>::value;
126  p2_[f_idx_++] = static_cast<float> (*reinterpret_cast<const T*>(data_ptr));
127  }
128 
129  private:
130  const Pod &p1_;
131  Eigen::VectorXf &p2_;
132  int f_idx_;
133  public:
135  };
136 
137  /** \brief PointCloud represents the base class in PCL for storing collections of 3D points.
138  *
139  * The class is templated, which means you need to specify the type of data
140  * that it should contain. For example, to create a point cloud that holds 4
141  * random XYZ data points, use:
142  *
143  * \code
144  * pcl::PointCloud<pcl::PointXYZ> cloud;
145  * cloud.push_back (pcl::PointXYZ (rand (), rand (), rand ()));
146  * cloud.push_back (pcl::PointXYZ (rand (), rand (), rand ()));
147  * cloud.push_back (pcl::PointXYZ (rand (), rand (), rand ()));
148  * cloud.push_back (pcl::PointXYZ (rand (), rand (), rand ()));
149  * \endcode
150  *
151  * The PointCloud class contains the following elements:
152  * - \b width - specifies the width of the point cloud dataset in the number of points. WIDTH has two meanings:
153  * - it can specify the total number of points in the cloud (equal with POINTS see below) for unorganized datasets;
154  * - it can specify the width (total number of points in a row) of an organized point cloud dataset.
155  * \a Mandatory.
156  * - \b height - specifies the height of the point cloud dataset in the number of points. HEIGHT has two meanings:
157  * - it can specify the height (total number of rows) of an organized point cloud dataset;
158  * - it is set to 1 for unorganized datasets (thus used to check whether a dataset is organized or not).
159  * \a Mandatory.
160  * - \b points - the data array where all points of type <b>PointT</b> are stored. \a Mandatory.
161  *
162  * - \b is_dense - specifies if all the data in <b>points</b> is finite (true), or whether it might contain Inf/NaN values
163  * (false). \a Mandatory.
164  *
165  * - \b sensor_origin_ - specifies the sensor acquisition pose (origin/translation). \a Optional.
166  * - \b sensor_orientation_ - specifies the sensor acquisition pose (rotation). \a Optional.
167  *
168  * \author Patrick Mihelich, Radu B. Rusu
169  */
170  template <typename PointT>
171  class PCL_EXPORTS PointCloud
172  {
173  public:
174  /** \brief Default constructor. Sets \ref is_dense to true, \ref width
175  * and \ref height to 0, and the \ref sensor_origin_ and \ref
176  * sensor_orientation_ to identity.
177  */
178  PointCloud () = default;
179 
180  /** \brief Copy constructor from point cloud subset
181  * \param[in] pc the cloud to copy into this
182  * \param[in] indices the subset to copy
183  */
185  const Indices &indices) :
186  header (pc.header), points (indices.size ()), width (indices.size ()), height (1), is_dense (pc.is_dense),
187  sensor_origin_ (pc.sensor_origin_), sensor_orientation_ (pc.sensor_orientation_)
188  {
189  // Copy the obvious
190  assert (indices.size () <= pc.size ());
191  for (std::size_t i = 0; i < indices.size (); i++)
192  points[i] = pc[indices[i]];
193  }
194 
195  /** \brief Allocate constructor from point cloud subset
196  * \param[in] width_ the cloud width
197  * \param[in] height_ the cloud height
198  * \param[in] value_ default value
199  */
200  PointCloud (std::uint32_t width_, std::uint32_t height_, const PointT& value_ = PointT ())
201  : points (width_ * height_, value_)
202  , width (width_)
203  , height (height_)
204  {}
205 
206  //TODO: check if copy/move contructors/assignment operators are needed
207 
208  /** \brief Add a point cloud to the current cloud.
209  * \param[in] rhs the cloud to add to the current cloud
210  * \return the new cloud as a concatenation of the current cloud and the new given cloud
211  */
212  inline PointCloud&
213  operator += (const PointCloud& rhs)
214  {
215  concatenate((*this), rhs);
216  return (*this);
217  }
218 
219  /** \brief Add a point cloud to another cloud.
220  * \param[in] rhs the cloud to add to the current cloud
221  * \return the new cloud as a concatenation of the current cloud and the new given cloud
222  */
223  inline PointCloud
224  operator + (const PointCloud& rhs)
225  {
226  return (PointCloud (*this) += rhs);
227  }
228 
229  inline static bool
231  const pcl::PointCloud<PointT> &cloud2)
232  {
233  // Make the resultant point cloud take the newest stamp
234  cloud1.header.stamp = std::max (cloud1.header.stamp, cloud2.header.stamp);
235 
236  // libstdc++ (GCC) on calling reserve allocates new memory, copies and deallocates old vector
237  // This causes a drastic performance hit. Prefer not to use reserve with libstdc++ (default on clang)
238  cloud1.insert (cloud1.end (), cloud2.begin (), cloud2.end ());
239 
240  cloud1.width = cloud1.size ();
241  cloud1.height = 1;
242  cloud1.is_dense = cloud1.is_dense && cloud2.is_dense;
243  return true;
244  }
245 
246  inline static bool
248  const pcl::PointCloud<PointT> &cloud2,
249  pcl::PointCloud<PointT> &cloud_out)
250  {
251  cloud_out = cloud1;
252  return concatenate(cloud_out, cloud2);
253  }
254 
255  /** \brief Obtain the point given by the (column, row) coordinates. Only works on organized
256  * datasets (those that have height != 1).
257  * \param[in] column the column coordinate
258  * \param[in] row the row coordinate
259  */
260  inline const PointT&
261  at (int column, int row) const
262  {
263  if (this->height > 1)
264  return (points.at (row * this->width + column));
265  else
266  throw UnorganizedPointCloudException ("Can't use 2D indexing with an unorganized point cloud");
267  }
268 
269  /** \brief Obtain the point given by the (column, row) coordinates. Only works on organized
270  * datasets (those that have height != 1).
271  * \param[in] column the column coordinate
272  * \param[in] row the row coordinate
273  */
274  inline PointT&
275  at (int column, int row)
276  {
277  if (this->height > 1)
278  return (points.at (row * this->width + column));
279  else
280  throw UnorganizedPointCloudException ("Can't use 2D indexing with an unorganized point cloud");
281  }
282 
283  /** \brief Obtain the point given by the (column, row) coordinates. Only works on organized
284  * datasets (those that have height != 1).
285  * \param[in] column the column coordinate
286  * \param[in] row the row coordinate
287  */
288  inline const PointT&
289  operator () (std::size_t column, std::size_t row) const
290  {
291  return (points[row * this->width + column]);
292  }
293 
294  /** \brief Obtain the point given by the (column, row) coordinates. Only works on organized
295  * datasets (those that have height != 1).
296  * \param[in] column the column coordinate
297  * \param[in] row the row coordinate
298  */
299  inline PointT&
300  operator () (std::size_t column, std::size_t row)
301  {
302  return (points[row * this->width + column]);
303  }
304 
305  /** \brief Return whether a dataset is organized (e.g., arranged in a structured grid).
306  * \note The height value must be different than 1 for a dataset to be organized.
307  */
308  inline bool
309  isOrganized () const
310  {
311  return (height > 1);
312  }
313 
314  /** \brief Return an Eigen MatrixXf (assumes float values) mapped to the specified dimensions of the PointCloud.
315  * \note This method is for advanced users only! Use with care!
316  *
317  * \attention Since 1.4.0, Eigen matrices are forced to Row Major to increase the efficiency of the algorithms in PCL
318  * This means that the behavior of getMatrixXfMap changed, and is now correctly mapping 1-1 with a PointCloud structure,
319  * that is: number of points in a cloud = rows in a matrix, number of point dimensions = columns in a matrix
320  *
321  * \param[in] dim the number of dimensions to consider for each point
322  * \param[in] stride the number of values in each point (will be the number of values that separate two of the columns)
323  * \param[in] offset the number of dimensions to skip from the beginning of each point
324  * (stride = offset + dim + x, where x is the number of dimensions to skip from the end of each point)
325  * \note for getting only XYZ coordinates out of PointXYZ use dim=3, stride=4 and offset=0 due to the alignment.
326  * \attention PointT types are most of the time aligned, so the offsets are not continuous!
327  */
328  inline Eigen::Map<Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >
329  getMatrixXfMap (int dim, int stride, int offset)
330  {
331  if (Eigen::MatrixXf::Flags & Eigen::RowMajorBit)
332  return (Eigen::Map<Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >(reinterpret_cast<float*>(&points[0])+offset, size (), dim, Eigen::OuterStride<> (stride)));
333  else
334  return (Eigen::Map<Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >(reinterpret_cast<float*>(&points[0])+offset, dim, size (), Eigen::OuterStride<> (stride)));
335  }
336 
337  /** \brief Return an Eigen MatrixXf (assumes float values) mapped to the specified dimensions of the PointCloud.
338  * \note This method is for advanced users only! Use with care!
339  *
340  * \attention Since 1.4.0, Eigen matrices are forced to Row Major to increase the efficiency of the algorithms in PCL
341  * This means that the behavior of getMatrixXfMap changed, and is now correctly mapping 1-1 with a PointCloud structure,
342  * that is: number of points in a cloud = rows in a matrix, number of point dimensions = columns in a matrix
343  *
344  * \param[in] dim the number of dimensions to consider for each point
345  * \param[in] stride the number of values in each point (will be the number of values that separate two of the columns)
346  * \param[in] offset the number of dimensions to skip from the beginning of each point
347  * (stride = offset + dim + x, where x is the number of dimensions to skip from the end of each point)
348  * \note for getting only XYZ coordinates out of PointXYZ use dim=3, stride=4 and offset=0 due to the alignment.
349  * \attention PointT types are most of the time aligned, so the offsets are not continuous!
350  */
351  inline const Eigen::Map<const Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >
352  getMatrixXfMap (int dim, int stride, int offset) const
353  {
354  if (Eigen::MatrixXf::Flags & Eigen::RowMajorBit)
355  return (Eigen::Map<const Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >(reinterpret_cast<float*>(const_cast<PointT*>(&points[0]))+offset, size (), dim, Eigen::OuterStride<> (stride)));
356  else
357  return (Eigen::Map<const Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >(reinterpret_cast<float*>(const_cast<PointT*>(&points[0]))+offset, dim, size (), Eigen::OuterStride<> (stride)));
358  }
359 
360  /**
361  * \brief Return an Eigen MatrixXf (assumes float values) mapped to the PointCloud.
362  * \note This method is for advanced users only! Use with care!
363  * \attention PointT types are most of the time aligned, so the offsets are not continuous!
364  * \overload Eigen::Map<Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> > pcl::PointCloud::getMatrixXfMap ()
365  */
366  inline Eigen::Map<Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >
368  {
369  return (getMatrixXfMap (sizeof (PointT) / sizeof (float), sizeof (PointT) / sizeof (float), 0));
370  }
371 
372  /**
373  * \brief Return an Eigen MatrixXf (assumes float values) mapped to the PointCloud.
374  * \note This method is for advanced users only! Use with care!
375  * \attention PointT types are most of the time aligned, so the offsets are not continuous!
376  * \overload const Eigen::Map<Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> > pcl::PointCloud::getMatrixXfMap () const
377  */
378  inline const Eigen::Map<const Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >
379  getMatrixXfMap () const
380  {
381  return (getMatrixXfMap (sizeof (PointT) / sizeof (float), sizeof (PointT) / sizeof (float), 0));
382  }
383 
384  /** \brief The point cloud header. It contains information about the acquisition time. */
386 
387  /** \brief The point data. */
388  std::vector<PointT, Eigen::aligned_allocator<PointT> > points;
389 
390  /** \brief The point cloud width (if organized as an image-structure). */
391  std::uint32_t width = 0;
392  /** \brief The point cloud height (if organized as an image-structure). */
393  std::uint32_t height = 0;
394 
395  /** \brief True if no points are invalid (e.g., have NaN or Inf values in any of their floating point fields). */
396  bool is_dense = true;
397 
398  /** \brief Sensor acquisition pose (origin/translation). */
399  Eigen::Vector4f sensor_origin_ = Eigen::Vector4f::Zero ();
400  /** \brief Sensor acquisition pose (rotation). */
401  Eigen::Quaternionf sensor_orientation_ = Eigen::Quaternionf::Identity ();
402 
403  using PointType = PointT; // Make the template class available from the outside
404  using VectorType = std::vector<PointT, Eigen::aligned_allocator<PointT> >;
405  using CloudVectorType = std::vector<PointCloud<PointT>, Eigen::aligned_allocator<PointCloud<PointT> > >;
406  using Ptr = shared_ptr<PointCloud<PointT> >;
407  using ConstPtr = shared_ptr<const PointCloud<PointT> >;
408 
409  // std container compatibility typedefs according to
410  // http://en.cppreference.com/w/cpp/concept/Container
412  using reference = PointT&;
413  using const_reference = const PointT&;
414  using difference_type = typename VectorType::difference_type;
415  using size_type = typename VectorType::size_type;
416 
417  // iterators
418  using iterator = typename VectorType::iterator;
419  using const_iterator = typename VectorType::const_iterator;
420  using reverse_iterator = typename VectorType::reverse_iterator;
421  using const_reverse_iterator = typename VectorType::const_reverse_iterator;
422  inline iterator begin () noexcept { return (points.begin ()); }
423  inline iterator end () noexcept { return (points.end ()); }
424  inline const_iterator begin () const noexcept { return (points.begin ()); }
425  inline const_iterator end () const noexcept { return (points.end ()); }
426  inline const_iterator cbegin () const noexcept { return (points.cbegin ()); }
427  inline const_iterator cend () const noexcept { return (points.cend ()); }
428  inline reverse_iterator rbegin () noexcept { return (points.rbegin ()); }
429  inline reverse_iterator rend () noexcept { return (points.rend ()); }
430  inline const_reverse_iterator rbegin () const noexcept { return (points.rbegin ()); }
431  inline const_reverse_iterator rend () const noexcept { return (points.rend ()); }
432  inline const_reverse_iterator crbegin () const noexcept { return (points.crbegin ()); }
433  inline const_reverse_iterator crend () const noexcept { return (points.crend ()); }
434 
435  //capacity
436  inline std::size_t size () const { return points.size (); }
437  index_t max_size() const noexcept { return static_cast<index_t>(points.max_size()); }
438  inline void reserve (std::size_t n) { points.reserve (n); }
439  inline bool empty () const { return points.empty (); }
440  PointT* data() noexcept { return points.data(); }
441  const PointT* data() const noexcept { return points.data(); }
442 
443  /**
444  * \brief Resizes the container to contain `count` elements
445  * \details
446  * * If the current size is greater than `count`, the pointcloud is reduced to its
447  * first `count` elements
448  * * If the current size is less than `count`, additional default-inserted points
449  * are appended
450  * \note This potentially breaks the organized structure of the cloud by setting
451  * the height to 1 IFF `width * height != count`!
452  * \param[in] count new size of the point cloud
453  */
454  inline void
455  resize(std::size_t count)
456  {
457  points.resize(count);
458  if (width * height != count) {
459  width = static_cast<std::uint32_t>(count);
460  height = 1;
461  }
462  }
463 
464  /**
465  * \brief Resizes the container to contain count elements
466  * \details
467  * * If the current size is greater than `count`, the pointcloud is reduced to its
468  * first `count` elements
469  * * If the current size is less than `count`, additional copies of `value` are
470  * appended
471  * \note This potentially breaks the organized structure of the cloud by setting
472  * the height to 1 IFF `width * height != count`!
473  * \param[in] count new size of the point cloud
474  * \param[in] value the value to initialize the new points with
475  */
476  void
477  resize(index_t count, const PointT& value)
478  {
479  points.resize(count, value);
480  if (width * height != count) {
481  width = count;
482  height = 1;
483  }
484  }
485 
486  //element access
487  inline const PointT& operator[] (std::size_t n) const { return (points[n]); }
488  inline PointT& operator[] (std::size_t n) { return (points[n]); }
489  inline const PointT& at (std::size_t n) const { return (points.at (n)); }
490  inline PointT& at (std::size_t n) { return (points.at (n)); }
491  inline const PointT& front () const { return (points.front ()); }
492  inline PointT& front () { return (points.front ()); }
493  inline const PointT& back () const { return (points.back ()); }
494  inline PointT& back () { return (points.back ()); }
495 
496  /**
497  * \brief Replaces the points with `count` copies of `value`
498  * \note This breaks the organized structure of the cloud by setting the height to
499  * 1!
500  */
501  void
502  assign(index_t count, const PointT& value)
503  {
504  points.assign(count, value);
505  width = static_cast<std::uint32_t>(size());
506  height = 1;
507  }
508 
509  /**
510  * \brief Replaces the points with copies of those in the range `[first, last)`
511  * \details The behavior is undefined if either argument is an iterator into
512  * `*this`
513  * \note This breaks the organized structure of the cloud by setting the height to
514  * 1!
515  */
516  template <class InputIt>
517  void
518  assign(InputIt first, InputIt last)
519  {
520  points.assign(std::move(first), std::move(last));
521  width = static_cast<std::uint32_t>(size());
522  height = 1;
523  }
524 
525  /**
526  * \brief Replaces the points with the elements from the initializer list `ilist`
527  * \note This breaks the organized structure of the cloud by setting the height to
528  * 1!
529  */
530  void
531  assign(std::initializer_list<PointT> ilist)
532  {
533  points.assign(std::move(ilist));
534  width = static_cast<std::uint32_t>(size());
535  height = 1;
536  }
537 
538  /** \brief Insert a new point in the cloud, at the end of the container.
539  * \note This breaks the organized structure of the cloud by setting the height to 1!
540  * \param[in] pt the point to insert
541  */
542  inline void
543  push_back (const PointT& pt)
544  {
545  points.push_back (pt);
546  width = size ();
547  height = 1;
548  }
549 
550  /** \brief Emplace a new point in the cloud, at the end of the container.
551  * \note This breaks the organized structure of the cloud by setting the height to 1!
552  * \param[in] args the parameters to forward to the point to construct
553  * \return reference to the emplaced point
554  */
555  template <class... Args> inline reference
556  emplace_back (Args&& ...args)
557  {
558  points.emplace_back (std::forward<Args> (args)...);
559  width = size ();
560  height = 1;
561  return points.back();
562  }
563 
564  /** \brief Insert a new point in the cloud, given an iterator.
565  * \note This breaks the organized structure of the cloud by setting the height to 1!
566  * \param[in] position where to insert the point
567  * \param[in] pt the point to insert
568  * \return returns the new position iterator
569  */
570  inline iterator
571  insert (iterator position, const PointT& pt)
572  {
573  iterator it = points.insert (position, pt);
574  width = size ();
575  height = 1;
576  return (it);
577  }
578 
579  /** \brief Insert a new point in the cloud N times, given an iterator.
580  * \note This breaks the organized structure of the cloud by setting the height to 1!
581  * \param[in] position where to insert the point
582  * \param[in] n the number of times to insert the point
583  * \param[in] pt the point to insert
584  */
585  inline void
586  insert (iterator position, std::size_t n, const PointT& pt)
587  {
588  points.insert (position, n, pt);
589  width = size ();
590  height = 1;
591  }
592 
593  /** \brief Insert a new range of points in the cloud, at a certain position.
594  * \note This breaks the organized structure of the cloud by setting the height to 1!
595  * \param[in] position where to insert the data
596  * \param[in] first where to start inserting the points from
597  * \param[in] last where to stop inserting the points from
598  */
599  template <class InputIterator> inline void
600  insert (iterator position, InputIterator first, InputIterator last)
601  {
602  points.insert (position, first, last);
603  width = size ();
604  height = 1;
605  }
606 
607  /** \brief Emplace a new point in the cloud, given an iterator.
608  * \note This breaks the organized structure of the cloud by setting the height to 1!
609  * \param[in] position iterator before which the point will be emplaced
610  * \param[in] args the parameters to forward to the point to construct
611  * \return returns the new position iterator
612  */
613  template <class... Args> inline iterator
614  emplace (iterator position, Args&& ...args)
615  {
616  iterator it = points.emplace (position, std::forward<Args> (args)...);
617  width = size ();
618  height = 1;
619  return (it);
620  }
621 
622  /** \brief Erase a point in the cloud.
623  * \note This breaks the organized structure of the cloud by setting the height to 1!
624  * \param[in] position what data point to erase
625  * \return returns the new position iterator
626  */
627  inline iterator
628  erase (iterator position)
629  {
630  iterator it = points.erase (position);
631  width = size ();
632  height = 1;
633  return (it);
634  }
635 
636  /** \brief Erase a set of points given by a (first, last) iterator pair
637  * \note This breaks the organized structure of the cloud by setting the height to 1!
638  * \param[in] first where to start erasing points from
639  * \param[in] last where to stop erasing points from
640  * \return returns the new position iterator
641  */
642  inline iterator
643  erase (iterator first, iterator last)
644  {
645  iterator it = points.erase (first, last);
646  width = size ();
647  height = 1;
648  return (it);
649  }
650 
651  /** \brief Swap a point cloud with another cloud.
652  * \param[in,out] rhs point cloud to swap this with
653  */
654  inline void
656  {
657  std::swap (header, rhs.header);
658  this->points.swap (rhs.points);
659  std::swap (width, rhs.width);
660  std::swap (height, rhs.height);
661  std::swap (is_dense, rhs.is_dense);
662  std::swap (sensor_origin_, rhs.sensor_origin_);
663  std::swap (sensor_orientation_, rhs.sensor_orientation_);
664  }
665 
666  /** \brief Removes all points in a cloud and sets the width and height to 0. */
667  inline void
668  clear ()
669  {
670  points.clear ();
671  width = 0;
672  height = 0;
673  }
674 
675  /** \brief Copy the cloud to the heap and return a smart pointer
676  * Note that deep copy is performed, so avoid using this function on non-empty clouds.
677  * The changes of the returned cloud are not mirrored back to this one.
678  * \return shared pointer to the copy of the cloud
679  */
680  inline Ptr
681  makeShared () const { return Ptr (new PointCloud<PointT> (*this)); }
682 
684  };
685 
686 
687  template <typename PointT> std::ostream&
688  operator << (std::ostream& s, const pcl::PointCloud<PointT> &p)
689  {
690  s << "header: " << p.header << std::endl;
691  s << "points[]: " << p.size () << std::endl;
692  s << "width: " << p.width << std::endl;
693  s << "height: " << p.height << std::endl;
694  s << "is_dense: " << p.is_dense << std::endl;
695  s << "sensor origin (xyz): [" <<
696  p.sensor_origin_.x () << ", " <<
697  p.sensor_origin_.y () << ", " <<
698  p.sensor_origin_.z () << "] / orientation (xyzw): [" <<
699  p.sensor_orientation_.x () << ", " <<
700  p.sensor_orientation_.y () << ", " <<
701  p.sensor_orientation_.z () << ", " <<
702  p.sensor_orientation_.w () << "]" <<
703  std::endl;
704  return (s);
705  }
706 }
707 
708 #define PCL_INSTANTIATE_PointCloud(T) template class PCL_EXPORTS pcl::PointCloud<T>;
pcl::PCLHeader::stamp
std::uint64_t stamp
A timestamp associated with the time when the data was acquired.
Definition: PCLHeader.h:18
pcl::PointCloud::swap
void swap(PointCloud< PointT > &rhs)
Swap a point cloud with another cloud.
Definition: point_cloud.h:655
pcl::PointCloud< pcl::RGB >::const_reverse_iterator
typename VectorType::const_reverse_iterator const_reverse_iterator
Definition: point_cloud.h:421
pcl_macros.h
Defines all the PCL and non-PCL macros used.
pcl
Definition: convolution.h:46
pcl::PointCloud::makeShared
Ptr makeShared() const
Copy the cloud to the heap and return a smart pointer Note that deep copy is performed,...
Definition: point_cloud.h:681
pcl::NdCopyEigenPointFunctor
Helper functor structure for copying data between an Eigen type and a PointT.
Definition: point_cloud.h:75
pcl::PointCloud::assign
void assign(std::initializer_list< PointT > ilist)
Replaces the points with the elements from the initializer list ilist
Definition: point_cloud.h:531
pcl::PointCloud::height
std::uint32_t height
The point cloud height (if organized as an image-structure).
Definition: point_cloud.h:393
pcl::PointCloud::resize
void resize(index_t count, const PointT &value)
Resizes the container to contain count elements.
Definition: point_cloud.h:477
pcl::PointCloud::erase
iterator erase(iterator first, iterator last)
Erase a set of points given by a (first, last) iterator pair.
Definition: point_cloud.h:643
pcl::PointCloud::cbegin
const_iterator cbegin() const noexcept
Definition: point_cloud.h:426
pcl::PointCloud::points
std::vector< PointT, Eigen::aligned_allocator< PointT > > points
The point data.
Definition: point_cloud.h:388
pcl::PointCloud::rbegin
reverse_iterator rbegin() noexcept
Definition: point_cloud.h:428
types.h
Defines basic non-point types used by PCL.
pcl::NdCopyEigenPointFunctor::Pod
typename traits::POD< PointOutT >::type Pod
Definition: point_cloud.h:77
pcl::NdCopyEigenPointFunctor::operator()
void operator()()
Operator.
Definition: point_cloud.h:90
pcl::PointCloud::begin
iterator begin() noexcept
Definition: point_cloud.h:422
pcl::PointCloud::at
const PointT & at(std::size_t n) const
Definition: point_cloud.h:489
pcl::PointCloud::empty
bool empty() const
Definition: point_cloud.h:439
pcl::PointCloud::cend
const_iterator cend() const noexcept
Definition: point_cloud.h:427
pcl::NdCopyPointEigenFunctor::Pod
typename traits::POD< PointInT >::type Pod
Definition: point_cloud.h:110
pcl::PointCloud::erase
iterator erase(iterator position)
Erase a point in the cloud.
Definition: point_cloud.h:628
pcl::PointCloud::emplace
iterator emplace(iterator position, Args &&...args)
Emplace a new point in the cloud, given an iterator.
Definition: point_cloud.h:614
pcl::PointCloud
PointCloud represents the base class in PCL for storing collections of 3D points.
Definition: distances.h:55
pcl::PointCloud::at
PointT & at(int column, int row)
Obtain the point given by the (column, row) coordinates.
Definition: point_cloud.h:275
pcl::index_t
detail::int_type_t< detail::index_type_size, detail::index_type_signed > index_t
Type used for an index in PCL.
Definition: types.h:110
pcl::PointCloud< pcl::RGB >::VectorType
std::vector< pcl::RGB, Eigen::aligned_allocator< pcl::RGB > > VectorType
Definition: point_cloud.h:404
pcl::PointXYZRGB
A point structure representing Euclidean xyz coordinates, and the RGB color.
Definition: point_types.hpp:628
pcl::NdCopyPointEigenFunctor::operator()
void operator()()
Operator.
Definition: point_cloud.h:121
pcl::PointCloud::at
const PointT & at(int column, int row) const
Obtain the point given by the (column, row) coordinates.
Definition: point_cloud.h:261
pcl::PointCloud::front
PointT & front()
Definition: point_cloud.h:492
pcl::detail::FieldMapping
Definition: point_cloud.h:61
pcl::PointCloud::isOrganized
bool isOrganized() const
Return whether a dataset is organized (e.g., arranged in a structured grid).
Definition: point_cloud.h:309
pcl::PointCloud< pcl::RGB >::CloudVectorType
std::vector< PointCloud< pcl::RGB >, Eigen::aligned_allocator< PointCloud< pcl::RGB > > > CloudVectorType
Definition: point_cloud.h:405
pcl::PointCloud::data
const PointT * data() const noexcept
Definition: point_cloud.h:441
pcl::operator<<
std::ostream & operator<<(std::ostream &os, const BivariatePolynomialT< real > &p)
Definition: bivariate_polynomial.hpp:240
pcl::detail::FieldMapping::size
std::size_t size
Definition: point_cloud.h:65
pcl::PointCloud::width
std::uint32_t width
The point cloud width (if organized as an image-structure).
Definition: point_cloud.h:391
pcl::PointCloud< pcl::RGB >::difference_type
typename VectorType::difference_type difference_type
Definition: point_cloud.h:414
pcl::PointCloud::getMatrixXfMap
Eigen::Map< Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> > getMatrixXfMap(int dim, int stride, int offset)
Return an Eigen MatrixXf (assumes float values) mapped to the specified dimensions of the PointCloud.
Definition: point_cloud.h:329
pcl::PointCloud::rend
const_reverse_iterator rend() const noexcept
Definition: point_cloud.h:431
pcl::PointCloud::getMatrixXfMap
const Eigen::Map< const Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> > getMatrixXfMap() const
Definition: point_cloud.h:379
pcl::PointCloud< pcl::RGB >::size_type
typename VectorType::size_type size_type
Definition: point_cloud.h:415
pcl::PointCloud::end
const_iterator end() const noexcept
Definition: point_cloud.h:425
pcl::PointCloud::back
const PointT & back() const
Definition: point_cloud.h:493
pcl::PointCloud::getMatrixXfMap
Eigen::Map< Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> > getMatrixXfMap()
Definition: point_cloud.h:367
pcl::PointCloud::rend
reverse_iterator rend() noexcept
Definition: point_cloud.h:429
pcl::PointCloud::end
iterator end() noexcept
Definition: point_cloud.h:423
pcl::PointCloud::getMatrixXfMap
const Eigen::Map< const Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> > getMatrixXfMap(int dim, int stride, int offset) const
Return an Eigen MatrixXf (assumes float values) mapped to the specified dimensions of the PointCloud.
Definition: point_cloud.h:352
pcl::PointCloud::crend
const_reverse_iterator crend() const noexcept
Definition: point_cloud.h:433
PCL_MAKE_ALIGNED_OPERATOR_NEW
#define PCL_MAKE_ALIGNED_OPERATOR_NEW
Macro to signal a class requires a custom allocator.
Definition: memory.h:63
pcl::RGB
A structure representing RGB color information.
Definition: point_types.hpp:345
pcl::PointCloud::reserve
void reserve(std::size_t n)
Definition: point_cloud.h:438
pcl::PointCloud::sensor_origin_
Eigen::Vector4f sensor_origin_
Sensor acquisition pose (origin/translation).
Definition: point_cloud.h:399
pcl::PointCloud::sensor_orientation_
Eigen::Quaternionf sensor_orientation_
Sensor acquisition pose (rotation).
Definition: point_cloud.h:401
pcl::NdCopyEigenPointFunctor::NdCopyEigenPointFunctor
NdCopyEigenPointFunctor(const Eigen::VectorXf &p1, PointOutT &p2)
Constructor.
Definition: point_cloud.h:83
pcl::PointCloud::is_dense
bool is_dense
True if no points are invalid (e.g., have NaN or Inf values in any of their floating point fields).
Definition: point_cloud.h:396
pcl::PointCloud::resize
void resize(std::size_t count)
Resizes the container to contain count elements.
Definition: point_cloud.h:455
pcl::PointCloud< pcl::RGB >::reverse_iterator
typename VectorType::reverse_iterator reverse_iterator
Definition: point_cloud.h:420
pcl::PointCloud::header
pcl::PCLHeader header
The point cloud header.
Definition: point_cloud.h:385
pcl::NdCopyPointEigenFunctor
Helper functor structure for copying data between an Eigen type and a PointT.
Definition: point_cloud.h:108
pcl::Indices
IndicesAllocator<> Indices
Type used for indices in PCL.
Definition: types.h:131
pcl::UnorganizedPointCloudException
An exception that is thrown when an organized point cloud is needed but not provided.
Definition: exceptions.h:207
pcl::PointCloud::concatenate
static bool concatenate(pcl::PointCloud< PointT > &cloud1, const pcl::PointCloud< PointT > &cloud2)
Definition: point_cloud.h:230
pcl::PointCloud::size
std::size_t size() const
Definition: point_cloud.h:436
pcl::PointCloud::begin
const_iterator begin() const noexcept
Definition: point_cloud.h:424
pcl::PointCloud::insert
iterator insert(iterator position, const PointT &pt)
Insert a new point in the cloud, given an iterator.
Definition: point_cloud.h:571
pcl::PointCloud< pcl::RGB >::Ptr
shared_ptr< PointCloud< pcl::RGB > > Ptr
Definition: point_cloud.h:406
pcl::concatenate
PCL_EXPORTS bool concatenate(const pcl::PointCloud< PointT > &cloud1, const pcl::PointCloud< PointT > &cloud2, pcl::PointCloud< PointT > &cloud_out)
Concatenate two pcl::PointCloud<PointT>
Definition: io.h:249
pcl::PointCloud::emplace_back
reference emplace_back(Args &&...args)
Emplace a new point in the cloud, at the end of the container.
Definition: point_cloud.h:556
pcl::PointCloud::insert
void insert(iterator position, std::size_t n, const PointT &pt)
Insert a new point in the cloud N times, given an iterator.
Definition: point_cloud.h:586
pcl::PointCloud::assign
void assign(index_t count, const PointT &value)
Replaces the points with count copies of value
Definition: point_cloud.h:502
pcl::PointCloud::rbegin
const_reverse_iterator rbegin() const noexcept
Definition: point_cloud.h:430
pcl::PointCloud::front
const PointT & front() const
Definition: point_cloud.h:491
pcl::PointCloud::insert
void insert(iterator position, InputIterator first, InputIterator last)
Insert a new range of points in the cloud, at a certain position.
Definition: point_cloud.h:600
pcl::PointCloud< pcl::RGB >::const_iterator
typename VectorType::const_iterator const_iterator
Definition: point_cloud.h:419
pcl::PointCloud::assign
void assign(InputIt first, InputIt last)
Replaces the points with copies of those in the range [first, last)
Definition: point_cloud.h:518
pcl::PointCloud::clear
void clear()
Removes all points in a cloud and sets the width and height to 0.
Definition: point_cloud.h:668
pcl::PointCloud::back
PointT & back()
Definition: point_cloud.h:494
pcl::PointCloud::PointCloud
PointCloud(const PointCloud< PointT > &pc, const Indices &indices)
Copy constructor from point cloud subset.
Definition: point_cloud.h:184
pcl::PointCloud::data
PointT * data() noexcept
Definition: point_cloud.h:440
pcl::PointCloud< pcl::RGB >::ConstPtr
shared_ptr< const PointCloud< pcl::RGB > > ConstPtr
Definition: point_cloud.h:407
pcl::PointCloud::PointCloud
PointCloud(std::uint32_t width_, std::uint32_t height_, const PointT &value_=PointT())
Allocate constructor from point cloud subset.
Definition: point_cloud.h:200
pcl::PointCloud::concatenate
static bool concatenate(const pcl::PointCloud< PointT > &cloud1, const pcl::PointCloud< PointT > &cloud2, pcl::PointCloud< PointT > &cloud_out)
Definition: point_cloud.h:247
pcl::PointCloud::max_size
index_t max_size() const noexcept
Definition: point_cloud.h:437
pcl::detail::FieldMapping::serialized_offset
std::size_t serialized_offset
Definition: point_cloud.h:63
pcl::MsgFieldMap
std::vector< detail::FieldMapping > MsgFieldMap
Definition: point_cloud.h:71
pcl::PointCloud< pcl::RGB >::iterator
typename VectorType::iterator iterator
Definition: point_cloud.h:418
pcl::PointCloud::push_back
void push_back(const PointT &pt)
Insert a new point in the cloud, at the end of the container.
Definition: point_cloud.h:543
pcl::NdCopyPointEigenFunctor::NdCopyPointEigenFunctor
NdCopyPointEigenFunctor(const PointInT &p1, Eigen::VectorXf &p2)
Constructor.
Definition: point_cloud.h:116
pcl::PointCloud::crbegin
const_reverse_iterator crbegin() const noexcept
Definition: point_cloud.h:432
memory.h
Defines functions, macros and traits for allocating and using memory.
pcl::PCLHeader
Definition: PCLHeader.h:10
PCL_EXPORTS
#define PCL_EXPORTS
Definition: pcl_macros.h:323
pcl::detail::FieldMapping::struct_offset
std::size_t struct_offset
Definition: point_cloud.h:64
pcl::PointCloud::at
PointT & at(std::size_t n)
Definition: point_cloud.h:490