ply2raw.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Point Cloud Library (PCL) - www.pointclouds.org
00005  *  Copyright (c) 2007-2012, Ares Lagae
00006  *  Copyright (c) 2012, Willow Garage, Inc.
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 Willow Garage, Inc. 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: ply2raw.cpp 4918 2012-03-05 17:41:10Z nizar $
00037  *
00038  */
00039 
00040 #include <cstdlib>
00041 #include <cstring>
00042 #include <fstream>
00043 #include <iostream>
00044 
00045 #include <boost/bind.hpp>
00046 
00047 #include <pcl/io/ply/ply_parser.h>
00048 
00062 class ply_to_raw_converter
00063 {
00064   public:
00065     ply_to_raw_converter () : 
00066       ostream_ (), vertex_x_ (0), vertex_y_ (0), vertex_z_ (0), 
00067       face_vertex_indices_element_index_ (),
00068       face_vertex_indices_first_element_ (), 
00069       face_vertex_indices_previous_element_ (),
00070       vertices_ ()
00071     {}
00072 
00073     ply_to_raw_converter (const ply_to_raw_converter &f) :
00074       ostream_ (), vertex_x_ (0), vertex_y_ (0), vertex_z_ (0), 
00075       face_vertex_indices_element_index_ (),
00076       face_vertex_indices_first_element_ (), 
00077       face_vertex_indices_previous_element_ (),
00078       vertices_ ()
00079     {
00080       *this = f;
00081     }
00082 
00083     ply_to_raw_converter&
00084     operator = (const ply_to_raw_converter &f)
00085     {
00086       ostream_ = f.ostream_;
00087       vertex_x_ = f.vertex_x_;
00088       vertex_y_ = f.vertex_y_;
00089       vertex_z_ = f.vertex_z_;
00090       face_vertex_indices_element_index_ = f.face_vertex_indices_element_index_;
00091       face_vertex_indices_first_element_ = f.face_vertex_indices_first_element_;
00092       face_vertex_indices_previous_element_ = f.face_vertex_indices_previous_element_;
00093       return (*this);
00094     }
00095 
00096     bool 
00097     convert (std::istream& istream, const std::string& istream_filename, std::ostream& ostream, const std::string& ostream_filename);
00098 
00099   private:
00100     void
00101     info_callback (const std::string& filename, std::size_t line_number, const std::string& message);
00102 
00103     void
00104     warning_callback (const std::string& filename, std::size_t line_number, const std::string& message);
00105 
00106     void
00107     error_callback (const std::string& filename, std::size_t line_number, const std::string& message);
00108 
00109     boost::tuple<boost::function<void ()>, boost::function<void ()> > 
00110     element_definition_callback (const std::string& element_name, std::size_t count);
00111 
00112     template <typename ScalarType> boost::function<void (ScalarType)> 
00113     scalar_property_definition_callback (const std::string& element_name, const std::string& property_name);
00114 
00115     template <typename SizeType, typename ScalarType>  boost::tuple<boost::function<void (SizeType)>, 
00116                                                                        boost::function<void (ScalarType)>, 
00117                                                                        boost::function<void ()> > 
00118     list_property_definition_callback (const std::string& element_name, const std::string& property_name);
00119 
00120     void
00121     vertex_begin ();
00122 
00123     void
00124     vertex_x (pcl::io::ply::float32 x);
00125 
00126     void
00127     vertex_y (pcl::io::ply::float32 y);
00128 
00129     void
00130     vertex_z (pcl::io::ply::float32 z);
00131 
00132     void
00133     vertex_end ();
00134 
00135     void
00136     face_begin ();
00137 
00138     void
00139     face_vertex_indices_begin (pcl::io::ply::uint8 size);
00140 
00141     void
00142     face_vertex_indices_element (pcl::io::ply::int32 vertex_index);
00143 
00144     void
00145     face_vertex_indices_end ();
00146 
00147     void
00148     face_end ();
00149 
00150     std::ostream* ostream_;
00151     pcl::io::ply::float32 vertex_x_, vertex_y_, vertex_z_;
00152     pcl::io::ply::int32 face_vertex_indices_element_index_, face_vertex_indices_first_element_, face_vertex_indices_previous_element_;
00153     std::vector<boost::tuple<pcl::io::ply::float32, pcl::io::ply::float32, pcl::io::ply::float32> > vertices_;
00154 };
00155 
00156 void
00157 ply_to_raw_converter::info_callback (const std::string& filename, std::size_t line_number, const std::string& message)
00158 {
00159   std::cerr << filename << ":" << line_number << ": " << "info: " << message << std::endl;
00160 }
00161 
00162 void
00163 ply_to_raw_converter::warning_callback (const std::string& filename, std::size_t line_number, const std::string& message)
00164 {
00165   std::cerr << filename << ":" << line_number << ": " << "warning: " << message << std::endl;
00166 }
00167 
00168 void
00169 ply_to_raw_converter::error_callback (const std::string& filename, std::size_t line_number, const std::string& message)
00170 {
00171   std::cerr << filename << ":" << line_number << ": " << "error: " << message << std::endl;
00172 }
00173 
00174 boost::tuple<boost::function<void ()>, boost::function<void ()> > 
00175 ply_to_raw_converter::element_definition_callback (const std::string& element_name, std::size_t)
00176 {
00177   if (element_name == "vertex") {
00178     return boost::tuple<boost::function<void ()>, boost::function<void ()> > (
00179       boost::bind (&ply_to_raw_converter::vertex_begin, this),
00180       boost::bind (&ply_to_raw_converter::vertex_end, this)
00181     );
00182   }
00183   else if (element_name == "face") {
00184     return boost::tuple<boost::function<void ()>, boost::function<void ()> > (
00185       boost::bind (&ply_to_raw_converter::face_begin, this),
00186       boost::bind (&ply_to_raw_converter::face_end, this)
00187     );
00188   }
00189   else {
00190     return boost::tuple<boost::function<void ()>, boost::function<void ()> > (0, 0);
00191   }
00192 }
00193 
00194 template <> boost::function<void (pcl::io::ply::float32)> 
00195 ply_to_raw_converter::scalar_property_definition_callback (const std::string& element_name, const std::string& property_name)
00196 {
00197   if (element_name == "vertex") {
00198     if (property_name == "x") {
00199       return boost::bind (&ply_to_raw_converter::vertex_x, this, _1);
00200     }
00201     else if (property_name == "y") {
00202       return boost::bind (&ply_to_raw_converter::vertex_y, this, _1);
00203     }
00204     else if (property_name == "z") {
00205       return boost::bind (&ply_to_raw_converter::vertex_z, this, _1);
00206     }
00207     else {
00208       return 0;
00209     }
00210   }
00211   else {
00212     return 0;
00213   }
00214 }
00215 
00216 template <> boost::tuple<boost::function<void (pcl::io::ply::uint8)>, 
00217                             boost::function<void (pcl::io::ply::int32)>, 
00218                             boost::function<void ()> > 
00219 ply_to_raw_converter::list_property_definition_callback (const std::string& element_name, const std::string& property_name)
00220 {
00221   if ((element_name == "face") && (property_name == "vertex_indices")) 
00222   {
00223     return boost::tuple<boost::function<void (pcl::io::ply::uint8)>, 
00224       boost::function<void (pcl::io::ply::int32)>, 
00225       boost::function<void ()> > (
00226         boost::bind (&ply_to_raw_converter::face_vertex_indices_begin, this, _1),
00227       boost::bind (&ply_to_raw_converter::face_vertex_indices_element, this, _1),
00228       boost::bind (&ply_to_raw_converter::face_vertex_indices_end, this)
00229     );
00230   }
00231   else {
00232     return boost::tuple<boost::function<void (pcl::io::ply::uint8)>, 
00233       boost::function<void (pcl::io::ply::int32)>, 
00234       boost::function<void ()> > (0, 0, 0);
00235   }
00236 }
00237 
00238 void
00239 ply_to_raw_converter::vertex_begin () {}
00240 
00241 void
00242 ply_to_raw_converter::vertex_x (pcl::io::ply::float32 x)
00243 {
00244   vertex_x_ = x;
00245 }
00246 
00247 void
00248 ply_to_raw_converter::vertex_y (pcl::io::ply::float32 y)
00249 {
00250   vertex_y_ = y;
00251 }
00252 
00253 void
00254 ply_to_raw_converter::vertex_z (pcl::io::ply::float32 z)
00255 {
00256   vertex_z_ = z;
00257 }
00258 
00259 void
00260 ply_to_raw_converter::vertex_end ()
00261 {
00262   vertices_.push_back (boost::tuple<pcl::io::ply::float32, pcl::io::ply::float32, pcl::io::ply::float32 > (vertex_x_, vertex_y_, vertex_z_));
00263 }
00264 
00265 void
00266 ply_to_raw_converter::face_begin () {}
00267 
00268 void
00269 ply_to_raw_converter::face_vertex_indices_begin (pcl::io::ply::uint8)
00270 {
00271   face_vertex_indices_element_index_ = 0;
00272 }
00273 
00274 void
00275 ply_to_raw_converter::face_vertex_indices_element (pcl::io::ply::int32 vertex_index)
00276 {
00277   if (face_vertex_indices_element_index_ == 0) {
00278     face_vertex_indices_first_element_ = vertex_index;
00279   }
00280   else if (face_vertex_indices_element_index_ == 1) {
00281     face_vertex_indices_previous_element_ = vertex_index;
00282   }
00283   else {
00284     (*ostream_) << boost::get<0> (vertices_[   face_vertex_indices_first_element_])
00285          << " " << boost::get<1> (vertices_[   face_vertex_indices_first_element_])
00286          << " " << boost::get<2> (vertices_[   face_vertex_indices_first_element_])
00287          << " " << boost::get<0> (vertices_[face_vertex_indices_previous_element_])
00288          << " " << boost::get<1> (vertices_[face_vertex_indices_previous_element_])
00289          << " " << boost::get<2> (vertices_[face_vertex_indices_previous_element_])
00290          << " " << boost::get<0> (vertices_[                         vertex_index])
00291          << " " << boost::get<1> (vertices_[                         vertex_index])
00292          << " " << boost::get<2> (vertices_[                         vertex_index]) << "\n";
00293     face_vertex_indices_previous_element_ = vertex_index;
00294   }
00295   ++face_vertex_indices_element_index_;
00296 }
00297 
00298 void
00299 ply_to_raw_converter::face_vertex_indices_end () {}
00300 
00301 void
00302 ply_to_raw_converter::face_end () {}
00303 
00304 bool 
00305 ply_to_raw_converter::convert (std::istream&, const std::string& istream_filename, std::ostream& ostream, const std::string&)
00306 {
00307   pcl::io::ply::ply_parser::flags_type ply_parser_flags = 0;
00308   pcl::io::ply::ply_parser ply_parser (ply_parser_flags);
00309 
00310   ply_parser.info_callback (boost::bind (&ply_to_raw_converter::info_callback, this, boost::ref (istream_filename), _1, _2));
00311   ply_parser.warning_callback (boost::bind (&ply_to_raw_converter::warning_callback, this, boost::ref (istream_filename), _1, _2));
00312   ply_parser.error_callback (boost::bind (&ply_to_raw_converter::error_callback, this, boost::ref (istream_filename), _1, _2)); 
00313 
00314   ply_parser.element_definition_callback (boost::bind (&ply_to_raw_converter::element_definition_callback, this, _1, _2));
00315 
00316   pcl::io::ply::ply_parser::scalar_property_definition_callbacks_type scalar_property_definition_callbacks;
00317   pcl::io::ply::at<pcl::io::ply::float32> (scalar_property_definition_callbacks) = boost::bind (&ply_to_raw_converter::scalar_property_definition_callback<pcl::io::ply::float32>, this, _1, _2);
00318   ply_parser.scalar_property_definition_callbacks (scalar_property_definition_callbacks);
00319 
00320   pcl::io::ply::ply_parser::list_property_definition_callbacks_type list_property_definition_callbacks;
00321   pcl::io::ply::at<pcl::io::ply::uint8, pcl::io::ply::int32> (list_property_definition_callbacks) = boost::bind (&ply_to_raw_converter::list_property_definition_callback<pcl::io::ply::uint8, pcl::io::ply::int32>, this, _1, _2);
00322   ply_parser.list_property_definition_callbacks (list_property_definition_callbacks);
00323 
00324   ostream_ = &ostream;
00325 
00326   return ply_parser.parse (istream_filename);
00327 }
00328 
00329 int main (int argc, char* argv[])
00330 {
00331   int argi;
00332   for (argi = 1; argi < argc; ++argi) {
00333 
00334     if (argv[argi][0] != '-') {
00335       break;
00336     }
00337     if (argv[argi][1] == 0) {
00338       ++argi;
00339       break;
00340     }
00341     char short_opt, *long_opt, *opt_arg;
00342     if (argv[argi][1] != '-') {
00343       short_opt = argv[argi][1];
00344       opt_arg = &argv[argi][2];
00345       long_opt = &argv[argi][2];
00346       while (*long_opt != '\0') {
00347         ++long_opt;
00348       }
00349     }
00350     else {
00351       short_opt = 0;
00352       long_opt = &argv[argi][2];
00353       opt_arg = long_opt;
00354       while ((*opt_arg != '=') && (*opt_arg != '\0')) {
00355         ++opt_arg;
00356       }
00357       if (*opt_arg == '=') {
00358         *opt_arg++ = '\0';
00359       }
00360     }
00361 
00362     if ((short_opt == 'h') || (std::strcmp (long_opt, "help") == 0)) {
00363       std::cout << "Usage: ply2raw [OPTION] [[INFILE] OUTFILE]\n";
00364       std::cout << "Convert from PLY to POV-Ray RAW triangle format.\n";
00365       std::cout << "\n";
00366       std::cout << "  -h, --help       display this help and exit\n";
00367       std::cout << "  -v, --version    output version information and exit\n";
00368       std::cout << "\n";
00369       std::cout << "With no INFILE/OUTFILE, or when INFILE/OUTFILE is -, read standard input/output.\n";
00370       std::cout << "\n";
00371       std::cout << "The following PLY elements and properties are supported.\n";
00372       std::cout << "  element vertex\n";
00373       std::cout << "    property float32 x\n";
00374       std::cout << "    property float32 y\n";
00375       std::cout << "    property float32 z\n";
00376       std::cout << "  element face\n";
00377       std::cout << "    property list uint8 int32 vertex_indices.\n";
00378       std::cout << "\n";
00379       std::cout << "Report bugs to <www.pointclouds.org/issues>.\n";
00380       return EXIT_SUCCESS;
00381     }
00382 
00383     else if ((short_opt == 'v') || (std::strcmp (long_opt, "version") == 0)) {
00384       std::cout << "ply2raw \n";
00385       std::cout << " Point Cloud Library (PCL) - www.pointclouds.org\n";
00386       std::cout << " Copyright (c) 2007-2012, Ares Lagae\n";
00387       std::cout << " Copyright (c) 2012, Willow Garage, Inc.\n";
00388       std::cout << " All rights reserved.\n";
00389       std::cout << " Redistribution and use in source and binary forms, with or without\n";
00390       std::cout << " modification, are permitted provided that the following conditions\n";
00391       std::cout << " are met:\n";
00392       std::cout << "  * Redistributions of source code must retain the above copyright\n";
00393       std::cout << "    notice, this list of conditions and the following disclaimer.\n";
00394       std::cout << "  * Redistributions in binary form must reproduce the above\n";
00395       std::cout << "    copyright notice, this list of conditions and the following\n";
00396       std::cout << "    disclaimer in the documentation and/or other materials provided\n";
00397       std::cout << "    with the distribution.\n";
00398       std::cout << "  * Neither the name of Willow Garage, Inc. nor the names of its\n";
00399       std::cout << "    contributors may be used to endorse or promote products derived\n";
00400       std::cout << "    from this software without specific prior written permission.\n";
00401       std::cout << " THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n";
00402       std::cout << " \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n";
00403       std::cout << " LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n";
00404       std::cout << " FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n";
00405       std::cout << " COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n";
00406       std::cout << " INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n";
00407       std::cout << " BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n";
00408       std::cout << " LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n";
00409       std::cout << " CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n";
00410       std::cout << " LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n";
00411       std::cout << " ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n";
00412       std::cout << " POSSIBILITY OF SUCH DAMAGE.\n";
00413       return EXIT_SUCCESS;
00414     }
00415 
00416     else {
00417       std::cerr << "ply2raw: " << "invalid option `" << argv[argi] << "'" << "\n";
00418       std::cerr << "Try `" << argv[0] << " --help' for more information.\n";
00419       return EXIT_FAILURE;
00420     }
00421   }
00422 
00423   int parc = argc - argi;
00424   char** parv = argv + argi;
00425   if (parc > 2) {
00426     std::cerr << "ply2raw: " << "too many parameters" << "\n";
00427     std::cerr << "Try `" << argv[0] << " --help' for more information.\n";
00428     return EXIT_FAILURE;
00429   }
00430 
00431   std::ifstream ifstream;
00432   const char* istream_filename = "";
00433   if (parc > 0) {
00434     istream_filename = parv[0];
00435     if (std::strcmp (istream_filename, "-") != 0) {
00436       ifstream.open (istream_filename);
00437       if (!ifstream.is_open ()) {
00438         std::cerr << "ply2raw: " << istream_filename << ": " << "no such file or directory" << "\n";
00439         return EXIT_FAILURE;
00440       }
00441     }
00442   }
00443 
00444   std::ofstream ofstream;
00445   const char* ostream_filename = "";
00446   if (parc > 1) {
00447     ostream_filename = parv[1];
00448     if (std::strcmp (ostream_filename, "-") != 0) {
00449       ofstream.open (ostream_filename);
00450       if (!ofstream.is_open ()) {
00451         std::cerr << "ply2raw: " << ostream_filename << ": " << "could not open file" << "\n";
00452         return EXIT_FAILURE;
00453       }
00454     }
00455   }
00456 
00457   std::istream& istream = ifstream.is_open () ? ifstream : std::cin;
00458   std::ostream& ostream = ofstream.is_open () ? ofstream : std::cout;
00459 
00460   class ply_to_raw_converter ply_to_raw_converter;
00461   return ply_to_raw_converter.convert (istream, istream_filename, ostream, ostream_filename);
00462 }


pcl
Author(s): Open Perception
autogenerated on Mon Oct 6 2014 03:16:32