40 #ifndef PCL_IO_PCD_IO_IMPL_H_ 41 #define PCL_IO_PCD_IO_IMPL_H_ 47 #include <pcl/io/boost.h> 48 #include <pcl/console/print.h> 49 #include <pcl/io/pcd_io.h> 53 # ifndef WIN32_LEAN_AND_MEAN 54 # define WIN32_LEAN_AND_MEAN 55 # endif // WIN32_LEAN_AND_MEAN 60 # define pcl_open _open 61 # define pcl_close(fd) _close(fd) 62 # define pcl_lseek(fd,offset,origin) _lseek(fd,offset,origin) 64 # include <sys/mman.h> 65 # define pcl_open open 66 # define pcl_close(fd) close(fd) 67 # define pcl_lseek(fd,offset,origin) lseek(fd,offset,origin) 70 #include <pcl/io/lzf.h> 73 template <
typename Po
intT> std::string
76 std::ostringstream oss;
77 oss.imbue (std::locale::classic ());
79 oss <<
"# .PCD v0.7 - Point Cloud Data file format" 83 std::vector<pcl::PCLPointField> fields;
86 std::stringstream field_names, field_types, field_sizes, field_counts;
87 for (
size_t i = 0; i < fields.size (); ++i)
89 if (fields[i].name ==
"_")
92 field_names <<
" " << fields[i].name;
94 if (
"rgb" == fields[i].name)
95 field_types <<
" " <<
"U";
98 int count = abs (static_cast<int> (fields[i].count));
99 if (count == 0) count = 1;
100 field_counts <<
" " << count;
102 oss << field_names.str ();
103 oss <<
"\nSIZE" << field_sizes.str ()
104 <<
"\nTYPE" << field_types.str ()
105 <<
"\nCOUNT" << field_counts.str ();
107 if (nr_points != std::numeric_limits<int>::max ())
108 oss <<
"\nWIDTH " << nr_points <<
"\nHEIGHT " << 1 <<
"\n";
110 oss <<
"\nWIDTH " << cloud.
width <<
"\nHEIGHT " << cloud.
height <<
"\n";
119 if (nr_points != std::numeric_limits<int>::max ())
120 oss <<
"POINTS " << nr_points <<
"\n";
122 oss <<
"POINTS " << cloud.
points.size () <<
"\n";
128 template <
typename Po
intT>
int 134 throw pcl::IOException (
"[pcl::PCDWriter::writeBinary] Input point cloud has no data!");
138 std::ostringstream oss;
139 oss << generateHeader<PointT> (cloud) <<
"DATA binary\n";
141 data_idx = static_cast<int> (oss.tellp ());
144 HANDLE h_native_file = CreateFileA (file_name.c_str (), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
145 if (h_native_file == INVALID_HANDLE_VALUE)
147 throw pcl::IOException (
"[pcl::PCDWriter::writeBinary] Error during CreateFile!");
151 int fd = pcl_open (file_name.c_str (), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
154 throw pcl::IOException (
"[pcl::PCDWriter::writeBinary] Error during open!");
159 boost::interprocess::file_lock file_lock;
160 setLockingPermissions (file_name, file_lock);
162 std::vector<pcl::PCLPointField> fields;
163 std::vector<int> fields_sizes;
165 size_t data_size = 0;
169 for (
size_t i = 0; i < fields.size (); ++i)
171 if (fields[i].name ==
"_")
174 int fs = fields[i].count *
getFieldSize (fields[i].datatype);
176 fields_sizes.push_back (fs);
177 fields[nri++] = fields[i];
181 data_size = cloud.
points.size () * fsize;
185 HANDLE fm = CreateFileMappingA (h_native_file, NULL, PAGE_READWRITE, 0, (DWORD) (data_idx + data_size), NULL);
186 char *map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, data_idx + data_size));
191 off_t result = pcl_lseek (fd, getpagesize () + data_size - 1, SEEK_SET);
196 resetLockingPermissions (file_name, file_lock);
197 PCL_ERROR (
"[pcl::PCDWriter::writeBinary] lseek errno: %d strerror: %s\n", errno, strerror (errno));
199 throw pcl::IOException (
"[pcl::PCDWriter::writeBinary] Error during lseek ()!");
203 result = static_cast<int> (::
write (fd,
"", 1));
207 resetLockingPermissions (file_name, file_lock);
208 throw pcl::IOException (
"[pcl::PCDWriter::writeBinary] Error during write ()!");
212 char *map = static_cast<char*> (mmap (0, data_idx + data_size, PROT_WRITE, MAP_SHARED, fd, 0));
213 if (map == reinterpret_cast<char*> (-1))
216 resetLockingPermissions (file_name, file_lock);
217 throw pcl::IOException (
"[pcl::PCDWriter::writeBinary] Error during mmap ()!");
223 memcpy (&map[0], oss.str ().c_str (), data_idx);
226 char *out = &map[0] + data_idx;
227 for (
size_t i = 0; i < cloud.
points.size (); ++i)
230 for (
size_t j = 0; j < fields.size (); ++j)
232 memcpy (out, reinterpret_cast<const char*> (&cloud.
points[i]) + fields[j].offset, fields_sizes[nrj]);
233 out += fields_sizes[nrj++];
239 if (map_synchronization_)
240 msync (map, data_idx + data_size, MS_SYNC);
245 UnmapViewOfFile (map);
247 if (munmap (map, (data_idx + data_size)) == -1)
250 resetLockingPermissions (file_name, file_lock);
251 throw pcl::IOException (
"[pcl::PCDWriter::writeBinary] Error during munmap ()!");
257 CloseHandle (h_native_file);
261 resetLockingPermissions (file_name, file_lock);
266 template <
typename Po
intT>
int 270 if (cloud.
points.empty ())
272 throw pcl::IOException (
"[pcl::PCDWriter::writeBinaryCompressed] Input point cloud has no data!");
276 std::ostringstream oss;
277 oss << generateHeader<PointT> (cloud) <<
"DATA binary_compressed\n";
279 data_idx = static_cast<int> (oss.tellp ());
282 HANDLE h_native_file = CreateFileA (file_name.c_str (), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
283 if (h_native_file == INVALID_HANDLE_VALUE)
285 throw pcl::IOException (
"[pcl::PCDWriter::writeBinaryCompressed] Error during CreateFile!");
289 int fd = pcl_open (file_name.c_str (), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
292 throw pcl::IOException (
"[pcl::PCDWriter::writeBinaryCompressed] Error during open!");
298 boost::interprocess::file_lock file_lock;
299 setLockingPermissions (file_name, file_lock);
301 std::vector<pcl::PCLPointField> fields;
303 size_t data_size = 0;
306 std::vector<int> fields_sizes (fields.size ());
308 for (
size_t i = 0; i < fields.size (); ++i)
310 if (fields[i].name ==
"_")
314 fsize += fields_sizes[nri];
315 fields[nri] = fields[i];
318 fields_sizes.resize (nri);
322 data_size = cloud.
points.size () * fsize;
329 char *only_valid_data = static_cast<char*> (malloc (data_size));
339 std::vector<char*> pters (fields.size ());
341 for (
size_t i = 0; i < pters.size (); ++i)
343 pters[i] = &only_valid_data[toff];
344 toff += fields_sizes[i] * static_cast<int> (cloud.
points.size ());
348 for (
size_t i = 0; i < cloud.
points.size (); ++i)
350 for (
size_t j = 0; j < fields.size (); ++j)
352 memcpy (pters[j], reinterpret_cast<const char*> (&cloud.
points[i]) + fields[j].offset, fields_sizes[j]);
354 pters[j] += fields_sizes[j];
358 char* temp_buf = static_cast<char*> (malloc (static_cast<size_t> (static_cast<float> (data_size) * 1.5f + 8.0f)));
361 static_cast<uint32_t> (data_size),
363 static_cast<uint32_t> (static_cast<float>(data_size) * 1.5f));
364 unsigned int compressed_final_size = 0;
368 char *header = &temp_buf[0];
369 memcpy (&header[0], &compressed_size,
sizeof (
unsigned int));
370 memcpy (&header[4], &data_size,
sizeof (
unsigned int));
371 data_size = compressed_size + 8;
372 compressed_final_size = static_cast<uint32_t> (data_size) + data_idx;
379 resetLockingPermissions (file_name, file_lock);
380 throw pcl::IOException (
"[pcl::PCDWriter::writeBinaryCompressed] Error during compression!");
386 off_t result = pcl_lseek (fd, getpagesize () + data_size - 1, SEEK_SET);
390 resetLockingPermissions (file_name, file_lock);
391 PCL_ERROR (
"[pcl::PCDWriter::writeBinary] lseek errno: %d strerror: %s\n", errno, strerror (errno));
393 throw pcl::IOException (
"[pcl::PCDWriter::writeBinaryCompressed] Error during lseek ()!");
397 result = static_cast<int> (::
write (fd,
"", 1));
401 resetLockingPermissions (file_name, file_lock);
402 throw pcl::IOException (
"[pcl::PCDWriter::writeBinaryCompressed] Error during write ()!");
409 HANDLE fm = CreateFileMapping (h_native_file, NULL, PAGE_READWRITE, 0, compressed_final_size, NULL);
410 char *map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, compressed_final_size));
414 char *map = static_cast<char*> (mmap (0, compressed_final_size, PROT_WRITE, MAP_SHARED, fd, 0));
415 if (map == reinterpret_cast<char*> (-1))
418 resetLockingPermissions (file_name, file_lock);
419 throw pcl::IOException (
"[pcl::PCDWriter::writeBinaryCompressed] Error during mmap ()!");
425 memcpy (&map[0], oss.str ().c_str (), data_idx);
427 memcpy (&map[data_idx], temp_buf, data_size);
431 if (map_synchronization_)
432 msync (map, compressed_final_size, MS_SYNC);
437 UnmapViewOfFile (map);
439 if (munmap (map, (compressed_final_size)) == -1)
442 resetLockingPermissions (file_name, file_lock);
443 throw pcl::IOException (
"[pcl::PCDWriter::writeBinaryCompressed] Error during munmap ()!");
450 CloseHandle (h_native_file);
454 resetLockingPermissions (file_name, file_lock);
456 free (only_valid_data);
462 template <
typename Po
intT>
int 468 throw pcl::IOException (
"[pcl::PCDWriter::writeASCII] Input point cloud has no data!");
474 throw pcl::IOException (
"[pcl::PCDWriter::writeASCII] Number of points different than width * height!");
479 fs.open (file_name.c_str ());
481 if (!fs.is_open () || fs.fail ())
483 throw pcl::IOException (
"[pcl::PCDWriter::writeASCII] Could not open file for writing!");
488 boost::interprocess::file_lock file_lock;
489 setLockingPermissions (file_name, file_lock);
491 fs.precision (precision);
492 fs.imbue (std::locale::classic ());
494 std::vector<pcl::PCLPointField> fields;
498 fs << generateHeader<PointT> (cloud) <<
"DATA ascii\n";
500 std::ostringstream stream;
501 stream.precision (precision);
502 stream.imbue (std::locale::classic ());
504 for (
size_t i = 0; i < cloud.
points.size (); ++i)
506 for (
size_t d = 0; d < fields.size (); ++d)
509 if (fields[d].name ==
"_")
512 int count = fields[d].count;
516 for (
int c = 0; c < count; ++c)
518 switch (fields[d].datatype)
523 memcpy (&value, reinterpret_cast<const char*> (&cloud.
points[i]) + fields[d].offset + c * sizeof (int8_t),
sizeof (int8_t));
524 if (pcl_isnan (value))
527 stream << boost::numeric_cast<uint32_t>(value);
533 memcpy (&value, reinterpret_cast<const char*> (&cloud.
points[i]) + fields[d].offset + c * sizeof (uint8_t),
sizeof (uint8_t));
534 if (pcl_isnan (value))
537 stream << boost::numeric_cast<uint32_t>(value);
543 memcpy (&value, reinterpret_cast<const char*> (&cloud.
points[i]) + fields[d].offset + c * sizeof (int16_t),
sizeof (int16_t));
544 if (pcl_isnan (value))
547 stream << boost::numeric_cast<int16_t>(value);
553 memcpy (&value, reinterpret_cast<const char*> (&cloud.
points[i]) + fields[d].offset + c * sizeof (uint16_t),
sizeof (uint16_t));
554 if (pcl_isnan (value))
557 stream << boost::numeric_cast<uint16_t>(value);
563 memcpy (&value, reinterpret_cast<const char*> (&cloud.
points[i]) + fields[d].offset + c * sizeof (int32_t),
sizeof (int32_t));
564 if (pcl_isnan (value))
567 stream << boost::numeric_cast<int32_t>(value);
573 memcpy (&value, reinterpret_cast<const char*> (&cloud.
points[i]) + fields[d].offset + c * sizeof (uint32_t),
sizeof (uint32_t));
574 if (pcl_isnan (value))
577 stream << boost::numeric_cast<uint32_t>(value);
587 if (
"rgb" == fields[d].name)
590 memcpy (&value, reinterpret_cast<const char*> (&cloud.
points[i]) + fields[d].offset + c * sizeof (
float),
sizeof (
float));
591 if (pcl_isnan (value))
594 stream << boost::numeric_cast<uint32_t>(value);
600 memcpy (&value, reinterpret_cast<const char*> (&cloud.
points[i]) + fields[d].offset + c * sizeof (
float),
sizeof (
float));
601 if (pcl_isnan (value))
604 stream << boost::numeric_cast<float>(value);
611 memcpy (&value, reinterpret_cast<const char*> (&cloud.
points[i]) + fields[d].offset + c * sizeof (
double),
sizeof (
double));
612 if (pcl_isnan (value))
615 stream << boost::numeric_cast<double>(value);
619 PCL_WARN (
"[pcl::PCDWriter::writeASCII] Incorrect field data type specified (%d)!\n", fields[d].datatype);
623 if (d < fields.size () - 1 || c < static_cast<int> (fields[d].count - 1))
628 std::string result = stream.str ();
629 boost::trim (result);
631 fs << result <<
"\n";
634 resetLockingPermissions (file_name, file_lock);
640 template <
typename Po
intT>
int 643 const std::vector<int> &indices)
645 if (cloud.
points.empty () || indices.empty ())
647 throw pcl::IOException (
"[pcl::PCDWriter::writeBinary] Input point cloud has no data or empty indices given!");
651 std::ostringstream oss;
652 oss << generateHeader<PointT> (cloud, static_cast<int> (indices.size ())) <<
"DATA binary\n";
654 data_idx = static_cast<int> (oss.tellp ());
657 HANDLE h_native_file = CreateFileA (file_name.c_str (), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
658 if (h_native_file == INVALID_HANDLE_VALUE)
660 throw pcl::IOException (
"[pcl::PCDWriter::writeBinary] Error during CreateFile!");
664 int fd = pcl_open (file_name.c_str (), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
667 throw pcl::IOException (
"[pcl::PCDWriter::writeBinary] Error during open!");
672 boost::interprocess::file_lock file_lock;
673 setLockingPermissions (file_name, file_lock);
675 std::vector<pcl::PCLPointField> fields;
676 std::vector<int> fields_sizes;
678 size_t data_size = 0;
682 for (
size_t i = 0; i < fields.size (); ++i)
684 if (fields[i].name ==
"_")
687 int fs = fields[i].count *
getFieldSize (fields[i].datatype);
689 fields_sizes.push_back (fs);
690 fields[nri++] = fields[i];
694 data_size = indices.size () * fsize;
698 HANDLE fm = CreateFileMapping (h_native_file, NULL, PAGE_READWRITE, 0, data_idx + data_size, NULL);
699 char *map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, data_idx + data_size));
704 off_t result = pcl_lseek (fd, getpagesize () + data_size - 1, SEEK_SET);
708 resetLockingPermissions (file_name, file_lock);
709 PCL_ERROR (
"[pcl::PCDWriter::writeBinary] lseek errno: %d strerror: %s\n", errno, strerror (errno));
711 throw pcl::IOException (
"[pcl::PCDWriter::writeBinary] Error during lseek ()!");
715 result = static_cast<int> (::
write (fd,
"", 1));
719 resetLockingPermissions (file_name, file_lock);
720 throw pcl::IOException (
"[pcl::PCDWriter::writeBinary] Error during write ()!");
724 char *map = static_cast<char*> (mmap (0, data_idx + data_size, PROT_WRITE, MAP_SHARED, fd, 0));
725 if (map == reinterpret_cast<char*> (-1))
728 resetLockingPermissions (file_name, file_lock);
729 throw pcl::IOException (
"[pcl::PCDWriter::writeBinary] Error during mmap ()!");
735 memcpy (&map[0], oss.str ().c_str (), data_idx);
737 char *out = &map[0] + data_idx;
739 for (
size_t i = 0; i < indices.size (); ++i)
742 for (
size_t j = 0; j < fields.size (); ++j)
744 memcpy (out, reinterpret_cast<const char*> (&cloud.
points[indices[i]]) + fields[j].offset, fields_sizes[nrj]);
745 out += fields_sizes[nrj++];
751 if (map_synchronization_)
752 msync (map, data_idx + data_size, MS_SYNC);
757 UnmapViewOfFile (map);
759 if (munmap (map, (data_idx + data_size)) == -1)
762 resetLockingPermissions (file_name, file_lock);
763 throw pcl::IOException (
"[pcl::PCDWriter::writeBinary] Error during munmap ()!");
769 CloseHandle(h_native_file);
774 resetLockingPermissions (file_name, file_lock);
779 template <
typename Po
intT>
int 782 const std::vector<int> &indices,
785 if (cloud.
points.empty () || indices.empty ())
787 throw pcl::IOException (
"[pcl::PCDWriter::writeASCII] Input point cloud has no data or empty indices given!");
793 throw pcl::IOException (
"[pcl::PCDWriter::writeASCII] Number of points different than width * height!");
798 fs.open (file_name.c_str ());
799 if (!fs.is_open () || fs.fail ())
801 throw pcl::IOException (
"[pcl::PCDWriter::writeASCII] Could not open file for writing!");
806 boost::interprocess::file_lock file_lock;
807 setLockingPermissions (file_name, file_lock);
809 fs.precision (precision);
810 fs.imbue (std::locale::classic ());
812 std::vector<pcl::PCLPointField> fields;
816 fs << generateHeader<PointT> (cloud, static_cast<int> (indices.size ())) <<
"DATA ascii\n";
818 std::ostringstream stream;
819 stream.precision (precision);
820 stream.imbue (std::locale::classic ());
823 for (
size_t i = 0; i < indices.size (); ++i)
825 for (
size_t d = 0; d < fields.size (); ++d)
828 if (fields[d].name ==
"_")
831 int count = fields[d].count;
835 for (
int c = 0; c < count; ++c)
837 switch (fields[d].datatype)
842 memcpy (&value, reinterpret_cast<const char*> (&cloud.
points[indices[i]]) + fields[d].offset + c * sizeof (int8_t),
sizeof (int8_t));
843 if (pcl_isnan (value))
846 stream << boost::numeric_cast<uint32_t>(value);
852 memcpy (&value, reinterpret_cast<const char*> (&cloud.
points[indices[i]]) + fields[d].offset + c * sizeof (uint8_t),
sizeof (uint8_t));
853 if (pcl_isnan (value))
856 stream << boost::numeric_cast<uint32_t>(value);
862 memcpy (&value, reinterpret_cast<const char*> (&cloud.
points[indices[i]]) + fields[d].offset + c * sizeof (int16_t),
sizeof (int16_t));
863 if (pcl_isnan (value))
866 stream << boost::numeric_cast<int16_t>(value);
872 memcpy (&value, reinterpret_cast<const char*> (&cloud.
points[indices[i]]) + fields[d].offset + c * sizeof (uint16_t),
sizeof (uint16_t));
873 if (pcl_isnan (value))
876 stream << boost::numeric_cast<uint16_t>(value);
882 memcpy (&value, reinterpret_cast<const char*> (&cloud.
points[indices[i]]) + fields[d].offset + c * sizeof (int32_t),
sizeof (int32_t));
883 if (pcl_isnan (value))
886 stream << boost::numeric_cast<int32_t>(value);
892 memcpy (&value, reinterpret_cast<const char*> (&cloud.
points[indices[i]]) + fields[d].offset + c * sizeof (uint32_t),
sizeof (uint32_t));
893 if (pcl_isnan (value))
896 stream << boost::numeric_cast<uint32_t>(value);
906 if (
"rgb" == fields[d].name)
909 memcpy (&value, reinterpret_cast<const char*> (&cloud.
points[indices[i]]) + fields[d].offset + c * sizeof (
float),
sizeof (
float));
910 if (pcl_isnan (value))
913 stream << boost::numeric_cast<uint32_t>(value);
918 memcpy (&value, reinterpret_cast<const char*> (&cloud.
points[indices[i]]) + fields[d].offset + c * sizeof (
float),
sizeof (
float));
919 if (pcl_isnan (value))
922 stream << boost::numeric_cast<float>(value);
929 memcpy (&value, reinterpret_cast<const char*> (&cloud.
points[indices[i]]) + fields[d].offset + c * sizeof (
double),
sizeof (
double));
930 if (pcl_isnan (value))
933 stream << boost::numeric_cast<double>(value);
937 PCL_WARN (
"[pcl::PCDWriter::writeASCII] Incorrect field data type specified (%d)!\n", fields[d].datatype);
941 if (d < fields.size () - 1 || c < static_cast<int> (fields[d].count - 1))
946 std::string result = stream.str ();
947 boost::trim (result);
949 fs << result <<
"\n";
953 resetLockingPermissions (file_name, file_lock);
958 #endif //#ifndef PCL_IO_PCD_IO_H_
std::vector< PointT, Eigen::aligned_allocator< PointT > > points
The point data.
int writeBinaryCompressed(const std::string &file_name, const pcl::PCLPointCloud2 &cloud, const Eigen::Vector4f &origin=Eigen::Vector4f::Zero(), const Eigen::Quaternionf &orientation=Eigen::Quaternionf::Identity())
Save point cloud data to a PCD file containing n-D points, in BINARY_COMPRESSED format.
static std::string generateHeader(const pcl::PointCloud< PointT > &cloud, const int nr_points=std::numeric_limits< int >::max())
Generate the header of a PCD file format.
int writeASCII(const std::string &file_name, const pcl::PCLPointCloud2 &cloud, const Eigen::Vector4f &origin=Eigen::Vector4f::Zero(), const Eigen::Quaternionf &orientation=Eigen::Quaternionf::Identity(), const int precision=8)
Save point cloud data to a PCD file containing n-D points, in ASCII format.
int writeBinary(const std::string &file_name, const pcl::PCLPointCloud2 &cloud, const Eigen::Vector4f &origin=Eigen::Vector4f::Zero(), const Eigen::Quaternionf &orientation=Eigen::Quaternionf::Identity())
Save point cloud data to a PCD file containing n-D points, in BINARY format.
int getFieldType(const int size, char type)
Obtains the type of the PCLPointField from a specific size and type.
uint32_t height
The point cloud height (if organized as an image-structure).
Eigen::Vector4f sensor_origin_
Sensor acquisition pose (origin/translation).
uint32_t width
The point cloud width (if organized as an image-structure).
Eigen::Quaternionf sensor_orientation_
Sensor acquisition pose (rotation).
int getFieldSize(const int datatype)
Obtains the size of a specific field data type in bytes.
An exception that is thrown during an IO error (typical read/write errors)
PointCloud represents the base class in PCL for storing collections of 3D points.
PCL_EXPORTS unsigned int lzfCompress(const void *const in_data, unsigned int in_len, void *out_data, unsigned int out_len)
Compress in_len bytes stored at the memory block starting at in_data and write the result to out_data...
void write(std::ostream &stream, Type value)
Function for writing data to a stream.
void getFields(const pcl::PointCloud< PointT > &cloud, std::vector< pcl::PCLPointField > &fields)
Get the list of available fields (i.e., dimension/channel)