Point Cloud Library (PCL)  1.6.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ply_io.h
Go to the documentation of this file.
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 Willow Garage, Inc. 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: ply_io.h 5354 2012-03-27 22:13:21Z nizar $
37  *
38  */
39 
40 #ifndef PCL_IO_PLY_IO_H_
41 #define PCL_IO_PLY_IO_H_
42 
43 #include <pcl/io/file_io.h>
44 #include <pcl/io/ply/ply_parser.h>
45 #include <boost/bind.hpp>
46 #include <pcl/PolygonMesh.h>
47 #include <sstream>
48 
49 namespace pcl
50 {
78  {
79  public:
80  enum
81  {
82  PLY_V0 = 0,
83  PLY_V1 = 1
84  };
85 
87  : FileReader ()
88  , parser_ ()
89  , origin_ (Eigen::Vector4f::Zero ())
90  , orientation_ (Eigen::Matrix3f::Zero ())
91  , cloud_ ()
92  , vertex_count_ (0)
93  , vertex_properties_counter_ (0)
94  , vertex_offset_before_ (0)
95  , range_grid_ (0)
96  , range_count_ (0)
97  , range_grid_vertex_indices_element_index_ (0)
98  , rgb_offset_before_ (0)
99  {}
100 
101  PLYReader (const PLYReader &p)
102  : parser_ ()
103  , origin_ (Eigen::Vector4f::Zero ())
104  , orientation_ (Eigen::Matrix3f::Zero ())
105  , cloud_ ()
106  , vertex_count_ (0)
107  , vertex_properties_counter_ (0)
108  , vertex_offset_before_ (0)
109  , range_grid_ (0)
110  , range_count_ (0)
111  , range_grid_vertex_indices_element_index_ (0)
112  , rgb_offset_before_ (0)
113  {
114  *this = p;
115  }
116 
117  PLYReader&
118  operator = (const PLYReader &p)
119  {
120  origin_ = p.origin_;
121  orientation_ = p.orientation_;
122  range_grid_ = p.range_grid_;
123  return (*this);
124  }
125 
126  ~PLYReader () { delete range_grid_; }
149  int
150  readHeader (const std::string &file_name, sensor_msgs::PointCloud2 &cloud,
151  Eigen::Vector4f &origin, Eigen::Quaternionf &orientation,
152  int &ply_version, int &data_type, unsigned int &data_idx, const int offset = 0);
153 
166  int
167  read (const std::string &file_name, sensor_msgs::PointCloud2 &cloud,
168  Eigen::Vector4f &origin, Eigen::Quaternionf &orientation, int& ply_version, const int offset = 0);
169 
185  inline int
186  read (const std::string &file_name, sensor_msgs::PointCloud2 &cloud, const int offset = 0)
187  {
188  Eigen::Vector4f origin;
189  Eigen::Quaternionf orientation;
190  int ply_version;
191  return read (file_name, cloud, origin, orientation, ply_version, offset);
192  }
193 
203  template<typename PointT> inline int
204  read (const std::string &file_name, pcl::PointCloud<PointT> &cloud, const int offset = 0)
205  {
207  int ply_version;
208  int res = read (file_name, blob, cloud.sensor_origin_, cloud.sensor_orientation_,
209  ply_version, offset);
210 
211  // Exit in case of error
212  if (res < 0)
213  return (res);
214  pcl::fromROSMsg (blob, cloud);
215  return (0);
216  }
217 
218  private:
220 
221  bool
222  parse (const std::string& istream_filename);
223 
229  void
230  infoCallback (const std::string& filename, std::size_t line_number, const std::string& message)
231  {
232  PCL_DEBUG ("[pcl::PLYReader] %s:%lu: %s\n", filename.c_str (), line_number, message.c_str ());
233  }
234 
240  void
241  warningCallback (const std::string& filename, std::size_t line_number, const std::string& message)
242  {
243  PCL_WARN ("[pcl::PLYReader] %s:%lu: %s\n", filename.c_str (), line_number, message.c_str ());
244  }
245 
251  void
252  errorCallback (const std::string& filename, std::size_t line_number, const std::string& message)
253  {
254  PCL_ERROR ("[pcl::PLYReader] %s:%lu: %s\n", filename.c_str (), line_number, message.c_str ());
255  }
256 
261  boost::tuple<boost::function<void ()>, boost::function<void ()> >
262  elementDefinitionCallback (const std::string& element_name, std::size_t count);
263 
264  bool
265  endHeaderCallback ();
266 
271  template <typename ScalarType> boost::function<void (ScalarType)>
272  scalarPropertyDefinitionCallback (const std::string& element_name, const std::string& property_name);
273 
278  template <typename SizeType, typename ScalarType>
279  boost::tuple<boost::function<void (SizeType)>, boost::function<void (ScalarType)>, boost::function<void ()> >
280  listPropertyDefinitionCallback (const std::string& element_name, const std::string& property_name);
281 
286  inline void
287  vertexFloatPropertyCallback (pcl::io::ply::float32 value);
288 
295  inline void
296  vertexColorCallback (const std::string& color_name, pcl::io::ply::uint8 color);
297 
302  inline void
303  vertexIntensityCallback (pcl::io::ply::uint8 intensity);
304 
308  inline void
309  originXCallback (const float& value) { origin_[0] = value; }
310 
314  inline void
315  originYCallback (const float& value) { origin_[1] = value; }
316 
320  inline void
321  originZCallback (const float& value) { origin_[2] = value; }
322 
326  inline void
327  orientationXaxisXCallback (const float& value) { orientation_ (0,0) = value; }
328 
332  inline void
333  orientationXaxisYCallback (const float& value) { orientation_ (0,1) = value; }
334 
338  inline void
339  orientationXaxisZCallback (const float& value) { orientation_ (0,2) = value; }
340 
344  inline void
345  orientationYaxisXCallback (const float& value) { orientation_ (1,0) = value; }
346 
350  inline void
351  orientationYaxisYCallback (const float& value) { orientation_ (1,1) = value; }
352 
356  inline void
357  orientationYaxisZCallback (const float& value) { orientation_ (1,2) = value; }
358 
362  inline void
363  orientationZaxisXCallback (const float& value) { orientation_ (2,0) = value; }
364 
368  inline void
369  orientationZaxisYCallback (const float& value) { orientation_ (2,1) = value; }
370 
374  inline void
375  orientationZaxisZCallback (const float& value) { orientation_ (2,2) = value; }
376 
380  inline void
381  cloudHeightCallback (const int &height) { cloud_->height = height; }
382 
386  inline void
387  cloudWidthCallback (const int &width) { cloud_->width = width; }
388 
394  void
395  appendFloatProperty (const std::string& name, const size_t& count = 1);
396 
398  void
399  vertexBeginCallback ();
400 
402  void
403  vertexEndCallback ();
404 
406  void
407  rangeGridBeginCallback ();
408 
412  void
413  rangeGridVertexIndicesBeginCallback (pcl::io::ply::uint8 size);
414 
418  void
419  rangeGridVertexIndicesElementCallback (pcl::io::ply::int32 vertex_index);
420 
422  void
423  rangeGridVertexIndicesEndCallback ();
424 
426  void
427  rangeGridEndCallback ();
428 
430  void
431  objInfoCallback (const std::string& line);
432 
434  Eigen::Vector4f origin_;
435 
437  Eigen::Matrix3f orientation_;
438 
439  //vertex element artifacts
440  sensor_msgs::PointCloud2 *cloud_;
441  size_t vertex_count_, vertex_properties_counter_;
442  int vertex_offset_before_;
443  //range element artifacts
444  std::vector<std::vector <int> > *range_grid_;
445  size_t range_count_, range_grid_vertex_indices_element_index_;
446  size_t rgb_offset_before_;
447 
448  public:
449  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
450  };
451 
457  {
458  public:
460  PLYWriter () : FileWriter () {};
461 
463  ~PLYWriter () {};
464 
474  inline std::string
475  generateHeaderBinary (const sensor_msgs::PointCloud2 &cloud,
476  const Eigen::Vector4f &origin,
477  const Eigen::Quaternionf &orientation,
478  int valid_points,
479  bool use_camera = true)
480  {
481  return (generateHeader (cloud, origin, orientation, true, use_camera, valid_points));
482  }
483 
493  inline std::string
494  generateHeaderASCII (const sensor_msgs::PointCloud2 &cloud,
495  const Eigen::Vector4f &origin,
496  const Eigen::Quaternionf &orientation,
497  int valid_points,
498  bool use_camera = true)
499  {
500  return (generateHeader (cloud, origin, orientation, false, use_camera, valid_points));
501  }
502 
512  int
513  writeASCII (const std::string &file_name, const sensor_msgs::PointCloud2 &cloud,
514  const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (),
515  const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (),
516  int precision = 8,
517  bool use_camera = true);
518 
525  int
526  writeBinary (const std::string &file_name, const sensor_msgs::PointCloud2 &cloud,
527  const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (),
528  const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity ());
529 
538  inline int
539  write (const std::string &file_name, const sensor_msgs::PointCloud2 &cloud,
540  const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (),
541  const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (),
542  const bool binary = false)
543  {
544  if (binary)
545  return (this->writeBinary (file_name, cloud, origin, orientation));
546  else
547  return (this->writeASCII (file_name, cloud, origin, orientation, 8, true));
548  }
549 
560  inline int
561  write (const std::string &file_name, const sensor_msgs::PointCloud2 &cloud,
562  const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (),
563  const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (),
564  bool binary = false,
565  bool use_camera = true)
566  {
567  if (binary)
568  return (this->writeBinary (file_name, cloud, origin, orientation));
569  else
570  return (this->writeASCII (file_name, cloud, origin, orientation, 8, use_camera));
571  }
572 
583  inline int
584  write (const std::string &file_name, const sensor_msgs::PointCloud2::ConstPtr &cloud,
585  const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (),
586  const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (),
587  bool binary = false,
588  bool use_camera = true)
589  {
590  return (write (file_name, *cloud, origin, orientation, binary, use_camera));
591  }
592 
601  template<typename PointT> inline int
602  write (const std::string &file_name,
603  const pcl::PointCloud<PointT> &cloud,
604  bool binary = false,
605  bool use_camera = true)
606  {
607  Eigen::Vector4f origin = cloud.sensor_origin_;
608  Eigen::Quaternionf orientation = cloud.sensor_orientation_;
609 
611  pcl::toROSMsg (cloud, blob);
612 
613  // Save the data
614  return (this->write (file_name, blob, origin, orientation, binary, use_camera));
615  }
616 
617  private:
622  std::string
623  generateHeader (const sensor_msgs::PointCloud2 &cloud,
624  const Eigen::Vector4f &origin,
625  const Eigen::Quaternionf &orientation,
626  bool binary,
627  bool use_camera,
628  int valid_points);
629 
630  void
631  writeContentWithCameraASCII (int nr_points,
632  int point_size,
633  const sensor_msgs::PointCloud2 &cloud,
634  const Eigen::Vector4f &origin,
635  const Eigen::Quaternionf &orientation,
636  std::ofstream& fs);
637 
638  void
639  writeContentWithRangeGridASCII (int nr_points,
640  int point_size,
641  const sensor_msgs::PointCloud2 &cloud,
642  std::ostringstream& fs,
643  int& nb_valid_points);
644  };
645 
646  namespace io
647  {
657  inline int
658  loadPLYFile (const std::string &file_name, sensor_msgs::PointCloud2 &cloud)
659  {
660  pcl::PLYReader p;
661  return (p.read (file_name, cloud));
662  }
663 
672  inline int
673  loadPLYFile (const std::string &file_name, sensor_msgs::PointCloud2 &cloud,
674  Eigen::Vector4f &origin, Eigen::Quaternionf &orientation)
675  {
676  pcl::PLYReader p;
677  int ply_version;
678  return (p.read (file_name, cloud, origin, orientation, ply_version));
679  }
680 
686  template<typename PointT> inline int
687  loadPLYFile (const std::string &file_name, pcl::PointCloud<PointT> &cloud)
688  {
689  pcl::PLYReader p;
690  return (p.read (file_name, cloud));
691  }
692 
701  inline int
702  savePLYFile (const std::string &file_name, const sensor_msgs::PointCloud2 &cloud,
703  const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (),
704  const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (),
705  bool binary_mode = false, bool use_camera = true)
706  {
707  PLYWriter w;
708  return (w.write (file_name, cloud, origin, orientation, binary_mode, use_camera));
709  }
710 
718  template<typename PointT> inline int
719  savePLYFile (const std::string &file_name, const pcl::PointCloud<PointT> &cloud, bool binary_mode = false)
720  {
721  PLYWriter w;
722  return (w.write<PointT> (file_name, cloud, binary_mode));
723  }
724 
731  template<typename PointT> inline int
732  savePLYFileASCII (const std::string &file_name, const pcl::PointCloud<PointT> &cloud)
733  {
734  PLYWriter w;
735  return (w.write<PointT> (file_name, cloud, false));
736  }
737 
743  template<typename PointT> inline int
744  savePLYFileBinary (const std::string &file_name, const pcl::PointCloud<PointT> &cloud)
745  {
746  PLYWriter w;
747  return (w.write<PointT> (file_name, cloud, true));
748  }
749 
757  template<typename PointT> int
758  savePLYFile (const std::string &file_name, const pcl::PointCloud<PointT> &cloud,
759  const std::vector<int> &indices, bool binary_mode = false)
760  {
761  // Copy indices to a new point cloud
762  pcl::PointCloud<PointT> cloud_out;
763  copyPointCloud (cloud, indices, cloud_out);
764  // Save the data
765  PLYWriter w;
766  return (w.write<PointT> (file_name, cloud_out, binary_mode));
767  }
768 
775  PCL_EXPORTS int
776  savePLYFile (const std::string &file_name, const pcl::PolygonMesh &mesh, unsigned precision = 5);
777  }
778 }
779 
780 #endif //#ifndef PCL_IO_PLY_IO_H_