ModelLoader_impl.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008, AIST, the University of Tokyo and General Robotix Inc.
00003  * All rights reserved. This program is made available under the terms of the
00004  * Eclipse Public License v1.0 which accompanies this distribution, and is
00005  * available at http://www.eclipse.org/legal/epl-v10.html
00006  * Contributors:
00007  * National Institute of Advanced Industrial Science and Technology (AIST)
00008  */
00009 
00015 #include "ModelLoader_impl.h"
00016 
00017 #include <iostream>
00018 #include <sys/types.h>
00019 #include <sys/stat.h>
00020 
00021 #include "VrmlUtil.h"
00022 
00023 using namespace std;
00024 
00025 #ifdef OPENHRP_COLLADA_FOUND
00026 #include <boost/foreach.hpp>
00027 #include "ColladaWriter.h"
00028 #include "BodyInfoCollada_impl.h"
00029 #include "SceneInfoCollada_impl.h"
00030 
00031 static bool IsColladaFile(const std::string& filename)
00032 {
00033     size_t len = filename.size();
00034     if( len < 4 ) {
00035         return false;
00036     }
00037     if( filename[len-4] == '.' && ::tolower(filename[len-3]) == 'd' && ::tolower(filename[len-2]) == 'a' && ::tolower(filename[len-1]) == 'e' ) {
00038         return true;
00039     }
00040     if( filename[len-4] == '.' && ::tolower(filename[len-3]) == 'z' && ::tolower(filename[len-2]) == 'a' && ::tolower(filename[len-1]) == 'e' ) {
00041         return true;
00042     }
00043     return false;
00044 }
00045 
00046 #endif
00047 
00048 std::string replaceProjectDir(std::string url) {
00049   std::string path = url;
00050   if ( path.find("$(PROJECT_DIR)") != std::string::npos ) {
00051     std::string shdir = OPENHRP_SHARE_DIR;
00052     std::string pjdir = shdir + "/sample/project";
00053     path.replace(path.find("$(PROJECT_DIR)"),14, pjdir);
00054   }
00055   return path;
00056 }
00057 
00058 ModelLoader_impl::ModelLoader_impl(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa)
00059     :
00060     orb(CORBA::ORB::_duplicate(orb)),
00061     poa(PortableServer::POA::_duplicate(poa))
00062 {
00063 
00064 }
00065 
00066 
00067 ModelLoader_impl::~ModelLoader_impl()
00068 {
00069     clearData();
00070 }
00071 
00072 
00073 PortableServer::POA_ptr ModelLoader_impl::_default_POA()
00074 {
00075     return PortableServer::POA::_duplicate(poa);
00076 }
00077 
00078 // the dynamic casts are necessary since the changetoBoundingBox functions are not part of BodyInfo class.
00079 static void setLastUpdateTime(POA_OpenHRP::BodyInfo* bodyInfo, time_t time)
00080 {
00081     BodyInfo_impl* pBodyInfo_impl = dynamic_cast<BodyInfo_impl*>(bodyInfo);
00082     if( !!pBodyInfo_impl ) {
00083         pBodyInfo_impl->setLastUpdateTime(time);
00084         return;
00085     }
00086 #ifdef OPENHRP_COLLADA_FOUND
00087     BodyInfoCollada_impl* pBodyInfoCollada_impl = dynamic_cast<BodyInfoCollada_impl*>(bodyInfo);
00088     if( !!pBodyInfoCollada_impl ) {
00089         pBodyInfoCollada_impl->setLastUpdateTime(time);
00090         return;
00091     }
00092 #endif
00093     throw ModelLoader::ModelLoaderException("setLastUpdateTime invalid pointer");
00094 };
00095 
00096 static time_t getLastUpdateTime(POA_OpenHRP::BodyInfo* bodyInfo) {
00097     BodyInfo_impl* pBodyInfo_impl = dynamic_cast<BodyInfo_impl*>(bodyInfo);
00098     if( !!pBodyInfo_impl ) {
00099         return pBodyInfo_impl->getLastUpdateTime();
00100     }
00101 #ifdef OPENHRP_COLLADA_FOUND
00102     BodyInfoCollada_impl* pBodyInfoCollada_impl = dynamic_cast<BodyInfoCollada_impl*>(bodyInfo);
00103     if( !!pBodyInfoCollada_impl ) {
00104         return pBodyInfoCollada_impl->getLastUpdateTime();
00105     }
00106 #endif
00107     throw ModelLoader::ModelLoaderException("getLastUpdateTime invalid pointer");
00108 }
00109 
00110 static bool checkInlineFileUpdateTime(POA_OpenHRP::BodyInfo* bodyInfo)
00111 {
00112     BodyInfo_impl* pBodyInfo_impl = dynamic_cast<BodyInfo_impl*>(bodyInfo);
00113     if( !!pBodyInfo_impl ) {
00114         return pBodyInfo_impl->checkInlineFileUpdateTime();
00115     }
00116 #ifdef OPENHRP_COLLADA_FOUND
00117     BodyInfoCollada_impl* pBodyInfoCollada_impl = dynamic_cast<BodyInfoCollada_impl*>(bodyInfo);
00118     if( !!pBodyInfoCollada_impl ) {
00119         return pBodyInfoCollada_impl->checkInlineFileUpdateTime();
00120     }
00121 #endif
00122     throw ModelLoader::ModelLoaderException("checkInlineFileUpdateTime invalid pointer");
00123 }
00124 
00125 static void setParam(POA_OpenHRP::BodyInfo* bodyInfo, std::string param, int value)
00126 {
00127     BodyInfo_impl* pBodyInfo_impl = dynamic_cast<BodyInfo_impl*>(bodyInfo);
00128     if( !!pBodyInfo_impl ) {
00129         pBodyInfo_impl->setParam(param,value);
00130         return;
00131     }
00132 #ifdef OPENHRP_COLLADA_FOUND
00133     BodyInfoCollada_impl* pBodyInfoCollada_impl = dynamic_cast<BodyInfoCollada_impl*>(bodyInfo);
00134     if( !!pBodyInfoCollada_impl ) {
00135         pBodyInfoCollada_impl->setParam(param,value);
00136         return;
00137     }
00138 #endif
00139     throw ModelLoader::ModelLoaderException("setParam(param,value) invalid pointer");
00140 }
00141 
00142 static void changetoBoundingBox(POA_OpenHRP::BodyInfo* bodyInfo, unsigned int* depth)
00143 {
00144     BodyInfo_impl* pBodyInfo_impl = dynamic_cast<BodyInfo_impl*>(bodyInfo);
00145     if( !!pBodyInfo_impl ) {
00146         pBodyInfo_impl->changetoBoundingBox(depth);
00147         return;
00148     }
00149 #ifdef OPENHRP_COLLADA_FOUND
00150     BodyInfoCollada_impl* pBodyInfoCollada_impl = dynamic_cast<BodyInfoCollada_impl*>(bodyInfo);
00151     if( !!pBodyInfoCollada_impl ) {
00152         pBodyInfoCollada_impl->changetoBoundingBox(depth);
00153         return;
00154     }
00155 #endif
00156     throw ModelLoader::ModelLoaderException("changetoBoundingBox(depth) invalid pointer");
00157 }
00158 
00159 BodyInfo_ptr ModelLoader_impl::loadBodyInfo(const char* url)
00160     throw (CORBA::SystemException, OpenHRP::ModelLoader::ModelLoaderException)
00161 {
00162     OpenHRP::ModelLoader::ModelLoadOption option;
00163     option.readImage = false;
00164     option.AABBdata.length(0);
00165     option.AABBtype = OpenHRP::ModelLoader::AABB_NUM;
00166     POA_OpenHRP::BodyInfo* bodyInfo = loadBodyInfoFromModelFile(replaceProjectDir(std::string(url)), option);
00167     return bodyInfo->_this();
00168 }
00169 
00170 BodyInfo_ptr ModelLoader_impl::loadBodyInfoEx(const char* url, const OpenHRP::ModelLoader::ModelLoadOption& option)
00171     throw (CORBA::SystemException, OpenHRP::ModelLoader::ModelLoaderException)
00172 {
00173     POA_OpenHRP::BodyInfo* bodyInfo = loadBodyInfoFromModelFile(replaceProjectDir(std::string(url)), option);
00174     if(option.AABBdata.length()){
00175         setParam(bodyInfo,"AABBType", (int)option.AABBtype);
00176         int length=option.AABBdata.length();
00177         unsigned int* _AABBdata = new unsigned int[length];
00178         for(int i=0; i<length; i++)
00179             _AABBdata[i] = option.AABBdata[i];
00180         changetoBoundingBox(bodyInfo,_AABBdata);
00181         delete[] _AABBdata;
00182     }
00183     return bodyInfo->_this();
00184 }
00185 
00186 BodyInfo_ptr ModelLoader_impl::getBodyInfoEx(const char* url0, const OpenHRP::ModelLoader::ModelLoadOption& option)
00187     throw (CORBA::SystemException, OpenHRP::ModelLoader::ModelLoaderException)
00188 {
00189     string url(url0);
00190 
00191     BodyInfo_ptr bodyInfo = 0;
00192     string filename(deleteURLScheme(replaceProjectDir(url)));
00193     struct stat statbuff;
00194     time_t mtime = 0;
00195 
00196     // get a file modification time
00197     if( stat( filename.c_str(), &statbuff ) == 0 ){
00198         mtime = statbuff.st_mtime;
00199     }
00200 
00201     UrlToBodyInfoMap::iterator p = urlToBodyInfoMap.find(url);
00202     if(p != urlToBodyInfoMap.end() && mtime == getLastUpdateTime(p->second) && checkInlineFileUpdateTime(p->second)){
00203         bodyInfo = p->second->_this();
00204         cout << string("cache found for ") + url << endl;
00205         if(option.AABBdata.length()){
00206             setParam(p->second,"AABBType", (int)option.AABBtype);
00207             int length=option.AABBdata.length();
00208             unsigned int* _AABBdata = new unsigned int[length];
00209             for(int i=0; i<length; i++)
00210                 _AABBdata[i] = option.AABBdata[i];
00211             changetoBoundingBox(p->second,_AABBdata);
00212             delete[] _AABBdata;
00213         }
00214         return bodyInfo;
00215     } 
00216     return loadBodyInfoEx(url0, option);
00217 }
00218 
00219 BodyInfo_ptr ModelLoader_impl::getBodyInfo(const char* url)
00220     throw (CORBA::SystemException, OpenHRP::ModelLoader::ModelLoaderException)
00221 {
00222     OpenHRP::ModelLoader::ModelLoadOption option;
00223     option.readImage = false;
00224     option.AABBdata.length(0);
00225     option.AABBtype = OpenHRP::ModelLoader::AABB_NUM;
00226     return getBodyInfoEx(url, option);
00227 }
00228 
00229 POA_OpenHRP::BodyInfo* ModelLoader_impl::loadBodyInfoFromModelFile(const string url, const OpenHRP::ModelLoader::ModelLoadOption option)
00230 {
00231     cout << "loading " << url << endl;
00232     POA_OpenHRP::BodyInfo* bodyInfo;
00233     try {
00234 #ifdef OPENHRP_COLLADA_FOUND
00235         if( IsColladaFile(url) ) {
00236             BodyInfoCollada_impl* p = new BodyInfoCollada_impl(poa);
00237             p->setParam("readImage", option.readImage);
00238             p->loadModelFile(url);
00239             bodyInfo = p;
00240         }
00241         else
00242 #endif
00243         {
00244             BodyInfo_impl* p = new BodyInfo_impl(poa);
00245             p->setParam("readImage", option.readImage);
00246             p->loadModelFile(url);
00247             bodyInfo = p;
00248         }
00249     }
00250     catch(OpenHRP::ModelLoader::ModelLoaderException& ex){
00251         cout << "loading failed.\n";
00252         cout << ex.description << endl;
00253         //bodyInfo->_remove_ref();
00254         throw;
00255     }
00256         
00257     cout << "The model was successfully loaded ! " << endl;
00258     
00259 #ifdef OPENHRP_COLLADA_FOUND
00260 //    cout << "Saving COLLADA file to hiro.dae" << endl;
00261 //    ColladaWriter colladawriter;
00262 //    colladawriter.Write(bodyInfo);
00263 //    colladawriter.Save("/home/jsk/rdiankov/hiro.dae");
00264 #endif
00265 
00266     //poa->activate_object(bodyInfo);
00267     urlToBodyInfoMap[url] = bodyInfo;
00268 
00269     string filename(deleteURLScheme(url));
00270     struct stat statbuff;
00271     time_t mtime = 0;
00272 
00273     // get a file modification time
00274     if( stat( filename.c_str(), &statbuff ) == 0 ){
00275         mtime = statbuff.st_mtime;
00276     }
00277     setLastUpdateTime(bodyInfo, mtime );
00278 
00279     return bodyInfo;
00280 }
00281 
00282 
00283 
00284 SceneInfo_ptr ModelLoader_impl::loadSceneInfo(const char* url)
00285     throw (CORBA::SystemException, OpenHRP::ModelLoader::ModelLoaderException)
00286 {
00287     cout << "loading " << url << endl;
00288 
00289     SceneInfo_impl* sceneInfo;
00290     try {
00291 #ifdef OPENHRP_COLLADA_FOUND
00292         if( IsColladaFile(url) ) {
00293             SceneInfoCollada_impl* p = new SceneInfoCollada_impl(poa);
00294             p->load(url);
00295             sceneInfo = p;
00296         }
00297         else
00298 #endif
00299         {
00300             SceneInfo_impl* p = new SceneInfo_impl(poa);
00301             p->load(url);
00302             sceneInfo = p;
00303         }
00304     }
00305     catch(OpenHRP::ModelLoader::ModelLoaderException& ex){
00306         cout << "loading failed.\n";
00307         cout << ex.description << endl;
00308         //sceneInfo->_remove_ref();
00309         throw;
00310     }
00311     cout << url << " was successfully loaded ! " << endl;
00312     
00313     //poa->activate_object(sceneInfo);
00314 
00315     return sceneInfo->_this();
00316 }
00317 
00318 
00319 void ModelLoader_impl::clearData()
00320 {
00321     //UrlToBodyInfoMap::iterator p;
00322     //for(p = urlToBodyInfoMap.begin(); p != urlToBodyInfoMap.end(); ++p){
00323     //  BodyInfo_impl* bodyInfo = p->second;
00324     //  PortableServer::ObjectId_var objectId = poa->servant_to_id(bodyInfo);
00325     //  poa->deactivate_object(objectId);
00326     //  bodyInfo->_remove_ref();
00327     //}
00328     urlToBodyInfoMap.clear();
00329 }
00330 
00331 
00332 void ModelLoader_impl::shutdown()
00333 {
00334     clearData();
00335     orb->shutdown(false);
00336 }


openhrp3
Author(s): AIST, General Robotix Inc., Nakamura Lab of Dept. of Mechano Informatics at University of Tokyo
autogenerated on Thu Apr 11 2019 03:30:17