diff options
Diffstat (limited to 'src/3rdparty/assimp/code/Importer.cpp')
-rw-r--r-- | src/3rdparty/assimp/code/Importer.cpp | 1487 |
1 files changed, 793 insertions, 694 deletions
diff --git a/src/3rdparty/assimp/code/Importer.cpp b/src/3rdparty/assimp/code/Importer.cpp index ea81f4972..3599138eb 100644 --- a/src/3rdparty/assimp/code/Importer.cpp +++ b/src/3rdparty/assimp/code/Importer.cpp @@ -3,12 +3,12 @@ Open Asset Import Library (assimp) --------------------------------------------------------------------------- -Copyright (c) 2006-2012, assimp team +Copyright (c) 2006-2016, assimp team All rights reserved. -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above @@ -25,16 +25,16 @@ conditions are met: derived from this software without specific prior written permission of the assimp team. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- */ @@ -43,25 +43,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * @brief Implementation of the CPP-API class #Importer */ -#include "AssimpPCH.h" -#include "../include/assimp/version.h" +#include <assimp/version.h> // ------------------------------------------------------------------------------------------------ /* Uncomment this line to prevent Assimp from catching unknown exceptions. * - * Note that any Exception except DeadlyImportError may lead to + * Note that any Exception except DeadlyImportError may lead to * undefined behaviour -> loaders could remain in an unusable state and * further imports with the same Importer instance could fail/crash/burn ... */ // ------------------------------------------------------------------------------------------------ #ifndef ASSIMP_BUILD_DEBUG -# define ASSIMP_CATCH_GLOBAL_EXCEPTIONS +# define ASSIMP_CATCH_GLOBAL_EXCEPTIONS #endif // ------------------------------------------------------------------------------------------------ // Internal headers // ------------------------------------------------------------------------------------------------ #include "Importer.h" +#include "BaseImporter.h" #include "BaseProcess.h" #include "DefaultIOStream.h" @@ -70,22 +70,30 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "GenericProperty.h" #include "ProcessHelper.h" #include "ScenePreprocessor.h" +#include "ScenePrivate.h" #include "MemoryIOWrapper.h" #include "Profiler.h" #include "TinyFormatter.h" +#include "Exceptional.h" +#include "Profiler.h" +#include <set> +#include <memory> +#include <cctype> #ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS -# include "ValidateDataStructure.h" +# include "ValidateDataStructure.h" #endif using namespace Assimp::Profiling; using namespace Assimp::Formatter; namespace Assimp { - // ImporterRegistry.cpp - void GetImporterInstanceList(std::vector< BaseImporter* >& out); - // PostStepRegistry.cpp - void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out); + // ImporterRegistry.cpp + void GetImporterInstanceList(std::vector< BaseImporter* >& out); + void DeleteImporterInstanceList(std::vector< BaseImporter* >& out); + + // PostStepRegistry.cpp + void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out); } using namespace Assimp; @@ -97,625 +105,638 @@ using namespace Assimp::Intern; // utilize our DLL heap. // See http://www.gotw.ca/publications/mill15.htm // ------------------------------------------------------------------------------------------------ -void* AllocateFromAssimpHeap::operator new ( size_t num_bytes) { - return ::operator new(num_bytes); +void* AllocateFromAssimpHeap::operator new ( size_t num_bytes) { + return ::operator new(num_bytes); } -void* AllocateFromAssimpHeap::operator new ( size_t num_bytes, const std::nothrow_t& ) throw() { - try { - return AllocateFromAssimpHeap::operator new( num_bytes ); - } - catch( ... ) { - return NULL; - } +void* AllocateFromAssimpHeap::operator new ( size_t num_bytes, const std::nothrow_t& ) throw() { + try { + return AllocateFromAssimpHeap::operator new( num_bytes ); + } + catch( ... ) { + return NULL; + } } -void AllocateFromAssimpHeap::operator delete ( void* data) { - return ::operator delete(data); +void AllocateFromAssimpHeap::operator delete ( void* data) { + return ::operator delete(data); } -void* AllocateFromAssimpHeap::operator new[] ( size_t num_bytes) { - return ::operator new[](num_bytes); +void* AllocateFromAssimpHeap::operator new[] ( size_t num_bytes) { + return ::operator new[](num_bytes); } void* AllocateFromAssimpHeap::operator new[] ( size_t num_bytes, const std::nothrow_t& ) throw() { - try { - return AllocateFromAssimpHeap::operator new[]( num_bytes ); - } - catch( ... ) { - return NULL; - } + try { + return AllocateFromAssimpHeap::operator new[]( num_bytes ); + } + catch( ... ) { + return NULL; + } } -void AllocateFromAssimpHeap::operator delete[] ( void* data) { - return ::operator delete[](data); +void AllocateFromAssimpHeap::operator delete[] ( void* data) { + return ::operator delete[](data); } // ------------------------------------------------------------------------------------------------ -// Importer constructor. -Importer::Importer() -{ - // allocate the pimpl first - pimpl = new ImporterPimpl(); - - pimpl->mScene = NULL; - pimpl->mErrorString = ""; - - // Allocate a default IO handler - pimpl->mIOHandler = new DefaultIOSystem; - pimpl->mIsDefaultHandler = true; - pimpl->bExtraVerbose = false; // disable extra verbose mode by default - - pimpl->mProgressHandler = new DefaultProgressHandler(); - pimpl->mIsDefaultProgressHandler = true; - - GetImporterInstanceList(pimpl->mImporter); - GetPostProcessingStepInstanceList(pimpl->mPostProcessingSteps); - - // Allocate a SharedPostProcessInfo object and store pointers to it in all post-process steps in the list. - pimpl->mPPShared = new SharedPostProcessInfo(); - for (std::vector<BaseProcess*>::iterator it = pimpl->mPostProcessingSteps.begin(); - it != pimpl->mPostProcessingSteps.end(); - ++it) { - - (*it)->SetSharedData(pimpl->mPPShared); - } +// Importer constructor. +Importer::Importer() + : pimpl( NULL ) { + // allocate the pimpl first + pimpl = new ImporterPimpl(); + + pimpl->mScene = NULL; + pimpl->mErrorString = ""; + + // Allocate a default IO handler + pimpl->mIOHandler = new DefaultIOSystem; + pimpl->mIsDefaultHandler = true; + pimpl->bExtraVerbose = false; // disable extra verbose mode by default + + pimpl->mProgressHandler = new DefaultProgressHandler(); + pimpl->mIsDefaultProgressHandler = true; + + GetImporterInstanceList(pimpl->mImporter); + GetPostProcessingStepInstanceList(pimpl->mPostProcessingSteps); + + // Allocate a SharedPostProcessInfo object and store pointers to it in all post-process steps in the list. + pimpl->mPPShared = new SharedPostProcessInfo(); + for (std::vector<BaseProcess*>::iterator it = pimpl->mPostProcessingSteps.begin(); + it != pimpl->mPostProcessingSteps.end(); + ++it) { + + (*it)->SetSharedData(pimpl->mPPShared); + } } // ------------------------------------------------------------------------------------------------ // Destructor of Importer Importer::~Importer() { - // Delete all import plugins - for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) - delete pimpl->mImporter[a]; + // Delete all import plugins + DeleteImporterInstanceList(pimpl->mImporter); - // Delete all post-processing plug-ins - for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) - delete pimpl->mPostProcessingSteps[a]; + // Delete all post-processing plug-ins + for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) + delete pimpl->mPostProcessingSteps[a]; - // Delete the assigned IO and progress handler - delete pimpl->mIOHandler; - delete pimpl->mProgressHandler; + // Delete the assigned IO and progress handler + delete pimpl->mIOHandler; + delete pimpl->mProgressHandler; - // Kill imported scene. Destructors should do that recursivly - delete pimpl->mScene; + // Kill imported scene. Destructors should do that recursivly + delete pimpl->mScene; - // Delete shared post-processing data - delete pimpl->mPPShared; + // Delete shared post-processing data + delete pimpl->mPPShared; - // and finally the pimpl itself - delete pimpl; + // and finally the pimpl itself + delete pimpl; } // ------------------------------------------------------------------------------------------------ // Copy constructor - copies the config of another Importer, not the scene Importer::Importer(const Importer &other) -{ - new(this) Importer(); + : pimpl(NULL) { + new(this) Importer(); - pimpl->mIntProperties = other.pimpl->mIntProperties; - pimpl->mFloatProperties = other.pimpl->mFloatProperties; - pimpl->mStringProperties = other.pimpl->mStringProperties; - pimpl->mMatrixProperties = other.pimpl->mMatrixProperties; + pimpl->mIntProperties = other.pimpl->mIntProperties; + pimpl->mFloatProperties = other.pimpl->mFloatProperties; + pimpl->mStringProperties = other.pimpl->mStringProperties; + pimpl->mMatrixProperties = other.pimpl->mMatrixProperties; } // ------------------------------------------------------------------------------------------------ // Register a custom post-processing step aiReturn Importer::RegisterPPStep(BaseProcess* pImp) { - ai_assert(NULL != pImp); - ASSIMP_BEGIN_EXCEPTION_REGION(); - - pimpl->mPostProcessingSteps.push_back(pImp); - DefaultLogger::get()->info("Registering custom post-processing step"); - - ASSIMP_END_EXCEPTION_REGION(aiReturn); - return AI_SUCCESS; + ai_assert(NULL != pImp); + ASSIMP_BEGIN_EXCEPTION_REGION(); + + pimpl->mPostProcessingSteps.push_back(pImp); + DefaultLogger::get()->info("Registering custom post-processing step"); + + ASSIMP_END_EXCEPTION_REGION(aiReturn); + return AI_SUCCESS; } // ------------------------------------------------------------------------------------------------ // Register a custom loader plugin aiReturn Importer::RegisterLoader(BaseImporter* pImp) { - ai_assert(NULL != pImp); - ASSIMP_BEGIN_EXCEPTION_REGION(); + ai_assert(NULL != pImp); + ASSIMP_BEGIN_EXCEPTION_REGION(); - // -------------------------------------------------------------------- - // Check whether we would have two loaders for the same file extension - // This is absolutely OK, but we should warn the developer of the new - // loader that his code will probably never be called if the first - // loader is a bit too lazy in his file checking. - // -------------------------------------------------------------------- - std::set<std::string> st; - std::string baked; - pImp->GetExtensionList(st); + // -------------------------------------------------------------------- + // Check whether we would have two loaders for the same file extension + // This is absolutely OK, but we should warn the developer of the new + // loader that his code will probably never be called if the first + // loader is a bit too lazy in his file checking. + // -------------------------------------------------------------------- + std::set<std::string> st; + std::string baked; + pImp->GetExtensionList(st); - for(std::set<std::string>::const_iterator it = st.begin(); it != st.end(); ++it) { + for(std::set<std::string>::const_iterator it = st.begin(); it != st.end(); ++it) { #ifdef ASSIMP_BUILD_DEBUG - if (IsExtensionSupported(*it)) { - DefaultLogger::get()->warn("The file extension " + *it + " is already in use"); - } + if (IsExtensionSupported(*it)) { + DefaultLogger::get()->warn("The file extension " + *it + " is already in use"); + } #endif - baked += *it; - } - - // add the loader - pimpl->mImporter.push_back(pImp); - DefaultLogger::get()->info("Registering custom importer for these file extensions: " + baked); - ASSIMP_END_EXCEPTION_REGION(aiReturn); - return AI_SUCCESS; + baked += *it; + } + + // add the loader + pimpl->mImporter.push_back(pImp); + DefaultLogger::get()->info("Registering custom importer for these file extensions: " + baked); + ASSIMP_END_EXCEPTION_REGION(aiReturn); + return AI_SUCCESS; } // ------------------------------------------------------------------------------------------------ // Unregister a custom loader plugin aiReturn Importer::UnregisterLoader(BaseImporter* pImp) { - if(!pImp) { - // unregistering a NULL importer is no problem for us ... really! - return AI_SUCCESS; - } - - ASSIMP_BEGIN_EXCEPTION_REGION(); - std::vector<BaseImporter*>::iterator it = std::find(pimpl->mImporter.begin(), - pimpl->mImporter.end(),pImp); - - if (it != pimpl->mImporter.end()) { - pimpl->mImporter.erase(it); - - std::set<std::string> st; - pImp->GetExtensionList(st); - - DefaultLogger::get()->info("Unregistering custom importer: "); - return AI_SUCCESS; - } - DefaultLogger::get()->warn("Unable to remove custom importer: I can't find you ..."); - ASSIMP_END_EXCEPTION_REGION(aiReturn); - return AI_FAILURE; + if(!pImp) { + // unregistering a NULL importer is no problem for us ... really! + return AI_SUCCESS; + } + + ASSIMP_BEGIN_EXCEPTION_REGION(); + std::vector<BaseImporter*>::iterator it = std::find(pimpl->mImporter.begin(), + pimpl->mImporter.end(),pImp); + + if (it != pimpl->mImporter.end()) { + pimpl->mImporter.erase(it); + + std::set<std::string> st; + pImp->GetExtensionList(st); + + DefaultLogger::get()->info("Unregistering custom importer: "); + return AI_SUCCESS; + } + DefaultLogger::get()->warn("Unable to remove custom importer: I can't find you ..."); + ASSIMP_END_EXCEPTION_REGION(aiReturn); + return AI_FAILURE; } // ------------------------------------------------------------------------------------------------ // Unregister a custom loader plugin aiReturn Importer::UnregisterPPStep(BaseProcess* pImp) { - if(!pImp) { - // unregistering a NULL ppstep is no problem for us ... really! - return AI_SUCCESS; - } - - ASSIMP_BEGIN_EXCEPTION_REGION(); - std::vector<BaseProcess*>::iterator it = std::find(pimpl->mPostProcessingSteps.begin(), - pimpl->mPostProcessingSteps.end(),pImp); - - if (it != pimpl->mPostProcessingSteps.end()) { - pimpl->mPostProcessingSteps.erase(it); - DefaultLogger::get()->info("Unregistering custom post-processing step"); - return AI_SUCCESS; - } - DefaultLogger::get()->warn("Unable to remove custom post-processing step: I can't find you .."); - ASSIMP_END_EXCEPTION_REGION(aiReturn); - return AI_FAILURE; + if(!pImp) { + // unregistering a NULL ppstep is no problem for us ... really! + return AI_SUCCESS; + } + + ASSIMP_BEGIN_EXCEPTION_REGION(); + std::vector<BaseProcess*>::iterator it = std::find(pimpl->mPostProcessingSteps.begin(), + pimpl->mPostProcessingSteps.end(),pImp); + + if (it != pimpl->mPostProcessingSteps.end()) { + pimpl->mPostProcessingSteps.erase(it); + DefaultLogger::get()->info("Unregistering custom post-processing step"); + return AI_SUCCESS; + } + DefaultLogger::get()->warn("Unable to remove custom post-processing step: I can't find you .."); + ASSIMP_END_EXCEPTION_REGION(aiReturn); + return AI_FAILURE; } // ------------------------------------------------------------------------------------------------ // Supplies a custom IO handler to the importer to open and access files. void Importer::SetIOHandler( IOSystem* pIOHandler) { - ASSIMP_BEGIN_EXCEPTION_REGION(); - // If the new handler is zero, allocate a default IO implementation. - if (!pIOHandler) - { - // Release pointer in the possession of the caller - pimpl->mIOHandler = new DefaultIOSystem(); - pimpl->mIsDefaultHandler = true; - } - // Otherwise register the custom handler - else if (pimpl->mIOHandler != pIOHandler) - { - delete pimpl->mIOHandler; - pimpl->mIOHandler = pIOHandler; - pimpl->mIsDefaultHandler = false; - } - ASSIMP_END_EXCEPTION_REGION(void); + ASSIMP_BEGIN_EXCEPTION_REGION(); + // If the new handler is zero, allocate a default IO implementation. + if (!pIOHandler) + { + // Release pointer in the possession of the caller + pimpl->mIOHandler = new DefaultIOSystem(); + pimpl->mIsDefaultHandler = true; + } + // Otherwise register the custom handler + else if (pimpl->mIOHandler != pIOHandler) + { + delete pimpl->mIOHandler; + pimpl->mIOHandler = pIOHandler; + pimpl->mIsDefaultHandler = false; + } + ASSIMP_END_EXCEPTION_REGION(void); } // ------------------------------------------------------------------------------------------------ // Get the currently set IO handler IOSystem* Importer::GetIOHandler() const { - return pimpl->mIOHandler; + return pimpl->mIOHandler; } // ------------------------------------------------------------------------------------------------ // Check whether a custom IO handler is currently set bool Importer::IsDefaultIOHandler() const { - return pimpl->mIsDefaultHandler; + return pimpl->mIsDefaultHandler; } // ------------------------------------------------------------------------------------------------ // Supplies a custom progress handler to get regular callbacks during importing void Importer::SetProgressHandler ( ProgressHandler* pHandler ) { - ASSIMP_BEGIN_EXCEPTION_REGION(); - // If the new handler is zero, allocate a default implementation. - if (!pHandler) - { - // Release pointer in the possession of the caller - pimpl->mProgressHandler = new DefaultProgressHandler(); - pimpl->mIsDefaultProgressHandler = true; - } - // Otherwise register the custom handler - else if (pimpl->mProgressHandler != pHandler) - { - delete pimpl->mProgressHandler; - pimpl->mProgressHandler = pHandler; - pimpl->mIsDefaultProgressHandler = false; - } - ASSIMP_END_EXCEPTION_REGION(void); + ASSIMP_BEGIN_EXCEPTION_REGION(); + // If the new handler is zero, allocate a default implementation. + if (!pHandler) + { + // Release pointer in the possession of the caller + pimpl->mProgressHandler = new DefaultProgressHandler(); + pimpl->mIsDefaultProgressHandler = true; + } + // Otherwise register the custom handler + else if (pimpl->mProgressHandler != pHandler) + { + delete pimpl->mProgressHandler; + pimpl->mProgressHandler = pHandler; + pimpl->mIsDefaultProgressHandler = false; + } + ASSIMP_END_EXCEPTION_REGION(void); } // ------------------------------------------------------------------------------------------------ // Get the currently set progress handler ProgressHandler* Importer::GetProgressHandler() const { - return pimpl->mProgressHandler; + return pimpl->mProgressHandler; } // ------------------------------------------------------------------------------------------------ // Check whether a custom progress handler is currently set bool Importer::IsDefaultProgressHandler() const { - return pimpl->mIsDefaultProgressHandler; + return pimpl->mIsDefaultProgressHandler; } // ------------------------------------------------------------------------------------------------ -// Validate post process step flags -bool _ValidateFlags(unsigned int pFlags) +// Validate post process step flags +bool _ValidateFlags(unsigned int pFlags) { - if (pFlags & aiProcess_GenSmoothNormals && pFlags & aiProcess_GenNormals) { - DefaultLogger::get()->error("#aiProcess_GenSmoothNormals and #aiProcess_GenNormals are incompatible"); - return false; - } - if (pFlags & aiProcess_OptimizeGraph && pFlags & aiProcess_PreTransformVertices) { - DefaultLogger::get()->error("#aiProcess_OptimizeGraph and #aiProcess_PreTransformVertices are incompatible"); - return false; - } - return true; + if (pFlags & aiProcess_GenSmoothNormals && pFlags & aiProcess_GenNormals) { + DefaultLogger::get()->error("#aiProcess_GenSmoothNormals and #aiProcess_GenNormals are incompatible"); + return false; + } + if (pFlags & aiProcess_OptimizeGraph && pFlags & aiProcess_PreTransformVertices) { + DefaultLogger::get()->error("#aiProcess_OptimizeGraph and #aiProcess_PreTransformVertices are incompatible"); + return false; + } + return true; } // ------------------------------------------------------------------------------------------------ // Free the current scene void Importer::FreeScene( ) { - ASSIMP_BEGIN_EXCEPTION_REGION(); - delete pimpl->mScene; - pimpl->mScene = NULL; + ASSIMP_BEGIN_EXCEPTION_REGION(); + delete pimpl->mScene; + pimpl->mScene = NULL; - pimpl->mErrorString = ""; - ASSIMP_END_EXCEPTION_REGION(void); + pimpl->mErrorString = ""; + ASSIMP_END_EXCEPTION_REGION(void); } // ------------------------------------------------------------------------------------------------ // Get the current error string, if any -const char* Importer::GetErrorString() const -{ - /* Must remain valid as long as ReadFile() or FreeFile() are not called */ - return pimpl->mErrorString.c_str(); +const char* Importer::GetErrorString() const +{ + /* Must remain valid as long as ReadFile() or FreeFile() are not called */ + return pimpl->mErrorString.c_str(); } // ------------------------------------------------------------------------------------------------ // Enable extra-verbose mode void Importer::SetExtraVerbose(bool bDo) { - pimpl->bExtraVerbose = bDo; + pimpl->bExtraVerbose = bDo; } // ------------------------------------------------------------------------------------------------ // Get the current scene const aiScene* Importer::GetScene() const { - return pimpl->mScene; + return pimpl->mScene; } // ------------------------------------------------------------------------------------------------ // Orphan the current scene and return it. aiScene* Importer::GetOrphanedScene() { - aiScene* s = pimpl->mScene; + aiScene* s = pimpl->mScene; - ASSIMP_BEGIN_EXCEPTION_REGION(); - pimpl->mScene = NULL; + ASSIMP_BEGIN_EXCEPTION_REGION(); + pimpl->mScene = NULL; - pimpl->mErrorString = ""; /* reset error string */ - ASSIMP_END_EXCEPTION_REGION(aiScene*); - return s; + pimpl->mErrorString = ""; /* reset error string */ + ASSIMP_END_EXCEPTION_REGION(aiScene*); + return s; } // ------------------------------------------------------------------------------------------------ // Validate post-processing flags bool Importer::ValidateFlags(unsigned int pFlags) const { - ASSIMP_BEGIN_EXCEPTION_REGION(); - // run basic checks for mutually exclusive flags - if(!_ValidateFlags(pFlags)) { - return false; - } + ASSIMP_BEGIN_EXCEPTION_REGION(); + // run basic checks for mutually exclusive flags + if(!_ValidateFlags(pFlags)) { + return false; + } - // ValidateDS does not anymore occur in the pp list, it plays an awesome extra role ... + // ValidateDS does not anymore occur in the pp list, it plays an awesome extra role ... #ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS - if (pFlags & aiProcess_ValidateDataStructure) { - return false; - } + if (pFlags & aiProcess_ValidateDataStructure) { + return false; + } #endif - pFlags &= ~aiProcess_ValidateDataStructure; - - // Now iterate through all bits which are set in the flags and check whether we find at least - // one pp plugin which handles it. - for (unsigned int mask = 1; mask < (1u << (sizeof(unsigned int)*8-1));mask <<= 1) { - - if (pFlags & mask) { - - bool have = false; - for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) { - if (pimpl->mPostProcessingSteps[a]-> IsActive(mask) ) { - - have = true; - break; - } - } - if (!have) { - return false; - } - } - } - ASSIMP_END_EXCEPTION_REGION(bool); - return true; + pFlags &= ~aiProcess_ValidateDataStructure; + + // Now iterate through all bits which are set in the flags and check whether we find at least + // one pp plugin which handles it. + for (unsigned int mask = 1; mask < (1u << (sizeof(unsigned int)*8-1));mask <<= 1) { + + if (pFlags & mask) { + + bool have = false; + for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) { + if (pimpl->mPostProcessingSteps[a]-> IsActive(mask) ) { + + have = true; + break; + } + } + if (!have) { + return false; + } + } + } + ASSIMP_END_EXCEPTION_REGION(bool); + return true; } // ------------------------------------------------------------------------------------------------ const aiScene* Importer::ReadFileFromMemory( const void* pBuffer, - size_t pLength, - unsigned int pFlags, - const char* pHint /*= ""*/) + size_t pLength, + unsigned int pFlags, + const char* pHint /*= ""*/) { - ASSIMP_BEGIN_EXCEPTION_REGION(); - if (!pHint) { - pHint = ""; - } + ASSIMP_BEGIN_EXCEPTION_REGION(); + if (!pHint) { + pHint = ""; + } - if (!pBuffer || !pLength || strlen(pHint) > 100) { - pimpl->mErrorString = "Invalid parameters passed to ReadFileFromMemory()"; - return NULL; - } + if (!pBuffer || !pLength || strlen(pHint) > MaxLenHint ) { + pimpl->mErrorString = "Invalid parameters passed to ReadFileFromMemory()"; + return NULL; + } - // prevent deletion of the previous IOHandler - IOSystem* io = pimpl->mIOHandler; - pimpl->mIOHandler = NULL; + // prevent deletion of the previous IOHandler + IOSystem* io = pimpl->mIOHandler; + pimpl->mIOHandler = NULL; - SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength)); + SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength)); - // read the file and recover the previous IOSystem - char fbuff[128]; - sprintf(fbuff,"%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint); + // read the file and recover the previous IOSystem + static const size_t BufferSize(Importer::MaxLenHint + 28); + char fbuff[ BufferSize ]; + ai_snprintf(fbuff, BufferSize, "%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint); - ReadFile(fbuff,pFlags); - SetIOHandler(io); + ReadFile(fbuff,pFlags); + SetIOHandler(io); - ASSIMP_END_EXCEPTION_REGION(const aiScene*); - return pimpl->mScene; + ASSIMP_END_EXCEPTION_REGION(const aiScene*); + return pimpl->mScene; } // ------------------------------------------------------------------------------------------------ void WriteLogOpening(const std::string& file) { - Logger* l = DefaultLogger::get(); - if (!l) { - return; - } - l->info("Load " + file); - - // print a full version dump. This is nice because we don't - // need to ask the authors of incoming bug reports for - // the library version they're using - a log dump is - // sufficient. - const unsigned int flags = aiGetCompileFlags(); - l->debug(format() - << "Assimp " - << aiGetVersionMajor() - << "." - << aiGetVersionMinor() - << "." - << aiGetVersionRevision() - - << " " + Logger* l = DefaultLogger::get(); + if (!l) { + return; + } + l->info("Load " + file); + + // print a full version dump. This is nice because we don't + // need to ask the authors of incoming bug reports for + // the library version they're using - a log dump is + // sufficient. + const unsigned int flags = aiGetCompileFlags(); + l->debug(format() + << "Assimp " + << aiGetVersionMajor() + << "." + << aiGetVersionMinor() + << "." + << aiGetVersionRevision() + + << " " #if defined(ASSIMP_BUILD_ARCHITECTURE) - << ASSIMP_BUILD_ARCHITECTURE + << ASSIMP_BUILD_ARCHITECTURE #elif defined(_M_IX86) || defined(__x86_32__) || defined(__i386__) - << "x86" -#elif defined(_M_X64) || defined(__x86_64__) - << "amd64" + << "x86" +#elif defined(_M_X64) || defined(__x86_64__) + << "amd64" #elif defined(_M_IA64) || defined(__ia64__) - << "itanium" + << "itanium" #elif defined(__ppc__) || defined(__powerpc__) - << "ppc32" + << "ppc32" #elif defined(__powerpc64__) - << "ppc64" + << "ppc64" #elif defined(__arm__) - << "arm" + << "arm" #else - << "<unknown architecture>" + << "<unknown architecture>" #endif - << " " + << " " #if defined(ASSIMP_BUILD_COMPILER) - << ASSIMP_BUILD_COMPILER + << ASSIMP_BUILD_COMPILER #elif defined(_MSC_VER) - << "msvc" + << "msvc" #elif defined(__GNUC__) - << "gcc" + << "gcc" #else - << "<unknown compiler>" + << "<unknown compiler>" #endif #ifdef ASSIMP_BUILD_DEBUG - << " debug" + << " debug" #endif - << (flags & ASSIMP_CFLAGS_NOBOOST ? " noboost" : "") - << (flags & ASSIMP_CFLAGS_SHARED ? " shared" : "") - << (flags & ASSIMP_CFLAGS_SINGLETHREADED ? " singlethreaded" : "") - ); + << (flags & ASSIMP_CFLAGS_NOBOOST ? " noboost" : "") + << (flags & ASSIMP_CFLAGS_SHARED ? " shared" : "") + << (flags & ASSIMP_CFLAGS_SINGLETHREADED ? " singlethreaded" : "") + ); } // ------------------------------------------------------------------------------------------------ // Reads the given file and returns its contents if successful. const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) { - ASSIMP_BEGIN_EXCEPTION_REGION(); - const std::string pFile(_pFile); + ASSIMP_BEGIN_EXCEPTION_REGION(); + const std::string pFile(_pFile); - // ---------------------------------------------------------------------- - // Put a large try block around everything to catch all std::exception's - // that might be thrown by STL containers or by new(). - // ImportErrorException's are throw by ourselves and caught elsewhere. - //----------------------------------------------------------------------- + // ---------------------------------------------------------------------- + // Put a large try block around everything to catch all std::exception's + // that might be thrown by STL containers or by new(). + // ImportErrorException's are throw by ourselves and caught elsewhere. + //----------------------------------------------------------------------- - WriteLogOpening(pFile); + WriteLogOpening(pFile); #ifdef ASSIMP_CATCH_GLOBAL_EXCEPTIONS - try + try #endif // ! ASSIMP_CATCH_GLOBAL_EXCEPTIONS - { - // Check whether this Importer instance has already loaded - // a scene. In this case we need to delete the old one - if (pimpl->mScene) { - - DefaultLogger::get()->debug("(Deleting previous scene)"); - FreeScene(); - } - - // First check if the file is accessable at all - if( !pimpl->mIOHandler->Exists( pFile)) { - - pimpl->mErrorString = "Unable to open file \"" + pFile + "\"."; - DefaultLogger::get()->error(pimpl->mErrorString); - return NULL; - } - - boost::scoped_ptr<Profiler> profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME,0)?new Profiler():NULL); - if (profiler) { - profiler->BeginRegion("total"); - } - - // Find an worker class which can handle the file - BaseImporter* imp = NULL; - for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) { - - if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, false)) { - imp = pimpl->mImporter[a]; - break; - } - } - - if (!imp) { - // not so bad yet ... try format auto detection. - const std::string::size_type s = pFile.find_last_of('.'); - if (s != std::string::npos) { - DefaultLogger::get()->info("File extension not known, trying signature-based detection"); - for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) { - - if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, true)) { - imp = pimpl->mImporter[a]; - break; - } - } - } - // Put a proper error message if no suitable importer was found - if( !imp) { - pimpl->mErrorString = "No suitable reader found for the file format of file \"" + pFile + "\"."; - DefaultLogger::get()->error(pimpl->mErrorString); - return NULL; - } - } - - // Dispatch the reading to the worker class for this format - DefaultLogger::get()->info("Found a matching importer for this file format"); - pimpl->mProgressHandler->Update(); - - if (profiler) { - profiler->BeginRegion("import"); - } - - pimpl->mScene = imp->ReadFile( this, pFile, pimpl->mIOHandler); - pimpl->mProgressHandler->Update(); - - if (profiler) { - profiler->EndRegion("import"); - } - - // If successful, apply all active post processing steps to the imported data - if( pimpl->mScene) { + { + // Check whether this Importer instance has already loaded + // a scene. In this case we need to delete the old one + if (pimpl->mScene) { + + DefaultLogger::get()->debug("(Deleting previous scene)"); + FreeScene(); + } + + // First check if the file is accessible at all + if( !pimpl->mIOHandler->Exists( pFile)) { + + pimpl->mErrorString = "Unable to open file \"" + pFile + "\"."; + DefaultLogger::get()->error(pimpl->mErrorString); + return NULL; + } + + std::unique_ptr<Profiler> profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME,0)?new Profiler():NULL); + if (profiler) { + profiler->BeginRegion("total"); + } + + // Find an worker class which can handle the file + BaseImporter* imp = NULL; + for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) { + + if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, false)) { + imp = pimpl->mImporter[a]; + break; + } + } + + if (!imp) { + // not so bad yet ... try format auto detection. + const std::string::size_type s = pFile.find_last_of('.'); + if (s != std::string::npos) { + DefaultLogger::get()->info("File extension not known, trying signature-based detection"); + for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) { + + if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, true)) { + imp = pimpl->mImporter[a]; + break; + } + } + } + // Put a proper error message if no suitable importer was found + if( !imp) { + pimpl->mErrorString = "No suitable reader found for the file format of file \"" + pFile + "\"."; + DefaultLogger::get()->error(pimpl->mErrorString); + return NULL; + } + } + + // Get file size for progress handler + IOStream * fileIO = pimpl->mIOHandler->Open( pFile ); + uint32_t fileSize = 0; + if (fileIO) + { + fileSize = fileIO->FileSize(); + pimpl->mIOHandler->Close( fileIO ); + } + + // Dispatch the reading to the worker class for this format + const aiImporterDesc *desc( imp->GetInfo() ); + std::string ext( "unknown" ); + if ( NULL != desc ) { + ext = desc->mName; + } + DefaultLogger::get()->info("Found a matching importer for this file format: " + ext + "." ); + pimpl->mProgressHandler->UpdateFileRead( 0, fileSize ); + + if (profiler) { + profiler->BeginRegion("import"); + } + + pimpl->mScene = imp->ReadFile( this, pFile, pimpl->mIOHandler); + pimpl->mProgressHandler->UpdateFileRead( fileSize, fileSize ); + + if (profiler) { + profiler->EndRegion("import"); + } + + // If successful, apply all active post processing steps to the imported data + if( pimpl->mScene) { #ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS - // The ValidateDS process is an exception. It is executed first, even before ScenePreprocessor is called. - if (pFlags & aiProcess_ValidateDataStructure) - { - ValidateDSProcess ds; - ds.ExecuteOnScene (this); - if (!pimpl->mScene) { - return NULL; - } - } + // The ValidateDS process is an exception. It is executed first, even before ScenePreprocessor is called. + if (pFlags & aiProcess_ValidateDataStructure) + { + ValidateDSProcess ds; + ds.ExecuteOnScene (this); + if (!pimpl->mScene) { + return NULL; + } + } #endif // no validation - // Preprocess the scene and prepare it for post-processing - if (profiler) { - profiler->BeginRegion("preprocess"); - } - - ScenePreprocessor pre(pimpl->mScene); - pre.ProcessScene(); - - pimpl->mProgressHandler->Update(); - if (profiler) { - profiler->EndRegion("preprocess"); - } - - // Ensure that the validation process won't be called twice - ApplyPostProcessing(pFlags & (~aiProcess_ValidateDataStructure)); - } - // if failed, extract the error string - else if( !pimpl->mScene) { - pimpl->mErrorString = imp->GetErrorText(); - } - - // clear any data allocated by post-process steps - pimpl->mPPShared->Clean(); - - if (profiler) { - profiler->EndRegion("total"); - } - } + // Preprocess the scene and prepare it for post-processing + if (profiler) { + profiler->BeginRegion("preprocess"); + } + + ScenePreprocessor pre(pimpl->mScene); + pre.ProcessScene(); + + if (profiler) { + profiler->EndRegion("preprocess"); + } + + // Ensure that the validation process won't be called twice + ApplyPostProcessing(pFlags & (~aiProcess_ValidateDataStructure)); + } + // if failed, extract the error string + else if( !pimpl->mScene) { + pimpl->mErrorString = imp->GetErrorText(); + } + + // clear any data allocated by post-process steps + pimpl->mPPShared->Clean(); + + if (profiler) { + profiler->EndRegion("total"); + } + } #ifdef ASSIMP_CATCH_GLOBAL_EXCEPTIONS - catch (std::exception &e) - { -#if (defined _MSC_VER) && (defined _CPPRTTI) - // if we have RTTI get the full name of the exception that occured - pimpl->mErrorString = std::string(typeid( e ).name()) + ": " + e.what(); + catch (std::exception &e) + { +#if (defined _MSC_VER) && (defined _CPPRTTI) + // if we have RTTI get the full name of the exception that occurred + pimpl->mErrorString = std::string(typeid( e ).name()) + ": " + e.what(); #else - pimpl->mErrorString = std::string("std::exception: ") + e.what(); + pimpl->mErrorString = std::string("std::exception: ") + e.what(); #endif - DefaultLogger::get()->error(pimpl->mErrorString); - delete pimpl->mScene; pimpl->mScene = NULL; - } + DefaultLogger::get()->error(pimpl->mErrorString); + delete pimpl->mScene; pimpl->mScene = NULL; + } #endif // ! ASSIMP_CATCH_GLOBAL_EXCEPTIONS - // either successful or failure - the pointer expresses it anyways - ASSIMP_END_EXCEPTION_REGION(const aiScene*); - return pimpl->mScene; + // either successful or failure - the pointer expresses it anyways + ASSIMP_END_EXCEPTION_REGION(const aiScene*); + return pimpl->mScene; } @@ -723,374 +744,452 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) // Apply post-processing to the currently bound scene const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) { - ASSIMP_BEGIN_EXCEPTION_REGION(); - // Return immediately if no scene is active - if (!pimpl->mScene) { - return NULL; - } + ASSIMP_BEGIN_EXCEPTION_REGION(); + // Return immediately if no scene is active + if (!pimpl->mScene) { + return NULL; + } - // If no flags are given, return the current scene with no further action - if (!pFlags) { - return pimpl->mScene; - } + // If no flags are given, return the current scene with no further action + if (!pFlags) { + return pimpl->mScene; + } - // In debug builds: run basic flag validation - ai_assert(_ValidateFlags(pFlags)); - DefaultLogger::get()->info("Entering post processing pipeline"); + // In debug builds: run basic flag validation + ai_assert(_ValidateFlags(pFlags)); + DefaultLogger::get()->info("Entering post processing pipeline"); #ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS - // The ValidateDS process plays an exceptional role. It isn't contained in the global - // list of post-processing steps, so we need to call it manually. - if (pFlags & aiProcess_ValidateDataStructure) - { - ValidateDSProcess ds; - ds.ExecuteOnScene (this); - if (!pimpl->mScene) { - return NULL; - } - } + // The ValidateDS process plays an exceptional role. It isn't contained in the global + // list of post-processing steps, so we need to call it manually. + if (pFlags & aiProcess_ValidateDataStructure) + { + ValidateDSProcess ds; + ds.ExecuteOnScene (this); + if (!pimpl->mScene) { + return NULL; + } + } #endif // no validation #ifdef ASSIMP_BUILD_DEBUG - if (pimpl->bExtraVerbose) - { + if (pimpl->bExtraVerbose) + { #ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS - DefaultLogger::get()->error("Verbose Import is not available due to build settings"); + DefaultLogger::get()->error("Verbose Import is not available due to build settings"); #endif // no validation - pFlags |= aiProcess_ValidateDataStructure; - } + pFlags |= aiProcess_ValidateDataStructure; + } #else - if (pimpl->bExtraVerbose) { - DefaultLogger::get()->warn("Not a debug build, ignoring extra verbose setting"); - } + if (pimpl->bExtraVerbose) { + DefaultLogger::get()->warn("Not a debug build, ignoring extra verbose setting"); + } #endif // ! DEBUG - boost::scoped_ptr<Profiler> profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME,0)?new Profiler():NULL); - for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) { + std::unique_ptr<Profiler> profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME,0)?new Profiler():NULL); + for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) { - BaseProcess* process = pimpl->mPostProcessingSteps[a]; - if( process->IsActive( pFlags)) { + BaseProcess* process = pimpl->mPostProcessingSteps[a]; + pimpl->mProgressHandler->UpdatePostProcess( a, pimpl->mPostProcessingSteps.size() ); + if( process->IsActive( pFlags)) { - if (profiler) { - profiler->BeginRegion("postprocess"); - } + if (profiler) { + profiler->BeginRegion("postprocess"); + } - process->ExecuteOnScene ( this ); - pimpl->mProgressHandler->Update(); + process->ExecuteOnScene ( this ); - if (profiler) { - profiler->EndRegion("postprocess"); - } - } - if( !pimpl->mScene) { - break; - } + if (profiler) { + profiler->EndRegion("postprocess"); + } + } + if( !pimpl->mScene) { + break; + } #ifdef ASSIMP_BUILD_DEBUG #ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS - continue; + continue; #endif // no validation - // If the extra verbose mode is active, execute the ValidateDataStructureStep again - after each step - if (pimpl->bExtraVerbose) { - DefaultLogger::get()->debug("Verbose Import: revalidating data structures"); - - ValidateDSProcess ds; - ds.ExecuteOnScene (this); - if( !pimpl->mScene) { - DefaultLogger::get()->error("Verbose Import: failed to revalidate data structures"); - break; - } - } + // If the extra verbose mode is active, execute the ValidateDataStructureStep again - after each step + if (pimpl->bExtraVerbose) { + DefaultLogger::get()->debug("Verbose Import: revalidating data structures"); + + ValidateDSProcess ds; + ds.ExecuteOnScene (this); + if( !pimpl->mScene) { + DefaultLogger::get()->error("Verbose Import: failed to revalidate data structures"); + break; + } + } #endif // ! DEBUG - } + } + pimpl->mProgressHandler->UpdatePostProcess( pimpl->mPostProcessingSteps.size(), pimpl->mPostProcessingSteps.size() ); - // update private scene flags + // update private scene flags if( pimpl->mScene ) - ScenePriv(pimpl->mScene)->mPPStepsApplied |= pFlags; + ScenePriv(pimpl->mScene)->mPPStepsApplied |= pFlags; + + // clear any data allocated by post-process steps + pimpl->mPPShared->Clean(); + DefaultLogger::get()->info("Leaving post processing pipeline"); + + ASSIMP_END_EXCEPTION_REGION(const aiScene*); + return pimpl->mScene; +} + +// ------------------------------------------------------------------------------------------------ +const aiScene* Importer::ApplyCustomizedPostProcessing( BaseProcess *rootProcess, bool requestValidation ) { + ASSIMP_BEGIN_EXCEPTION_REGION(); + + // Return immediately if no scene is active + if ( NULL == pimpl->mScene ) { + return NULL; + } - // clear any data allocated by post-process steps - pimpl->mPPShared->Clean(); - DefaultLogger::get()->info("Leaving post processing pipeline"); + // If no flags are given, return the current scene with no further action + if ( NULL == rootProcess ) { + return pimpl->mScene; + } - ASSIMP_END_EXCEPTION_REGION(const aiScene*); - return pimpl->mScene; + // In debug builds: run basic flag validation + DefaultLogger::get()->info( "Entering customized post processing pipeline" ); + +#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS + // The ValidateDS process plays an exceptional role. It isn't contained in the global + // list of post-processing steps, so we need to call it manually. + if ( requestValidation ) + { + ValidateDSProcess ds; + ds.ExecuteOnScene( this ); + if ( !pimpl->mScene ) { + return NULL; + } + } +#endif // no validation +#ifdef ASSIMP_BUILD_DEBUG + if ( pimpl->bExtraVerbose ) + { +#ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS + DefaultLogger::get()->error( "Verbose Import is not available due to build settings" ); +#endif // no validation + } +#else + if ( pimpl->bExtraVerbose ) { + DefaultLogger::get()->warn( "Not a debug build, ignoring extra verbose setting" ); + } +#endif // ! DEBUG + + std::unique_ptr<Profiler> profiler( GetPropertyInteger( AI_CONFIG_GLOB_MEASURE_TIME, 0 ) ? new Profiler() : NULL ); + + if ( profiler ) { + profiler->BeginRegion( "postprocess" ); + } + + rootProcess->ExecuteOnScene( this ); + + if ( profiler ) { + profiler->EndRegion( "postprocess" ); + } + + // If the extra verbose mode is active, execute the ValidateDataStructureStep again - after each step + if ( pimpl->bExtraVerbose || requestValidation ) { + DefaultLogger::get()->debug( "Verbose Import: revalidating data structures" ); + + ValidateDSProcess ds; + ds.ExecuteOnScene( this ); + if ( !pimpl->mScene ) { + DefaultLogger::get()->error( "Verbose Import: failed to revalidate data structures" ); + } + } + + // clear any data allocated by post-process steps + pimpl->mPPShared->Clean(); + DefaultLogger::get()->info( "Leaving customized post processing pipeline" ); + + ASSIMP_END_EXCEPTION_REGION( const aiScene* ); + + return pimpl->mScene; } // ------------------------------------------------------------------------------------------------ // Helper function to check whether an extension is supported by ASSIMP bool Importer::IsExtensionSupported(const char* szExtension) const { - return NULL != GetImporter(szExtension); + return NULL != GetImporter(szExtension); } // ------------------------------------------------------------------------------------------------ size_t Importer::GetImporterCount() const { - return pimpl->mImporter.size(); + return pimpl->mImporter.size(); } // ------------------------------------------------------------------------------------------------ const aiImporterDesc* Importer::GetImporterInfo(size_t index) const { - if (index >= pimpl->mImporter.size()) { - return NULL; - } - return pimpl->mImporter[index]->GetInfo(); + if (index >= pimpl->mImporter.size()) { + return NULL; + } + return pimpl->mImporter[index]->GetInfo(); } // ------------------------------------------------------------------------------------------------ BaseImporter* Importer::GetImporter (size_t index) const { - if (index >= pimpl->mImporter.size()) { - return NULL; - } - return pimpl->mImporter[index]; + if (index >= pimpl->mImporter.size()) { + return NULL; + } + return pimpl->mImporter[index]; } // ------------------------------------------------------------------------------------------------ // Find a loader plugin for a given file extension BaseImporter* Importer::GetImporter (const char* szExtension) const { - return GetImporter(GetImporterIndex(szExtension)); + return GetImporter(GetImporterIndex(szExtension)); } // ------------------------------------------------------------------------------------------------ // Find a loader plugin for a given file extension size_t Importer::GetImporterIndex (const char* szExtension) const { - ai_assert(szExtension); - ASSIMP_BEGIN_EXCEPTION_REGION(); - - // skip over wildcard and dot characters at string head -- - for(;*szExtension == '*' || *szExtension == '.'; ++szExtension); - - std::string ext(szExtension); - if (ext.empty()) { - return static_cast<size_t>(-1); - } - std::transform(ext.begin(),ext.end(), ext.begin(), tolower); - - std::set<std::string> str; - for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) { - str.clear(); - - (*i)->GetExtensionList(str); - for (std::set<std::string>::const_iterator it = str.begin(); it != str.end(); ++it) { - if (ext == *it) { - return std::distance(static_cast< std::vector<BaseImporter*>::const_iterator >(pimpl->mImporter.begin()), i); - } - } - } - ASSIMP_END_EXCEPTION_REGION(size_t); - return static_cast<size_t>(-1); + ai_assert(szExtension); + ASSIMP_BEGIN_EXCEPTION_REGION(); + + // skip over wildcard and dot characters at string head -- + for(;*szExtension == '*' || *szExtension == '.'; ++szExtension); + + std::string ext(szExtension); + if (ext.empty()) { + return static_cast<size_t>(-1); + } + std::transform(ext.begin(),ext.end(), ext.begin(), tolower); + + std::set<std::string> str; + for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) { + str.clear(); + + (*i)->GetExtensionList(str); + for (std::set<std::string>::const_iterator it = str.begin(); it != str.end(); ++it) { + if (ext == *it) { + return std::distance(static_cast< std::vector<BaseImporter*>::const_iterator >(pimpl->mImporter.begin()), i); + } + } + } + ASSIMP_END_EXCEPTION_REGION(size_t); + return static_cast<size_t>(-1); } // ------------------------------------------------------------------------------------------------ // Helper function to build a list of all file extensions supported by ASSIMP void Importer::GetExtensionList(aiString& szOut) const { - ASSIMP_BEGIN_EXCEPTION_REGION(); - std::set<std::string> str; - for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) { - (*i)->GetExtensionList(str); - } - - for (std::set<std::string>::const_iterator it = str.begin();; ) { - szOut.Append("*."); - szOut.Append((*it).c_str()); - - if (++it == str.end()) { - break; - } - szOut.Append(";"); - } - ASSIMP_END_EXCEPTION_REGION(void); + ASSIMP_BEGIN_EXCEPTION_REGION(); + std::set<std::string> str; + for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) { + (*i)->GetExtensionList(str); + } + + for (std::set<std::string>::const_iterator it = str.begin();; ) { + szOut.Append("*."); + szOut.Append((*it).c_str()); + + if (++it == str.end()) { + break; + } + szOut.Append(";"); + } + ASSIMP_END_EXCEPTION_REGION(void); } // ------------------------------------------------------------------------------------------------ // Set a configuration property -void Importer::SetPropertyInteger(const char* szName, int iValue, - bool* bWasExisting /*= NULL*/) +bool Importer::SetPropertyInteger(const char* szName, int iValue) { - ASSIMP_BEGIN_EXCEPTION_REGION(); - SetGenericProperty<int>(pimpl->mIntProperties, szName,iValue,bWasExisting); - ASSIMP_END_EXCEPTION_REGION(void); + bool existing; + ASSIMP_BEGIN_EXCEPTION_REGION(); + existing = SetGenericProperty<int>(pimpl->mIntProperties, szName,iValue); + ASSIMP_END_EXCEPTION_REGION(bool); + return existing; } // ------------------------------------------------------------------------------------------------ // Set a configuration property -void Importer::SetPropertyFloat(const char* szName, float iValue, - bool* bWasExisting /*= NULL*/) +bool Importer::SetPropertyFloat(const char* szName, float iValue) { - ASSIMP_BEGIN_EXCEPTION_REGION(); - SetGenericProperty<float>(pimpl->mFloatProperties, szName,iValue,bWasExisting); - ASSIMP_END_EXCEPTION_REGION(void); + bool exising; + ASSIMP_BEGIN_EXCEPTION_REGION(); + exising = SetGenericProperty<float>(pimpl->mFloatProperties, szName,iValue); + ASSIMP_END_EXCEPTION_REGION(bool); + return exising; } // ------------------------------------------------------------------------------------------------ // Set a configuration property -void Importer::SetPropertyString(const char* szName, const std::string& value, - bool* bWasExisting /*= NULL*/) +bool Importer::SetPropertyString(const char* szName, const std::string& value) { - ASSIMP_BEGIN_EXCEPTION_REGION(); - SetGenericProperty<std::string>(pimpl->mStringProperties, szName,value,bWasExisting); - ASSIMP_END_EXCEPTION_REGION(void); + bool exising; + ASSIMP_BEGIN_EXCEPTION_REGION(); + exising = SetGenericProperty<std::string>(pimpl->mStringProperties, szName,value); + ASSIMP_END_EXCEPTION_REGION(bool); + return exising; } // ------------------------------------------------------------------------------------------------ // Set a configuration property -void Importer::SetPropertyMatrix(const char* szName, const aiMatrix4x4& value, - bool* bWasExisting /*= NULL*/) +bool Importer::SetPropertyMatrix(const char* szName, const aiMatrix4x4& value) { - ASSIMP_BEGIN_EXCEPTION_REGION(); - SetGenericProperty<aiMatrix4x4>(pimpl->mMatrixProperties, szName,value,bWasExisting); - ASSIMP_END_EXCEPTION_REGION(void); + bool exising; + ASSIMP_BEGIN_EXCEPTION_REGION(); + exising = SetGenericProperty<aiMatrix4x4>(pimpl->mMatrixProperties, szName,value); + ASSIMP_END_EXCEPTION_REGION(bool); + return exising; } // ------------------------------------------------------------------------------------------------ // Get a configuration property -int Importer::GetPropertyInteger(const char* szName, - int iErrorReturn /*= 0xffffffff*/) const +int Importer::GetPropertyInteger(const char* szName, + int iErrorReturn /*= 0xffffffff*/) const { - return GetGenericProperty<int>(pimpl->mIntProperties,szName,iErrorReturn); + return GetGenericProperty<int>(pimpl->mIntProperties,szName,iErrorReturn); } // ------------------------------------------------------------------------------------------------ // Get a configuration property -float Importer::GetPropertyFloat(const char* szName, - float iErrorReturn /*= 10e10*/) const +float Importer::GetPropertyFloat(const char* szName, + float iErrorReturn /*= 10e10*/) const { - return GetGenericProperty<float>(pimpl->mFloatProperties,szName,iErrorReturn); + return GetGenericProperty<float>(pimpl->mFloatProperties,szName,iErrorReturn); } // ------------------------------------------------------------------------------------------------ // Get a configuration property -const std::string Importer::GetPropertyString(const char* szName, - const std::string& iErrorReturn /*= ""*/) const +const std::string Importer::GetPropertyString(const char* szName, + const std::string& iErrorReturn /*= ""*/) const { - return GetGenericProperty<std::string>(pimpl->mStringProperties,szName,iErrorReturn); + return GetGenericProperty<std::string>(pimpl->mStringProperties,szName,iErrorReturn); } // ------------------------------------------------------------------------------------------------ // Get a configuration property -const aiMatrix4x4 Importer::GetPropertyMatrix(const char* szName, - const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const +const aiMatrix4x4 Importer::GetPropertyMatrix(const char* szName, + const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const { - return GetGenericProperty<aiMatrix4x4>(pimpl->mMatrixProperties,szName,iErrorReturn); + return GetGenericProperty<aiMatrix4x4>(pimpl->mMatrixProperties,szName,iErrorReturn); } // ------------------------------------------------------------------------------------------------ // Get the memory requirements of a single node inline void AddNodeWeight(unsigned int& iScene,const aiNode* pcNode) { - iScene += sizeof(aiNode); - iScene += sizeof(unsigned int) * pcNode->mNumMeshes; - iScene += sizeof(void*) * pcNode->mNumChildren; - - for (unsigned int i = 0; i < pcNode->mNumChildren;++i) { - AddNodeWeight(iScene,pcNode->mChildren[i]); - } + iScene += sizeof(aiNode); + iScene += sizeof(unsigned int) * pcNode->mNumMeshes; + iScene += sizeof(void*) * pcNode->mNumChildren; + + for (unsigned int i = 0; i < pcNode->mNumChildren;++i) { + AddNodeWeight(iScene,pcNode->mChildren[i]); + } } // ------------------------------------------------------------------------------------------------ // Get the memory requirements of the scene void Importer::GetMemoryRequirements(aiMemoryInfo& in) const { - in = aiMemoryInfo(); - aiScene* mScene = pimpl->mScene; - - // return if we have no scene loaded - if (!pimpl->mScene) - return; - - - in.total = sizeof(aiScene); - - // add all meshes - for (unsigned int i = 0; i < mScene->mNumMeshes;++i) - { - in.meshes += sizeof(aiMesh); - if (mScene->mMeshes[i]->HasPositions()) { - in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices; - } - - if (mScene->mMeshes[i]->HasNormals()) { - in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices; - } - - if (mScene->mMeshes[i]->HasTangentsAndBitangents()) { - in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices * 2; - } - - for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS;++a) { - if (mScene->mMeshes[i]->HasVertexColors(a)) { - in.meshes += sizeof(aiColor4D) * mScene->mMeshes[i]->mNumVertices; - } - else break; - } - for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a) { - if (mScene->mMeshes[i]->HasTextureCoords(a)) { - in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices; - } - else break; - } - if (mScene->mMeshes[i]->HasBones()) { - in.meshes += sizeof(void*) * mScene->mMeshes[i]->mNumBones; - for (unsigned int p = 0; p < mScene->mMeshes[i]->mNumBones;++p) { - in.meshes += sizeof(aiBone); - in.meshes += mScene->mMeshes[i]->mBones[p]->mNumWeights * sizeof(aiVertexWeight); - } - } - in.meshes += (sizeof(aiFace) + 3 * sizeof(unsigned int))*mScene->mMeshes[i]->mNumFaces; - } + in = aiMemoryInfo(); + aiScene* mScene = pimpl->mScene; + + // return if we have no scene loaded + if (!pimpl->mScene) + return; + + + in.total = sizeof(aiScene); + + // add all meshes + for (unsigned int i = 0; i < mScene->mNumMeshes;++i) + { + in.meshes += sizeof(aiMesh); + if (mScene->mMeshes[i]->HasPositions()) { + in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices; + } + + if (mScene->mMeshes[i]->HasNormals()) { + in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices; + } + + if (mScene->mMeshes[i]->HasTangentsAndBitangents()) { + in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices * 2; + } + + for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS;++a) { + if (mScene->mMeshes[i]->HasVertexColors(a)) { + in.meshes += sizeof(aiColor4D) * mScene->mMeshes[i]->mNumVertices; + } + else break; + } + for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a) { + if (mScene->mMeshes[i]->HasTextureCoords(a)) { + in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices; + } + else break; + } + if (mScene->mMeshes[i]->HasBones()) { + in.meshes += sizeof(void*) * mScene->mMeshes[i]->mNumBones; + for (unsigned int p = 0; p < mScene->mMeshes[i]->mNumBones;++p) { + in.meshes += sizeof(aiBone); + in.meshes += mScene->mMeshes[i]->mBones[p]->mNumWeights * sizeof(aiVertexWeight); + } + } + in.meshes += (sizeof(aiFace) + 3 * sizeof(unsigned int))*mScene->mMeshes[i]->mNumFaces; + } in.total += in.meshes; - // add all embedded textures - for (unsigned int i = 0; i < mScene->mNumTextures;++i) { - const aiTexture* pc = mScene->mTextures[i]; - in.textures += sizeof(aiTexture); - if (pc->mHeight) { - in.textures += 4 * pc->mHeight * pc->mWidth; - } - else in.textures += pc->mWidth; - } - in.total += in.textures; - - // add all animations - for (unsigned int i = 0; i < mScene->mNumAnimations;++i) { - const aiAnimation* pc = mScene->mAnimations[i]; - in.animations += sizeof(aiAnimation); - - // add all bone anims - for (unsigned int a = 0; a < pc->mNumChannels; ++a) { - const aiNodeAnim* pc2 = pc->mChannels[i]; - in.animations += sizeof(aiNodeAnim); - in.animations += pc2->mNumPositionKeys * sizeof(aiVectorKey); - in.animations += pc2->mNumScalingKeys * sizeof(aiVectorKey); - in.animations += pc2->mNumRotationKeys * sizeof(aiQuatKey); - } - } - in.total += in.animations; - - // add all cameras and all lights - in.total += in.cameras = sizeof(aiCamera) * mScene->mNumCameras; - in.total += in.lights = sizeof(aiLight) * mScene->mNumLights; - - // add all nodes - AddNodeWeight(in.nodes,mScene->mRootNode); - in.total += in.nodes; - - // add all materials - for (unsigned int i = 0; i < mScene->mNumMaterials;++i) { - const aiMaterial* pc = mScene->mMaterials[i]; - in.materials += sizeof(aiMaterial); - in.materials += pc->mNumAllocated * sizeof(void*); - - for (unsigned int a = 0; a < pc->mNumProperties;++a) { - in.materials += pc->mProperties[a]->mDataLength; - } - } - in.total += in.materials; + // add all embedded textures + for (unsigned int i = 0; i < mScene->mNumTextures;++i) { + const aiTexture* pc = mScene->mTextures[i]; + in.textures += sizeof(aiTexture); + if (pc->mHeight) { + in.textures += 4 * pc->mHeight * pc->mWidth; + } + else in.textures += pc->mWidth; + } + in.total += in.textures; + + // add all animations + for (unsigned int i = 0; i < mScene->mNumAnimations;++i) { + const aiAnimation* pc = mScene->mAnimations[i]; + in.animations += sizeof(aiAnimation); + + // add all bone anims + for (unsigned int a = 0; a < pc->mNumChannels; ++a) { + const aiNodeAnim* pc2 = pc->mChannels[i]; + in.animations += sizeof(aiNodeAnim); + in.animations += pc2->mNumPositionKeys * sizeof(aiVectorKey); + in.animations += pc2->mNumScalingKeys * sizeof(aiVectorKey); + in.animations += pc2->mNumRotationKeys * sizeof(aiQuatKey); + } + } + in.total += in.animations; + + // add all cameras and all lights + in.total += in.cameras = sizeof(aiCamera) * mScene->mNumCameras; + in.total += in.lights = sizeof(aiLight) * mScene->mNumLights; + + // add all nodes + AddNodeWeight(in.nodes,mScene->mRootNode); + in.total += in.nodes; + + // add all materials + for (unsigned int i = 0; i < mScene->mNumMaterials;++i) { + const aiMaterial* pc = mScene->mMaterials[i]; + in.materials += sizeof(aiMaterial); + in.materials += pc->mNumAllocated * sizeof(void*); + + for (unsigned int a = 0; a < pc->mNumProperties;++a) { + in.materials += pc->mProperties[a]->mDataLength; + } + } + in.total += in.materials; } - |