Point Cloud Library (PCL)
1.7.0
|
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Point Cloud Library (PCL) - www.pointclouds.org 00005 * Copyright (c) 2010-2011, Willow Garage, Inc. 00006 * 00007 * All rights reserved. 00008 * 00009 * Redistribution and use in source and binary forms, with or without 00010 * modification, are permitted provided that the following conditions 00011 * are met: 00012 * 00013 * * Redistributions of source code must retain the above copyright 00014 * notice, this list of conditions and the following disclaimer. 00015 * * Redistributions in binary form must reproduce the above 00016 * copyright notice, this list of conditions and the following 00017 * disclaimer in the documentation and/or other materials provided 00018 * with the distribution. 00019 * * Neither the name of the copyright holder(s) nor the names of its 00020 * contributors may be used to endorse or promote products derived 00021 * from this software without specific prior written permission. 00022 * 00023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00024 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00025 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00026 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00027 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00028 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00029 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00030 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00031 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00032 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00033 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00034 * POSSIBILITY OF SUCH DAMAGE. 00035 * 00036 * $Id$ 00037 * 00038 */ 00039 00040 #ifndef PCL_IO_PLY_IO_H_ 00041 #define PCL_IO_PLY_IO_H_ 00042 00043 #include <pcl/io/boost.h> 00044 #include <pcl/io/file_io.h> 00045 #include <pcl/io/ply/ply_parser.h> 00046 #include <pcl/PolygonMesh.h> 00047 #include <sstream> 00048 00049 namespace pcl 00050 { 00051 /** \brief Point Cloud Data (PLY) file format reader. 00052 * 00053 * The PLY data format is organized in the following way: 00054 * lines beginning with "comment" are treated as comments 00055 * - ply 00056 * - format [ascii|binary_little_endian|binary_big_endian] 1.0 00057 * - element vertex COUNT 00058 * - property float x 00059 * - property float y 00060 * - [property float z] 00061 * - [property float normal_x] 00062 * - [property float normal_y] 00063 * - [property float normal_z] 00064 * - [property uchar red] 00065 * - [property uchar green] 00066 * - [property uchar blue] ... 00067 * - ascii/binary point coordinates 00068 * - [element camera 1] 00069 * - [property float view_px] ... 00070 * - [element range_grid COUNT] 00071 * - [property list uchar int vertex_indices] 00072 * - end header 00073 * 00074 * \author Nizar Sallem 00075 * \ingroup io 00076 */ 00077 class PCL_EXPORTS PLYReader : public FileReader 00078 { 00079 public: 00080 enum 00081 { 00082 PLY_V0 = 0, 00083 PLY_V1 = 1 00084 }; 00085 00086 PLYReader () 00087 : FileReader () 00088 , parser_ () 00089 , origin_ (Eigen::Vector4f::Zero ()) 00090 , orientation_ (Eigen::Matrix3f::Zero ()) 00091 , cloud_ () 00092 , vertex_count_ (0) 00093 , vertex_properties_counter_ (0) 00094 , vertex_offset_before_ (0) 00095 , range_grid_ (0) 00096 , range_count_ (0) 00097 , range_grid_vertex_indices_element_index_ (0) 00098 , rgb_offset_before_ (0) 00099 , do_resize_ (false) 00100 {} 00101 00102 PLYReader (const PLYReader &p) 00103 : FileReader () 00104 , parser_ () 00105 , origin_ (Eigen::Vector4f::Zero ()) 00106 , orientation_ (Eigen::Matrix3f::Zero ()) 00107 , cloud_ () 00108 , vertex_count_ (0) 00109 , vertex_properties_counter_ (0) 00110 , vertex_offset_before_ (0) 00111 , range_grid_ (0) 00112 , range_count_ (0) 00113 , range_grid_vertex_indices_element_index_ (0) 00114 , rgb_offset_before_ (0) 00115 , do_resize_ (false) 00116 { 00117 *this = p; 00118 } 00119 00120 PLYReader& 00121 operator = (const PLYReader &p) 00122 { 00123 origin_ = p.origin_; 00124 orientation_ = p.orientation_; 00125 range_grid_ = p.range_grid_; 00126 return (*this); 00127 } 00128 00129 ~PLYReader () { delete range_grid_; } 00130 /** \brief Read a point cloud data header from a PLY file. 00131 * 00132 * Load only the meta information (number of points, their types, etc), 00133 * and not the points themselves, from a given PLY file. Useful for fast 00134 * evaluation of the underlying data structure. 00135 * 00136 * Returns: 00137 * * < 0 (-1) on error 00138 * * > 0 on success 00139 * \param[in] file_name the name of the file to load 00140 * \param[out] cloud the resultant point cloud dataset (only the header will be filled) 00141 * \param[in] origin the sensor data acquisition origin (translation) 00142 * \param[in] orientation the sensor data acquisition origin (rotation) 00143 * \param[out] ply_version the PLY version read from the file 00144 * \param[out] data_type the type of PLY data stored in the file 00145 * \param[out] data_idx the data index 00146 * \param[in] offset the offset in the file where to expect the true header to begin. 00147 * One usage example for setting the offset parameter is for reading 00148 * data from a TAR "archive containing multiple files: TAR files always 00149 * add a 512 byte header in front of the actual file, so set the offset 00150 * to the next byte after the header (e.g., 513). 00151 */ 00152 int 00153 readHeader (const std::string &file_name, pcl::PCLPointCloud2 &cloud, 00154 Eigen::Vector4f &origin, Eigen::Quaternionf &orientation, 00155 int &ply_version, int &data_type, unsigned int &data_idx, const int offset = 0); 00156 00157 /** \brief Read a point cloud data from a PLY file and store it into a pcl/PCLPointCloud2. 00158 * \param[in] file_name the name of the file containing the actual PointCloud data 00159 * \param[out] cloud the resultant PointCloud message read from disk 00160 * \param[in] origin the sensor data acquisition origin (translation) 00161 * \param[in] orientation the sensor data acquisition origin (rotation) 00162 * \param[out] ply_version the PLY version read from the file 00163 * \param[in] offset the offset in the file where to expect the true header to begin. 00164 * One usage example for setting the offset parameter is for reading 00165 * data from a TAR "archive containing multiple files: TAR files always 00166 * add a 512 byte header in front of the actual file, so set the offset 00167 * to the next byte after the header (e.g., 513). 00168 */ 00169 int 00170 read (const std::string &file_name, pcl::PCLPointCloud2 &cloud, 00171 Eigen::Vector4f &origin, Eigen::Quaternionf &orientation, int& ply_version, const int offset = 0); 00172 00173 /** \brief Read a point cloud data from a PLY file (PLY_V6 only!) and store it into a pcl/PCLPointCloud2. 00174 * 00175 * \note This function is provided for backwards compatibility only and 00176 * it can only read PLY_V6 files correctly, as pcl::PCLPointCloud2 00177 * does not contain a sensor origin/orientation. Reading any file 00178 * > PLY_V6 will generate a warning. 00179 * 00180 * \param[in] file_name the name of the file containing the actual PointCloud data 00181 * \param[out] cloud the resultant PointCloud message read from disk 00182 * \param[in] offset the offset in the file where to expect the true header to begin. 00183 * One usage example for setting the offset parameter is for reading 00184 * data from a TAR "archive containing multiple files: TAR files always 00185 * add a 512 byte header in front of the actual file, so set the offset 00186 * to the next byte after the header (e.g., 513). 00187 */ 00188 inline int 00189 read (const std::string &file_name, pcl::PCLPointCloud2 &cloud, const int offset = 0) 00190 { 00191 Eigen::Vector4f origin; 00192 Eigen::Quaternionf orientation; 00193 int ply_version; 00194 return read (file_name, cloud, origin, orientation, ply_version, offset); 00195 } 00196 00197 /** \brief Read a point cloud data from any PLY file, and convert it to the given template format. 00198 * \param[in] file_name the name of the file containing the actual PointCloud data 00199 * \param[out] cloud the resultant PointCloud message read from disk 00200 * \param[in] offset the offset in the file where to expect the true header to begin. 00201 * One usage example for setting the offset parameter is for reading 00202 * data from a TAR "archive containing multiple files: TAR files always 00203 * add a 512 byte header in front of the actual file, so set the offset 00204 * to the next byte after the header (e.g., 513). 00205 */ 00206 template<typename PointT> inline int 00207 read (const std::string &file_name, pcl::PointCloud<PointT> &cloud, const int offset = 0) 00208 { 00209 pcl::PCLPointCloud2 blob; 00210 int ply_version; 00211 int res = read (file_name, blob, cloud.sensor_origin_, cloud.sensor_orientation_, 00212 ply_version, offset); 00213 00214 // Exit in case of error 00215 if (res < 0) 00216 return (res); 00217 pcl::fromPCLPointCloud2 (blob, cloud); 00218 return (0); 00219 } 00220 00221 private: 00222 ::pcl::io::ply::ply_parser parser_; 00223 00224 bool 00225 parse (const std::string& istream_filename); 00226 00227 /** \brief Info callback function 00228 * \param[in] filename PLY file read 00229 * \param[in] line_number line triggering the callback 00230 * \param[in] message information message 00231 */ 00232 void 00233 infoCallback (const std::string& filename, std::size_t line_number, const std::string& message) 00234 { 00235 PCL_DEBUG ("[pcl::PLYReader] %s:%lu: %s\n", filename.c_str (), line_number, message.c_str ()); 00236 } 00237 00238 /** \brief Warning callback function 00239 * \param[in] filename PLY file read 00240 * \param[in] line_number line triggering the callback 00241 * \param[in] message warning message 00242 */ 00243 void 00244 warningCallback (const std::string& filename, std::size_t line_number, const std::string& message) 00245 { 00246 PCL_WARN ("[pcl::PLYReader] %s:%lu: %s\n", filename.c_str (), line_number, message.c_str ()); 00247 } 00248 00249 /** \brief Error callback function 00250 * \param[in] filename PLY file read 00251 * \param[in] line_number line triggering the callback 00252 * \param[in] message error message 00253 */ 00254 void 00255 errorCallback (const std::string& filename, std::size_t line_number, const std::string& message) 00256 { 00257 PCL_ERROR ("[pcl::PLYReader] %s:%lu: %s\n", filename.c_str (), line_number, message.c_str ()); 00258 } 00259 00260 /** \brief function called when the keyword element is parsed 00261 * \param[in] element_name element name 00262 * \param[in] count number of instances 00263 */ 00264 boost::tuple<boost::function<void ()>, boost::function<void ()> > 00265 elementDefinitionCallback (const std::string& element_name, std::size_t count); 00266 00267 bool 00268 endHeaderCallback (); 00269 00270 /** \brief function called when a scalar property is parsed 00271 * \param[in] element_name element name to which the property belongs 00272 * \param[in] property_name property name 00273 */ 00274 template <typename ScalarType> boost::function<void (ScalarType)> 00275 scalarPropertyDefinitionCallback (const std::string& element_name, const std::string& property_name); 00276 00277 /** \brief function called when a list property is parsed 00278 * \param[in] element_name element name to which the property belongs 00279 * \param[in] property_name list property name 00280 */ 00281 template <typename SizeType, typename ScalarType> 00282 boost::tuple<boost::function<void (SizeType)>, boost::function<void (ScalarType)>, boost::function<void ()> > 00283 listPropertyDefinitionCallback (const std::string& element_name, const std::string& property_name); 00284 00285 /** \brief function called at the beginning of a list property parsing. 00286 * \param[in] size number of elements in the list 00287 */ 00288 template <typename SizeType> void 00289 vertexListPropertyBeginCallback (const std::string& property_name, SizeType size); 00290 00291 /** \brief function called when a list element is parsed. 00292 * \param[in] value the list's element value 00293 */ 00294 template <typename ContentType> void 00295 vertexListPropertyContentCallback (ContentType value); 00296 00297 /** \brief function called at the end of a list property parsing */ 00298 inline void 00299 vertexListPropertyEndCallback (); 00300 00301 /** Callback function for an anonymous vertex double property. 00302 * Writes down a double value in cloud data. 00303 * param[in] value double value parsed 00304 */ 00305 inline void 00306 vertexDoublePropertyCallback (pcl::io::ply::float64 value); 00307 00308 /** Callback function for an anonymous vertex float property. 00309 * Writes down a float value in cloud data. 00310 * param[in] value float value parsed 00311 */ 00312 inline void 00313 vertexFloatPropertyCallback (pcl::io::ply::float32 value); 00314 00315 /** Callback function for an anonymous vertex int property. 00316 * Writes down a int value in cloud data. 00317 * param[in] value int value parsed 00318 */ 00319 inline void 00320 vertexIntPropertyCallback (pcl::io::ply::int32 value); 00321 00322 /** Callback function for an anonymous vertex uint property. 00323 * Writes down a uint value in cloud data. 00324 * param[in] value uint value parsed 00325 */ 00326 inline void 00327 vertexUnsignedIntPropertyCallback (pcl::io::ply::uint32 value); 00328 00329 /** Callback function for an anonymous vertex short property. 00330 * Writes down a short value in cloud data. 00331 * param[in] value short value parsed 00332 */ 00333 inline void 00334 vertexShortPropertyCallback (pcl::io::ply::int16 value); 00335 00336 /** Callback function for an anonymous vertex ushort property. 00337 * Writes down a ushort value in cloud data. 00338 * param[in] value ushort value parsed 00339 */ 00340 inline void 00341 vertexUnsignedShortPropertyCallback (pcl::io::ply::uint16 value); 00342 00343 /** Callback function for an anonymous vertex char property. 00344 * Writes down a char value in cloud data. 00345 * param[in] value char value parsed 00346 */ 00347 inline void 00348 vertexCharPropertyCallback (pcl::io::ply::int8 value); 00349 00350 /** Callback function for an anonymous vertex uchar property. 00351 * Writes down a uchar value in cloud data. 00352 * param[in] value uchar value parsed 00353 */ 00354 inline void 00355 vertexUnsignedCharPropertyCallback (pcl::io::ply::uint8 value); 00356 00357 /** Callback function for vertex RGB color. 00358 * This callback is in charge of packing red green and blue in a single int 00359 * before writing it down in cloud data. 00360 * param[in] color_name color name in {red, green, blue} 00361 * param[in] color value of {red, green, blue} property 00362 */ 00363 inline void 00364 vertexColorCallback (const std::string& color_name, pcl::io::ply::uint8 color); 00365 00366 /** Callback function for vertex intensity. 00367 * converts intensity from int to float before writing it down in cloud data. 00368 * param[in] intensity 00369 */ 00370 inline void 00371 vertexIntensityCallback (pcl::io::ply::uint8 intensity); 00372 00373 /** Callback function for vertex alpha. 00374 * extracts RGB value, append alpha and put it back 00375 * param[in] alpha 00376 */ 00377 inline void 00378 vertexAlphaCallback (pcl::io::ply::uint8 alpha); 00379 00380 /** Callback function for origin x component. 00381 * param[in] value origin x value 00382 */ 00383 inline void 00384 originXCallback (const float& value) { origin_[0] = value; } 00385 00386 /** Callback function for origin y component. 00387 * param[in] value origin y value 00388 */ 00389 inline void 00390 originYCallback (const float& value) { origin_[1] = value; } 00391 00392 /** Callback function for origin z component. 00393 * param[in] value origin z value 00394 */ 00395 inline void 00396 originZCallback (const float& value) { origin_[2] = value; } 00397 00398 /** Callback function for orientation x axis x component. 00399 * param[in] value orientation x axis x value 00400 */ 00401 inline void 00402 orientationXaxisXCallback (const float& value) { orientation_ (0,0) = value; } 00403 00404 /** Callback function for orientation x axis y component. 00405 * param[in] value orientation x axis y value 00406 */ 00407 inline void 00408 orientationXaxisYCallback (const float& value) { orientation_ (0,1) = value; } 00409 00410 /** Callback function for orientation x axis z component. 00411 * param[in] value orientation x axis z value 00412 */ 00413 inline void 00414 orientationXaxisZCallback (const float& value) { orientation_ (0,2) = value; } 00415 00416 /** Callback function for orientation y axis x component. 00417 * param[in] value orientation y axis x value 00418 */ 00419 inline void 00420 orientationYaxisXCallback (const float& value) { orientation_ (1,0) = value; } 00421 00422 /** Callback function for orientation y axis y component. 00423 * param[in] value orientation y axis y value 00424 */ 00425 inline void 00426 orientationYaxisYCallback (const float& value) { orientation_ (1,1) = value; } 00427 00428 /** Callback function for orientation y axis z component. 00429 * param[in] value orientation y axis z value 00430 */ 00431 inline void 00432 orientationYaxisZCallback (const float& value) { orientation_ (1,2) = value; } 00433 00434 /** Callback function for orientation z axis x component. 00435 * param[in] value orientation z axis x value 00436 */ 00437 inline void 00438 orientationZaxisXCallback (const float& value) { orientation_ (2,0) = value; } 00439 00440 /** Callback function for orientation z axis y component. 00441 * param[in] value orientation z axis y value 00442 */ 00443 inline void 00444 orientationZaxisYCallback (const float& value) { orientation_ (2,1) = value; } 00445 00446 /** Callback function for orientation z axis z component. 00447 * param[in] value orientation z axis z value 00448 */ 00449 inline void 00450 orientationZaxisZCallback (const float& value) { orientation_ (2,2) = value; } 00451 00452 /** Callback function to set the cloud height 00453 * param[in] height cloud height 00454 */ 00455 inline void 00456 cloudHeightCallback (const int &height) { cloud_->height = height; } 00457 00458 /** Callback function to set the cloud width 00459 * param[in] width cloud width 00460 */ 00461 inline void 00462 cloudWidthCallback (const int &width) { cloud_->width = width; } 00463 00464 /** Append a double property to the cloud fields. 00465 * param[in] name property name 00466 * param[in] count property count: 1 for scalar properties and higher for a 00467 * list property. 00468 */ 00469 void 00470 appendDoubleProperty (const std::string& name, const size_t& count = 1); 00471 00472 /** Append a float property to the cloud fields. 00473 * param[in] name property name 00474 * param[in] count property count: 1 for scalar properties and higher for a 00475 * list property. 00476 */ 00477 void 00478 appendFloatProperty (const std::string& name, const size_t& count = 1); 00479 00480 /** Append an unsigned int property to the cloud fields. 00481 * param[in] name property name 00482 * param[in] count property count: 1 for scalar properties and higher for a 00483 * list property. 00484 */ 00485 void 00486 appendIntProperty (const std::string& name, const size_t& count = 1); 00487 00488 /** Append an unsigned int property to the cloud fields. 00489 * param[in] name property name 00490 * param[in] count property count: 1 for scalar properties and higher for a 00491 * list property. 00492 */ 00493 void 00494 appendUnsignedIntProperty (const std::string& name, const size_t& count = 1); 00495 00496 /** Append a short property to the cloud fields. 00497 * param[in] name property name 00498 * param[in] count property count: 1 for scalar properties and higher for a 00499 * list property. 00500 */ 00501 void 00502 appendShortProperty (const std::string& name, const size_t& count = 1); 00503 00504 /** Append a short property to the cloud fields. 00505 * param[in] name property name 00506 * param[in] count property count: 1 for scalar properties and higher for a 00507 * list property. 00508 */ 00509 void 00510 appendUnsignedShortProperty (const std::string& name, const size_t& count = 1); 00511 00512 /** Append a char property to the cloud fields. 00513 * param[in] name property name 00514 * param[in] count property count: 1 for scalar properties and higher for a 00515 * list property. 00516 */ 00517 void 00518 appendCharProperty (const std::string& name, const size_t& count = 1); 00519 00520 /** Append a char property to the cloud fields. 00521 * param[in] name property name 00522 * param[in] count property count: 1 for scalar properties and higher for a 00523 * list property. 00524 */ 00525 void 00526 appendUnsignedCharProperty (const std::string& name, const size_t& count = 1); 00527 00528 /** Amend property from cloud fields identified by \a old_name renaming 00529 * it \a new_name. 00530 * param[in] old_name property old name 00531 * param[in] new_name property new name 00532 */ 00533 void 00534 amendProperty (const std::string& old_name, const std::string& new_name, uint8_t datatype = 0); 00535 00536 /** Callback function for the begin of vertex line */ 00537 void 00538 vertexBeginCallback (); 00539 00540 /** Callback function for the end of vertex line */ 00541 void 00542 vertexEndCallback (); 00543 00544 /** Callback function for the begin of range_grid line */ 00545 void 00546 rangeGridBeginCallback (); 00547 00548 /** Callback function for the begin of range_grid vertex_indices property 00549 * param[in] size vertex_indices list size 00550 */ 00551 void 00552 rangeGridVertexIndicesBeginCallback (pcl::io::ply::uint8 size); 00553 00554 /** Callback function for each range_grid vertex_indices element 00555 * param[in] vertex_index index of the vertex in vertex_indices 00556 */ 00557 void 00558 rangeGridVertexIndicesElementCallback (pcl::io::ply::int32 vertex_index); 00559 00560 /** Callback function for the end of a range_grid vertex_indices property */ 00561 void 00562 rangeGridVertexIndicesEndCallback (); 00563 00564 /** Callback function for the end of a range_grid element end */ 00565 void 00566 rangeGridEndCallback (); 00567 00568 /** Callback function for obj_info */ 00569 void 00570 objInfoCallback (const std::string& line); 00571 00572 /// origin 00573 Eigen::Vector4f origin_; 00574 00575 /// orientation 00576 Eigen::Matrix3f orientation_; 00577 00578 //vertex element artifacts 00579 pcl::PCLPointCloud2 *cloud_; 00580 size_t vertex_count_, vertex_properties_counter_; 00581 int vertex_offset_before_; 00582 //range element artifacts 00583 std::vector<std::vector <int> > *range_grid_; 00584 size_t range_count_, range_grid_vertex_indices_element_index_; 00585 size_t rgb_offset_before_; 00586 bool do_resize_; 00587 public: 00588 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00589 }; 00590 00591 /** \brief Point Cloud Data (PLY) file format writer. 00592 * \author Nizar Sallem 00593 * \ingroup io 00594 */ 00595 class PCL_EXPORTS PLYWriter : public FileWriter 00596 { 00597 public: 00598 ///Constructor 00599 PLYWriter () : FileWriter () {}; 00600 00601 ///Destructor 00602 ~PLYWriter () {}; 00603 00604 /** \brief Generate the header of a PLY v.7 file format 00605 * \param[in] cloud the point cloud data message 00606 * \param[in] origin the sensor data acquisition origin (translation) 00607 * \param[in] orientation the sensor data acquisition origin (rotation) 00608 * \param[in] valid_points number of valid points (finite ones for range_grid and 00609 * all of them for camer) 00610 * \param[in] use_camera if set to true then PLY file will use element camera else 00611 * element range_grid will be used. 00612 */ 00613 inline std::string 00614 generateHeaderBinary (const pcl::PCLPointCloud2 &cloud, 00615 const Eigen::Vector4f &origin, 00616 const Eigen::Quaternionf &orientation, 00617 int valid_points, 00618 bool use_camera = true) 00619 { 00620 return (generateHeader (cloud, origin, orientation, true, use_camera, valid_points)); 00621 } 00622 00623 /** \brief Generate the header of a PLY v.7 file format 00624 * \param[in] cloud the point cloud data message 00625 * \param[in] origin the sensor data acquisition origin (translation) 00626 * \param[in] orientation the sensor data acquisition origin (rotation) 00627 * \param[in] valid_points number of valid points (finite ones for range_grid and 00628 * all of them for camer) 00629 * \param[in] use_camera if set to true then PLY file will use element camera else 00630 * element range_grid will be used. 00631 */ 00632 inline std::string 00633 generateHeaderASCII (const pcl::PCLPointCloud2 &cloud, 00634 const Eigen::Vector4f &origin, 00635 const Eigen::Quaternionf &orientation, 00636 int valid_points, 00637 bool use_camera = true) 00638 { 00639 return (generateHeader (cloud, origin, orientation, false, use_camera, valid_points)); 00640 } 00641 00642 /** \brief Save point cloud data to a PLY file containing n-D points, in ASCII format 00643 * \param[in] file_name the output file name 00644 * \param[in] cloud the point cloud data message 00645 * \param[in] origin the sensor data acquisition origin (translation) 00646 * \param[in] orientation the sensor data acquisition origin (rotation) 00647 * \param[in] precision the specified output numeric stream precision (default: 8) 00648 * \param[in] use_camera if set to true then PLY file will use element camera else 00649 * element range_grid will be used. 00650 */ 00651 int 00652 writeASCII (const std::string &file_name, const pcl::PCLPointCloud2 &cloud, 00653 const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (), 00654 const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (), 00655 int precision = 8, 00656 bool use_camera = true); 00657 00658 /** \brief Save point cloud data to a PLY file containing n-D points, in BINARY format 00659 * \param[in] file_name the output file name 00660 * \param[in] cloud the point cloud data message 00661 * \param[in] origin the sensor data acquisition origin (translation) 00662 * \param[in] orientation the sensor data acquisition origin (rotation) 00663 * \param[in] use_camera if set to true then PLY file will use element camera else 00664 * element range_grid will be used 00665 */ 00666 int 00667 writeBinary (const std::string &file_name, const pcl::PCLPointCloud2 &cloud, 00668 const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (), 00669 const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (), 00670 bool use_camera = true); 00671 00672 /** \brief Save point cloud data to a PLY file containing n-D points 00673 * \param[in] file_name the output file name 00674 * \param[in] cloud the point cloud data message 00675 * \param[in] origin the sensor acquisition origin 00676 * \param[in] orientation the sensor acquisition orientation 00677 * \param[in] binary set to true if the file is to be written in a binary 00678 * PLY format, false (default) for ASCII 00679 */ 00680 inline int 00681 write (const std::string &file_name, const pcl::PCLPointCloud2 &cloud, 00682 const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (), 00683 const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (), 00684 const bool binary = false) 00685 { 00686 if (binary) 00687 return (this->writeBinary (file_name, cloud, origin, orientation, true)); 00688 else 00689 return (this->writeASCII (file_name, cloud, origin, orientation, 8, true)); 00690 } 00691 00692 /** \brief Save point cloud data to a PLY file containing n-D points 00693 * \param[in] file_name the output file name 00694 * \param[in] cloud the point cloud data message 00695 * \param[in] origin the sensor acquisition origin 00696 * \param[in] orientation the sensor acquisition orientation 00697 * \param[in] binary set to true if the file is to be written in a binary 00698 * PLY format, false (default) for ASCII 00699 * \param[in] use_camera set to true to use camera element and false to 00700 * use range_grid element 00701 */ 00702 inline int 00703 write (const std::string &file_name, const pcl::PCLPointCloud2 &cloud, 00704 const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (), 00705 const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (), 00706 bool binary = false, 00707 bool use_camera = true) 00708 { 00709 if (binary) 00710 return (this->writeBinary (file_name, cloud, origin, orientation, use_camera)); 00711 else 00712 return (this->writeASCII (file_name, cloud, origin, orientation, 8, use_camera)); 00713 } 00714 00715 /** \brief Save point cloud data to a PLY file containing n-D points 00716 * \param[in] file_name the output file name 00717 * \param[in] cloud the point cloud data message (boost shared pointer) 00718 * \param[in] origin the sensor acquisition origin 00719 * \param[in] orientation the sensor acquisition orientation 00720 * \param[in] binary set to true if the file is to be written in a binary 00721 * PLY format, false (default) for ASCII 00722 * \param[in] use_camera set to true to use camera element and false to 00723 * use range_grid element 00724 */ 00725 inline int 00726 write (const std::string &file_name, const pcl::PCLPointCloud2::ConstPtr &cloud, 00727 const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (), 00728 const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (), 00729 bool binary = false, 00730 bool use_camera = true) 00731 { 00732 return (write (file_name, *cloud, origin, orientation, binary, use_camera)); 00733 } 00734 00735 /** \brief Save point cloud data to a PLY file containing n-D points 00736 * \param[in] file_name the output file name 00737 * \param[in] cloud the pcl::PointCloud data 00738 * \param[in] binary set to true if the file is to be written in a binary 00739 * PLY format, false (default) for ASCII 00740 * \param[in] use_camera set to true to use camera element and false to 00741 * use range_grid element 00742 */ 00743 template<typename PointT> inline int 00744 write (const std::string &file_name, 00745 const pcl::PointCloud<PointT> &cloud, 00746 bool binary = false, 00747 bool use_camera = true) 00748 { 00749 Eigen::Vector4f origin = cloud.sensor_origin_; 00750 Eigen::Quaternionf orientation = cloud.sensor_orientation_; 00751 00752 pcl::PCLPointCloud2 blob; 00753 pcl::toPCLPointCloud2 (cloud, blob); 00754 00755 // Save the data 00756 return (this->write (file_name, blob, origin, orientation, binary, use_camera)); 00757 } 00758 00759 private: 00760 /** \brief Generate a PLY header. 00761 * \param[in] cloud the input point cloud 00762 * \param[in] binary whether the PLY file should be saved as binary data (true) or ascii (false) 00763 */ 00764 std::string 00765 generateHeader (const pcl::PCLPointCloud2 &cloud, 00766 const Eigen::Vector4f &origin, 00767 const Eigen::Quaternionf &orientation, 00768 bool binary, 00769 bool use_camera, 00770 int valid_points); 00771 00772 void 00773 writeContentWithCameraASCII (int nr_points, 00774 int point_size, 00775 const pcl::PCLPointCloud2 &cloud, 00776 const Eigen::Vector4f &origin, 00777 const Eigen::Quaternionf &orientation, 00778 std::ofstream& fs); 00779 00780 void 00781 writeContentWithRangeGridASCII (int nr_points, 00782 int point_size, 00783 const pcl::PCLPointCloud2 &cloud, 00784 std::ostringstream& fs, 00785 int& nb_valid_points); 00786 }; 00787 00788 namespace io 00789 { 00790 /** \brief Load a PLY v.6 file into a templated PointCloud type. 00791 * 00792 * Any PLY files containg sensor data will generate a warning as a 00793 * pcl/PCLPointCloud2 message cannot hold the sensor origin. 00794 * 00795 * \param[in] file_name the name of the file to load 00796 * \param[in] cloud the resultant templated point cloud 00797 * \ingroup io 00798 */ 00799 inline int 00800 loadPLYFile (const std::string &file_name, pcl::PCLPointCloud2 &cloud) 00801 { 00802 pcl::PLYReader p; 00803 return (p.read (file_name, cloud)); 00804 } 00805 00806 /** \brief Load any PLY file into a templated PointCloud type. 00807 * \param[in] file_name the name of the file to load 00808 * \param[in] cloud the resultant templated point cloud 00809 * \param[in] origin the sensor acquisition origin (only for > PLY_V7 - null if not present) 00810 * \param[in] orientation the sensor acquisition orientation if availble, 00811 * identity if not present 00812 * \ingroup io 00813 */ 00814 inline int 00815 loadPLYFile (const std::string &file_name, pcl::PCLPointCloud2 &cloud, 00816 Eigen::Vector4f &origin, Eigen::Quaternionf &orientation) 00817 { 00818 pcl::PLYReader p; 00819 int ply_version; 00820 return (p.read (file_name, cloud, origin, orientation, ply_version)); 00821 } 00822 00823 /** \brief Load any PLY file into a templated PointCloud type 00824 * \param[in] file_name the name of the file to load 00825 * \param[in] cloud the resultant templated point cloud 00826 * \ingroup io 00827 */ 00828 template<typename PointT> inline int 00829 loadPLYFile (const std::string &file_name, pcl::PointCloud<PointT> &cloud) 00830 { 00831 pcl::PLYReader p; 00832 return (p.read (file_name, cloud)); 00833 } 00834 00835 /** \brief Save point cloud data to a PLY file containing n-D points 00836 * \param[in] file_name the output file name 00837 * \param[in] cloud the point cloud data message 00838 * \param[in] origin the sensor data acquisition origin (translation) 00839 * \param[in] orientation the sensor data acquisition origin (rotation) 00840 * \param[in] binary_mode true for binary mode, false (default) for ASCII 00841 * \ingroup io 00842 */ 00843 inline int 00844 savePLYFile (const std::string &file_name, const pcl::PCLPointCloud2 &cloud, 00845 const Eigen::Vector4f &origin = Eigen::Vector4f::Zero (), 00846 const Eigen::Quaternionf &orientation = Eigen::Quaternionf::Identity (), 00847 bool binary_mode = false, bool use_camera = true) 00848 { 00849 PLYWriter w; 00850 return (w.write (file_name, cloud, origin, orientation, binary_mode, use_camera)); 00851 } 00852 00853 /** \brief Templated version for saving point cloud data to a PLY file 00854 * containing a specific given cloud format 00855 * \param[in] file_name the output file name 00856 * \param[in] cloud the point cloud data message 00857 * \param[in] binary_mode true for binary mode, false (default) for ASCII 00858 * \ingroup io 00859 */ 00860 template<typename PointT> inline int 00861 savePLYFile (const std::string &file_name, const pcl::PointCloud<PointT> &cloud, bool binary_mode = false) 00862 { 00863 PLYWriter w; 00864 return (w.write<PointT> (file_name, cloud, binary_mode)); 00865 } 00866 00867 /** \brief Templated version for saving point cloud data to a PLY file 00868 * containing a specific given cloud format. 00869 * \param[in] file_name the output file name 00870 * \param[in] cloud the point cloud data message 00871 * \ingroup io 00872 */ 00873 template<typename PointT> inline int 00874 savePLYFileASCII (const std::string &file_name, const pcl::PointCloud<PointT> &cloud) 00875 { 00876 PLYWriter w; 00877 return (w.write<PointT> (file_name, cloud, false)); 00878 } 00879 00880 /** \brief Templated version for saving point cloud data to a PLY file containing a specific given cloud format. 00881 * \param[in] file_name the output file name 00882 * \param[in] cloud the point cloud data message 00883 * \ingroup io 00884 */ 00885 template<typename PointT> inline int 00886 savePLYFileBinary (const std::string &file_name, const pcl::PointCloud<PointT> &cloud) 00887 { 00888 PLYWriter w; 00889 return (w.write<PointT> (file_name, cloud, true)); 00890 } 00891 00892 /** \brief Templated version for saving point cloud data to a PLY file containing a specific given cloud format 00893 * \param[in] file_name the output file name 00894 * \param[in] cloud the point cloud data message 00895 * \param[in] indices the set of indices to save 00896 * \param[in] binary_mode true for binary mode, false (default) for ASCII 00897 * \ingroup io 00898 */ 00899 template<typename PointT> int 00900 savePLYFile (const std::string &file_name, const pcl::PointCloud<PointT> &cloud, 00901 const std::vector<int> &indices, bool binary_mode = false) 00902 { 00903 // Copy indices to a new point cloud 00904 pcl::PointCloud<PointT> cloud_out; 00905 copyPointCloud (cloud, indices, cloud_out); 00906 // Save the data 00907 PLYWriter w; 00908 return (w.write<PointT> (file_name, cloud_out, binary_mode)); 00909 } 00910 00911 /** \brief Saves a PolygonMesh in ascii PLY format. 00912 * \param[in] file_name the name of the file to write to disk 00913 * \param[in] mesh the polygonal mesh to save 00914 * \param[in] precision the output ASCII precision default 5 00915 * \ingroup io 00916 */ 00917 PCL_EXPORTS int 00918 savePLYFile (const std::string &file_name, const pcl::PolygonMesh &mesh, unsigned precision = 5); 00919 00920 /** \brief Saves a PolygonMesh in binary PLY format. 00921 * \param[in] file_name the name of the file to write to disk 00922 * \param[in] mesh the polygonal mesh to save 00923 * \ingroup io 00924 */ 00925 PCL_EXPORTS int 00926 savePLYFileBinary (const std::string &file_name, const pcl::PolygonMesh &mesh); 00927 } 00928 } 00929 00930 #endif //#ifndef PCL_IO_PLY_IO_H_