Point Cloud Library (PCL)  1.11.0-dev
ply_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 #pragma once
41 
42 #include <pcl/memory.h>
43 #include <pcl/pcl_macros.h>
44 #include <pcl/io/boost.h>
45 #include <pcl/io/file_io.h>
46 #include <pcl/io/ply/ply_parser.h>
47 #include <pcl/PolygonMesh.h>
48 
49 #include <sstream>
50 #include <tuple>
51 
52 namespace pcl
53 {
54  /** \brief Point Cloud Data (PLY) file format reader.
55  *
56  * The PLY data format is organized in the following way:
57  * lines beginning with "comment" are treated as comments
58  * - ply
59  * - format [ascii|binary_little_endian|binary_big_endian] 1.0
60  * - element vertex COUNT
61  * - property float x
62  * - property float y
63  * - [property float z]
64  * - [property float normal_x]
65  * - [property float normal_y]
66  * - [property float normal_z]
67  * - [property uchar red]
68  * - [property uchar green]
69  * - [property uchar blue] ...
70  * - ascii/binary point coordinates
71  * - [element camera 1]
72  * - [property float view_px] ...
73  * - [element range_grid COUNT]
74  * - [property list uchar int vertex_indices]
75  * - end header
76  *
77  * \author Nizar Sallem
78  * \ingroup io
79  */
81  {
82  public:
83  enum
84  {
85  PLY_V0 = 0,
86  PLY_V1 = 1
87  };
88 
90  : origin_ (Eigen::Vector4f::Zero ())
91  , orientation_ (Eigen::Matrix3f::Zero ())
92  , cloud_ ()
93  , vertex_count_ (0)
94  , vertex_offset_before_ (0)
95  , range_grid_ (nullptr)
96  , rgb_offset_before_ (0)
97  , do_resize_ (false)
98  , polygons_ (nullptr)
99  , r_(0), g_(0), b_(0)
100  , a_(0), rgba_(0)
101  {}
102 
103  PLYReader (const PLYReader &p)
104  : origin_ (Eigen::Vector4f::Zero ())
105  , orientation_ (Eigen::Matrix3f::Zero ())
106  , cloud_ ()
107  , vertex_count_ (0)
108  , vertex_offset_before_ (0)
109  , range_grid_ (nullptr)
110  , rgb_offset_before_ (0)
111  , do_resize_ (false)
112  , polygons_ (nullptr)
113  , r_(0), g_(0), b_(0)
114  , a_(0), rgba_(0)
115  {
116  *this = p;
117  }
118 
119  PLYReader&
120  operator = (const PLYReader &p)
121  {
122  origin_ = p.origin_;
123  orientation_ = p.orientation_;
124  range_grid_ = p.range_grid_;
125  polygons_ = p.polygons_;
126  return (*this);
127  }
128 
129  ~PLYReader () { delete range_grid_; }
130  /** \brief Read a point cloud data header from a PLY file.
131  *
132  * Load only the meta information (number of points, their types, etc),
133  * and not the points themselves, from a given PLY file. Useful for fast
134  * evaluation of the underlying data structure.
135  *
136  * Returns:
137  * * < 0 (-1) on error
138  * * > 0 on success
139  * \param[in] file_name the name of the file to load
140  * \param[out] cloud the resultant point cloud dataset (only the header will be filled)
141  * \param[in] origin the sensor data acquisition origin (translation)
142  * \param[in] orientation the sensor data acquisition origin (rotation)
143  * \param[out] ply_version the PLY version read from the file
144  * \param[out] data_type the type of PLY data stored in the file
145  * \param[out] data_idx the data index
146  * \param[in] offset the offset in the file where to expect the true header to begin.
147  * One usage example for setting the offset parameter is for reading
148  * data from a TAR "archive containing multiple files: TAR files always
149  * add a 512 byte header in front of the actual file, so set the offset
150  * to the next byte after the header (e.g., 513).
151  */
152  int
153  readHeader (const std::string &file_name, pcl::PCLPointCloud2 &cloud,
154  Eigen::Vector4f &origin, Eigen::Quaternionf &orientation,
155  int &ply_version, int &data_type, unsigned int &data_idx, const int offset = 0) override;
156 
157  /** \brief Read a point cloud data from a PLY file and store it into a pcl/PCLPointCloud2.
158  * \param[in] file_name the name of the file containing the actual PointCloud data
159  * \param[out] cloud the resultant PointCloud message read from disk
160  * \param[in] origin the sensor data acquisition origin (translation)
161  * \param[in] orientation the sensor data acquisition origin (rotation)
162  * \param[out] ply_version the PLY version read from the file
163  * \param[in] offset the offset in the file where to expect the true header to begin.
164  * One usage example for setting the offset parameter is for reading
165  * data from a TAR "archive containing multiple files: TAR files always
166  * add a 512 byte header in front of the actual file, so set the offset
167  * to the next byte after the header (e.g., 513).
168  */
169  int
170  read (const std::string &file_name, pcl::PCLPointCloud2 &cloud,
171  Eigen::Vector4f &origin, Eigen::Quaternionf &orientation, int& ply_version, const int offset = 0) override;
172 
173  /** \brief Read a point cloud data from a PLY file and store it into a pcl/PCLPointCloud2.
174  * \note This function is provided for backwards compatibility only
175  * \param[in] file_name the name of the file containing the actual PointCloud data
176  * \param[out] cloud the resultant PointCloud message read from disk
177  * \param[in] offset the offset in the file where to expect the true header to begin.
178  * One usage example for setting the offset parameter is for reading
179  * data from a TAR "archive containing multiple files: TAR files always
180  * add a 512 byte header in front of the actual file, so set the offset
181  * to the next byte after the header (e.g., 513).
182  */
183  inline int
184  read (const std::string &file_name, pcl::PCLPointCloud2 &cloud, const int offset = 0)
185  {
186  Eigen::Vector4f origin;
187  Eigen::Quaternionf orientation;
188  int ply_version;
189  return read (file_name, cloud, origin, orientation, ply_version, offset);
190  }
191 
192  /** \brief Read a point cloud data from any PLY file, and convert it to the given template format.
193  * \param[in] file_name the name of the file containing the actual PointCloud data
194  * \param[out] cloud the resultant PointCloud message read from disk
195  * \param[in] offset the offset in the file where to expect the true header to begin.
196  * One usage example for setting the offset parameter is for reading
197  * data from a TAR "archive containing multiple files: TAR files always
198  * add a 512 byte header in front of the actual file, so set the offset
199  * to the next byte after the header (e.g., 513).
200  */
201  template<typename PointT> inline int
202  read (const std::string &file_name, pcl::PointCloud<PointT> &cloud, const int offset = 0)
203  {
204  pcl::PCLPointCloud2 blob;
205  int ply_version;
206  int res = read (file_name, blob, cloud.sensor_origin_, cloud.sensor_orientation_,
207  ply_version, offset);
208 
209  // Exit in case of error
210  if (res < 0)
211  return (res);
212  pcl::fromPCLPointCloud2 (blob, cloud);
213  return (0);
214  }
215 
216  /** \brief Read a point cloud data from a PLY file and store it into a pcl/PolygonMesh.
217  *
218  * \param[in] file_name the name of the file containing the actual PointCloud data
219  * \param[out] mesh the resultant PolygonMesh message read from disk
220  * \param[in] origin the sensor data acquisition origin (translation)
221  * \param[in] orientation the sensor data acquisition origin (rotation)
222  * \param[out] ply_version the PLY version read from the file
223  * \param[in] offset the offset in the file where to expect the true header to begin.
224  * One usage example for setting the offset parameter is for reading
225  * data from a TAR "archive containing multiple files: TAR files always
226  * add a 512 byte header in front of the actual file, so set the offset
227  * to the next byte after the header (e.g., 513).
228  */
229  int
230  read (const std::string &file_name, pcl::PolygonMesh &mesh,
231  Eigen::Vector4f &origin, Eigen::Quaternionf &orientation,
232  int& ply_version, const int offset = 0);
233 
234  /** \brief Read a point cloud data from a PLY file and store it into a pcl/PolygonMesh.
235  *
236  * \param[in] file_name the name of the file containing the actual PointCloud data
237  * \param[out] mesh the resultant PolygonMesh message read from disk
238  * \param[in] offset the offset in the file where to expect the true header to begin.
239  * One usage example for setting the offset parameter is for reading
240  * data from a TAR "archive containing multiple files: TAR files always
241  * add a 512 byte header in front of the actual file, so set the offset
242  * to the next byte after the header (e.g., 513).
243  */
244  int
245  read (const std::string &file_name, pcl::PolygonMesh &mesh, const int offset = 0);
246 
247  private:
249 
250  bool
251  parse (const std::string& istream_filename);
252 
253  /** \brief Info callback function
254  * \param[in] filename PLY file read
255  * \param[in] line_number line triggering the callback
256  * \param[in] message information message
257  */
258  void
259  infoCallback (const std::string& filename, std::size_t line_number, const std::string& message)
260  {
261  PCL_DEBUG ("[pcl::PLYReader] %s:%lu: %s\n", filename.c_str (), line_number, message.c_str ());
262  }
263 
264  /** \brief Warning callback function
265  * \param[in] filename PLY file read
266  * \param[in] line_number line triggering the callback
267  * \param[in] message warning message
268  */
269  void
270  warningCallback (const std::string& filename, std::size_t line_number, const std::string& message)
271  {
272  PCL_WARN ("[pcl::PLYReader] %s:%lu: %s\n", filename.c_str (), line_number, message.c_str ());
273  }
274 
275  /** \brief Error callback function
276  * \param[in] filename PLY file read
277  * \param[in] line_number line triggering the callback
278  * \param[in] message error message
279  */
280  void
281  errorCallback (const std::string& filename, std::size_t line_number, const std::string& message)
282  {
283  PCL_ERROR ("[pcl::PLYReader] %s:%lu: %s\n", filename.c_str (), line_number, message.c_str ());
284  }
285 
286  /** \brief function called when the keyword element is parsed
287  * \param[in] element_name element name
288  * \param[in] count number of instances
289  */
290  std::tuple<std::function<void ()>, std::function<void ()> >
291  elementDefinitionCallback (const std::string& element_name, std::size_t count);
292 
293  bool
294  endHeaderCallback ();
295 
296  /** \brief function called when a scalar property is parsed
297  * \param[in] element_name element name to which the property belongs
298  * \param[in] property_name property name
299  */
300  template <typename ScalarType> std::function<void (ScalarType)>
301  scalarPropertyDefinitionCallback (const std::string& element_name, const std::string& property_name);
302 
303  /** \brief function called when a list property is parsed
304  * \param[in] element_name element name to which the property belongs
305  * \param[in] property_name list property name
306  */
307  template <typename SizeType, typename ScalarType>
308  std::tuple<std::function<void (SizeType)>, std::function<void (ScalarType)>, std::function<void ()> >
309  listPropertyDefinitionCallback (const std::string& element_name, const std::string& property_name);
310 
311  /** \brief function called at the beginning of a list property parsing.
312  * \param[in] size number of elements in the list
313  */
314  template <typename SizeType> void
315  vertexListPropertyBeginCallback (const std::string& property_name, SizeType size);
316 
317  /** \brief function called when a list element is parsed.
318  * \param[in] value the list's element value
319  */
320  template <typename ContentType> void
321  vertexListPropertyContentCallback (ContentType value);
322 
323  /** \brief function called at the end of a list property parsing */
324  inline void
325  vertexListPropertyEndCallback ();
326 
327  /** Callback function for an anonymous vertex scalar property.
328  * Writes down a double value in cloud data.
329  * param[in] value double value parsed
330  */
331  template<typename Scalar> void
332  vertexScalarPropertyCallback (Scalar value);
333 
334  /** Callback function for vertex RGB color.
335  * This callback is in charge of packing red green and blue in a single int
336  * before writing it down in cloud data.
337  * param[in] color_name color name in {red, green, blue}
338  * param[in] color value of {red, green, blue} property
339  */
340  inline void
341  vertexColorCallback (const std::string& color_name, pcl::io::ply::uint8 color);
342 
343  /** Callback function for vertex intensity.
344  * converts intensity from int to float before writing it down in cloud data.
345  * param[in] intensity
346  */
347  inline void
348  vertexIntensityCallback (pcl::io::ply::uint8 intensity);
349 
350  /** Callback function for vertex alpha.
351  * extracts RGB value, append alpha and put it back
352  * param[in] alpha
353  */
354  inline void
355  vertexAlphaCallback (pcl::io::ply::uint8 alpha);
356 
357  /** Callback function for origin x component.
358  * param[in] value origin x value
359  */
360  inline void
361  originXCallback (const float& value) { origin_[0] = value; }
362 
363  /** Callback function for origin y component.
364  * param[in] value origin y value
365  */
366  inline void
367  originYCallback (const float& value) { origin_[1] = value; }
368 
369  /** Callback function for origin z component.
370  * param[in] value origin z value
371  */
372  inline void
373  originZCallback (const float& value) { origin_[2] = value; }
374 
375  /** Callback function for orientation x axis x component.
376  * param[in] value orientation x axis x value
377  */
378  inline void
379  orientationXaxisXCallback (const float& value) { orientation_ (0,0) = value; }
380 
381  /** Callback function for orientation x axis y component.
382  * param[in] value orientation x axis y value
383  */
384  inline void
385  orientationXaxisYCallback (const float& value) { orientation_ (0,1) = value; }
386 
387  /** Callback function for orientation x axis z component.
388  * param[in] value orientation x axis z value
389  */
390  inline void
391  orientationXaxisZCallback (const float& value) { orientation_ (0,2) = value; }
392 
393  /** Callback function for orientation y axis x component.
394  * param[in] value orientation y axis x value
395  */
396  inline void
397  orientationYaxisXCallback (const float& value) { orientation_ (1,0) = value; }
398 
399  /** Callback function for orientation y axis y component.
400  * param[in] value orientation y axis y value
401  */
402  inline void
403  orientationYaxisYCallback (const float& value) { orientation_ (1,1) = value; }
404 
405  /** Callback function for orientation y axis z component.
406  * param[in] value orientation y axis z value
407  */
408  inline void
409  orientationYaxisZCallback (const float& value) { orientation_ (1,2) = value; }
410 
411  /** Callback function for orientation z axis x component.
412  * param[in] value orientation z axis x value
413  */
414  inline void
415  orientationZaxisXCallback (const float& value) { orientation_ (2,0) = value; }
416 
417  /** Callback function for orientation z axis y component.
418  * param[in] value orientation z axis y value
419  */
420  inline void
421  orientationZaxisYCallback (const float& value) { orientation_ (2,1) = value; }
422 
423  /** Callback function for orientation z axis z component.
424  * param[in] value orientation z axis z value
425  */
426  inline void
427  orientationZaxisZCallback (const float& value) { orientation_ (2,2) = value; }
428 
429  /** Callback function to set the cloud height
430  * param[in] height cloud height
431  */
432  inline void
433  cloudHeightCallback (const int &height) { cloud_->height = height; }
434 
435  /** Callback function to set the cloud width
436  * param[in] width cloud width
437  */
438  inline void
439  cloudWidthCallback (const int &width) { cloud_->width = width; }
440 
441  /** Append a scalar property to the cloud fields.
442  * param[in] name property name
443  * param[in] count property count: 1 for scalar properties and higher for a
444  * list property.
445  */
446  template<typename Scalar> void
447  appendScalarProperty (const std::string& name, const std::size_t& count = 1);
448 
449  /** Amend property from cloud fields identified by \a old_name renaming
450  * it \a new_name.
451  * param[in] old_name property old name
452  * param[in] new_name property new name
453  */
454  void
455  amendProperty (const std::string& old_name, const std::string& new_name, std::uint8_t datatype = 0);
456 
457  /** Callback function for the begin of vertex line */
458  void
459  vertexBeginCallback ();
460 
461  /** Callback function for the end of vertex line */
462  void
463  vertexEndCallback ();
464 
465  /** Callback function for the begin of range_grid line */
466  void
467  rangeGridBeginCallback ();
468 
469  /** Callback function for the begin of range_grid vertex_indices property
470  * param[in] size vertex_indices list size
471  */
472  void
473  rangeGridVertexIndicesBeginCallback (pcl::io::ply::uint8 size);
474 
475  /** Callback function for each range_grid vertex_indices element
476  * param[in] vertex_index index of the vertex in vertex_indices
477  */
478  void
479  rangeGridVertexIndicesElementCallback (pcl::io::ply::int32 vertex_index);
480 
481  /** Callback function for the end of a range_grid vertex_indices property */
482  void
483  rangeGridVertexIndicesEndCallback ();
484 
485  /** Callback function for the end of a range_grid element end */
486  void
487  rangeGridEndCallback ();
488 
489  /** Callback function for obj_info */
490  void
491  objInfoCallback (const std::string& line);
492 
493  /** Callback function for the begin of face line */
494  void
495  faceBeginCallback ();
496 
497  /** Callback function for the begin of face vertex_indices property
498  * param[in] size vertex_indices list size
499  */
500  void
501  faceVertexIndicesBeginCallback (pcl::io::ply::uint8 size);
502 
503  /** Callback function for each face vertex_indices element
504  * param[in] vertex_index index of the vertex in vertex_indices
505  */
506  void
507  faceVertexIndicesElementCallback (pcl::io::ply::int32 vertex_index);
508 
509  /** Callback function for the end of a face vertex_indices property */
510  void
511  faceVertexIndicesEndCallback ();
512 
513  /** Callback function for the end of a face element end */
514  void
515  faceEndCallback ();
516 
517  /// origin
518  Eigen::Vector4f origin_;
519 
520  /// orientation
521  Eigen::Matrix3f orientation_;
522 
523  //vertex element artifacts
524  pcl::PCLPointCloud2 *cloud_;
525  std::size_t vertex_count_;
526  int vertex_offset_before_;
527  //range element artifacts
528  std::vector<std::vector <int> > *range_grid_;
529  std::size_t rgb_offset_before_;
530  bool do_resize_;
531  //face element artifact
532  std::vector<pcl::Vertices> *polygons_;
533  public:
535 
536  private:
537  // RGB values stored by vertexColorCallback()
538  std::int32_t r_, g_, b_;
539  // Color values stored by vertexAlphaCallback()
540  std::uint32_t a_, rgba_;
541  };
542 
543  /** \brief Point Cloud Data (PLY) file format writer.
544  * \author Nizar Sallem
545  * \ingroup io
546  */
548  {
549  public:
550  ///Constructor
551  PLYWriter () {};
552 
553  ///Destructor
554  ~PLYWriter () {};
555 
556  /** \brief Generate the header of a PLY v.7 file format
557  * \param[in] cloud the point cloud data message
558  * \param[in] origin the sensor data acquisition origin (translation)
559  * \param[in] orientation the sensor data acquisition origin (rotation)
560  * \param[in] valid_points number of valid points (finite ones for range_grid and
561  * all of them for camer)
562  * \param[in] use_camera if set to true then PLY file will use element camera else
563  * element range_grid will be used.
564  */
565  inline std::string
567  const Eigen::Vector4f &origin,
568  const Eigen::Quaternionf &orientation,
569  int valid_points,
570  bool use_camera = true)
571  {
572  return (generateHeader (cloud, origin, orientation, true, use_camera, valid_points));
573  }
574 
575  /** \brief Generate the header of a PLY v.7 file format
576  * \param[in] cloud the point cloud data message
577  * \param[in] origin the sensor data acquisition origin (translation)
578  * \param[in] orientation the sensor data acquisition origin (rotation)
579  * \param[in] valid_points number of valid points (finite ones for range_grid and
580  * all of them for camer)
581  * \param[in] use_camera if set to true then PLY file will use element camera else
582  * element range_grid will be used.
583  */
584  inline std::string
586  const Eigen::Vector4f &origin,
587  const Eigen::Quaternionf &orientation,
588  int valid_points,
589  bool use_camera = true)
590  {
591  return (generateHeader (cloud, origin, orientation, false, use_camera, valid_points));
592  }
593 
594  /** \brief Save point cloud data to a PLY file containing n-D points, in ASCII format
595  * \param[in] file_name the output file name
596  * \param[in] cloud the point cloud data message
597  * \param[in] origin the sensor data acquisition origin (translation)
598  * \param[in] orientation the sensor data acquisition origin (rotation)
599  * \param[in] precision the specified output numeric stream precision (default: 8)
600  * \param[in] use_camera if set to true then PLY file will use element camera else
601  * element range_grid will be used.
602  */
603  int
604  writeASCII (const std::string &file_name, const pcl::PCLPointCloud2 &cloud,
605  const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (),
606  const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (),
607  int precision = 8,
608  bool use_camera = true);
609 
610  /** \brief Save point cloud data to a PLY file containing n-D points, in BINARY format
611  * \param[in] file_name the output file name
612  * \param[in] cloud the point cloud data message
613  * \param[in] origin the sensor data acquisition origin (translation)
614  * \param[in] orientation the sensor data acquisition origin (rotation)
615  * \param[in] use_camera if set to true then PLY file will use element camera else
616  * element range_grid will be used
617  */
618  int
619  writeBinary (const std::string &file_name, const pcl::PCLPointCloud2 &cloud,
620  const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (),
621  const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (),
622  bool use_camera = true);
623 
624  /** \brief Save point cloud data to a PLY file containing n-D points
625  * \param[in] file_name the output file name
626  * \param[in] cloud the point cloud data message
627  * \param[in] origin the sensor acquisition origin
628  * \param[in] orientation the sensor acquisition orientation
629  * \param[in] binary set to true if the file is to be written in a binary
630  * PLY format, false (default) for ASCII
631  */
632  inline int
633  write (const std::string &file_name, const pcl::PCLPointCloud2 &cloud,
634  const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (),
635  const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (),
636  const bool binary = false) override
637  {
638  if (binary)
639  return (this->writeBinary (file_name, cloud, origin, orientation, true));
640  return (this->writeASCII (file_name, cloud, origin, orientation, 8, true));
641  }
642 
643  /** \brief Save point cloud data to a PLY file containing n-D points
644  * \param[in] file_name the output file name
645  * \param[in] cloud the point cloud data message
646  * \param[in] origin the sensor acquisition origin
647  * \param[in] orientation the sensor acquisition orientation
648  * \param[in] binary set to true if the file is to be written in a binary
649  * PLY format, false (default) for ASCII
650  * \param[in] use_camera set to true to use camera element and false to
651  * use range_grid element
652  */
653  inline int
654  write (const std::string &file_name, const pcl::PCLPointCloud2 &cloud,
655  const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (),
656  const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (),
657  bool binary = false,
658  bool use_camera = true)
659  {
660  if (binary)
661  return (this->writeBinary (file_name, cloud, origin, orientation, use_camera));
662  return (this->writeASCII (file_name, cloud, origin, orientation, 8, use_camera));
663  }
664 
665  /** \brief Save point cloud data to a PLY file containing n-D points
666  * \param[in] file_name the output file name
667  * \param[in] cloud the point cloud data message (boost shared pointer)
668  * \param[in] origin the sensor acquisition origin
669  * \param[in] orientation the sensor acquisition orientation
670  * \param[in] binary set to true if the file is to be written in a binary
671  * PLY format, false (default) for ASCII
672  * \param[in] use_camera set to true to use camera element and false to
673  * use range_grid element
674  */
675  inline int
676  write (const std::string &file_name, const pcl::PCLPointCloud2::ConstPtr &cloud,
677  const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (),
678  const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (),
679  bool binary = false,
680  bool use_camera = true)
681  {
682  return (write (file_name, *cloud, origin, orientation, binary, use_camera));
683  }
684 
685  /** \brief Save point cloud data to a PLY file containing n-D points
686  * \param[in] file_name the output file name
687  * \param[in] cloud the pcl::PointCloud data
688  * \param[in] binary set to true if the file is to be written in a binary
689  * PLY format, false (default) for ASCII
690  * \param[in] use_camera set to true to use camera element and false to
691  * use range_grid element
692  */
693  template<typename PointT> inline int
694  write (const std::string &file_name,
695  const pcl::PointCloud<PointT> &cloud,
696  bool binary = false,
697  bool use_camera = true)
698  {
699  Eigen::Vector4f origin = cloud.sensor_origin_;
700  Eigen::Quaternionf orientation = cloud.sensor_orientation_;
701 
702  pcl::PCLPointCloud2 blob;
703  pcl::toPCLPointCloud2 (cloud, blob);
704 
705  // Save the data
706  return (this->write (file_name, blob, origin, orientation, binary, use_camera));
707  }
708 
709  private:
710  /** \brief Generate a PLY header.
711  * \param[in] cloud the input point cloud
712  * \param[in] binary whether the PLY file should be saved as binary data (true) or ascii (false)
713  */
714  std::string
715  generateHeader (const pcl::PCLPointCloud2 &cloud,
716  const Eigen::Vector4f &origin,
717  const Eigen::Quaternionf &orientation,
718  bool binary,
719  bool use_camera,
720  int valid_points);
721 
722  void
723  writeContentWithCameraASCII (int nr_points,
724  int point_size,
725  const pcl::PCLPointCloud2 &cloud,
726  const Eigen::Vector4f &origin,
727  const Eigen::Quaternionf &orientation,
728  std::ofstream& fs);
729 
730  void
731  writeContentWithRangeGridASCII (int nr_points,
732  int point_size,
733  const pcl::PCLPointCloud2 &cloud,
734  std::ostringstream& fs,
735  int& nb_valid_points);
736  };
737 
738  namespace io
739  {
740  /** \brief Load a PLY v.6 file into a templated PointCloud type.
741  *
742  * Any PLY files containing sensor data will generate a warning as a
743  * pcl/PCLPointCloud2 message cannot hold the sensor origin.
744  *
745  * \param[in] file_name the name of the file to load
746  * \param[in] cloud the resultant templated point cloud
747  * \ingroup io
748  */
749  inline int
750  loadPLYFile (const std::string &file_name, pcl::PCLPointCloud2 &cloud)
751  {
752  pcl::PLYReader p;
753  return (p.read (file_name, cloud));
754  }
755 
756  /** \brief Load any PLY file into a templated PointCloud type.
757  * \param[in] file_name the name of the file to load
758  * \param[in] cloud the resultant templated point cloud
759  * \param[in] origin the sensor acquisition origin (only for > PLY_V7 - null if not present)
760  * \param[in] orientation the sensor acquisition orientation if available,
761  * identity if not present
762  * \ingroup io
763  */
764  inline int
765  loadPLYFile (const std::string &file_name, pcl::PCLPointCloud2 &cloud,
766  Eigen::Vector4f &origin, Eigen::Quaternionf &orientation)
767  {
768  pcl::PLYReader p;
769  int ply_version;
770  return (p.read (file_name, cloud, origin, orientation, ply_version));
771  }
772 
773  /** \brief Load any PLY file into a templated PointCloud type
774  * \param[in] file_name the name of the file to load
775  * \param[in] cloud the resultant templated point cloud
776  * \ingroup io
777  */
778  template<typename PointT> inline int
779  loadPLYFile (const std::string &file_name, pcl::PointCloud<PointT> &cloud)
780  {
781  pcl::PLYReader p;
782  return (p.read (file_name, cloud));
783  }
784 
785  /** \brief Load a PLY file into a PolygonMesh type.
786  *
787  * Any PLY files containing sensor data will generate a warning as a
788  * pcl/PolygonMesh message cannot hold the sensor origin.
789  *
790  * \param[in] file_name the name of the file to load
791  * \param[in] mesh the resultant polygon mesh
792  * \ingroup io
793  */
794  inline int
795  loadPLYFile (const std::string &file_name, pcl::PolygonMesh &mesh)
796  {
797  pcl::PLYReader p;
798  return (p.read (file_name, mesh));
799  }
800 
801  /** \brief Save point cloud data to a PLY file containing n-D points
802  * \param[in] file_name the output file name
803  * \param[in] cloud the point cloud data message
804  * \param[in] origin the sensor data acquisition origin (translation)
805  * \param[in] orientation the sensor data acquisition origin (rotation)
806  * \param[in] binary_mode true for binary mode, false (default) for ASCII
807  * \param[in] use_camera
808  * \ingroup io
809  */
810  inline int
811  savePLYFile (const std::string &file_name, const pcl::PCLPointCloud2 &cloud,
812  const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (),
813  const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (),
814  bool binary_mode = false, bool use_camera = true)
815  {
816  PLYWriter w;
817  return (w.write (file_name, cloud, origin, orientation, binary_mode, use_camera));
818  }
819 
820  /** \brief Templated version for saving point cloud data to a PLY file
821  * containing a specific given cloud format
822  * \param[in] file_name the output file name
823  * \param[in] cloud the point cloud data message
824  * \param[in] binary_mode true for binary mode, false (default) for ASCII
825  * \ingroup io
826  */
827  template<typename PointT> inline int
828  savePLYFile (const std::string &file_name, const pcl::PointCloud<PointT> &cloud, bool binary_mode = false)
829  {
830  PLYWriter w;
831  return (w.write<PointT> (file_name, cloud, binary_mode));
832  }
833 
834  /** \brief Templated version for saving point cloud data to a PLY file
835  * containing a specific given cloud format.
836  * \param[in] file_name the output file name
837  * \param[in] cloud the point cloud data message
838  * \ingroup io
839  */
840  template<typename PointT> inline int
841  savePLYFileASCII (const std::string &file_name, const pcl::PointCloud<PointT> &cloud)
842  {
843  PLYWriter w;
844  return (w.write<PointT> (file_name, cloud, false));
845  }
846 
847  /** \brief Templated version for saving point cloud data to a PLY file containing a specific given cloud format.
848  * \param[in] file_name the output file name
849  * \param[in] cloud the point cloud data message
850  * \ingroup io
851  */
852  template<typename PointT> inline int
853  savePLYFileBinary (const std::string &file_name, const pcl::PointCloud<PointT> &cloud)
854  {
855  PLYWriter w;
856  return (w.write<PointT> (file_name, cloud, true));
857  }
858 
859  /** \brief Templated version for saving point cloud data to a PLY file containing a specific given cloud format
860  * \param[in] file_name the output file name
861  * \param[in] cloud the point cloud data message
862  * \param[in] indices the set of indices to save
863  * \param[in] binary_mode true for binary mode, false (default) for ASCII
864  * \ingroup io
865  */
866  template<typename PointT> int
867  savePLYFile (const std::string &file_name, const pcl::PointCloud<PointT> &cloud,
868  const std::vector<int> &indices, bool binary_mode = false)
869  {
870  // Copy indices to a new point cloud
871  pcl::PointCloud<PointT> cloud_out;
872  copyPointCloud (cloud, indices, cloud_out);
873  // Save the data
874  PLYWriter w;
875  return (w.write<PointT> (file_name, cloud_out, binary_mode));
876  }
877 
878  /** \brief Saves a PolygonMesh in ascii PLY format.
879  * \param[in] file_name the name of the file to write to disk
880  * \param[in] mesh the polygonal mesh to save
881  * \param[in] precision the output ASCII precision default 5
882  * \ingroup io
883  */
884  PCL_EXPORTS int
885  savePLYFile (const std::string &file_name, const pcl::PolygonMesh &mesh, unsigned precision = 5);
886 
887  /** \brief Saves a PolygonMesh in binary PLY format.
888  * \param[in] file_name the name of the file to write to disk
889  * \param[in] mesh the polygonal mesh to save
890  * \ingroup io
891  */
892  PCL_EXPORTS int
893  savePLYFileBinary (const std::string &file_name, const pcl::PolygonMesh &mesh);
894  }
895 }
pcl_macros.h
Defines all the PCL and non-PCL macros used.
pcl::PLYWriter::generateHeaderBinary
std::string generateHeaderBinary(const pcl::PCLPointCloud2 &cloud, const Eigen::Vector4f &origin, const Eigen::Quaternionf &orientation, int valid_points, bool use_camera=true)
Generate the header of a PLY v.7 file format.
Definition: ply_io.h:566
pcl
Definition: convolution.h:46
pcl::uint32_t
std::uint32_t uint32_t
Definition: types.h:58
Eigen
Definition: bfgs.h:9
pcl::int32_t
std::int32_t int32_t
Definition: types.h:59
pcl::PLYWriter
Point Cloud Data (PLY) file format writer.
Definition: ply_io.h:547
pcl::io::savePLYFile
int savePLYFile(const std::string &file_name, const pcl::PCLPointCloud2 &cloud, const Eigen::Vector4f &origin=Eigen::Vector4f::Zero(), const Eigen::Quaternionf &orientation=Eigen::Quaternionf::Identity(), bool binary_mode=false, bool use_camera=true)
Save point cloud data to a PLY file containing n-D points.
Definition: ply_io.h:811
pcl::PLYWriter::PLYWriter
PLYWriter()
Constructor.
Definition: ply_io.h:551
pcl::PointCloud
PointCloud represents the base class in PCL for storing collections of 3D points.
Definition: projection_matrix.h:53
pcl::PLYReader::PLYReader
PLYReader()
Definition: ply_io.h:89
pcl::PointXYZRGB
A point structure representing Euclidean xyz coordinates, and the RGB color.
Definition: point_types.hpp:628
pcl::io::ply::uint8
std::uint8_t uint8
Definition: ply.h:61
pcl::copyPointCloud
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:121
pcl::FileWriter
Point Cloud Data (FILE) file format writer.
Definition: file_io.h:161
pcl::read
void read(std::istream &stream, Type &value)
Function for reading data from a stream.
Definition: region_xy.h:46
pcl::io::savePLYFileBinary
int savePLYFileBinary(const std::string &file_name, const pcl::PointCloud< PointT > &cloud)
Templated version for saving point cloud data to a PLY file containing a specific given cloud format.
Definition: ply_io.h:853
pcl::PLYReader::read
int read(const std::string &file_name, pcl::PCLPointCloud2 &cloud, Eigen::Vector4f &origin, Eigen::Quaternionf &orientation, int &ply_version, const int offset=0) override
Read a point cloud data from a PLY file and store it into a pcl/PCLPointCloud2.
pcl::PCLPointCloud2::ConstPtr
shared_ptr< const ::pcl::PCLPointCloud2 > ConstPtr
Definition: PCLPointCloud2.h:35
pcl::PLYReader
Point Cloud Data (PLY) file format reader.
Definition: ply_io.h:80
pcl::PLYReader::PLYReader
PLYReader(const PLYReader &p)
Definition: ply_io.h:103
pcl::io::savePLYFileASCII
int savePLYFileASCII(const std::string &file_name, const pcl::PointCloud< PointT > &cloud)
Templated version for saving point cloud data to a PLY file containing a specific given cloud format.
Definition: ply_io.h:841
pcl::PolygonMesh
Definition: PolygonMesh.h:15
pcl::PLYReader::~PLYReader
~PLYReader()
Definition: ply_io.h:129
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::FileReader
Point Cloud Data (FILE) file format reader interface.
Definition: file_io.h:55
pcl::io::ply::ply_parser
Class ply_parser parses a PLY file and generates appropriate atomic parsers for the body.
Definition: ply_parser.h:69
pcl::PointCloud::sensor_origin_
Eigen::Vector4f sensor_origin_
Sensor acquisition pose (origin/translation).
Definition: point_cloud.h:422
pcl::PointCloud::sensor_orientation_
Eigen::Quaternionf sensor_orientation_
Sensor acquisition pose (rotation).
Definition: point_cloud.h:424
pcl::PCLPointCloud2
Definition: PCLPointCloud2.h:15
pcl::io::loadPLYFile
int loadPLYFile(const std::string &file_name, pcl::PCLPointCloud2 &cloud)
Load a PLY v.6 file into a templated PointCloud type.
Definition: ply_io.h:750
pcl::PLYWriter::write
int write(const std::string &file_name, const pcl::PointCloud< PointT > &cloud, bool binary=false, bool use_camera=true)
Save point cloud data to a PLY file containing n-D points.
Definition: ply_io.h:694
pcl::PLYWriter::~PLYWriter
~PLYWriter()
Destructor.
Definition: ply_io.h:554
pcl::write
void write(std::ostream &stream, Type value)
Function for writing data to a stream.
Definition: region_xy.h:63
pcl::io::ply::int32
std::int32_t int32
Definition: ply.h:60
pcl::uint8_t
std::uint8_t uint8_t
Definition: types.h:54
pcl::PLYWriter::write
int write(const std::string &file_name, const pcl::PCLPointCloud2::ConstPtr &cloud, const Eigen::Vector4f &origin=Eigen::Vector4f::Zero(), const Eigen::Quaternionf &orientation=Eigen::Quaternionf::Identity(), bool binary=false, bool use_camera=true)
Save point cloud data to a PLY file containing n-D points.
Definition: ply_io.h:676
pcl::PLYReader::read
int read(const std::string &file_name, pcl::PointCloud< PointT > &cloud, const int offset=0)
Read a point cloud data from any PLY file, and convert it to the given template format.
Definition: ply_io.h:202
pcl::PLYWriter::write
int write(const std::string &file_name, const pcl::PCLPointCloud2 &cloud, const Eigen::Vector4f &origin=Eigen::Vector4f::Zero(), const Eigen::Quaternionf &orientation=Eigen::Quaternionf::Identity(), const bool binary=false) override
Save point cloud data to a PLY file containing n-D points.
Definition: ply_io.h:633
pcl::toPCLPointCloud2
void toPCLPointCloud2(const pcl::PointCloud< PointT > &cloud, pcl::PCLPointCloud2 &msg)
Convert a pcl::PointCloud<T> object to a PCLPointCloud2 binary data blob.
Definition: conversions.h:241
pcl::PLYWriter::write
int write(const std::string &file_name, const pcl::PCLPointCloud2 &cloud, const Eigen::Vector4f &origin=Eigen::Vector4f::Zero(), const Eigen::Quaternionf &orientation=Eigen::Quaternionf::Identity(), bool binary=false, bool use_camera=true)
Save point cloud data to a PLY file containing n-D points.
Definition: ply_io.h:654
pcl::PLYWriter::generateHeaderASCII
std::string generateHeaderASCII(const pcl::PCLPointCloud2 &cloud, const Eigen::Vector4f &origin, const Eigen::Quaternionf &orientation, int valid_points, bool use_camera=true)
Generate the header of a PLY v.7 file format.
Definition: ply_io.h:585
pcl::PLYReader::read
int read(const std::string &file_name, pcl::PCLPointCloud2 &cloud, const int offset=0)
Read a point cloud data from a PLY file and store it into a pcl/PCLPointCloud2.
Definition: ply_io.h:184
memory.h
Defines functions, macros and traits for allocating and using memory.
PCL_EXPORTS
#define PCL_EXPORTS
Definition: pcl_macros.h:331
pcl::fromPCLPointCloud2
void fromPCLPointCloud2(const pcl::PCLPointCloud2 &msg, pcl::PointCloud< PointT > &cloud, const MsgFieldMap &field_map)
Convert a PCLPointCloud2 binary data blob into a pcl::PointCloud<T> object using a field_map.
Definition: conversions.h:168