Point Cloud Library (PCL)  1.7.0
pcd_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  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of the copyright holder(s) nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  * $Id$
37  *
38  */
39 
40 #ifndef PCL_IO_PCD_IO_H_
41 #define PCL_IO_PCD_IO_H_
42 
43 #include <pcl/point_cloud.h>
44 #include <pcl/io/file_io.h>
45 
46 namespace pcl
47 {
48  /** \brief Point Cloud Data (PCD) file format reader.
49  * \author Radu B. Rusu
50  * \ingroup io
51  */
52  class PCL_EXPORTS PCDReader : public FileReader
53  {
54  public:
55  /** Empty constructor */
56  PCDReader () : FileReader () {}
57  /** Empty destructor */
58  ~PCDReader () {}
59 
60  /** \brief Various PCD file versions.
61  *
62  * PCD_V6 represents PCD files with version 0.6, which contain the following fields:
63  * - lines beginning with # are treated as comments
64  * - FIELDS ...
65  * - SIZE ...
66  * - TYPE ...
67  * - COUNT ...
68  * - WIDTH ...
69  * - HEIGHT ...
70  * - POINTS ...
71  * - DATA ascii/binary
72  *
73  * Everything that follows \b DATA is intepreted as data points and
74  * will be read accordingly.
75  *
76  * PCD_V7 represents PCD files with version 0.7 and has an important
77  * addon: it adds sensor origin/orientation (aka viewpoint) information
78  * to a dataset through the use of a new header field:
79  * - VIEWPOINT tx ty tz qw qx qy qz
80  */
81  enum
82  {
83  PCD_V6 = 0,
84  PCD_V7 = 1
85  };
86 
87  /** \brief Read a point cloud data header from a PCD file.
88  *
89  * Load only the meta information (number of points, their types, etc),
90  * and not the points themselves, from a given PCD file. Useful for fast
91  * evaluation of the underlying data structure.
92  *
93  * \attention The PCD data is \b always stored in ROW major format! The
94  * read/write PCD methods will detect column major input and automatically convert it.
95  *
96  * \param[in] file_name the name of the file to load
97  * \param[out] cloud the resultant point cloud dataset (only the header will be filled)
98  * \param[out] origin the sensor acquisition origin (only for > PCD_V7 - null if not present)
99  * \param[out] orientation the sensor acquisition orientation (only for > PCD_V7 - identity if not present)
100  * \param[out] pcd_version the PCD version of the file (i.e., PCD_V6, PCD_V7)
101  * \param[out] data_type the type of data (0 = ASCII, 1 = Binary, 2 = Binary compressed)
102  * \param[out] data_idx the offset of cloud data within the file
103  * \param[in] offset the offset of where to expect the PCD Header in the
104  * file (optional parameter). One usage example for setting the offset
105  * parameter is for reading data from a TAR "archive containing multiple
106  * PCD files: TAR files always add a 512 byte header in front of the
107  * actual file, so set the offset to the next byte after the header
108  * (e.g., 513).
109  *
110  * \return
111  * * < 0 (-1) on error
112  * * == 0 on success
113  */
114  int
115  readHeader (const std::string &file_name, pcl::PCLPointCloud2 &cloud,
116  Eigen::Vector4f &origin, Eigen::Quaternionf &orientation, int &pcd_version,
117  int &data_type, unsigned int &data_idx, const int offset = 0);
118 
119 
120  /** \brief Read a point cloud data header from a PCD file.
121  *
122  * Load only the meta information (number of points, their types, etc),
123  * and not the points themselves, from a given PCD file. Useful for fast
124  * evaluation of the underlying data structure.
125  *
126  * \attention The PCD data is \b always stored in ROW major format! The
127  * read/write PCD methods will detect column major input and automatically convert it.
128  *
129  * \param[in] file_name the name of the file to load
130  * \param[out] cloud the resultant point cloud dataset (only the header will be filled)
131  * \param[in] offset the offset of where to expect the PCD Header in the
132  * file (optional parameter). One usage example for setting the offset
133  * parameter is for reading data from a TAR "archive containing multiple
134  * PCD files: TAR files always add a 512 byte header in front of the
135  * actual file, so set the offset to the next byte after the header
136  * (e.g., 513).
137  *
138  * \return
139  * * < 0 (-1) on error
140  * * == 0 on success
141  */
142  int
143  readHeader (const std::string &file_name, pcl::PCLPointCloud2 &cloud, const int offset = 0);
144 
145  /** \brief Read a point cloud data from a PCD file and store it into a pcl/PCLPointCloud2.
146  * \param[in] file_name the name of the file containing the actual PointCloud data
147  * \param[out] cloud the resultant PointCloud message read from disk
148  * \param[out] origin the sensor acquisition origin (only for > PCD_V7 - null if not present)
149  * \param[out] orientation the sensor acquisition orientation (only for > PCD_V7 - identity if not present)
150  * \param[out] pcd_version the PCD version of the file (either PCD_V6 or PCD_V7)
151  * \param[in] offset the offset of where to expect the PCD Header in the
152  * file (optional parameter). One usage example for setting the offset
153  * parameter is for reading data from a TAR "archive containing multiple
154  * PCD files: TAR files always add a 512 byte header in front of the
155  * actual file, so set the offset to the next byte after the header
156  * (e.g., 513).
157  *
158  * \return
159  * * < 0 (-1) on error
160  * * == 0 on success
161  */
162  int
163  read (const std::string &file_name, pcl::PCLPointCloud2 &cloud,
164  Eigen::Vector4f &origin, Eigen::Quaternionf &orientation, int &pcd_version, const int offset = 0);
165 
166  /** \brief Read a point cloud data from a PCD (PCD_V6) and store it into a pcl/PCLPointCloud2.
167  *
168  * \note This function is provided for backwards compatibility only and
169  * it can only read PCD_V6 files correctly, as pcl::PCLPointCloud2
170  * does not contain a sensor origin/orientation. Reading any file
171  * > PCD_V6 will generate a warning.
172  *
173  * \param[in] file_name the name of the file containing the actual PointCloud data
174  * \param[out] cloud the resultant PointCloud message read from disk
175  * \param[in] offset the offset of where to expect the PCD Header in the
176  * file (optional parameter). One usage example for setting the offset
177  * parameter is for reading data from a TAR "archive containing multiple
178  * PCD files: TAR files always add a 512 byte header in front of the
179  * actual file, so set the offset to the next byte after the header
180  * (e.g., 513).
181  *
182  * \return
183  * * < 0 (-1) on error
184  * * == 0 on success
185  */
186  int
187  read (const std::string &file_name, pcl::PCLPointCloud2 &cloud, const int offset = 0);
188 
189  /** \brief Read a point cloud data from any PCD file, and convert it to the given template format.
190  * \param[in] file_name the name of the file containing the actual PointCloud data
191  * \param[out] cloud the resultant PointCloud message read from disk
192  * \param[in] offset the offset of where to expect the PCD Header in the
193  * file (optional parameter). One usage example for setting the offset
194  * parameter is for reading data from a TAR "archive containing multiple
195  * PCD files: TAR files always add a 512 byte header in front of the
196  * actual file, so set the offset to the next byte after the header
197  * (e.g., 513).
198  *
199  * \return
200  * * < 0 (-1) on error
201  * * == 0 on success
202  */
203  template<typename PointT> int
204  read (const std::string &file_name, pcl::PointCloud<PointT> &cloud, const int offset = 0)
205  {
206  pcl::PCLPointCloud2 blob;
207  int pcd_version;
208  int res = read (file_name, blob, cloud.sensor_origin_, cloud.sensor_orientation_,
209  pcd_version, offset);
210 
211  // If no error, convert the data
212  if (res == 0)
213  pcl::fromPCLPointCloud2 (blob, cloud);
214  return (res);
215  }
216 
217  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
218  };
219 
220  /** \brief Point Cloud Data (PCD) file format writer.
221  * \author Radu Bogdan Rusu
222  * \ingroup io
223  */
224  class PCL_EXPORTS PCDWriter : public FileWriter
225  {
226  public:
227  PCDWriter() : FileWriter(), map_synchronization_(false) {}
229 
230  /** \brief Set whether mmap() synchornization via msync() is desired before munmap() calls.
231  * Setting this to true could prevent NFS data loss (see
232  * http://www.pcl-developers.org/PCD-IO-consistency-on-NFS-msync-needed-td4885942.html).
233  * Default: false
234  * \note This option should be used by advanced users only!
235  * \note Please note that using msync() on certain systems can reduce the I/O performance by up to 80%!
236  * \param[in] sync set to true if msync() should be called before munmap()
237  */
238  void
240  {
241  map_synchronization_ = sync;
242  }
243 
244  /** \brief Generate the header of a PCD file format
245  * \param[in] cloud the point cloud data message
246  * \param[in] origin the sensor acquisition origin
247  * \param[in] orientation the sensor acquisition orientation
248  */
249  std::string
250  generateHeaderBinary (const pcl::PCLPointCloud2 &cloud,
251  const Eigen::Vector4f &origin,
252  const Eigen::Quaternionf &orientation);
253 
254  /** \brief Generate the header of a BINARY_COMPRESSED PCD file format
255  * \param[in] cloud the point cloud data message
256  * \param[in] origin the sensor acquisition origin
257  * \param[in] orientation the sensor acquisition orientation
258  */
259  std::string
260  generateHeaderBinaryCompressed (const pcl::PCLPointCloud2 &cloud,
261  const Eigen::Vector4f &origin,
262  const Eigen::Quaternionf &orientation);
263 
264  /** \brief Generate the header of a PCD file format
265  * \param[in] cloud the point cloud data message
266  * \param[in] origin the sensor acquisition origin
267  * \param[in] orientation the sensor acquisition orientation
268  */
269  std::string
270  generateHeaderASCII (const pcl::PCLPointCloud2 &cloud,
271  const Eigen::Vector4f &origin,
272  const Eigen::Quaternionf &orientation);
273 
274  /** \brief Generate the header of a PCD file format
275  * \param[in] cloud the point cloud data message
276  * \param[in] nr_points if given, use this to fill in WIDTH, HEIGHT (=1), and POINTS in the header
277  * By default, nr_points is set to INTMAX, and the data in the header is used instead.
278  */
279  template <typename PointT> static std::string
280  generateHeader (const pcl::PointCloud<PointT> &cloud,
281  const int nr_points = std::numeric_limits<int>::max ());
282 
283  /** \brief Save point cloud data to a PCD file containing n-D points, in ASCII format
284  * \param[in] file_name the output file name
285  * \param[in] cloud the point cloud data message
286  * \param[in] origin the sensor acquisition origin
287  * \param[in] orientation the sensor acquisition orientation
288  * \param[in] precision the specified output numeric stream precision (default: 8)
289  *
290  * Caution: PointCloud structures containing an RGB field have
291  * traditionally used packed float values to store RGB data. Storing a
292  * float as ASCII can introduce variations to the smallest bits, and
293  * thus significantly alter the data. This is a known issue, and the fix
294  * involves switching RGB data to be stored as a packed integer in
295  * future versions of PCL.
296  *
297  * As an intermediary solution, precision 8 is used, which guarantees lossless storage for RGB.
298  */
299  int
300  writeASCII (const std::string &file_name, const pcl::PCLPointCloud2 &cloud,
301  const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (),
302  const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (),
303  const int precision = 8);
304 
305  /** \brief Save point cloud data to a PCD file containing n-D points, in BINARY format
306  * \param[in] file_name the output file name
307  * \param[in] cloud the point cloud data message
308  * \param[in] origin the sensor acquisition origin
309  * \param[in] orientation the sensor acquisition orientation
310  */
311  int
312  writeBinary (const std::string &file_name, const pcl::PCLPointCloud2 &cloud,
313  const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (),
314  const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity ());
315 
316  /** \brief Save point cloud data to a PCD file containing n-D points, in BINARY_COMPRESSED format
317  * \param[in] file_name the output file name
318  * \param[in] cloud the point cloud data message
319  * \param[in] origin the sensor acquisition origin
320  * \param[in] orientation the sensor acquisition orientation
321  */
322  int
323  writeBinaryCompressed (const std::string &file_name, const pcl::PCLPointCloud2 &cloud,
324  const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (),
325  const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity ());
326 
327  /** \brief Save point cloud data to a PCD file containing n-D points
328  * \param[in] file_name the output file name
329  * \param[in] cloud the point cloud data message
330  * \param[in] origin the sensor acquisition origin
331  * \param[in] orientation the sensor acquisition orientation
332  * \param[in] binary set to true if the file is to be written in a binary
333  * PCD format, false (default) for ASCII
334  *
335  * Caution: PointCloud structures containing an RGB field have
336  * traditionally used packed float values to store RGB data. Storing a
337  * float as ASCII can introduce variations to the smallest bits, and
338  * thus significantly alter the data. This is a known issue, and the fix
339  * involves switching RGB data to be stored as a packed integer in
340  * future versions of PCL.
341  *
342  * As an intermediary solution, precision 8 is used, which guarantees lossless storage for RGB.
343  */
344  inline int
345  write (const std::string &file_name, const pcl::PCLPointCloud2 &cloud,
346  const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (),
347  const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (),
348  const bool binary = false)
349  {
350  if (binary)
351  return (writeBinary (file_name, cloud, origin, orientation));
352  else
353  return (writeASCII (file_name, cloud, origin, orientation, 8));
354  }
355 
356  /** \brief Save point cloud data to a PCD file containing n-D points
357  * \param[in] file_name the output file name
358  * \param[in] cloud the point cloud data message (boost shared pointer)
359  * \param[in] binary set to true if the file is to be written in a binary PCD format,
360  * false (default) for ASCII
361  * \param[in] origin the sensor acquisition origin
362  * \param[in] orientation the sensor acquisition orientation
363  *
364  * Caution: PointCloud structures containing an RGB field have
365  * traditionally used packed float values to store RGB data. Storing a
366  * float as ASCII can introduce variations to the smallest bits, and
367  * thus significantly alter the data. This is a known issue, and the fix
368  * involves switching RGB data to be stored as a packed integer in
369  * future versions of PCL.
370  */
371  inline int
372  write (const std::string &file_name, const pcl::PCLPointCloud2::ConstPtr &cloud,
373  const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (),
374  const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (),
375  const bool binary = false)
376  {
377  return (write (file_name, *cloud, origin, orientation, binary));
378  }
379 
380  /** \brief Save point cloud data to a PCD file containing n-D points, in BINARY format
381  * \param[in] file_name the output file name
382  * \param[in] cloud the point cloud data message
383  */
384  template <typename PointT> int
385  writeBinary (const std::string &file_name,
386  const pcl::PointCloud<PointT> &cloud);
387 
388  /** \brief Save point cloud data to a binary comprssed PCD file
389  * \param[in] file_name the output file name
390  * \param[in] cloud the point cloud data message
391  */
392  template <typename PointT> int
393  writeBinaryCompressed (const std::string &file_name,
394  const pcl::PointCloud<PointT> &cloud);
395 
396  /** \brief Save point cloud data to a PCD file containing n-D points, in BINARY format
397  * \param[in] file_name the output file name
398  * \param[in] cloud the point cloud data message
399  * \param[in] indices the set of point indices that we want written to disk
400  */
401  template <typename PointT> int
402  writeBinary (const std::string &file_name,
403  const pcl::PointCloud<PointT> &cloud,
404  const std::vector<int> &indices);
405 
406  /** \brief Save point cloud data to a PCD file containing n-D points, in ASCII format
407  * \param[in] file_name the output file name
408  * \param[in] cloud the point cloud data message
409  * \param[in] precision the specified output numeric stream precision (default: 8)
410  */
411  template <typename PointT> int
412  writeASCII (const std::string &file_name,
413  const pcl::PointCloud<PointT> &cloud,
414  const int precision = 8);
415 
416  /** \brief Save point cloud data to a PCD file containing n-D points, in ASCII format
417  * \param[in] file_name the output file name
418  * \param[in] cloud the point cloud data message
419  * \param[in] indices the set of point indices that we want written to disk
420  * \param[in] precision the specified output numeric stream precision (default: 8)
421  */
422  template <typename PointT> int
423  writeASCII (const std::string &file_name,
424  const pcl::PointCloud<PointT> &cloud,
425  const std::vector<int> &indices,
426  const int precision = 8);
427 
428  /** \brief Save point cloud data to a PCD file containing n-D points
429  * \param[in] file_name the output file name
430  * \param[in] cloud the pcl::PointCloud data
431  * \param[in] binary set to true if the file is to be written in a binary
432  * PCD format, false (default) for ASCII
433  *
434  * Caution: PointCloud structures containing an RGB field have
435  * traditionally used packed float values to store RGB data. Storing a
436  * float as ASCII can introduce variations to the smallest bits, and
437  * thus significantly alter the data. This is a known issue, and the fix
438  * involves switching RGB data to be stored as a packed integer in
439  * future versions of PCL.
440  */
441  template<typename PointT> inline int
442  write (const std::string &file_name,
443  const pcl::PointCloud<PointT> &cloud,
444  const bool binary = false)
445  {
446  if (binary)
447  return (writeBinary<PointT> (file_name, cloud));
448  else
449  return (writeASCII<PointT> (file_name, cloud));
450  }
451 
452  /** \brief Save point cloud data to a PCD file containing n-D points
453  * \param[in] file_name the output file name
454  * \param[in] cloud the pcl::PointCloud data
455  * \param[in] indices the set of point indices that we want written to disk
456  * \param[in] binary set to true if the file is to be written in a binary
457  * PCD format, false (default) for ASCII
458  *
459  * Caution: PointCloud structures containing an RGB field have
460  * traditionally used packed float values to store RGB data. Storing a
461  * float as ASCII can introduce variations to the smallest bits, and
462  * thus significantly alter the data. This is a known issue, and the fix
463  * involves switching RGB data to be stored as a packed integer in
464  * future versions of PCL.
465  */
466  template<typename PointT> inline int
467  write (const std::string &file_name,
468  const pcl::PointCloud<PointT> &cloud,
469  const std::vector<int> &indices,
470  bool binary = false)
471  {
472  if (binary)
473  return (writeBinary<PointT> (file_name, cloud, indices));
474  else
475  return (writeASCII<PointT> (file_name, cloud, indices));
476  }
477 
478  protected:
479  /** \brief Set permissions for file locking (Boost 1.49+).
480  * \param[in] file_name the file name to set permission for file locking
481  * \param[in,out] lock the file lock
482  */
483  void
484  setLockingPermissions (const std::string &file_name,
485  boost::interprocess::file_lock &lock);
486 
487  /** \brief Reset permissions for file locking (Boost 1.49+).
488  * \param[in] file_name the file name to reset permission for file locking
489  * \param[in,out] lock the file lock
490  */
491  void
492  resetLockingPermissions (const std::string &file_name,
493  boost::interprocess::file_lock &lock);
494 
495  private:
496  /** \brief Set to true if msync() should be called before munmap(). Prevents data loss on NFS systems. */
497  bool map_synchronization_;
498  };
499 
500  namespace io
501  {
502  /** \brief Load a PCD v.6 file into a templated PointCloud type.
503  *
504  * Any PCD files > v.6 will generate a warning as a
505  * pcl/PCLPointCloud2 message cannot hold the sensor origin.
506  *
507  * \param[in] file_name the name of the file to load
508  * \param[out] cloud the resultant templated point cloud
509  * \ingroup io
510  */
511  inline int
512  loadPCDFile (const std::string &file_name, pcl::PCLPointCloud2 &cloud)
513  {
514  pcl::PCDReader p;
515  return (p.read (file_name, cloud));
516  }
517 
518  /** \brief Load any PCD file into a templated PointCloud type.
519  * \param[in] file_name the name of the file to load
520  * \param[out] cloud the resultant templated point cloud
521  * \param[out] origin the sensor acquisition origin (only for > PCD_V7 - null if not present)
522  * \param[out] orientation the sensor acquisition orientation (only for >
523  * PCD_V7 - identity if not present)
524  * \ingroup io
525  */
526  inline int
527  loadPCDFile (const std::string &file_name, pcl::PCLPointCloud2 &cloud,
528  Eigen::Vector4f &origin, Eigen::Quaternionf &orientation)
529  {
530  pcl::PCDReader p;
531  int pcd_version;
532  return (p.read (file_name, cloud, origin, orientation, pcd_version));
533  }
534 
535  /** \brief Load any PCD file into a templated PointCloud type
536  * \param[in] file_name the name of the file to load
537  * \param[out] cloud the resultant templated point cloud
538  * \ingroup io
539  */
540  template<typename PointT> inline int
541  loadPCDFile (const std::string &file_name, pcl::PointCloud<PointT> &cloud)
542  {
543  pcl::PCDReader p;
544  return (p.read (file_name, cloud));
545  }
546 
547  /** \brief Save point cloud data to a PCD file containing n-D points
548  * \param[in] file_name the output file name
549  * \param[in] cloud the point cloud data message
550  * \param[in] origin the sensor acquisition origin
551  * \param[in] orientation the sensor acquisition orientation
552  * \param[in] binary_mode true for binary mode, false (default) for ASCII
553  *
554  * Caution: PointCloud structures containing an RGB field have
555  * traditionally used packed float values to store RGB data. Storing a
556  * float as ASCII can introduce variations to the smallest bits, and
557  * thus significantly alter the data. This is a known issue, and the fix
558  * involves switching RGB data to be stored as a packed integer in
559  * future versions of PCL.
560  * \ingroup io
561  */
562  inline int
563  savePCDFile (const std::string &file_name, const pcl::PCLPointCloud2 &cloud,
564  const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (),
565  const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (),
566  const bool binary_mode = false)
567  {
568  PCDWriter w;
569  return (w.write (file_name, cloud, origin, orientation, binary_mode));
570  }
571 
572  /** \brief Templated version for saving point cloud data to a PCD file
573  * containing a specific given cloud format
574  * \param[in] file_name the output file name
575  * \param[in] cloud the point cloud data message
576  * \param[in] binary_mode true for binary mode, false (default) for ASCII
577  *
578  * Caution: PointCloud structures containing an RGB field have
579  * traditionally used packed float values to store RGB data. Storing a
580  * float as ASCII can introduce variations to the smallest bits, and
581  * thus significantly alter the data. This is a known issue, and the fix
582  * involves switching RGB data to be stored as a packed integer in
583  * future versions of PCL.
584  * \ingroup io
585  */
586  template<typename PointT> inline int
587  savePCDFile (const std::string &file_name, const pcl::PointCloud<PointT> &cloud, bool binary_mode = false)
588  {
589  PCDWriter w;
590  return (w.write<PointT> (file_name, cloud, binary_mode));
591  }
592 
593  /**
594  * \brief Templated version for saving point cloud data to a PCD file
595  * containing a specific given cloud format.
596  *
597  * This version is to retain backwards compatibility.
598  * \param[in] file_name the output file name
599  * \param[in] cloud the point cloud data message
600  *
601  * Caution: PointCloud structures containing an RGB field have
602  * traditionally used packed float values to store RGB data. Storing a
603  * float as ASCII can introduce variations to the smallest bits, and
604  * thus significantly alter the data. This is a known issue, and the fix
605  * involves switching RGB data to be stored as a packed integer in
606  * future versions of PCL.
607  * \ingroup io
608  */
609  template<typename PointT> inline int
610  savePCDFileASCII (const std::string &file_name, const pcl::PointCloud<PointT> &cloud)
611  {
612  PCDWriter w;
613  return (w.write<PointT> (file_name, cloud, false));
614  }
615 
616  /**
617  * \brief Templated version for saving point cloud data to a PCD file
618  * containing a specific given cloud format. The resulting file will be an uncompressed binary.
619  *
620  * This version is to retain backwards compatibility.
621  * \param[in] file_name the output file name
622  * \param[in] cloud the point cloud data message
623  * \ingroup io
624  */
625  template<typename PointT> inline int
626  savePCDFileBinary (const std::string &file_name, const pcl::PointCloud<PointT> &cloud)
627  {
628  PCDWriter w;
629  return (w.write<PointT> (file_name, cloud, true));
630  }
631 
632  /**
633  * \brief Templated version for saving point cloud data to a PCD file
634  * containing a specific given cloud format
635  *
636  * \param[in] file_name the output file name
637  * \param[in] cloud the point cloud data message
638  * \param[in] indices the set of indices to save
639  * \param[in] binary_mode true for binary mode, false (default) for ASCII
640  *
641  * Caution: PointCloud structures containing an RGB field have
642  * traditionally used packed float values to store RGB data. Storing a
643  * float as ASCII can introduce variations to the smallest bits, and
644  * thus significantly alter the data. This is a known issue, and the fix
645  * involves switching RGB data to be stored as a packed integer in
646  * future versions of PCL.
647  * \ingroup io
648  */
649  template<typename PointT> int
650  savePCDFile (const std::string &file_name,
651  const pcl::PointCloud<PointT> &cloud,
652  const std::vector<int> &indices,
653  const bool binary_mode = false)
654  {
655  // Save the data
656  PCDWriter w;
657  return (w.write<PointT> (file_name, cloud, indices, binary_mode));
658  }
659 
660 
661  /**
662  * \brief Templated version for saving point cloud data to a PCD file
663  * containing a specific given cloud format. This method will write a compressed binary file.
664  *
665  * This version is to retain backwards compatibility.
666  * \param[in] file_name the output file name
667  * \param[in] cloud the point cloud data message
668  * \ingroup io
669  */
670  template<typename PointT> inline int
671  savePCDFileBinaryCompressed (const std::string &file_name, const pcl::PointCloud<PointT> &cloud)
672  {
673  PCDWriter w;
674  return (w.writeBinaryCompressed<PointT> (file_name, cloud));
675  }
676 
677  }
678 }
679 
680 #include <pcl/io/impl/pcd_io.hpp>
681 
682 #endif //#ifndef PCL_IO_PCD_IO_H_