#include "osg/Notify" #include "osg/Object" #include "osg/Image" #include "osg/Node" #include "osg/Group" #include "osg/Geode" #include "osgDB/Registry" #include "osgDB/FileUtils" #include "osgDB/FileNameUtils" #include #include #include using namespace osg; using namespace osgDB; class RegistryPtr { public: RegistryPtr() : _ptr(0L) {} RegistryPtr(Registry* t): _ptr(t) {} RegistryPtr(const RegistryPtr& rp):_ptr(rp._ptr) { } ~RegistryPtr() { if (_ptr) delete _ptr; _ptr=0L; } inline Registry* get() { return _ptr; } Registry* _ptr; }; // definition of the Registry Registry::Registry() { notify(INFO) << "Constructing osg::Registry"<getName()<<")"<getAssociates(); for(DotOsgWrapper::Associates::const_iterator itr=assoc.begin(); itr!=assoc.end(); ++itr) { notify(INFO) << " ("<<*itr<<")"<getName(); const osg::Object* proto = wrapper->getPrototype(); _objectWrapperMap[name] = wrapper; if (proto) { if (wrapper->getReadWriteMode()==DotOsgWrapper::READ_AND_WRITE) _classNameWrapperMap[proto->className()] = wrapper; if (dynamic_cast(proto)) _imageWrapperMap[name] = wrapper; if (dynamic_cast(proto)) _drawableWrapperMap[name] = wrapper; if (dynamic_cast(proto)) _stateAttrWrapperMap[name] = wrapper; if (dynamic_cast(proto)) _nodeWrapperMap[name] = wrapper; } } #define EraseMacro(WL,W) \ { \ DotOsgWrapperMap::iterator itr = WL.find(W->getName()); \ if (itr!=WL.end() && itr->second.get()==W) WL.erase(itr); \ } void Registry::removeDotOsgWrapper(DotOsgWrapper* wrapper) { if (wrapper==0L) return; //// notify(INFO) << "osg::Registry::removeReaderWriter();"<className()<<")"<second); #ifdef WIN32 # ifdef _DEBUG return "osgdb_"+ext+"d.dll"; # else return "osgdb_"+ext+".dll"; # endif #elif macintosh return "osgdb_"+ext; #else return "osgdb_"+ext+".so"; #endif } bool Registry::loadLibrary(const std::string& fileName) { DynamicLibrary* dl = getLibrary(fileName); if (dl) return false; _openingLibrary=true; dl = DynamicLibrary::loadLibrary(fileName); _openingLibrary=false; if (dl) { dl->ref(); _dlList.push_back(dl); return true; } return false; } bool Registry::closeLibrary(const std::string& fileName) { DynamicLibraryList::iterator ditr = getLibraryItr(fileName); if (ditr!=_dlList.end()) { _dlList.erase(ditr); return true; } return false; } Registry::DynamicLibraryList::iterator Registry::getLibraryItr(const std::string& fileName) { DynamicLibraryList::iterator ditr = _dlList.begin(); for(;ditr!=_dlList.end();++ditr) { if ((*ditr)->getName()==fileName) return ditr; } return _dlList.end(); } DynamicLibrary* Registry::getLibrary(const std::string& fileName) { DynamicLibraryList::iterator ditr = getLibraryItr(fileName); if (ditr!=_dlList.end()) return ditr->get(); else return NULL; } osg::Object* Registry::readObjectOfType(const osg::Object& compObj,Input& fr) { const char *str = fr[0].getStr(); if (str==NULL) return NULL; if (fr[0].matchWord("Use")) { if (fr[1].isString()) { Object* obj = fr.getObjectForUniqueID(fr[1].getStr()); if (compObj.isSameKindAs(obj)) fr+=2; return obj; } else return NULL; } std::string name = str; DotOsgWrapperMap::iterator itr = _objectWrapperMap.find(name); if (itr!=_objectWrapperMap.end() && fr[1].isOpenBracket()) { DotOsgWrapper* wrapper = itr->second.get(); const osg::Object* proto = wrapper->getPrototype(); if (proto==NULL) { osg::notify(osg::WARN)<<"Token "<getAssociates(); osg::Object* obj = proto->clone(); while(!fr.eof() && fr[0].getNoNestedBrackets()>entry) { bool iteratorAdvanced = false; if (fr[0].matchWord("UniqueID") && fr[1].isString()) { fr.regisiterUniqueIDForObject(fr[1].getStr(),obj); fr += 2; iteratorAdvanced = true; } // read the local data by iterating through the associate // list, mapping the associate names to DotOsgWrapper's which // in turn have the appropriate functions. for(DotOsgWrapper::Associates::const_iterator aitr=assoc.begin(); aitr!=assoc.end(); ++aitr) { DotOsgWrapperMap::iterator mitr = _objectWrapperMap.find(*aitr); if (mitr!=_objectWrapperMap.end()) { // get the function to read the data... DotOsgWrapper::ReadFunc rf = mitr->second->getReadFunc(); if (rf && (*rf)(*obj,fr)) iteratorAdvanced = true; } } if (!iteratorAdvanced) ++fr; } ++fr; // step over trailing '}' return obj; } return 0L; } // // read object from input iterator. // osg::Object* Registry::readObject(DotOsgWrapperMap& dowMap,Input& fr) { const char *str = fr[0].getStr(); if (str==NULL) return NULL; std::string name = str; DotOsgWrapperMap::iterator itr = dowMap.find(name); if (itr!=dowMap.end() && fr[1].isOpenBracket()) { DotOsgWrapper* wrapper = itr->second.get(); const osg::Object* proto = wrapper->getPrototype(); if (proto==NULL) { osg::notify(osg::WARN)<<"Token "<getAssociates(); osg::Object* obj = proto->clone(); while(!fr.eof() && fr[0].getNoNestedBrackets()>entry) { bool iteratorAdvanced = false; if (fr[0].matchWord("UniqueID") && fr[1].isString()) { fr.regisiterUniqueIDForObject(fr[1].getStr(),obj); fr += 2; iteratorAdvanced = true; } // read the local data by iterating through the associate // list, mapping the associate names to DotOsgWrapper's which // in turn have the appropriate functions. for(DotOsgWrapper::Associates::const_iterator aitr=assoc.begin(); aitr!=assoc.end(); ++aitr) { DotOsgWrapperMap::iterator mitr = _objectWrapperMap.find(*aitr); if (mitr!=_objectWrapperMap.end()) { // get the function to read the data... DotOsgWrapper::ReadFunc rf = mitr->second->getReadFunc(); if (rf && (*rf)(*obj,fr)) iteratorAdvanced = true; } } if (!iteratorAdvanced) ++fr; } ++fr; // step over trailing '}' return obj; } return 0L; } // // read object from input iterator. // Object* Registry::readObject(Input& fr) { if (fr[0].matchWord("Use")) { if (fr[1].isString()) { Object* obj = fr.getObjectForUniqueID(fr[1].getStr()); if (obj) fr+=2; return obj; } else return NULL; } return readObject(_objectWrapperMap,fr); } // // read image from input iterator. // Image* Registry::readImage(Input& fr) { if (fr[0].matchWord("Use")) { if (fr[1].isString()) { Image* image = dynamic_cast(fr.getObjectForUniqueID(fr[1].getStr())); if (image) fr+=2; return image; } else return NULL; } return dynamic_cast(readObject(_imageWrapperMap,fr)); } // // read drawable from input iterator. // Drawable* Registry::readDrawable(Input& fr) { if (fr[0].matchWord("Use")) { if (fr[1].isString()) { Drawable* drawable = dynamic_cast(fr.getObjectForUniqueID(fr[1].getStr())); if (drawable) fr+=2; return drawable; } else return NULL; } return dynamic_cast(readObject(_drawableWrapperMap,fr)); } // // read drawable from input iterator. // StateAttribute* Registry::readStateAttribute(Input& fr) { if (fr[0].matchWord("Use")) { if (fr[1].isString()) { StateAttribute* attribute = dynamic_cast(fr.getObjectForUniqueID(fr[1].getStr())); if (attribute) fr+=2; return attribute; } else return NULL; } return dynamic_cast(readObject(_stateAttrWrapperMap,fr)); } // // read node from input iterator. // Node* Registry::readNode(Input& fr) { if (fr[0].matchWord("Use")) { if (fr[1].isString()) { Node* node = dynamic_cast(fr.getObjectForUniqueID(fr[1].getStr())); if (node) fr+=2; return node; } else return NULL; } return dynamic_cast(readObject(_nodeWrapperMap,fr)); } // // Write object to output // bool Registry::writeObject(const osg::Object& obj,Output& fw) { if (obj.referenceCount()>1) { std::string uniqueID; if (fw.getUniqueIDForObject(&obj,uniqueID)) { fw.indent() << "Use " << uniqueID << endl; return true; } } std::string classname = obj.className(); DotOsgWrapperMap::iterator itr = _classNameWrapperMap.find(classname); if (itr!=_classNameWrapperMap.end()) { DotOsgWrapper* wrapper = itr->second.get(); const DotOsgWrapper::Associates& assoc = wrapper->getAssociates(); fw.indent() << wrapper->getName() << " {"<1) { std::string uniqueID; fw.createUniqueIDForObject(&obj,uniqueID); fw.registerUniqueIDForObject(&obj,uniqueID); fw.indent() << "UniqueID " << uniqueID << endl; } // read the local data by iterating through the associate // list, mapping the associate names to DotOsgWrapper's which // in turn have the appropriate functions. for(DotOsgWrapper::Associates::const_iterator aitr=assoc.begin(); aitr!=assoc.end(); ++aitr) { DotOsgWrapperMap::iterator mitr = _objectWrapperMap.find(*aitr); if (mitr!=_objectWrapperMap.end()) { // get the function to read the data... DotOsgWrapper::WriteFunc wf = mitr->second->getWriteFunc(); if (wf) (*wf)(obj,fw); } } fw.moveOut(); fw.indent() << "}"< rwOriginal; // first attempt to load the file from existing ReaderWriter's for(ReaderWriterList::iterator itr=_rwList.begin(); itr!=_rwList.end(); ++itr) { rwOriginal.insert(itr->get()); Object* obj = (*itr)->readObject(file); if (obj) return obj; } // now look for a plug-in to load the file. std::string libraryName = createLibraryNameForFile(fileName); if (Registry::instance()->loadLibrary(libraryName)) { for(ReaderWriterList::iterator itr=_rwList.begin(); itr!=_rwList.end(); ++itr) { if (rwOriginal.find(itr->get())==rwOriginal.end()) { Object* obj = (*itr)->readObject(file); if (obj) return obj; } } } else { notify(NOTICE)<<"Warning: Could not find plugin to read file with extension ." < rwOriginal; // first attempt to load the file from existing ReaderWriter's for(ReaderWriterList::iterator itr=_rwList.begin(); itr!=_rwList.end(); ++itr) { rwOriginal.insert(itr->get()); if ((*itr)->writeObject(obj,fileName)) return true; } // now look for a plug-in to save the file. std::string libraryName = createLibraryNameForFile(fileName); if (loadLibrary(libraryName)) { for(ReaderWriterList::iterator itr=_rwList.begin(); itr!=_rwList.end(); ++itr) { if (rwOriginal.find(itr->get())==rwOriginal.end()) { if ((*itr)->writeObject(obj,fileName)) return true; } } } else { notify(NOTICE)<<"Warning: Could not find plugin to write file with extension ." < rwOriginal; // first attempt to load the file from existing ReaderWriter's for(ReaderWriterList::iterator itr=_rwList.begin(); itr!=_rwList.end(); ++itr) { rwOriginal.insert(itr->get()); Image* image = (*itr)->readImage(file); if (image) return image; } // now look for a plug-in to load the file. std::string libraryName = createLibraryNameForFile(fileName); if (loadLibrary(libraryName)) { for(ReaderWriterList::iterator itr=_rwList.begin(); itr!=_rwList.end(); ++itr) { if (rwOriginal.find(itr->get())==rwOriginal.end()) { Image* image = (*itr)->readImage(file); if (image) return image; } } } else { notify(NOTICE)<<"Warning: Could not find plugin to read file with extension ." < rwOriginal; // first attempt to load the file from existing ReaderWriter's for(ReaderWriterList::iterator itr=_rwList.begin(); itr!=_rwList.end(); ++itr) { rwOriginal.insert(itr->get()); if ((*itr)->writeImage(image,fileName)) return true; } // now look for a plug-in to save the file. std::string libraryName = createLibraryNameForFile(fileName); if (loadLibrary(libraryName)) { for(ReaderWriterList::iterator itr=_rwList.begin(); itr!=_rwList.end(); ++itr) { if (rwOriginal.find(itr->get())==rwOriginal.end()) { if ((*itr)->writeImage(image,fileName)) return true; } } } else { notify(NOTICE)<<"Warning: Could not find plugin to write file with extension ." < rwOriginal; // first attempt to load the file from existing ReaderWriter's for(ReaderWriterList::iterator itr=_rwList.begin(); itr!=_rwList.end(); ++itr) { rwOriginal.insert(itr->get()); Node* node = (*itr)->readNode(file); if (node) return node; } bool couldNotFindPlugin = false; // now look for a plug-in to load the file. std::string libraryName = createLibraryNameForFile(fileName); notify(INFO) << "Now checking for plug-in "<get())==rwOriginal.end()) { Node* node = (*itr)->readNode(file); if (node) return node; } } } else { couldNotFindPlugin = true; } if (_createNodeFromImage) { ref_ptr image = readImage(fileName); if (image.valid()) { return createGeodeForImage(image.get()); } } if (couldNotFindPlugin) { notify(NOTICE)<<"Warning: Could not find plugin to read file with extension ." < rwOriginal; // first attempt to write the file from existing ReaderWriter's for(ReaderWriterList::iterator itr=_rwList.begin(); itr!=_rwList.end(); ++itr) { rwOriginal.insert(itr->get()); if ((*itr)->writeNode(node,fileName)) return true; } // now look for a plug-in to save the file. std::string libraryName = createLibraryNameForFile(fileName); if (Registry::instance()->loadLibrary(libraryName)) { for(ReaderWriterList::iterator itr=_rwList.begin(); itr!=_rwList.end(); ++itr) { if (rwOriginal.find(itr->get())==rwOriginal.end()) { if ((*itr)->writeNode(node,fileName)) return true; } } } else { notify(NOTICE)<<"Warning: Could not find plugin to write file with extension ." <