load_assimp.cpp
Go to the documentation of this file.
00001 #include <ros/ros.h>
00002 
00003 #include <assimp/assimp.hpp> 
00004 #include <assimp/aiScene.h>
00005 #include <assimp/aiPostProcess.h>
00006 #include <assimp/IOStream.h>
00007 #include <assimp/IOSystem.h>
00008 
00009 #include <resource_retriever/retriever.h>
00010 
00011 class ResourceIOStream : public Assimp::IOStream
00012 {
00013 public:
00014   ResourceIOStream(const resource_retriever::MemoryResource& res)
00015     : res_(res)
00016     , pos_(res.data.get())
00017   {}
00018 
00019   ~ResourceIOStream()
00020   {}
00021 
00022   size_t Read(void* buffer, size_t size, size_t count)
00023   {
00024     size_t to_read = size * count;
00025     if (pos_ + to_read > res_.data.get() + res_.size)
00026       {
00027         to_read = res_.size - (pos_ - res_.data.get());
00028       }
00029 
00030     memcpy(buffer, pos_, to_read);
00031     pos_ += to_read;
00032 
00033     return to_read;
00034   }
00035 
00036   size_t Write( const void* buffer, size_t size, size_t count) {
00037     ROS_BREAK(); return 0; }
00038 
00039   aiReturn Seek( size_t offset, aiOrigin origin)
00040   {
00041     uint8_t* new_pos = 0;
00042     switch (origin)
00043       {
00044       case aiOrigin_SET:
00045         new_pos = res_.data.get() + offset;
00046         break;
00047       case aiOrigin_CUR:
00048         new_pos = pos_ + offset; // TODO is this right?  can offset  really not be negative
00049     break;
00050       case aiOrigin_END:
00051         new_pos = res_.data.get() + res_.size - offset; // TODO is   this right?
00052     break;
00053       default:
00054         ROS_BREAK();
00055       }
00056 
00057     if (new_pos < res_.data.get() || new_pos > res_.data.get() +
00058     res_.size)
00059       {
00060         return aiReturn_FAILURE;
00061       }
00062 
00063     pos_ = new_pos;
00064     return aiReturn_SUCCESS;
00065   }
00066 
00067   size_t Tell() const
00068   {
00069     return pos_ - res_.data.get();
00070   }
00071 
00072   size_t FileSize() const
00073   {
00074     return res_.size;
00075   }
00076 
00077   void Flush() {}
00078 
00079 private:
00080   resource_retriever::MemoryResource res_;
00081   uint8_t* pos_;
00082 };
00083 
00084 class ResourceIOSystem : public Assimp::IOSystem
00085 {
00086 public:
00087   ResourceIOSystem()
00088   {
00089   }
00090 
00091   ~ResourceIOSystem()
00092   {
00093   }
00094 
00095   // Check whether a specific file exists
00096   bool Exists(const char* file) const
00097   {
00098     // Ugly -- two retrievals where there should be one (Exists + Open)
00099   // resource_retriever needs a way of checking for existence
00100   // TODO: cache this
00101   resource_retriever::MemoryResource res;
00102       try 
00103         {   
00104           res = retriever_.get(file);
00105         }   
00106       catch (resource_retriever::Exception& e)
00107         {   
00108           return false;
00109         }   
00110 
00111   return true;
00112 }
00113 
00114 // Get the path delimiter character we'd like to see
00115   char getOsSeparator() const
00116   {
00117     return '/';
00118   }
00119 
00120 // ... and finally a method to open a custom stream
00121 Assimp::IOStream* Open(const char* file, const char* mode)
00122 {
00123   ROS_ASSERT(mode == std::string("r") || mode == std::string("rb"));
00124 
00125   // Ugly -- two retrievals where there should be one (Exists + Open)
00126   // resource_retriever needs a way of checking for existence
00127   resource_retriever::MemoryResource res;
00128       try 
00129         {   
00130           res = retriever_.get(file);
00131         }   
00132       catch (resource_retriever::Exception& e)
00133         {   
00134           return 0;
00135         }   
00136 
00137       return new ResourceIOStream(res);
00138 }
00139 
00140 void Close(Assimp::IOStream* stream) { delete stream; }
00141 
00142 private:
00143 mutable resource_retriever::Retriever retriever_;
00144 };
00145 
00146 
00147 int main(int argc, char **argv)
00148 {
00149   Assimp::Importer as_importer;
00150   as_importer.SetIOHandler(new ResourceIOSystem());
00151   std::string filename;
00152   if (argc == 2)
00153     filename = argv[1];
00154   else
00155     filename = "package://pr2_description/meshes/base_v0/base.stl";
00156   const aiScene* scene =
00157     as_importer.ReadFile(filename.c_str(), aiProcess_SortByPType|aiProcess_GenNormals|aiProcess_Triangulate|aiProcess_GenUVCoords|aiProcess_FlipUVs);
00158   
00159   if (!scene)
00160     {
00161       ROS_ERROR("Could not load resource [%s]: %s", filename.c_str(),
00162                 as_importer.GetErrorString());
00163     }
00164 }


camera_self_filter
Author(s): Christian Bersch (Maintained by Benjamin Pitzer)
autogenerated on Mon Oct 6 2014 10:08:56