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