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;
00049 break;
00050 case aiOrigin_END:
00051 new_pos = res_.data.get() + res_.size - offset;
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
00096 bool Exists(const char* file) const
00097 {
00098
00099
00100
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
00115 char getOsSeparator() const
00116 {
00117 return '/';
00118 }
00119
00120
00121 Assimp::IOStream* Open(const char* file, const char* mode)
00122 {
00123 ROS_ASSERT(mode == std::string("r") || mode == std::string("rb"));
00124
00125
00126
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 }