Point Cloud Library (PCL)  1.12.1-dev
io.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2011, 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  * $Id$
38  *
39  */
40 
41 #pragma once
42 
43 #include <numeric>
44 #include <string>
45 
46 #include <pcl/point_cloud.h>
47 #include <pcl/PointIndices.h>
48 #include <pcl/pcl_macros.h>
49 #include <pcl/PolygonMesh.h>
50 #include <locale>
51 
52 namespace pcl
53 {
54  /** \brief Get the index of a specified field (i.e., dimension/channel)
55  * \param[in] cloud the point cloud message
56  * \param[in] field_name the string defining the field name
57  * \ingroup common
58  */
59  inline int
60  getFieldIndex (const pcl::PCLPointCloud2 &cloud, const std::string &field_name)
61  {
62  // Get the index we need
63  const auto result = std::find_if(cloud.fields.begin (), cloud.fields.end (),
64  [&field_name](const auto field) { return field.name == field_name; });
65  if (result == cloud.fields.end ())
66  return -1;
67  return std::distance(cloud.fields.begin (), result);
68  }
69 
70  /** \brief Get the index of a specified field (i.e., dimension/channel)
71  * \tparam PointT datatype for which fields is being queries
72  * \param[in] field_name the string defining the field name
73  * \param[out] fields a vector to the original \a PCLPointField vector that the raw PointCloud message contains
74  * \ingroup common
75  */
76  template <typename PointT> inline int
77  getFieldIndex (const std::string &field_name,
78  std::vector<pcl::PCLPointField> &fields);
79  /** \brief Get the index of a specified field (i.e., dimension/channel)
80  * \tparam PointT datatype for which fields is being queries
81  * \param[in] field_name the string defining the field name
82  * \param[in] fields a vector to the original \a PCLPointField vector that the raw PointCloud message contains
83  * \ingroup common
84  */
85  template <typename PointT> inline int
86  getFieldIndex (const std::string &field_name,
87  const std::vector<pcl::PCLPointField> &fields);
88 
89  /** \brief Get the list of available fields (i.e., dimension/channel)
90  * \tparam PointT datatype whose details are requested
91  * \ingroup common
92  */
93  template <typename PointT> inline std::vector<pcl::PCLPointField>
94  getFields ();
95 
96  /** \brief Get the list of all fields available in a given cloud
97  * \param[in] cloud the point cloud message
98  * \ingroup common
99  */
100  template <typename PointT> inline std::string
101  getFieldsList (const pcl::PointCloud<PointT> &cloud);
102 
103  /** \brief Get the available point cloud fields as a space separated string
104  * \param[in] cloud a pointer to the PointCloud message
105  * \ingroup common
106  */
107  inline std::string
109  {
110  return std::accumulate(std::next (cloud.fields.begin ()), cloud.fields.end (), cloud.fields[0].name,
111  [](const auto& acc, const auto& field) { return acc + " " + field.name; });
112  }
113 
114  /** \brief Obtains the size of a specific field data type in bytes
115  * \param[in] datatype the field data type (see PCLPointField.h)
116  * \ingroup common
117  */
118  inline int
119  getFieldSize (const int datatype)
120  {
121  switch (datatype)
122  {
124  return sizeof(bool);
125 
128  return (1);
129 
132  return (2);
133 
137  return (4);
138 
142  return (8);
143 
144  default:
145  return (0);
146  }
147  }
148 
149  /** \brief Obtain a vector with the sizes of all valid fields (e.g., not "_")
150  * \param[in] fields the input vector containing the fields
151  * \param[out] field_sizes the resultant field sizes in bytes
152  */
153  PCL_EXPORTS void
154  getFieldsSizes (const std::vector<pcl::PCLPointField> &fields,
155  std::vector<int> &field_sizes);
156 
157  /** \brief Obtains the type of the PCLPointField from a specific size and type
158  * \param[in] size the size in bytes of the data field
159  * \param[in] type a char describing the type of the field ('B' = bool, 'F' = float, 'I' = signed, 'U' = unsigned)
160  * \ingroup common
161  */
162  inline int
163  getFieldType (const int size, char type)
164  {
165  type = std::toupper (type, std::locale::classic ());
166 
167  // extra logic for bool because its size is undefined
168  if (type == 'B') {
169  if (size == sizeof(bool)) {
171  } else {
172  return -1;
173  }
174  }
175 
176  switch (size)
177  {
178  case 1:
179  if (type == 'I')
180  return (pcl::PCLPointField::INT8);
181  if (type == 'U')
182  return (pcl::PCLPointField::UINT8);
183  break;
184 
185  case 2:
186  if (type == 'I')
187  return (pcl::PCLPointField::INT16);
188  if (type == 'U')
190  break;
191 
192  case 4:
193  if (type == 'I')
194  return (pcl::PCLPointField::INT32);
195  if (type == 'U')
197  if (type == 'F')
199  break;
200 
201  case 8:
202  if (type == 'I')
203  return (pcl::PCLPointField::INT64);
204  if (type == 'U')
206  if (type == 'F')
208  break;
209  }
210  return (-1);
211  }
212 
213  /** \brief Obtains the type of the PCLPointField from a specific PCLPointField as a char
214  * \param[in] type the PCLPointField field type
215  * \ingroup common
216  */
217  inline char
218  getFieldType (const int type)
219  {
220  switch (type)
221  {
223  return ('B');
224 
229  return ('I');
230 
235  return ('U');
236 
239  return ('F');
240 
241  default:
242  return ('?');
243  }
244  }
245 
247  {
252  };
253 
254  /** \brief \return the right index according to the interpolation type.
255  * \note this is adapted from OpenCV
256  * \param p the index of point to interpolate
257  * \param length the top/bottom row or left/right column index
258  * \param type the requested interpolation
259  * \throws pcl::BadArgumentException if type is unknown
260  */
261  PCL_EXPORTS int
262  interpolatePointIndex (int p, int length, InterpolationType type);
263 
264  /** \brief Concatenate two pcl::PointCloud<PointT>
265  * \param[in] cloud1 the first input point cloud dataset
266  * \param[in] cloud2 the second input point cloud dataset
267  * \param[out] cloud_out the resultant output point cloud dataset
268  * \return true if successful, false otherwise
269  * \ingroup common
270  */
271  template <typename PointT>
272  PCL_EXPORTS bool
274  const pcl::PointCloud<PointT> &cloud2,
275  pcl::PointCloud<PointT> &cloud_out)
276  {
277  return pcl::PointCloud<PointT>::concatenate(cloud1, cloud2, cloud_out);
278  }
279 
280  /** \brief Concatenate two pcl::PCLPointCloud2
281  *
282  * \warning This function will concatenate IFF the non-skip fields are in the correct
283  * order and same in number.
284  * \param[in] cloud1 the first input point cloud dataset
285  * \param[in] cloud2 the second input point cloud dataset
286  * \param[out] cloud_out the resultant output point cloud dataset
287  * \return true if successful, false otherwise
288  * \ingroup common
289  */
290  PCL_EXPORTS inline bool
292  const pcl::PCLPointCloud2 &cloud2,
293  pcl::PCLPointCloud2 &cloud_out)
294  {
295  return pcl::PCLPointCloud2::concatenate(cloud1, cloud2, cloud_out);
296  }
297 
298  /** \brief Concatenate two pcl::PolygonMesh
299  * \param[in] mesh1 the first input mesh
300  * \param[in] mesh2 the second input mesh
301  * \param[out] mesh_out the resultant output mesh
302  * \return true if successful, false otherwise
303  * \ingroup common
304  */
305  PCL_EXPORTS inline bool
307  const pcl::PolygonMesh &mesh2,
308  pcl::PolygonMesh &mesh_out)
309  {
310  return pcl::PolygonMesh::concatenate(mesh1, mesh2, mesh_out);
311  }
312 
313  /** \brief Extract the indices of a given point cloud as a new point cloud
314  * \param[in] cloud_in the input point cloud dataset
315  * \param[in] indices the vector of indices representing the points to be copied from \a cloud_in
316  * \param[out] cloud_out the resultant output point cloud dataset
317  * \note Assumes unique indices.
318  * \ingroup common
319  */
320  PCL_EXPORTS void
322  const Indices &indices,
323  pcl::PCLPointCloud2 &cloud_out);
324 
325  /** \brief Extract the indices of a given point cloud as a new point cloud
326  * \param[in] cloud_in the input point cloud dataset
327  * \param[in] indices the vector of indices representing the points to be copied from \a cloud_in
328  * \param[out] cloud_out the resultant output point cloud dataset
329  * \note Assumes unique indices.
330  * \ingroup common
331  */
332  PCL_EXPORTS void
334  const IndicesAllocator< Eigen::aligned_allocator<index_t> > &indices,
335  pcl::PCLPointCloud2 &cloud_out);
336 
337  /** \brief Copy fields and point cloud data from \a cloud_in to \a cloud_out
338  * \param[in] cloud_in the input point cloud dataset
339  * \param[out] cloud_out the resultant output point cloud dataset
340  * \ingroup common
341  */
342  PCL_EXPORTS void
344  pcl::PCLPointCloud2 &cloud_out);
345 
346  /** \brief Check if two given point types are the same or not. */
347 template <typename Point1T, typename Point2T> constexpr bool
348  isSamePointType() noexcept
349  {
350  return (std::is_same<remove_cvref_t<Point1T>, remove_cvref_t<Point2T>>::value);
351  }
352 
353  /** \brief Extract the indices of a given point cloud as a new point cloud
354  * \param[in] cloud_in the input point cloud dataset
355  * \param[in] indices the vector of indices representing the points to be copied from \a cloud_in
356  * \param[out] cloud_out the resultant output point cloud dataset
357  * \note Assumes unique indices.
358  * \ingroup common
359  */
360  template <typename PointT, typename IndicesVectorAllocator = std::allocator<index_t>> void
361  copyPointCloud (const pcl::PointCloud<PointT> &cloud_in,
362  const IndicesAllocator< IndicesVectorAllocator> &indices,
363  pcl::PointCloud<PointT> &cloud_out);
364 
365  /** \brief Extract the indices of a given point cloud as a new point cloud
366  * \param[in] cloud_in the input point cloud dataset
367  * \param[in] indices the PointIndices structure representing the points to be copied from cloud_in
368  * \param[out] cloud_out the resultant output point cloud dataset
369  * \note Assumes unique indices.
370  * \ingroup common
371  */
372  template <typename PointT> void
373  copyPointCloud (const pcl::PointCloud<PointT> &cloud_in,
374  const PointIndices &indices,
375  pcl::PointCloud<PointT> &cloud_out);
376 
377  /** \brief Extract the indices of a given point cloud as a new point cloud
378  * \param[in] cloud_in the input point cloud dataset
379  * \param[in] indices the vector of indices representing the points to be copied from \a cloud_in
380  * \param[out] cloud_out the resultant output point cloud dataset
381  * \note Assumes unique indices.
382  * \ingroup common
383  */
384  template <typename PointT> void
385  copyPointCloud (const pcl::PointCloud<PointT> &cloud_in,
386  const std::vector<pcl::PointIndices> &indices,
387  pcl::PointCloud<PointT> &cloud_out);
388 
389  /** \brief Copy all the fields from a given point cloud into a new point cloud
390  * \param[in] cloud_in the input point cloud dataset
391  * \param[out] cloud_out the resultant output point cloud dataset
392  * \ingroup common
393  */
394  template <typename PointInT, typename PointOutT> void
395  copyPointCloud (const pcl::PointCloud<PointInT> &cloud_in,
396  pcl::PointCloud<PointOutT> &cloud_out);
397 
398  /** \brief Extract the indices of a given point cloud as a new point cloud
399  * \param[in] cloud_in the input point cloud dataset
400  * \param[in] indices the vector of indices representing the points to be copied from \a cloud_in
401  * \param[out] cloud_out the resultant output point cloud dataset
402  * \note Assumes unique indices.
403  * \ingroup common
404  */
405  template <typename PointInT, typename PointOutT, typename IndicesVectorAllocator = std::allocator<index_t>> void
406  copyPointCloud (const pcl::PointCloud<PointInT> &cloud_in,
407  const IndicesAllocator<IndicesVectorAllocator> &indices,
408  pcl::PointCloud<PointOutT> &cloud_out);
409 
410  /** \brief Extract the indices of a given point cloud as a new point cloud
411  * \param[in] cloud_in the input point cloud dataset
412  * \param[in] indices the PointIndices structure representing the points to be copied from cloud_in
413  * \param[out] cloud_out the resultant output point cloud dataset
414  * \note Assumes unique indices.
415  * \ingroup common
416  */
417  template <typename PointInT, typename PointOutT> void
418  copyPointCloud (const pcl::PointCloud<PointInT> &cloud_in,
419  const PointIndices &indices,
420  pcl::PointCloud<PointOutT> &cloud_out);
421 
422  /** \brief Extract the indices of a given point cloud as a new point cloud
423  * \param[in] cloud_in the input point cloud dataset
424  * \param[in] indices the vector of indices representing the points to be copied from cloud_in
425  * \param[out] cloud_out the resultant output point cloud dataset
426  * \note Assumes unique indices.
427  * \ingroup common
428  */
429  template <typename PointInT, typename PointOutT> void
430  copyPointCloud (const pcl::PointCloud<PointInT> &cloud_in,
431  const std::vector<pcl::PointIndices> &indices,
432  pcl::PointCloud<PointOutT> &cloud_out);
433 
434  /** \brief Copy a point cloud inside a larger one interpolating borders.
435  * \param[in] cloud_in the input point cloud dataset
436  * \param[out] cloud_out the resultant output point cloud dataset
437  * \param top
438  * \param bottom
439  * \param left
440  * \param right
441  * Position of cloud_in inside cloud_out is given by \a top, \a left, \a bottom \a right.
442  * \param[in] border_type the interpolating method (pcl::BORDER_XXX)
443  * BORDER_REPLICATE: aaaaaa|abcdefgh|hhhhhhh
444  * BORDER_REFLECT: fedcba|abcdefgh|hgfedcb
445  * BORDER_REFLECT_101: gfedcb|abcdefgh|gfedcba
446  * BORDER_WRAP: cdefgh|abcdefgh|abcdefg
447  * BORDER_CONSTANT: iiiiii|abcdefgh|iiiiiii with some specified 'i'
448  * BORDER_TRANSPARENT: mnopqr|abcdefgh|tuvwxyz where m-r and t-z are original values of cloud_out
449  * \param value
450  * \throw pcl::BadArgumentException if any of top, bottom, left or right is negative.
451  * \ingroup common
452  */
453  template <typename PointT> void
454  copyPointCloud (const pcl::PointCloud<PointT> &cloud_in,
455  pcl::PointCloud<PointT> &cloud_out,
456  int top, int bottom, int left, int right,
457  pcl::InterpolationType border_type, const PointT& value);
458 
459  /** \brief Concatenate two datasets representing different fields.
460  *
461  * \note If the input datasets have overlapping fields (i.e., both contain
462  * the same fields), then the data in the second cloud (cloud2_in) will
463  * overwrite the data in the first (cloud1_in).
464  *
465  * \param[in] cloud1_in the first input dataset
466  * \param[in] cloud2_in the second input dataset (overwrites the fields of the first dataset for those that are shared)
467  * \param[out] cloud_out the resultant output dataset created by the concatenation of all the fields in the input datasets
468  * \ingroup common
469  */
470  template <typename PointIn1T, typename PointIn2T, typename PointOutT> void
472  const pcl::PointCloud<PointIn2T> &cloud2_in,
473  pcl::PointCloud<PointOutT> &cloud_out);
474 
475  /** \brief Concatenate two datasets representing different fields.
476  *
477  * \note If the input datasets have overlapping fields (i.e., both contain
478  * the same fields), then the data in the second cloud (cloud2_in) will
479  * overwrite the data in the first (cloud1_in).
480  *
481  * \param[in] cloud1_in the first input dataset
482  * \param[in] cloud2_in the second input dataset (overwrites the fields of the first dataset for those that are shared)
483  * \param[out] cloud_out the output dataset created by concatenating all the fields in the input datasets
484  * \ingroup common
485  */
486  PCL_EXPORTS bool
488  const pcl::PCLPointCloud2 &cloud2_in,
489  pcl::PCLPointCloud2 &cloud_out);
490 
491  /** \brief Copy the XYZ dimensions of a pcl::PCLPointCloud2 into Eigen format
492  * \param[in] in the point cloud message
493  * \param[out] out the resultant Eigen MatrixXf format containing XYZ0 / point
494  * \ingroup common
495  */
496  PCL_EXPORTS bool
497  getPointCloudAsEigen (const pcl::PCLPointCloud2 &in, Eigen::MatrixXf &out);
498 
499  /** \brief Copy the XYZ dimensions from an Eigen MatrixXf into a pcl::PCLPointCloud2 message
500  * \param[in] in the Eigen MatrixXf format containing XYZ0 / point
501  * \param[out] out the resultant point cloud message
502  * \note the method assumes that the PCLPointCloud2 message already has the fields set up properly !
503  * \ingroup common
504  */
505  PCL_EXPORTS bool
506  getEigenAsPointCloud (Eigen::MatrixXf &in, pcl::PCLPointCloud2 &out);
507 
508  namespace io
509  {
510  /** \brief swap bytes order of a char array of length N
511  * \param bytes char array to swap
512  * \ingroup common
513  */
514  template <std::size_t N> void
515  swapByte (char* bytes);
516 
517  /** \brief specialization of swapByte for dimension 1
518  * \param bytes char array to swap
519  */
520  template <> inline void
521  swapByte<1> (char* bytes) { bytes[0] = bytes[0]; }
522 
523 
524  /** \brief specialization of swapByte for dimension 2
525  * \param bytes char array to swap
526  */
527  template <> inline void
528  swapByte<2> (char* bytes) { std::swap (bytes[0], bytes[1]); }
529 
530  /** \brief specialization of swapByte for dimension 4
531  * \param bytes char array to swap
532  */
533  template <> inline void
534  swapByte<4> (char* bytes)
535  {
536  std::swap (bytes[0], bytes[3]);
537  std::swap (bytes[1], bytes[2]);
538  }
539 
540  /** \brief specialization of swapByte for dimension 8
541  * \param bytes char array to swap
542  */
543  template <> inline void
544  swapByte<8> (char* bytes)
545  {
546  std::swap (bytes[0], bytes[7]);
547  std::swap (bytes[1], bytes[6]);
548  std::swap (bytes[2], bytes[5]);
549  std::swap (bytes[3], bytes[4]);
550  }
551 
552  /** \brief swaps byte of an arbitrary type T casting it to char*
553  * \param value the data you want its bytes swapped
554  */
555  template <typename T> void
556  swapByte (T& value)
557  {
558  pcl::io::swapByte<sizeof(T)> (reinterpret_cast<char*> (&value));
559  }
560  }
561 }
562 
563 #include <pcl/common/impl/io.hpp>
PointCloud represents the base class in PCL for storing collections of 3D points.
Definition: point_cloud.h:173
static bool concatenate(pcl::PointCloud< PointT > &cloud1, const pcl::PointCloud< PointT > &cloud2)
Definition: point_cloud.h:231
void swapByte(char *bytes)
swap bytes order of a char array of length N
PCL_EXPORTS bool getPointCloudAsEigen(const pcl::PCLPointCloud2 &in, Eigen::MatrixXf &out)
Copy the XYZ dimensions of a pcl::PCLPointCloud2 into Eigen format.
PCL_EXPORTS bool getEigenAsPointCloud(Eigen::MatrixXf &in, pcl::PCLPointCloud2 &out)
Copy the XYZ dimensions from an Eigen MatrixXf into a pcl::PCLPointCloud2 message.
int getFieldSize(const int datatype)
Obtains the size of a specific field data type in bytes.
Definition: io.h:119
std::string getFieldsList(const pcl::PointCloud< PointT > &)
Get the list of all fields available in a given cloud.
Definition: io.hpp:107
int getFieldType(const int size, char type)
Obtains the type of the PCLPointField from a specific size and type.
Definition: io.h:163
void concatenateFields(const pcl::PointCloud< PointIn1T > &cloud1_in, const pcl::PointCloud< PointIn2T > &cloud2_in, pcl::PointCloud< PointOutT > &cloud_out)
Concatenate two datasets representing different fields.
Definition: io.hpp:303
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:273
#define PCL_FALLTHROUGH
Macro to add a no-op or a fallthrough attribute based on compiler feature.
Definition: pcl_macros.h:433
void copyPointCloud(const pcl::PointCloud< PointInT > &cloud_in, pcl::PointCloud< PointOutT > &cloud_out)
Copy all the fields from a given point cloud into a new point cloud.
Definition: io.hpp:142
float distance(const PointT &p1, const PointT &p2)
Definition: geometry.h:60
void swapByte< 1 >(char *bytes)
specialization of swapByte for dimension 1
Definition: io.h:521
void swapByte< 4 >(char *bytes)
specialization of swapByte for dimension 4
Definition: io.h:534
void swapByte< 2 >(char *bytes)
specialization of swapByte for dimension 2
Definition: io.h:528
void swapByte< 8 >(char *bytes)
specialization of swapByte for dimension 8
Definition: io.h:544
int getFieldIndex(const pcl::PointCloud< PointT > &, const std::string &field_name, std::vector< pcl::PCLPointField > &fields)
Definition: io.hpp:52
InterpolationType
Definition: io.h:247
@ BORDER_REFLECT
Definition: io.h:249
@ BORDER_REFLECT_101
Definition: io.h:250
@ BORDER_TRANSPARENT
Definition: io.h:250
@ BORDER_DEFAULT
Definition: io.h:251
@ BORDER_CONSTANT
Definition: io.h:248
@ BORDER_WRAP
Definition: io.h:249
@ BORDER_REPLICATE
Definition: io.h:248
PCL_EXPORTS int interpolatePointIndex(int p, int length, InterpolationType type)
constexpr bool isSamePointType() noexcept
Check if two given point types are the same or not.
Definition: io.h:348
std::vector< index_t, Allocator > IndicesAllocator
Type used for indices in PCL.
Definition: types.h:128
std::remove_cv_t< std::remove_reference_t< T > > remove_cvref_t
Definition: type_traits.h:298
IndicesAllocator<> Indices
Type used for indices in PCL.
Definition: types.h:133
PCL_EXPORTS void getFieldsSizes(const std::vector< pcl::PCLPointField > &fields, std::vector< int > &field_sizes)
Obtain a vector with the sizes of all valid fields (e.g., not "_")
void getFields(const pcl::PointCloud< PointT > &, std::vector< pcl::PCLPointField > &fields)
Definition: io.hpp:83
Defines all the PCL and non-PCL macros used.
#define PCL_EXPORTS
Definition: pcl_macros.h:323
std::vector<::pcl::PCLPointField > fields
static bool concatenate(pcl::PCLPointCloud2 &cloud1, const pcl::PCLPointCloud2 &cloud2)
Inplace concatenate two pcl::PCLPointCloud2.
A point structure representing Euclidean xyz coordinates, and the RGB color.
static bool concatenate(pcl::PolygonMesh &mesh1, const pcl::PolygonMesh &mesh2)
Inplace concatenate two pcl::PolygonMesh.
Definition: PolygonMesh.h:30