Logging functions are now available to C-Users, too. Cleaning up headers.

Changing spelling of some enums to camel.
Ply loader loads tristrips correctly now.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@425 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
aramis_acg 2009-05-28 11:32:54 +00:00
parent 1aa80ca8da
commit d881a16402
23 changed files with 1249 additions and 870 deletions

View File

@ -38,42 +38,63 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file Implementation of the Plain-C API */ /** @file Assimp.cpp
* @brief Implementation of the Plain-C API
*/
#include "AssimpPCH.h" #include "AssimpPCH.h"
#include "../include/assimp.h" #include "../include/assimp.h"
// public ASSIMP headers
#include "../include/aiFileIO.h" #include "../include/aiFileIO.h"
#include "GenericProperty.h" #include "GenericProperty.h"
#if (defined AI_C_THREADSAFE) // ------------------------------------------------------------------------------------------------
#ifdef AI_C_THREADSAFE
# include <boost/thread/thread.hpp> # include <boost/thread/thread.hpp>
# include <boost/thread/mutex.hpp> # include <boost/thread/mutex.hpp>
#endif #endif
// ------------------------------------------------------------------------------------------------
using namespace Assimp; using namespace Assimp;
/** Stores the importer objects for all active import processes */ /** Stores the importer objects for all active import processes */
typedef std::map< const aiScene*, Assimp::Importer* > ImporterMap; typedef std::map<const aiScene*, Assimp::Importer*> ImporterMap;
/** Stores the LogStream objects for all active C log streams */
struct mpred {
bool operator () (const aiLogStream& s0, const aiLogStream& s1) const {
return s0.callback<s1.callback&&s0.user<s1.user;
}
};
typedef std::map<aiLogStream, Assimp::LogStream*, mpred> LogStreamMap;
/** Stores the LogStream objects allocated by #aiGetPredefinedLogStream */
typedef std::list<Assimp::LogStream*> PredefLogStreamMap;
/** Local storage of all active import processes */ /** Local storage of all active import processes */
static ImporterMap gActiveImports; static ImporterMap gActiveImports;
/** Local storage of all active log streams */
static LogStreamMap gActiveLogStreams;
/** Local storage of LogStreams allocated by #aiGetPredefinedLogStream */
static PredefLogStreamMap gPredefinedStreams;
/** Error message of the last failed import process */ /** Error message of the last failed import process */
static std::string gLastErrorString; static std::string gLastErrorString;
/** Configuration properties */ /** Verbose logging active or not? */
static ImporterPimpl::IntPropertyMap gIntProperties; static aiBool gVerboseLogging = false;
static ImporterPimpl::FloatPropertyMap gFloatProperties;
static ImporterPimpl::StringPropertyMap gStringProperties;
#if (defined AI_C_THREADSAFE) /** Configuration properties */
static ImporterPimpl::IntPropertyMap gIntProperties;
static ImporterPimpl::FloatPropertyMap gFloatProperties;
static ImporterPimpl::StringPropertyMap gStringProperties;
#ifdef AI_C_THREADSAFE
/** Global mutex to manage the access to the importer map */ /** Global mutex to manage the access to the importer map */
static boost::mutex gMutex; static boost::mutex gMutex;
/** Global mutex to manage the access to the logstream map */
static boost::mutex gLogStreamMutex;
#endif #endif
class CIOSystemWrapper; class CIOSystemWrapper;
@ -90,46 +111,43 @@ public:
: mFile(pFile) : mFile(pFile)
{} {}
// ------------------------------------------------------------------- // ...................................................................
size_t Read(void* pvBuffer, size_t Read(void* pvBuffer,
size_t pSize, size_t pSize,
size_t pCount) size_t pCount
{ ){
// need to typecast here as C has no void* // need to typecast here as C has no void*
return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount); return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount);
} }
// ------------------------------------------------------------------- // ...................................................................
size_t Write(const void* pvBuffer, size_t Write(const void* pvBuffer,
size_t pSize, size_t pSize,
size_t pCount) size_t pCount
{ ){
// need to typecast here as C has no void* // need to typecast here as C has no void*
return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount); return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount);
} }
// ------------------------------------------------------------------- // ...................................................................
aiReturn Seek(size_t pOffset, aiReturn Seek(size_t pOffset,
aiOrigin pOrigin) aiOrigin pOrigin
{ ){
return mFile->SeekProc(mFile,pOffset,pOrigin); return mFile->SeekProc(mFile,pOffset,pOrigin);
} }
// ------------------------------------------------------------------- // ...................................................................
size_t Tell(void) const size_t Tell(void) const {
{
return mFile->TellProc(mFile); return mFile->TellProc(mFile);
} }
// ------------------------------------------------------------------- // ...................................................................
size_t FileSize() const size_t FileSize() const {
{
return mFile->FileSizeProc(mFile); return mFile->FileSizeProc(mFile);
} }
// ------------------------------------------------------------------- // ...................................................................
void Flush () void Flush () {
{
return mFile->FlushProc(mFile); return mFile->FlushProc(mFile);
} }
@ -137,20 +155,17 @@ private:
aiFile* mFile; aiFile* mFile;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Custom IOStream implementation for the C-API // Custom IOStream implementation for the C-API
class CIOSystemWrapper : public IOSystem class CIOSystemWrapper : public IOSystem
{ {
public: public:
CIOSystemWrapper(aiFileIO* pFile) CIOSystemWrapper(aiFileIO* pFile)
: mFileSystem(pFile) : mFileSystem(pFile)
{} {}
// ------------------------------------------------------------------- // ...................................................................
bool Exists( const char* pFile) const bool Exists( const char* pFile) const {
{
CIOSystemWrapper* pip = const_cast<CIOSystemWrapper*>(this); CIOSystemWrapper* pip = const_cast<CIOSystemWrapper*>(this);
IOStream* p = pip->Open(pFile); IOStream* p = pip->Open(pFile);
if (p){ if (p){
@ -160,40 +175,80 @@ public:
return false; return false;
} }
// ------------------------------------------------------------------- // ...................................................................
char getOsSeparator() const char getOsSeparator() const {
{ #ifndef _WIN32
// FIXME
return '/'; return '/';
#else
return '\\';
#endif
} }
// ------------------------------------------------------------------- // ...................................................................
IOStream* Open(const char* pFile,const char* pMode = "rb") IOStream* Open(const char* pFile,const char* pMode = "rb") {
{
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode); aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode);
if (!p)return NULL; if (!p) {
return NULL;
}
return new CIOStreamWrapper(p); return new CIOStreamWrapper(p);
} }
// ------------------------------------------------------------------- // ...................................................................
void Close( IOStream* pFile) void Close( IOStream* pFile) {
{ if (!pFile) {
if (!pFile)return; return;
}
mFileSystem->CloseProc(mFileSystem,((CIOStreamWrapper*) pFile)->mFile); mFileSystem->CloseProc(mFileSystem,((CIOStreamWrapper*) pFile)->mFile);
delete pFile; delete pFile;
} }
private:
aiFileIO* mFileSystem;
};
// ------------------------------------------------------------------------------------------------
// Custom LogStream implementation for the C-API
class LogToCallbackRedirector : public LogStream
{
public:
LogToCallbackRedirector(const aiLogStream& s)
: stream (s) {
ai_assert(NULL != s.callback);
}
~LogToCallbackRedirector() {
#ifdef AI_C_THREADSAFE
boost::mutex::scoped_lock lock(gLogStreamMutex);
#endif
// (HACK) Check whether the 'stream.user' pointer points to a
// custom LogStream allocated by #aiGetPredefinedLogStream.
// In this case, we need to delete it, too. Of course, this
// might cause strange problems, but the chance is quite low.
PredefLogStreamMap::iterator it = std::find(gPredefinedStreams.begin(),
gPredefinedStreams.end(), (Assimp::LogStream*)stream.user);
if (it != gPredefinedStreams.end()) {
delete *it;
gPredefinedStreams.erase(it);
}
}
/** @copydoc LogStream::write */
void write(const char* message) {
stream.callback(message,stream.user);
}
private: private:
aiLogStream stream;
aiFileIO* mFileSystem;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ReportSceneNotFoundError() void ReportSceneNotFoundError()
{ {
DefaultLogger::get()->error("Unable to find the Importer instance for this scene. " DefaultLogger::get()->error("Unable to find the Assimp::Importer for this aiScene. "
"Are you sure it has been created by aiImportFile(ex)(...)?"); "Are you playing fools with us? Don't mix cpp and c API. Thanks.");
assert(false);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -208,19 +263,23 @@ const aiScene* aiImportFileEx( const char* pFile, unsigned int pFlags,
aiFileIO* pFS) aiFileIO* pFS)
{ {
ai_assert(NULL != pFile); ai_assert(NULL != pFile);
// create an Importer for this file // create an Importer for this file
Assimp::Importer* imp = new Assimp::Importer; Assimp::Importer* imp = new Assimp::Importer;
#ifdef AI_C_THREADSAFE
boost::mutex::scoped_lock lock(gMutex);
#endif
// copy the global property lists to the Importer instance // copy the global property lists to the Importer instance
// (we are a friend of Importer)
imp->pimpl->mIntProperties = gIntProperties; imp->pimpl->mIntProperties = gIntProperties;
imp->pimpl->mFloatProperties = gFloatProperties; imp->pimpl->mFloatProperties = gFloatProperties;
imp->pimpl->mStringProperties = gStringProperties; imp->pimpl->mStringProperties = gStringProperties;
#ifdef AI_C_THREADSAFE
lock.unlock();
#endif
// setup a custom IO system if necessary // setup a custom IO system if necessary
if (pFS) if (pFS) {
{
imp->SetIOHandler( new CIOSystemWrapper (pFS) ); imp->SetIOHandler( new CIOSystemWrapper (pFS) );
} }
@ -228,15 +287,13 @@ const aiScene* aiImportFileEx( const char* pFile, unsigned int pFlags,
const aiScene* scene = imp->ReadFile( pFile, pFlags); const aiScene* scene = imp->ReadFile( pFile, pFlags);
// if succeeded, place it in the collection of active processes // if succeeded, place it in the collection of active processes
if( scene) if( scene) {
{ #ifdef AI_C_THREADSAFE
#if (defined AI_C_THREADSAFE) lock.lock();
boost::mutex::scoped_lock lock(gMutex);
#endif #endif
gActiveImports[scene] = imp; gActiveImports[scene] = imp;
} }
else else {
{
// if failed, extract error code and destroy the import // if failed, extract error code and destroy the import
gLastErrorString = imp->GetErrorString(); gLastErrorString = imp->GetErrorString();
delete imp; delete imp;
@ -250,18 +307,18 @@ const aiScene* aiImportFileEx( const char* pFile, unsigned int pFlags,
// Releases all resources associated with the given import process. // Releases all resources associated with the given import process.
void aiReleaseImport( const aiScene* pScene) void aiReleaseImport( const aiScene* pScene)
{ {
if (!pScene)return; if (!pScene) {
return;
}
// lock the mutex #ifdef AI_C_THREADSAFE
#if (defined AI_C_THREADSAFE)
boost::mutex::scoped_lock lock(gMutex); boost::mutex::scoped_lock lock(gMutex);
#endif #endif
// find the importer associated with this data // find the importer associated with this data
ImporterMap::iterator it = gActiveImports.find( pScene); ImporterMap::iterator it = gActiveImports.find( pScene);
// it should be there... else the user is playing fools with us // it should be there... else the user is playing fools with us
if( it == gActiveImports.end()) if( it == gActiveImports.end()) {
{
ReportSceneNotFoundError(); ReportSceneNotFoundError();
return; return;
} }
@ -271,6 +328,120 @@ void aiReleaseImport( const aiScene* pScene)
gActiveImports.erase( it); gActiveImports.erase( it);
} }
// ------------------------------------------------------------------------------------------------
ASSIMP_API const aiScene* aiApplyPostProcessing(const aiScene* pScene,
unsigned int pFlags)
{
#ifdef AI_C_THREADSAFE
boost::mutex::scoped_lock lock(gMutex);
#endif
// find the importer associated with this data
ImporterMap::iterator it = gActiveImports.find( pScene);
// it should be there... else the user is playing fools with us
if( it == gActiveImports.end()) {
ReportSceneNotFoundError();
return NULL;
}
#ifdef AI_C_THREADSAFE
lock.unlock();
#endif
const aiScene* sc = it->second->ApplyPostProcessing(pFlags);
#ifdef AI_C_THREADSAFE
lock.lock();
#endif
if (!sc) {
// kill the importer, the data dies with it
delete it->second;
gActiveImports.erase( it);
return NULL;
}
return it->first;
}
// ------------------------------------------------------------------------------------------------
void CallbackToLogRedirector (const char* msg, char* dt)
{
ai_assert(NULL != msg && NULL != dt);
LogStream* s = (LogStream*)dt;
s->write(msg);
}
// ------------------------------------------------------------------------------------------------
ASSIMP_API aiLogStream aiGetPredefinedLogStream(aiDefaultLogStream pStream,const char* file)
{
aiLogStream sout;
LogStream* stream = LogStream::createDefaultStream(pStream,file);
if (!stream) {
sout.callback = NULL;
}
else {
sout.callback = &CallbackToLogRedirector;
sout.user = (char*)stream;
}
gPredefinedStreams.push_back(stream);
return sout;
}
// ------------------------------------------------------------------------------------------------
ASSIMP_API void aiAttachLogStream( const aiLogStream* stream )
{
#ifdef AI_C_THREADSAFE
boost::mutex::scoped_lock lock(gLogStreamMutex);
#endif
LogStream* lg = new LogToCallbackRedirector(*stream);
gActiveLogStreams[*stream] = lg;
if (DefaultLogger::isNullLogger()) {
DefaultLogger::create(NULL,(gVerboseLogging == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL));
}
DefaultLogger::get()->attachStream(lg);
}
// ------------------------------------------------------------------------------------------------
ASSIMP_API aiReturn aiDetachLogStream( const aiLogStream* stream)
{
#ifdef AI_C_THREADSAFE
boost::mutex::scoped_lock lock(gLogStreamMutex);
#endif
// find the logstream associated with this data
LogStreamMap::iterator it = gActiveLogStreams.find( *stream);
// it should be there... else the user is playing fools with us
if( it == gActiveLogStreams.end()) {
return AI_FAILURE;
}
delete it->second;
gActiveLogStreams.erase( it);
if (gActiveLogStreams.empty()) {
DefaultLogger::kill();
}
return AI_SUCCESS;
}
// ------------------------------------------------------------------------------------------------
ASSIMP_API void aiDetachAllLogStreams(void)
{
#ifdef AI_C_THREADSAFE
boost::mutex::scoped_lock lock(gLogStreamMutex);
#endif
for (LogStreamMap::iterator it = gActiveLogStreams.begin(); it != gActiveLogStreams.end(); ++it) {
delete it->second;
}
gActiveLogStreams.clear();
DefaultLogger::kill();
}
// ------------------------------------------------------------------------------------------------
ASSIMP_API void aiEnableVerboseLogging(aiBool d)
{
if (!DefaultLogger::isNullLogger()) {
DefaultLogger::get()->setLogSeverity((d == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL));
}
gVerboseLogging = d;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns the error text of the last failed import process. // Returns the error text of the last failed import process.
const char* aiGetErrorString() const char* aiGetErrorString()
@ -280,25 +451,20 @@ const char* aiGetErrorString()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns the error text of the last failed import process. // Returns the error text of the last failed import process.
int aiIsExtensionSupported(const char* szExtension) aiBool aiIsExtensionSupported(const char* szExtension)
{ {
ai_assert(NULL != szExtension); ai_assert(NULL != szExtension);
#ifdef AI_C_THREADSAFE
// lock the mutex
#if (defined AI_C_THREADSAFE)
boost::mutex::scoped_lock lock(gMutex); boost::mutex::scoped_lock lock(gMutex);
#endif #endif
if (!gActiveImports.empty()) { if (!gActiveImports.empty()) {
return (int)((*(gActiveImports.begin())).second->IsExtensionSupported( szExtension )); return ((*(gActiveImports.begin())).second->IsExtensionSupported( szExtension )) ? AI_TRUE : AI_FALSE;
} }
// need to create a temporary Importer instance. // fixme: no need to create a temporary Importer instance just for that ..
// TODO: Find a better solution ... Assimp::Importer tmp;
Assimp::Importer* pcTemp = new Assimp::Importer(); return tmp.IsExtensionSupported(std::string(szExtension)) ? AI_TRUE : AI_FALSE;
int i = (int)pcTemp->IsExtensionSupported(std::string(szExtension));
delete pcTemp;
return i;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -306,9 +472,7 @@ int aiIsExtensionSupported(const char* szExtension)
void aiGetExtensionList(aiString* szOut) void aiGetExtensionList(aiString* szOut)
{ {
ai_assert(NULL != szOut); ai_assert(NULL != szOut);
#ifdef AI_C_THREADSAFE
// lock the mutex
#if (defined AI_C_THREADSAFE)
boost::mutex::scoped_lock lock(gMutex); boost::mutex::scoped_lock lock(gMutex);
#endif #endif
@ -317,65 +481,85 @@ void aiGetExtensionList(aiString* szOut)
(*(gActiveImports.begin())).second->GetExtensionList(*szOut); (*(gActiveImports.begin())).second->GetExtensionList(*szOut);
return; return;
} }
// need to create a temporary Importer instance. // fixme: no need to create a temporary Importer instance just for that ..
// TODO: Find a better solution ... Assimp::Importer tmp;
Assimp::Importer* pcTemp = new Assimp::Importer(); tmp.GetExtensionList(*szOut);
pcTemp->GetExtensionList(*szOut);
delete pcTemp;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get the memory requirements for a particular import.
void aiGetMemoryRequirements(const C_STRUCT aiScene* pIn, void aiGetMemoryRequirements(const C_STRUCT aiScene* pIn,
C_STRUCT aiMemoryInfo* in) C_STRUCT aiMemoryInfo* in)
{ {
// lock the mutex #ifdef AI_C_THREADSAFE
#if (defined AI_C_THREADSAFE)
boost::mutex::scoped_lock lock(gMutex); boost::mutex::scoped_lock lock(gMutex);
#endif #endif
// find the importer associated with this data // find the importer associated with this data
ImporterMap::iterator it = gActiveImports.find( pIn); ImporterMap::iterator it = gActiveImports.find( pIn);
// it should be there... else the user is playing fools with us // it should be there... else the user is playing fools with us
if( it == gActiveImports.end()) if( it == gActiveImports.end()) {
{
ReportSceneNotFoundError(); ReportSceneNotFoundError();
return; return;
} }
// get memory statistics // get memory statistics
#ifdef AI_C_THREADSAFE
lock.unlock();
#endif
it->second->GetMemoryRequirements(*in); it->second->GetMemoryRequirements(*in);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Importer::SetPropertyInteger
ASSIMP_API void aiSetImportPropertyInteger(const char* szName, int value) ASSIMP_API void aiSetImportPropertyInteger(const char* szName, int value)
{ {
#ifdef AI_C_THREADSAFE
boost::mutex::scoped_lock lock(gMutex);
#endif
SetGenericProperty<int>(gIntProperties,szName,value,NULL); SetGenericProperty<int>(gIntProperties,szName,value,NULL);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Importer::SetPropertyFloat
ASSIMP_API void aiSetImportPropertyFloat(const char* szName, float value) ASSIMP_API void aiSetImportPropertyFloat(const char* szName, float value)
{ {
#ifdef AI_C_THREADSAFE
boost::mutex::scoped_lock lock(gMutex);
#endif
SetGenericProperty<float>(gFloatProperties,szName,value,NULL); SetGenericProperty<float>(gFloatProperties,szName,value,NULL);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Importer::SetPropertyString
ASSIMP_API void aiSetImportPropertyString(const char* szName, ASSIMP_API void aiSetImportPropertyString(const char* szName,
const C_STRUCT aiString* st) const C_STRUCT aiString* st)
{ {
if (!st)return; if (!st) {
return;
}
#ifdef AI_C_THREADSAFE
boost::mutex::scoped_lock lock(gMutex);
#endif
SetGenericProperty<std::string>(gStringProperties,szName, SetGenericProperty<std::string>(gStringProperties,szName,
std::string( st->data ),NULL); std::string( st->data ),NULL);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Rotation matrix to quaternion
ASSIMP_API void aiCreateQuaternionFromMatrix(aiQuaternion* quat,const aiMatrix3x3* mat) ASSIMP_API void aiCreateQuaternionFromMatrix(aiQuaternion* quat,const aiMatrix3x3* mat)
{ {
ai_assert(NULL != quat && NULL != mat);
*quat = aiQuaternion(*mat); *quat = aiQuaternion(*mat);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
ASSIMP_API void aiDecomposeMatrix(const aiMatrix4x4* mat, aiVector3D* scaling, // Affline matrix decomposition
aiQuaternion* rotation,aiVector3D* position) ASSIMP_API void aiDecomposeMatrix(const aiMatrix4x4* mat,aiVector3D* scaling,
aiQuaternion* rotation,
aiVector3D* position)
{ {
ai_assert(NULL != rotation && NULL != position && NULL != scaling && NULL != mat);
mat->Decompose(*scaling,*rotation,*position); mat->Decompose(*scaling,*rotation,*position);
} }

View File

@ -88,14 +88,14 @@ struct LogStreamInfo
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Construct a default log stream // Construct a default log stream
LogStream* LogStream::createDefaultStream(DefaultLogStreams streams, LogStream* LogStream::createDefaultStream(aiDefaultLogStream streams,
const char* name /*= "AssimpLog.txt"*/, const char* name /*= "AssimpLog.txt"*/,
IOSystem* io /*= NULL*/) IOSystem* io /*= NULL*/)
{ {
switch (streams) switch (streams)
{ {
// This is a platform-specific feature // This is a platform-specific feature
case DLS_DEBUGGER: case aiDefaultLogStream_DEBUGGER:
#ifdef WIN32 #ifdef WIN32
return new Win32DebugLogStream(); return new Win32DebugLogStream();
#else #else
@ -103,11 +103,11 @@ LogStream* LogStream::createDefaultStream(DefaultLogStreams streams,
#endif #endif
// Platform-independent default streams // Platform-independent default streams
case DLS_CERR: case aiDefaultLogStream_STDERR:
return new StdOStreamLogStream(std::cerr); return new StdOStreamLogStream(std::cerr);
case DLS_COUT: case aiDefaultLogStream_STDOUT:
return new StdOStreamLogStream(std::cout); return new StdOStreamLogStream(std::cout);
case DLS_FILE: case aiDefaultLogStream_FILE:
return (name && *name ? new FileLogStream(name,io) : NULL); return (name && *name ? new FileLogStream(name,io) : NULL);
default: default:
// We don't know this default log stream, so raise an assertion // We don't know this default log stream, so raise an assertion
@ -123,7 +123,7 @@ LogStream* LogStream::createDefaultStream(DefaultLogStreams streams,
// Creates the only singleton instance // Creates the only singleton instance
Logger *DefaultLogger::create(const char* name /*= "AssimpLog.txt"*/, Logger *DefaultLogger::create(const char* name /*= "AssimpLog.txt"*/,
LogSeverity severity /*= NORMAL*/, LogSeverity severity /*= NORMAL*/,
unsigned int defStreams /*= DLS_DEBUGGER | DLS_FILE*/, unsigned int defStreams /*= aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE*/,
IOSystem* io /*= NULL*/) IOSystem* io /*= NULL*/)
{ {
// enter the mutex here to avoid concurrency problems // enter the mutex here to avoid concurrency problems
@ -138,20 +138,20 @@ Logger *DefaultLogger::create(const char* name /*= "AssimpLog.txt"*/,
// Attach default log streams // Attach default log streams
// Stream the log to the MSVC debugger? // Stream the log to the MSVC debugger?
if (defStreams & DLS_DEBUGGER) if (defStreams & aiDefaultLogStream_DEBUGGER)
m_pLogger->attachStream( LogStream::createDefaultStream(DLS_DEBUGGER)); m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_DEBUGGER));
// Stream the log to COUT? // Stream the log to COUT?
if (defStreams & DLS_COUT) if (defStreams & aiDefaultLogStream_STDOUT)
m_pLogger->attachStream( LogStream::createDefaultStream(DLS_COUT)); m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDOUT));
// Stream the log to CERR? // Stream the log to CERR?
if (defStreams & DLS_CERR) if (defStreams & aiDefaultLogStream_STDERR)
m_pLogger->attachStream( LogStream::createDefaultStream(DLS_CERR)); m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDERR));
// Stream the log to a file // Stream the log to a file
if (defStreams & DLS_FILE && name && *name) if (defStreams & aiDefaultLogStream_FILE && name && *name)
m_pLogger->attachStream( LogStream::createDefaultStream(DLS_FILE,name,io)); m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_FILE,name,io));
return m_pLogger; return m_pLogger;
} }

View File

@ -794,38 +794,39 @@ void PLYImporter::LoadFaces(std::vector<PLY::Face>* pvOut)
{ {
// normally we have only one triangle strip instance where // normally we have only one triangle strip instance where
// a value of -1 indicates a restart of the strip // a value of -1 indicates a restart of the strip
for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin(); bool flip = false;
i != pcList->alInstances.end();++i) for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin();i != pcList->alInstances.end();++i) {
{
const std::vector<PLY::PropertyInstance::ValueUnion>& quak = (*i).alProperties[iProperty].avList; const std::vector<PLY::PropertyInstance::ValueUnion>& quak = (*i).alProperties[iProperty].avList;
pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u)); pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u));
int aiTable[2] = {-1,-1}; int aiTable[2] = {-1,-1};
for (std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator a = quak.begin();a != quak.end();++a) { for (std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator a = quak.begin();a != quak.end();++a) {
const int p = PLY::PropertyInstance::ConvertTo<int>(*a,eType); const int p = PLY::PropertyInstance::ConvertTo<int>(*a,eType);
if (-1 == p)
{ if (-1 == p) {
// restart the strip ... // restart the strip ...
aiTable[0] = aiTable[1] = -1; aiTable[0] = aiTable[1] = -1;
flip = false;
continue; continue;
} }
if (-1 == aiTable[0]) if (-1 == aiTable[0]) {
{
aiTable[0] = p; aiTable[0] = p;
continue; continue;
} }
if (-1 == aiTable[1]) if (-1 == aiTable[1]) {
{
aiTable[1] = p; aiTable[1] = p;
continue; continue;
} }
pvOut->push_back(PLY::Face()); pvOut->push_back(PLY::Face());
PLY::Face& sFace = pvOut->back(); PLY::Face& sFace = pvOut->back();
sFace.mIndices.push_back((unsigned int)aiTable[0]); sFace.mIndices[0] = aiTable[0];
sFace.mIndices.push_back((unsigned int)aiTable[1]); sFace.mIndices[1] = aiTable[1];
sFace.mIndices.push_back((unsigned int)p); sFace.mIndices[2] = p;
if ((flip = !flip)) {
std::swap(sFace.mIndices[0],sFace.mIndices[1]);
}
aiTable[0] = aiTable[1]; aiTable[0] = aiTable[1];
aiTable[1] = p; aiTable[1] = p;
} }

Binary file not shown.

View File

@ -37,7 +37,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file DefaultLogger.h /** @file DefaultLogger.h
*/ */
@ -54,100 +53,127 @@ namespace Assimp {
class IOStream; class IOStream;
struct LogStreamInfo; struct LogStreamInfo;
//! Default log file name /** default name of logfile */
#define ASSIMP_DEFAULT_LOG_NAME "AssimpLog.txt" #define ASSIMP_DEFAULT_LOG_NAME "AssimpLog.txt"
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
/** @class DefaultLogger /** @class DefaultLogger
* @brief Default logging implementation. * @brief Primary logging implementation of Assimp.
* *
* todo .... move static stuff to Logger where it belongs to. * The library stores its primary #Logger as a static member of this class.
* #get() returns this primary logger. By default the underlying implementation is
* just a #NullLogger which rejects all log messages. By calling #create(), logging
* is turned on. To capture the log output multiple log streams (#LogStream) can be
* attach to the logger. Some default streams for common streaming locations (such as
* a file, std::cout, OutputDebugString()) are also provided.
*
* If you wish to customize the logging at an even deeper level supply your own
* implementation of #Logger to #set().
* @note The whole logging stuff causes a small extra overhead for all imports.
*/ */
class ASSIMP_API DefaultLogger : class ASSIMP_API DefaultLogger :
public Logger public Logger {
{
public: public:
/** @brief Creates a default logging instance (DefaultLogger) // ----------------------------------------------------------------------
* @param name Name for log file. Only valid in combination /** @brief Creates a logging instance.
* with the DLS_FILE flag. * @param name Name for log file. Only valid in combination
* @param severity Log severity, VERBOSE will activate debug messages * with the aiDefaultLogStream_FILE flag.
* @param defStreams Default log streams to be attached. Bitwise * @param severity Log severity, VERBOSE turns on debug messages
* combination of the DefaultLogStreams enumerated * @param defStreams Default log streams to be attached. Any bitwise
* values. If DLS_FILE is specified, but an empty * combination of the aiDefaultLogStream enumerated values.
* string is passed for 'name' no log file is created. * If #aiDefaultLogStream_FILE is specified but an empty string is
* @param io IOSystem to be used to open external files (such as the * passed for 'name', no log file is created at all.
* log file). Pass NULL for the default implementation. * @param io IOSystem to be used to open external files (such as the
* log file). Pass NULL to rely on the default implementation.
* *
* This replaces the default NullLogger with a DefaultLogger instance. * This replaces the default #NullLogger with a #DefaultLogger instance.
* @note You can't
*/ */
static Logger *create(const char* name = ASSIMP_DEFAULT_LOG_NAME, static Logger *create(const char* name = ASSIMP_DEFAULT_LOG_NAME,
LogSeverity severity = NORMAL, LogSeverity severity = NORMAL,
unsigned int defStreams = DLS_DEBUGGER | DLS_FILE, unsigned int defStreams = aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE,
IOSystem* io = NULL); IOSystem* io = NULL);
/** @brief Setup a custom implementation of the Logger interface as // ----------------------------------------------------------------------
* default logger. /** @brief Setup a custom #Logger implementation.
* *
* Use this if the provided DefaultLogger class doesn't fit into * Use this if the provided #DefaultLogger class doesn't fit into
* your needs. If the provided message formatting is OK for you, * your needs. If the provided message formatting is OK for you,
* it is easier to use create() to create a DefaultLogger and to attach * it's much easier to use #create() and to attach your own custom
* your own custom output streams to it than using this method. * output streams to it.
* @param logger Pass NULL to setup a default NullLogger * @param logger Pass NULL to setup a default NullLogger
*/ */
static void set (Logger *logger); static void set (Logger *logger);
// ----------------------------------------------------------------------
/** @brief Getter for singleton instance /** @brief Getter for singleton instance
* @return Only instance. This is never null, but it could be a * @return Only instance. This is never null, but it could be a
* NullLogger. Use isNullLogger to check this. * NullLogger. Use isNullLogger to check this.
*/ */
static Logger *get(); static Logger *get();
/** @brief Return whether a default NullLogger is currently active // ----------------------------------------------------------------------
* @return true if the current logger is a NullLogger. /** @brief Return whether a #NullLogger is currently active
* Use create() or set() to setup a custom logger. * @return true if the current logger is a #NullLogger.
* Use create() or set() to setup a logger that does actually do
* something else than just rejecting all log messages.
*/ */
static bool isNullLogger(); static bool isNullLogger();
/** @brief Will kill the singleton instance and setup a NullLogger as logger */ // ----------------------------------------------------------------------
/** @brief Kills the current singleton logger and replaces it with a
* #NullLogger instance.
*/
static void kill(); static void kill();
/** @brief Attach a stream to the logger. */ // ----------------------------------------------------------------------
/* override */ bool attachStream(LogStream *pStream, /** @copydoc Logger::attachStream
*/
bool attachStream(LogStream *pStream,
unsigned int severity); unsigned int severity);
/** @brief Detach a still attached stream from logger */ // ----------------------------------------------------------------------
/* override */ bool detatchStream(LogStream *pStream, /** @copydoc Logger::detatchStream
*/
bool detatchStream(LogStream *pStream,
unsigned int severity); unsigned int severity);
private: private:
/** @brief Logs debug infos, only been written when severity level VERBOSE is set */ // ----------------------------------------------------------------------
/* override */ void OnDebug(const char* message); /** @briefPrivate construction for internal use by create().
/** @brief Logs an info message */
/* override */ void OnInfo(const char* message);
/** @brief Logs a warning message */
/* override */ void OnWarn(const char* message);
/** @brief Logs an error message */
/* override */ void OnError(const char* message);
/** @brief Private construction for internal use by create().
* @param severity Logging granularity * @param severity Logging granularity
*/ */
DefaultLogger(LogSeverity severity); DefaultLogger(LogSeverity severity);
/** @brief Destructor */ // ----------------------------------------------------------------------
/** @briefDestructor */
~DefaultLogger(); ~DefaultLogger();
private:
/** @brief Logs debug infos, only been written when severity level VERBOSE is set */
void OnDebug(const char* message);
/** @brief Logs an info message */
void OnInfo(const char* message);
/** @brief Logs a warning message */
void OnWarn(const char* message);
/** @brief Logs an error message */
void OnError(const char* message);
// ----------------------------------------------------------------------
/** @brief Writes a message to all streams */ /** @brief Writes a message to all streams */
void WriteToStreams(const char* message, ErrorSeverity ErrorSev ); void WriteToStreams(const char* message, ErrorSeverity ErrorSev );
/** @brief Returns the thread id. // ----------------------------------------------------------------------
* @remark This is an OS specific feature, if not supported, a zero will be returned. /** @brief Returns the thread id.
* @note This is an OS specific feature, if not supported, a
* zero will be returned.
*/ */
unsigned int GetThreadID(); unsigned int GetThreadID();

View File

@ -44,49 +44,28 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef INCLUDED_AI_LOGSTREAM_H #ifndef INCLUDED_AI_LOGSTREAM_H
#define INCLUDED_AI_LOGSTREAM_H #define INCLUDED_AI_LOGSTREAM_H
#include "aiTypes.h" #include "aiTypes.h"
namespace Assimp { namespace Assimp {
class IOSystem; class IOSystem;
// ------------------------------------------------------------------------------------
/** @enum DefaultLogStreams
* @brief Enumerates default log streams supported by DefaultLogger
*
* These streams can be allocated using LogStream::createDefaultStream.
*/
enum DefaultLogStreams
{
// Stream the log to a file
DLS_FILE = 0x1,
// Stream the log to std::cout
DLS_COUT = 0x2,
// Stream the log to std::cerr
DLS_CERR = 0x4,
// MSVC only: Stream the log the the debugger
DLS_DEBUGGER = 0x8
}; // !enum DefaultLogStreams
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
/** @class LogStream /** @class LogStream
* @brief Abstract interface for log stream implementations. * @brief Abstract interface for log stream implementations.
* *
* Several default implementations are provided, see DefaultLogStreams for more * Several default implementations are provided, see #aiDefaultLogStream for more
* details. In most cases it shouldn't be necessary to write a custom log stream. * details. Writing your own implementation of LogStream is just necessary if these
* are not enough for your purposes.
*/ */
class ASSIMP_API LogStream : public Intern::AllocateFromAssimpHeap class ASSIMP_API LogStream
{ : public Intern::AllocateFromAssimpHeap {
protected: protected:
/** @brief Default constructor */ /** @brief Default constructor */
LogStream(); LogStream() {
}
public: public:
/** @brief Virtual destructor */ /** @brief Virtual destructor */
virtual ~LogStream(); virtual ~LogStream() {
}
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** @brief Overwrite this for your own output methods /** @brief Overwrite this for your own output methods
@ -94,39 +73,25 @@ public:
* Log messages *may* consist of multiple lines and you shouldn't * Log messages *may* consist of multiple lines and you shouldn't
* expect a consistent formatting. If you want custom formatting * expect a consistent formatting. If you want custom formatting
* (e.g. generate HTML), supply a custom instance of Logger to * (e.g. generate HTML), supply a custom instance of Logger to
* DefaultLogger:set(). Usually you can *expect* that a log message * #DefaultLogger:set(). Usually you can *expect* that a log message
* is exactly one line long, terminated with a single \n sequence. * is exactly one line and terminated with a single \n character.
* @param message Message to be written * @param message Message to be written
*/ */
virtual void write(const char* message) = 0; virtual void write(const char* message) = 0;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** @brief Creates a default log stream /** @brief Creates a default log stream
* @param streams Type of the default stream * @param streams Type of the default stream
* @param name For DLS_FILE: name of the output file * @param name For aiDefaultLogStream_FILE: name of the output file
* @param io For DLS_FILE: IOSystem to be used to open the output file. * @param io For aiDefaultLogStream_FILE: IOSystem to be used to open the output
* Pass NULL for the default implementation. * file. Pass NULL for the default implementation.
* @return New LogStream instance - you're responsible for it's destruction! * @return New LogStream instance.
*/ */
static LogStream* createDefaultStream(DefaultLogStreams streams, static LogStream* createDefaultStream(aiDefaultLogStream stream,
const char* name = "AssimpLog.txt", const char* name = "AssimpLog.txt",
IOSystem* io = NULL); IOSystem* io = NULL);
}; // !class LogStream }; // !class LogStream
// ------------------------------------------------------------------------------------
// Default constructor
inline LogStream::LogStream()
{
// empty
}
// ------------------------------------------------------------------------------------
// Virtual destructor
inline LogStream::~LogStream()
{
// empty
}
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
} // Namespace Assimp } // Namespace Assimp

View File

@ -41,31 +41,31 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Logger.h /** @file Logger.h
* @brief Abstract base class 'Logger', base of the logging system. * @brief Abstract base class 'Logger', base of the logging system.
*/ */
#ifndef INCLUDED_AI_LOGGER_H #ifndef INCLUDED_AI_LOGGER_H
#define INCLUDED_AI_LOGGER_H #define INCLUDED_AI_LOGGER_H
#include "aiTypes.h" #include "aiTypes.h"
namespace Assimp { namespace Assimp {
class LogStream; class LogStream;
// maximum length of a log message. Longer messages are rejected. // Maximum length of a log message. Longer messages are rejected.
#define MAX_LOG_MESSAGE_LENGTH 1024u #define MAX_LOG_MESSAGE_LENGTH 1024u
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
/** @class Logger /** @class Logger
* @brief Abstract interface for logger implementations. * @brief Abstract interface for logger implementations.
* Assimp provides a default implementation ('DefaultLogger'). * Assimp provides a default implementation and uses it for almost all
* logging stuff ('DefaultLogger'). This class defines just basic logging
* behaviour and is not of interest for you.
*/ */
class ASSIMP_API Logger : public Intern::AllocateFromAssimpHeap class ASSIMP_API Logger
: public Intern::AllocateFromAssimpHeap
{ {
public: public:
// ----------------------------------------------------------------------
/** @enum LogSeverity /** @enum LogSeverity
* @brief Log severity to describe the granularity of logging. * @brief Log severity to describe the granularity of logging.
*
* This is a general property of a Logger instance, NORMAL means
* that debug messages are rejected immediately.
*/ */
enum LogSeverity enum LogSeverity
{ {
@ -73,6 +73,7 @@ public:
VERBOSE //!< Debug infos will be logged, too VERBOSE //!< Debug infos will be logged, too
}; };
// ----------------------------------------------------------------------
/** @enum ErrorSeverity /** @enum ErrorSeverity
* @brief Description for severity of a log message. * @brief Description for severity of a log message.
* *
@ -93,35 +94,42 @@ public:
/** @brief Virtual destructor */ /** @brief Virtual destructor */
virtual ~Logger(); virtual ~Logger();
// ----------------------------------------------------------------------
/** @brief Writes a debug message /** @brief Writes a debug message
* @param message Debug message * @param message Debug message
*/ */
void debug(const std::string &message); void debug(const std::string &message);
// ----------------------------------------------------------------------
/** @brief Writes a info message /** @brief Writes a info message
* @param message Info message * @param message Info message
*/ */
void info(const std::string &message); void info(const std::string &message);
// ----------------------------------------------------------------------
/** @brief Writes a warning message /** @brief Writes a warning message
* @param message Warn message * @param message Warn message
*/ */
void warn(const std::string &message); void warn(const std::string &message);
// ----------------------------------------------------------------------
/** @brief Writes an error message /** @brief Writes an error message
* @param message Error message * @param message Error message
*/ */
void error(const std::string &message); void error(const std::string &message);
// ----------------------------------------------------------------------
/** @brief Set a new log severity. /** @brief Set a new log severity.
* @param log_severity New severity for logging * @param log_severity New severity for logging
*/ */
void setLogSeverity(LogSeverity log_severity); void setLogSeverity(LogSeverity log_severity);
/** @brief Get the current log severity // ----------------------------------------------------------------------
/** @brief Get the current log severity
*/ */
LogSeverity getLogSeverity() const; LogSeverity getLogSeverity() const;
// ----------------------------------------------------------------------
/** @brief Attach a new logstream /** @brief Attach a new logstream
* *
* The logger takes ownership of the stream and is responsible * The logger takes ownership of the stream and is responsible
@ -137,6 +145,7 @@ public:
virtual bool attachStream(LogStream *pStream, virtual bool attachStream(LogStream *pStream,
unsigned int severity = DEBUGGING | ERR | WARN | INFO) = 0; unsigned int severity = DEBUGGING | ERR | WARN | INFO) = 0;
// ----------------------------------------------------------------------
/** @brief Detach a still attached stream from the logger (or /** @brief Detach a still attached stream from the logger (or
* modify the filter flags bits) * modify the filter flags bits)
* @param pStream Logstream instance for detaching * @param pStream Logstream instance for detaching
@ -157,35 +166,39 @@ protected:
/** Construction with a given log severity */ /** Construction with a given log severity */
Logger(LogSeverity severity); Logger(LogSeverity severity);
/** @brief Called as a request to write a specific debug message // ----------------------------------------------------------------------
* @param message Debug message. Never longer than /** @brief Called as a request to write a specific debug message
* MAX_LOG_MESSAGE_LENGTH characters (exluding the '0'). * @param message Debug message. Never longer than
* @note The message string is only valid until the scope of * MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
* the function is left. * @note The message string is only valid until the scope of
* the function is left.
*/ */
virtual void OnDebug(const char* message)= 0; virtual void OnDebug(const char* message)= 0;
/** @brief Called as a request to write a specific info message // ----------------------------------------------------------------------
* @param message Info message. Never longer than /** @brief Called as a request to write a specific info message
* MAX_LOG_MESSAGE_LENGTH characters (exluding the '0'). * @param message Info message. Never longer than
* @note The message string is only valid until the scope of * MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
* the function is left. * @note The message string is only valid until the scope of
* the function is left.
*/ */
virtual void OnInfo(const char* message) = 0; virtual void OnInfo(const char* message) = 0;
/** @brief Called as a request to write a specific warn message // ----------------------------------------------------------------------
* @param message Warn message. Never longer than /** @brief Called as a request to write a specific warn message
* MAX_LOG_MESSAGE_LENGTH characters (exluding the '0'). * @param message Warn message. Never longer than
* @note The message string is only valid until the scope of * MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
* the function is left. * @note The message string is only valid until the scope of
* the function is left.
*/ */
virtual void OnWarn(const char* essage) = 0; virtual void OnWarn(const char* essage) = 0;
/** @brief Called as a request to write a specific error message // ----------------------------------------------------------------------
* @param message Error message. Never longer than /** @brief Called as a request to write a specific error message
* MAX_LOG_MESSAGE_LENGTH characters (exluding the '0'). * @param message Error message. Never longer than
* @note The message string is only valid until the scope of * MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
* the function is left. * @note The message string is only valid until the scope of
* the function is left.
*/ */
virtual void OnError(const char* message) = 0; virtual void OnError(const char* message) = 0;

View File

@ -45,15 +45,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef INCLUDED_AI_NULLLOGGER_H #ifndef INCLUDED_AI_NULLLOGGER_H
#define INCLUDED_AI_NULLLOGGER_H #define INCLUDED_AI_NULLLOGGER_H
#include "../include/Logger.h" #include "Logger.h"
namespace Assimp { namespace Assimp {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @class NullLogger /** @class NullLogger
* @brief Empty logging implementation. Does nothing. Used by default * @brief Empty logging implementation.
* if the application hasn't specified a custom logger (or DefaultLogger) *
* via DefaultLogger::set() or DefaultLogger::create(); * Does nothing. Used by default if the application hasn't requested a
* custom logger via #DefaultLogger::set() or #DefaultLogger::create();
*/ */
class ASSIMP_API NullLogger : public Logger class ASSIMP_API NullLogger : public Logger
{ {
@ -93,7 +92,5 @@ public:
private: private:
}; };
} }
#endif // !! AI_NULLLOGGER_H_INCLUDED #endif // !! AI_NULLLOGGER_H_INCLUDED

View File

@ -40,18 +40,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file aiFileIO.h /** @file aiFileIO.h
* @brief Defines generic routines to access memory-mapped files * @brief Defines generic C routines to access memory-mapped files
*/ */
#ifndef AI_FILEIO_H_INC #ifndef AI_FILEIO_H_INC
#define AI_FILEIO_H_INC #define AI_FILEIO_H_INC
#include "aiTypes.h" #include "aiTypes.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
struct aiFileIO; struct aiFileIO;
struct aiFile; struct aiFile;
@ -60,13 +57,13 @@ typedef size_t (*aiFileWriteProc) (C_STRUCT aiFile*, const char*, size_t, si
typedef size_t (*aiFileReadProc) (C_STRUCT aiFile*, char*, size_t,size_t); typedef size_t (*aiFileReadProc) (C_STRUCT aiFile*, char*, size_t,size_t);
typedef size_t (*aiFileTellProc) (C_STRUCT aiFile*); typedef size_t (*aiFileTellProc) (C_STRUCT aiFile*);
typedef void (*aiFileFlushProc) (C_STRUCT aiFile*); typedef void (*aiFileFlushProc) (C_STRUCT aiFile*);
typedef aiReturn (*aiFileSeek)(aiFile*, size_t, aiOrigin); typedef aiReturn (*aiFileSeek)(C_STRUCT aiFile*, size_t, aiOrigin);
// aiFileIO callbackss // aiFileIO callbackss
typedef aiFile* (*aiFileOpenProc) (C_STRUCT aiFileIO*, const char*, const char*); typedef aiFile* (*aiFileOpenProc) (C_STRUCT aiFileIO*, const char*, const char*);
typedef void (*aiFileCloseProc) (C_STRUCT aiFileIO*, C_STRUCT aiFile*); typedef void (*aiFileCloseProc) (C_STRUCT aiFileIO*, C_STRUCT aiFile*);
// represents user-defined data // Represents user-defined data
typedef char* aiUserData; typedef char* aiUserData;
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
@ -79,13 +76,15 @@ typedef char* aiUserData;
*/ */
struct aiFileIO struct aiFileIO
{ {
//! Function used to open a new file /** Function used to open a new file
*/
aiFileOpenProc OpenProc; aiFileOpenProc OpenProc;
//! Function used to close an existing file /** Function used to close an existing file
*/
aiFileCloseProc CloseProc; aiFileCloseProc CloseProc;
//! User-defined data /** User-defined, opaque data */
aiUserData UserData; aiUserData UserData;
}; };
@ -93,44 +92,47 @@ struct aiFileIO
/** @class aiFile /** @class aiFile
* @brief Represents a read/write file * @brief Represents a read/write file
* *
* Actually, it is a data structure to wrap a set of fXXXX (e.g fopen) * Actually, it's a data structure to wrap a set of fXXXX (e.g fopen)
* replacement functions * replacement functions
* *
* The default implementation of the functions utilizes the fXXX functions from * The default implementation of the functions utilizes the fXXX functions from
* the CRT. However, you can supply a custom implementation to Assimp by * the CRT. However, you can supply a custom implementation to Assimp by
* also supplying a custom aiFileIO. Use this to enable reading from other sources, * delivering a custom aiFileIO. Use this to enable reading from other sources,
* such as ZIPs or memory locations. * such as ZIP archives or memory locations.
*/ */
struct aiFile struct aiFile
{ {
//! Function used to read from a file /** Callback to read from a file */
aiFileReadProc ReadProc; aiFileReadProc ReadProc;
//! Function used to write to a file /** Callback to write to a file */
aiFileWriteProc WriteProc; aiFileWriteProc WriteProc;
//! Function used to retrieve the current /** Callback to retrieve the current position of
//! position of the file cursor (ftell()) * the file cursor (ftell())
*/
aiFileTellProc TellProc; aiFileTellProc TellProc;
//! Function used to retrieve the size of the file, in bytes /** Callback to retrieve the size of the file,
* in bytes
*/
aiFileTellProc FileSizeProc; aiFileTellProc FileSizeProc;
//! Function used to set the current position /** Callback to set the current position
//! of the file cursor (fseek()) * of the file cursor (fseek())
*/
aiFileSeek SeekProc; aiFileSeek SeekProc;
//! Function used to flush the file contents /** Callback to flush the file contents
*/
aiFileFlushProc FlushProc; aiFileFlushProc FlushProc;
//! User-defined data /** User-defined, opaque data
*/
aiUserData UserData; aiUserData UserData;
}; };
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif // AI_FILEIO_H_INC #endif // AI_FILEIO_H_INC

View File

@ -56,47 +56,6 @@ extern "C" {
#define AI_DEFAULT_MATERIAL_NAME "DefaultMaterial" #define AI_DEFAULT_MATERIAL_NAME "DefaultMaterial"
#define AI_DEFAULT_TEXTURED_MATERIAL_NAME "TexturedDefaultMaterial" #define AI_DEFAULT_TEXTURED_MATERIAL_NAME "TexturedDefaultMaterial"
// ---------------------------------------------------------------------------
/** @brief A very primitive RTTI system to store the data type of a
* material property.
*/
enum aiPropertyTypeInfo
{
/** Array of single-precision (32 Bit) floats
*
* It is possible to use aiGetMaterialInteger[Array]() (or the C++-API
* aiMaterial::Get()) to query properties stored in floating-point format.
* The material system performs the type conversion automatically.
*/
aiPTI_Float = 0x1,
/** The material property is an aiString.
*
* Arrays of strings aren't possible, aiGetMaterialString() (or the
* C++-API aiMaterial::Get()) *must* be used to query a string property.
*/
aiPTI_String = 0x3,
/** Array of (32 Bit) integers
*
* It is possible to use aiGetMaterialFloat[Array]() (or the C++-API
* aiMaterial::Get()) to query properties stored in integer format.
* The material system performs the type conversion automatically.
*/
aiPTI_Integer = 0x4,
/** Simple binary buffer, content undefined. Not convertible to anything.
*/
aiPTI_Buffer = 0x5,
/** This value is not used. It is just there to force the
* compiler to map this enum to a 32 Bit integer.
*/
_aiPTI_Force32Bit = 0x9fffffff
};
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief Defines how the Nth texture of a specific type is combined with /** @brief Defines how the Nth texture of a specific type is combined with
* the result of all previous layers. * the result of all previous layers.
@ -420,12 +379,11 @@ enum aiShadingMode
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief Defines some mixed flags for a particular texture. /** @brief Defines some mixed flags for a particular texture.
* *
* Usually you'll tell your cg artists how textures have to look like ... * Usually you'll instruct your cg artists how textures have to look like ...
* and hopefully the follow these rules. If they don't, restrict access * and how they will be processed in your application. However, if you use
* to the coffee machine for them. That should help. * Assimp for completely generic loading purposes you might also need to
* However, if you use Assimp for completely generic loading purposes you * process these flags in order to display as many 'unknown' 3D models as
* might also need to process these flags in order to display as many * possible correctly.
* 'unknown' 3D models as possible correctly.
* *
* This corresponds to the #AI_MATKEY_TEXFLAGS property. * This corresponds to the #AI_MATKEY_TEXFLAGS property.
*/ */
@ -435,7 +393,6 @@ enum aiTextureFlags
*/ */
aiTextureFlags_Invert = 0x1, aiTextureFlags_Invert = 0x1,
/** Explicit request to the application to process the alpha channel /** Explicit request to the application to process the alpha channel
* of the texture. * of the texture.
* *
@ -450,11 +407,9 @@ enum aiTextureFlags
/** Explicit request to the application to ignore the alpha channel /** Explicit request to the application to ignore the alpha channel
* of the texture. * of the texture.
* *
* Mutually exclusive with #aiTextureFlags_IgnoreAlpha. * Mutually exclusive with #aiTextureFlags_UseAlpha.
*/ */
aiTextureFlags_IgnoreAlpha = 0x4, aiTextureFlags_IgnoreAlpha = 0x4,
/** @cond never /** @cond never
* This value is not used. It forces the compiler to use at least * This value is not used. It forces the compiler to use at least
@ -560,6 +515,48 @@ struct aiUVTransform
#include "./Compiler/poppack1.h" #include "./Compiler/poppack1.h"
//! @cond AI_DOX_INCLUDE_INTERNAL
// ---------------------------------------------------------------------------
/** @brief A very primitive RTTI system for the contents of material
* properties.
*/
enum aiPropertyTypeInfo
{
/** Array of single-precision (32 Bit) floats
*
* It is possible to use aiGetMaterialInteger[Array]() (or the C++-API
* aiMaterial::Get()) to query properties stored in floating-point format.
* The material system performs the type conversion automatically.
*/
aiPTI_Float = 0x1,
/** The material property is an aiString.
*
* Arrays of strings aren't possible, aiGetMaterialString() (or the
* C++-API aiMaterial::Get()) *must* be used to query a string property.
*/
aiPTI_String = 0x3,
/** Array of (32 Bit) integers
*
* It is possible to use aiGetMaterialFloat[Array]() (or the C++-API
* aiMaterial::Get()) to query properties stored in integer format.
* The material system performs the type conversion automatically.
*/
aiPTI_Integer = 0x4,
/** Simple binary buffer, content undefined. Not convertible to anything.
*/
aiPTI_Buffer = 0x5,
/** This value is not used. It is just there to force the
* compiler to map this enum to a 32 Bit integer.
*/
_aiPTI_Force32Bit = 0x9fffffff
};
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief Data structure for a single material property /** @brief Data structure for a single material property
* *
@ -576,37 +573,30 @@ struct aiUVTransform
* 2nd: Public, but ignored by the #aiProcess_RemoveRedundantMaterials * 2nd: Public, but ignored by the #aiProcess_RemoveRedundantMaterials
* post-processing step. * post-processing step.
* ~<name> * ~<name>
* A temporary property for internal use. If someone forgets to * A temporary property for internal use.
* cleanup, some of these might still be contained in the output.
* Don't complain! If you understood what the first paragraph tried
* to tell you, you wouldn't even know.
* @endcode * @endcode
* @see aiMaterial * @see aiMaterial
*/ */
struct aiMaterialProperty struct aiMaterialProperty
{ {
/** Specifies the name of the property (key) /** Specifies the name of the property (key)
* * Keys are generally case insensitive.
* Keys are case insensitive.
*/ */
C_STRUCT aiString mKey; C_STRUCT aiString mKey;
/** Textures: Specifies the exact usage semantic. /** Textures: Specifies their exact usage semantic.
* * For non-texture properties, this member is always 0
* For non-texture properties, this member is always 0 * (or, better-said, #aiTextureType_NONE).
* or #aiTextureType_NONE.
*/ */
unsigned int mSemantic; unsigned int mSemantic;
/** Textures: Specifies the index of the texture /** Textures: Specifies the index of the texture.
*
* For non-texture properties, this member is always 0. * For non-texture properties, this member is always 0.
*/ */
unsigned int mIndex; unsigned int mIndex;
/** Size of the buffer mData is pointing to, in bytes. /** Size of the buffer mData is pointing to, in bytes.
* * This value may not be 0.
* This value may not be 0.
*/ */
unsigned int mDataLength; unsigned int mDataLength;
@ -619,8 +609,7 @@ struct aiMaterialProperty
*/ */
C_ENUM aiPropertyTypeInfo mType; C_ENUM aiPropertyTypeInfo mType;
/** Binary buffer to hold the property's value /** Binary buffer to hold the property's value.
*
* The size of the buffer is always mDataLength. * The size of the buffer is always mDataLength.
*/ */
char* mData; char* mData;
@ -638,6 +627,7 @@ struct aiMaterialProperty
#endif #endif
}; };
//! @endcond
#ifdef __cplusplus #ifdef __cplusplus
} // We need to leave the "C" block here to allow template member functions } // We need to leave the "C" block here to allow template member functions
@ -1177,15 +1167,15 @@ extern "C" {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief Retrieve a material property with a specific key from the material /** @brief Retrieve a material property with a specific key from the material
* *
* @param pMat Pointer to the input material. May not be NULL * @param pMat Pointer to the input material. May not be NULL
* @param pKey Key to search for. One of the AI_MATKEY_XXX constants. * @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
* @param type Specifies the type of the texture to be retrieved ( * @param type Specifies the type of the texture to be retrieved (
* e.g. diffuse, specular, height map ...) * e.g. diffuse, specular, height map ...)
* @param index Index of the texture to be retrieved. * @param index Index of the texture to be retrieved.
* @param pPropOut Pointer to receive a pointer to a valid aiMaterialProperty * @param pPropOut Pointer to receive a pointer to a valid aiMaterialProperty
* structure or NULL if the key has not been found. * structure or NULL if the key has not been found.
*/ */
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
ASSIMP_API C_ENUM aiReturn aiGetMaterialProperty( ASSIMP_API C_ENUM aiReturn aiGetMaterialProperty(
const C_STRUCT aiMaterial* pMat, const C_STRUCT aiMaterial* pMat,
@ -1196,30 +1186,30 @@ ASSIMP_API C_ENUM aiReturn aiGetMaterialProperty(
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief Retrieve an array of float values with a specific key /** @brief Retrieve an array of float values with a specific key
* from the material * from the material
* *
* Pass one of the AI_MATKEY_XXX constants for the last three parameters (the * Pass one of the AI_MATKEY_XXX constants for the last three parameters (the
* example reads the #AI_MATKEY_UVTRANSFORM property of the first diffuse texture) * example reads the #AI_MATKEY_UVTRANSFORM property of the first diffuse texture)
* @code * @code
* aiUVTransform trafo; * aiUVTransform trafo;
* unsigned int max = sizeof(aiUVTransform); * unsigned int max = sizeof(aiUVTransform);
* if (AI_SUCCESS != aiGetMaterialFloatArray(mat, AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE,0), * if (AI_SUCCESS != aiGetMaterialFloatArray(mat, AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE,0),
* (float*)&trafo, &max) || sizeof(aiUVTransform) != max) * (float*)&trafo, &max) || sizeof(aiUVTransform) != max)
* { * {
* // error handling * // error handling
* } * }
* @endcode * @endcode
* *
* @param pMat Pointer to the input material. May not be NULL * @param pMat Pointer to the input material. May not be NULL
* @param pKey Key to search for. One of the AI_MATKEY_XXX constants. * @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
* @param pOut Pointer to a buffer to receive the result. * @param pOut Pointer to a buffer to receive the result.
* @param pMax Specifies the size of the given buffer, in float's. * @param pMax Specifies the size of the given buffer, in float's.
* Receives the number of values (not bytes!) read. * Receives the number of values (not bytes!) read.
* @param type (see the code sample above) * @param type (see the code sample above)
* @param index (see the code sample above) * @param index (see the code sample above)
* @return Specifies whether the key has been found. If not, the output * @return Specifies whether the key has been found. If not, the output
* arrays remains unmodified and pMax is set to 0. * arrays remains unmodified and pMax is set to 0.
*/ */
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
ASSIMP_API C_ENUM aiReturn aiGetMaterialFloatArray( ASSIMP_API C_ENUM aiReturn aiGetMaterialFloatArray(
const C_STRUCT aiMaterial* pMat, const C_STRUCT aiMaterial* pMat,
@ -1272,11 +1262,10 @@ inline aiReturn aiGetMaterialFloat(const aiMaterial* pMat,
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief Retrieve an array of integer values with a specific key /** @brief Retrieve an array of integer values with a specific key
* from a material * from a material
* *
* See the sample for aiGetMaterialFloatArray for more information. * See the sample for aiGetMaterialFloatArray for more information.
*/ */
// ---------------------------------------------------------------------------
ASSIMP_API C_ENUM aiReturn aiGetMaterialIntegerArray(const C_STRUCT aiMaterial* pMat, ASSIMP_API C_ENUM aiReturn aiGetMaterialIntegerArray(const C_STRUCT aiMaterial* pMat,
const char* pKey, const char* pKey,
unsigned int type, unsigned int type,
@ -1289,9 +1278,9 @@ ASSIMP_API C_ENUM aiReturn aiGetMaterialIntegerArray(const C_STRUCT aiMaterial*
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief Retrieve an integer property with a specific key from a material /** @brief Retrieve an integer property with a specific key from a material
* *
* See the sample for aiGetMaterialFloat for more information. * See the sample for aiGetMaterialFloat for more information.
*/ */
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
inline aiReturn aiGetMaterialInteger(const C_STRUCT aiMaterial* pMat, inline aiReturn aiGetMaterialInteger(const C_STRUCT aiMaterial* pMat,
const char* pKey, const char* pKey,

View File

@ -40,12 +40,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file aiTypes.h /** @file aiTypes.h
*/ * Basic data types and primitives, such as vectors or colors.
*/
#ifndef AI_TYPES_H_INC #ifndef AI_TYPES_H_INC
#define AI_TYPES_H_INC #define AI_TYPES_H_INC
// Some CRT headers // Some runtime headers
#include <sys/types.h> #include <sys/types.h>
#include <memory.h> #include <memory.h>
#include <math.h> #include <math.h>
@ -67,17 +67,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp { namespace Assimp {
namespace Intern { namespace Intern {
// --------------------------------------------------------------------
/** @brief Internal helper class to utilize our internal new/delete /** @brief Internal helper class to utilize our internal new/delete
* routines for allocating object of this and derived classes. * routines for allocating object of this and derived classes.
* *
* By doing this you can safely share class objects between Assimp * By doing this you can safely share class objects between Assimp
* and the application - it works even over DLL boundaries. A good * and the application - it works even over DLL boundaries. A good
* example is the IOSystem where the application allocates its custom * example is the #IOSystem where the application allocates its custom
* IOSystem, then calls Importer::SetIOSystem(). When the Importer * #IOSystem, then calls #Importer::SetIOSystem(). When the Importer
* destructs, Assimp calls operator delete on the stored IOSystem. * destructs, Assimp calls operator delete on the stored #IOSystem.
* If it lies on a different heap than Assimp is working with, * If it lies on a different heap than Assimp is working with,
* the application is determined to crash. * the application is determined to crash.
*/ */
// --------------------------------------------------------------------
struct ASSIMP_API AllocateFromAssimpHeap { struct ASSIMP_API AllocateFromAssimpHeap {
// new/delete overload // new/delete overload
@ -122,7 +124,6 @@ struct aiPlane
float a,b,c,d; float a,b,c,d;
} PACK_STRUCT; // !struct aiPlane } PACK_STRUCT; // !struct aiPlane
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
/** Represents a ray /** Represents a ray
*/ */
@ -141,8 +142,6 @@ struct aiRay
C_STRUCT aiVector3D pos, dir; C_STRUCT aiVector3D pos, dir;
} PACK_STRUCT; // !struct aiRay } PACK_STRUCT; // !struct aiRay
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
/** Represents a color in Red-Green-Blue space. /** Represents a color in Red-Green-Blue space.
*/ */
@ -153,43 +152,48 @@ struct aiColor3D
aiColor3D (float _r, float _g, float _b) : r(_r), g(_g), b(_b) {} aiColor3D (float _r, float _g, float _b) : r(_r), g(_g), b(_b) {}
aiColor3D (const aiColor3D& o) : r(o.r), g(o.g), b(o.b) {} aiColor3D (const aiColor3D& o) : r(o.r), g(o.g), b(o.b) {}
// Component-wise comparison /** Component-wise comparison */
// TODO: add epsilon? // TODO: add epsilon?
bool operator == (const aiColor3D& other) const bool operator == (const aiColor3D& other) const
{return r == other.r && g == other.g && b == other.b;} {return r == other.r && g == other.g && b == other.b;}
// Component-wise inverse comparison /** Component-wise inverse comparison */
// TODO: add epsilon? // TODO: add epsilon?
bool operator != (const aiColor3D& other) const bool operator != (const aiColor3D& other) const
{return r != other.r || g != other.g || b != other.b;} {return r != other.r || g != other.g || b != other.b;}
// Component-wise addition /** Component-wise addition */
aiColor3D operator+(const aiColor3D& c) const { aiColor3D operator+(const aiColor3D& c) const {
return aiColor3D(r+c.r,g+c.g,b+c.b); return aiColor3D(r+c.r,g+c.g,b+c.b);
} }
// Component-wise subtraction /** Component-wise subtraction */
aiColor3D operator-(const aiColor3D& c) const { aiColor3D operator-(const aiColor3D& c) const {
return aiColor3D(r+c.r,g+c.g,b+c.b); return aiColor3D(r+c.r,g+c.g,b+c.b);
} }
// Component-wise multiplication /** Component-wise multiplication */
aiColor3D operator*(const aiColor3D& c) const { aiColor3D operator*(const aiColor3D& c) const {
return aiColor3D(r*c.r,g*c.g,b*c.b); return aiColor3D(r*c.r,g*c.g,b*c.b);
} }
// Multiply with a scalar /** Multiply with a scalar */
aiColor3D operator*(float f) const { aiColor3D operator*(float f) const {
return aiColor3D(r*f,g*f,b*f); return aiColor3D(r*f,g*f,b*f);
} }
// Access a specific color component /** Access a specific color component */
float operator[](unsigned int i) const {return *(&r + i);} float operator[](unsigned int i) const {
float& operator[](unsigned int i) {return *(&r + i);} return *(&r + i);
}
// Check whether a color is black /** Access a specific color component */
bool IsBlack() const float& operator[](unsigned int i) {
{ return *(&r + i);
}
/** Check whether a color is black */
bool IsBlack() const {
static const float epsilon = 10e-3f; static const float epsilon = 10e-3f;
return fabs( r ) < epsilon && fabs( g ) < epsilon && fabs( b ) < epsilon; return fabs( r ) < epsilon && fabs( g ) < epsilon && fabs( b ) < epsilon;
} }
@ -214,24 +218,28 @@ struct aiColor4D
aiColor4D (const aiColor4D& o) aiColor4D (const aiColor4D& o)
: r(o.r), g(o.g), b(o.b), a(o.a) {} : r(o.r), g(o.g), b(o.b), a(o.a) {}
// Component-wise comparison /** Component-wise comparison */
// TODO: add epsilon? // TODO: add epsilon?
bool operator == (const aiColor4D& other) const { bool operator == (const aiColor4D& other) const {
return r == other.r && g == other.g && b == other.b && a == other.a; return r == other.r && g == other.g && b == other.b && a == other.a;
} }
// Component-wise inverse comparison /** Component-wise inverse comparison */
// TODO: add epsilon? // TODO: add epsilon?
bool operator != (const aiColor4D& other) const { bool operator != (const aiColor4D& other) const {
return r != other.r || g != other.g || b != other.b || a != other.a; return r != other.r || g != other.g || b != other.b || a != other.a;
} }
// Access a specific color component /** Access a specific color component */
inline float operator[](unsigned int i) const {return *(&r + i);} inline float operator[](unsigned int i) const {
inline float& operator[](unsigned int i) {return *(&r + i);} return *(&r + i);
}
/** Access a specific color component */
inline float& operator[](unsigned int i) {
return *(&r + i);
}
// Check whether a color is black /** Check whether a color is black */
// TODO: add epsilon?
inline bool IsBlack() const inline bool IsBlack() const
{ {
// The alpha component doesn't care here. black is black. // The alpha component doesn't care here. black is black.
@ -244,11 +252,8 @@ struct aiColor4D
//! Red, green, blue and alpha color values //! Red, green, blue and alpha color values
float r, g, b, a; float r, g, b, a;
} PACK_STRUCT; // !struct aiColor4D } PACK_STRUCT; // !struct aiColor4D
#include "./Compiler/poppack1.h" #include "./Compiler/poppack1.h"
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
/** Represents a string, zero byte terminated. /** Represents a string, zero byte terminated.
* *
@ -258,8 +263,7 @@ struct aiColor4D
struct aiString struct aiString
{ {
#ifdef __cplusplus #ifdef __cplusplus
/** Default constructor, the string is set to have zero length */
//! Default constructor, the string is set to have zero length
aiString() : aiString() :
length(0) length(0)
{ {
@ -271,7 +275,7 @@ struct aiString
#endif #endif
} }
//! Copy constructor /** Copy constructor */
aiString(const aiString& rOther) : aiString(const aiString& rOther) :
length(rOther.length) length(rOther.length)
{ {
@ -279,7 +283,7 @@ struct aiString
data[length] = '\0'; data[length] = '\0';
} }
//! Constructor from std::string /** Constructor from std::string */
aiString(const std::string& pString) : aiString(const std::string& pString) :
length(pString.length()) length(pString.length())
{ {
@ -287,69 +291,65 @@ struct aiString
data[length] = '\0'; data[length] = '\0';
} }
//! Copy a std::string to the aiString /** Copy a std::string to the aiString */
void Set( const std::string& pString) void Set( const std::string& pString) {
{ if( pString.length() > MAXLEN - 1) {
if( pString.length() > MAXLEN - 1)
return; return;
}
length = pString.length(); length = pString.length();
::memcpy( data, pString.c_str(), length); ::memcpy( data, pString.c_str(), length);
data[length] = 0; data[length] = 0;
} }
//! Copy a const char* to the aiString /** Copy a const char* to the aiString */
void Set( const char* sz) void Set( const char* sz) {
{
const size_t len = ::strlen(sz); const size_t len = ::strlen(sz);
if( len > MAXLEN - 1) if( len > MAXLEN - 1) {
return; return;
}
length = len; length = len;
::memcpy( data, sz, len); ::memcpy( data, sz, len);
data[len] = 0; data[len] = 0;
} }
// Assign a const char* to the string /** Assign a const char* to the string */
aiString& operator = (const char* sz) aiString& operator = (const char* sz) {
{
Set(sz); Set(sz);
return *this; return *this;
} }
// Assign a cstd::string to the string /** Assign a cstd::string to the string */
aiString& operator = ( const std::string& pString) aiString& operator = ( const std::string& pString) {
{
Set(pString); Set(pString);
return *this; return *this;
} }
//! Comparison operator /** Comparison operator */
bool operator==(const aiString& other) const bool operator==(const aiString& other) const {
{
return (length == other.length && 0 == strcmp(this->data,other.data)); return (length == other.length && 0 == strcmp(this->data,other.data));
} }
//! Inverse comparison operator /** Inverse comparison operator */
bool operator!=(const aiString& other) const bool operator!=(const aiString& other) const {
{
return (length != other.length || 0 != ::strcmp(this->data,other.data)); return (length != other.length || 0 != ::strcmp(this->data,other.data));
} }
//! Append a string to the string /** Append a string to the string */
void Append (const char* app) void Append (const char* app) {
{
const size_t len = ::strlen(app); const size_t len = ::strlen(app);
if (!len)return; if (!len) {
if (length + len >= MAXLEN)
return; return;
}
if (length + len >= MAXLEN) {
return;
}
::memcpy(&data[length],app,len+1); ::memcpy(&data[length],app,len+1);
length += len; length += len;
} }
//! Clear the string - reset its length to zero /** Clear the string - reset its length to zero */
void Clear () void Clear () {
{
length = 0; length = 0;
data[0] = '\0'; data[0] = '\0';
@ -361,74 +361,107 @@ struct aiString
#endif // !__cplusplus #endif // !__cplusplus
//! Length of the string excluding the terminal 0 /** Length of the string excluding the terminal 0 */
size_t length; size_t length;
//! String buffer. Size limit is MAXLEN /** String buffer. Size limit is MAXLEN */
char data[MAXLEN]; char data[MAXLEN];
} ; // !struct aiString } ; // !struct aiString
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
/** Standard return type for all library functions. /** Standard return type for some library functions.
* * Rarely used, and if, mostly in the C API.
* To check whether or not a function failed check against */
* AI_SUCCESS. The error codes are mainly used by the C-API.
*/
enum aiReturn enum aiReturn
{ {
//! Indicates that a function was successful /** Indicates that a function was successful */
AI_SUCCESS = 0x0, aiReturn_SUCCESS = 0x0,
//! Indicates that a function failed /** Indicates that a function failed */
AI_FAILURE = -0x1, aiReturn_FAILURE = -0x1,
//! Indicates that a file was invalid /** Indicates that not enough memory was available
AI_INVALIDFILE = -0x2, * to perform the requested operation
*/
aiReturn_OUTOFMEMORY = -0x3,
//! Indicates that not enough memory was available /** @cond never
//! to perform the requested operation * Force 32-bit size enum
AI_OUTOFMEMORY = -0x3, */
//! Indicates that an illegal argument has been
//! passed to a function. This is rarely used,
//! most functions assert in this case.
AI_INVALIDARG = -0x4,
//! Force 32-bit size enum
_AI_ENFORCE_ENUM_SIZE = 0x7fffffff _AI_ENFORCE_ENUM_SIZE = 0x7fffffff
}; // !enum aiReturn }; // !enum aiReturn
// just for backwards compatibility, don't use these constants anymore
#define AI_SUCCESS aiReturn_SUCCESS
#define AI_FAILURE aiReturn_FAILURE
#define AI_OUTOFMEMORY aiReturn_OUTOFMEMORY
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
/** Seek origins (for the virtual file system API) /** Seek origins (for the virtual file system API).
*/ * Much cooler than using SEEK_SET, SEEK_CUR or SEEK_END.
*/
enum aiOrigin enum aiOrigin
{ {
//! Beginning of the file /** Beginning of the file */
aiOrigin_SET = 0x0, aiOrigin_SET = 0x0,
//! Current position of the file pointer /** Current position of the file pointer */
aiOrigin_CUR = 0x1, aiOrigin_CUR = 0x1,
//! End of the file, offsets must be negative /** End of the file, offsets must be negative */
aiOrigin_END = 0x2, aiOrigin_END = 0x2,
//! Force 32-bit size enum /** @cond never
* Force 32-bit size enum
*/
_AI_ORIGIN_ENFORCE_ENUM_SIZE = 0x7fffffff _AI_ORIGIN_ENFORCE_ENUM_SIZE = 0x7fffffff
}; // !enum aiOrigin }; // !enum aiOrigin
// ----------------------------------------------------------------------------------
/** @brief Enumerates predefined log streaming destinations.
* Logging to these streams can be enabled with a single call to
* #LogStream::createDefaultStream or #aiAttachPredefinedLogStream(),
* respectively.
*/
enum aiDefaultLogStream
{
/** Stream the log to a file */
aiDefaultLogStream_FILE = 0x1,
/** Stream the log to std::cout */
aiDefaultLogStream_STDOUT = 0x2,
/** Stream the log to std::cerr */
aiDefaultLogStream_STDERR = 0x4,
/** MSVC only: Stream the log the the debugger
* (this relies on OutputDebugString from the Win32 SDK)
*/
aiDefaultLogStream_DEBUGGER = 0x8,
/** @cond never
* Force 32-bit size enum
*/
_AI_DLS_ENFORCE_ENUM_SIZE = 0x7fffffff
}; // !enum aiDefaultLogStream
// just for backwards compatibility, don't use these constants anymore
#define DLS_FILE aiDefaultLogStream_FILE
#define DLS_STDOUT aiDefaultLogStream_STDOUT
#define DLS_STDERR aiDefaultLogStream_STDERR
#define DLS_DEBUGGER aiDefaultLogStream_DEBUGGER
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
/** Stores the memory requirements for different parts (e.g. meshes, materials, /** Stores the memory requirements for different components (e.g. meshes, materials,
* animations) of an import. * animations) of an import. All sizes are in bytes.
* @see Importer::GetMemoryRequirements() * @see Importer::GetMemoryRequirements()
*/ */
struct aiMemoryInfo struct aiMemoryInfo
{ {
#ifdef __cplusplus #ifdef __cplusplus
//! Default constructor /** Default constructor */
aiMemoryInfo() aiMemoryInfo()
: textures (0) : textures (0)
, materials (0) , materials (0)
@ -442,32 +475,31 @@ struct aiMemoryInfo
#endif #endif
//! Storage allocated for texture data, in bytes /** Storage allocated for texture data */
unsigned int textures; unsigned int textures;
//! Storage allocated for material data, in bytes /** Storage allocated for material data */
unsigned int materials; unsigned int materials;
//! Storage allocated for mesh data, in bytes /** Storage allocated for mesh data */
unsigned int meshes; unsigned int meshes;
//! Storage allocated for node data, in bytes /** Storage allocated for node data */
unsigned int nodes; unsigned int nodes;
//! Storage allocated for animation data, in bytes /** Storage allocated for animation data */
unsigned int animations; unsigned int animations;
//! Storage allocated for camera data, in bytes /** Storage allocated for camera data */
unsigned int cameras; unsigned int cameras;
//! Storage allocated for light data, in bytes /** Storage allocated for light data */
unsigned int lights; unsigned int lights;
//! Storage allocated for the full import, in bytes /** Total storage allocated for the full import. */
unsigned int total; unsigned int total;
}; // !struct aiMemoryInfo }; // !struct aiMemoryInfo
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif //! __cplusplus #endif //! __cplusplus
@ -476,8 +508,4 @@ struct aiMemoryInfo
#include "aiVector3D.inl" #include "aiVector3D.inl"
#include "aiMatrix3x3.inl" #include "aiMatrix3x3.inl"
#include "aiMatrix4x4.inl" #include "aiMatrix4x4.inl"
#endif //!! include guard #endif //!! include guard

View File

@ -39,154 +39,289 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file assimp.h /** @file assimp.h
@brief Defines the C-API to the Asset Import Library. */ * @brief Defines the C-API to the Open Asset Import Library.
*/
#ifndef AI_ASSIMP_H_INC #ifndef AI_ASSIMP_H_INC
#define AI_ASSIMP_H_INC #define AI_ASSIMP_H_INC
#include "aiTypes.h" #include "aiTypes.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
struct aiScene; struct aiScene; // aiScene.h
struct aiFileIO; struct aiFileIO; // aiFileIO.h
struct aiString; typedef void (*aiLogStreamCallback)(const char* /* message */, char* /* user */);
// --------------------------------------------------------------------------------
/** Represents a log stream. A log stream receives all log messages and streams
* them somewhere.
* @see aiGetPredefinedLogStream
* @see aiAttachLogStream
* @see aiDetachLogStream
*/
// --------------------------------------------------------------------------------
struct aiLogStream
{
/** callback to be called */
aiLogStreamCallback callback;
// --------------------------------------------------------------------------- /** user data to be passed to the callback */
char* user;
};
/** Our own C boolean type */
typedef int aiBool;
#define AI_FALSE 0
#define AI_TRUE 1
// --------------------------------------------------------------------------------
/** Reads the given file and returns its content. /** Reads the given file and returns its content.
* *
* If the call succeeds, the imported data is returned in an aiScene structure. * If the call succeeds, the imported data is returned in an aiScene structure.
* The data is intended to be read-only, it stays property of the ASSIMP * The data is intended to be read-only, it stays property of the ASSIMP
* library and will be stable until aiReleaseImport() is called. After you're * library and will be stable until aiReleaseImport() is called. After you're
* done with it, call aiReleaseImport() to free the resources associated with * done with it, call aiReleaseImport() to free the resources associated with
* this file. If the import fails, NULL is returned instead. Call * this file. If the import fails, NULL is returned instead. Call
* aiGetErrorString() to retrieve a human-readable error text. * aiGetErrorString() to retrieve a human-readable error text.
* @param pFile Path and filename of the file to be imported, * @param pFile Path and filename of the file to be imported,
* expected to be a null-terminated c-string. NULL is not a valid value. * expected to be a null-terminated c-string. NULL is not a valid value.
* @param pFlags Optional post processing steps to be executed after * @param pFlags Optional post processing steps to be executed after
* a successful import. Provide a bitwise combination of the * a successful import. Provide a bitwise combination of the
* #aiPostProcessSteps flags. * #aiPostProcessSteps flags.
* @return Pointer to the imported data or NULL if the import failed. * @return Pointer to the imported data or NULL if the import failed.
*/ */
// --------------------------------------------------------------------------- ASSIMP_API const C_STRUCT aiScene* aiImportFile(
ASSIMP_API const C_STRUCT aiScene* aiImportFile( const char* pFile, const char* pFile,
unsigned int pFlags); unsigned int pFlags);
// --------------------------------------------------------------------------------
// ---------------------------------------------------------------------------
/** Reads the given file using user-defined I/O functions and returns /** Reads the given file using user-defined I/O functions and returns
* its content. * its content.
* *
* If the call succeeds, the imported data is returned in an aiScene structure. * If the call succeeds, the imported data is returned in an aiScene structure.
* The data is intended to be read-only, it stays property of the ASSIMP * The data is intended to be read-only, it stays property of the ASSIMP
* library and will be stable until aiReleaseImport() is called. After you're * library and will be stable until aiReleaseImport() is called. After you're
* done with it, call aiReleaseImport() to free the resources associated with * done with it, call aiReleaseImport() to free the resources associated with
* this file. If the import fails, NULL is returned instead. Call * this file. If the import fails, NULL is returned instead. Call
* aiGetErrorString() to retrieve a human-readable error text. * aiGetErrorString() to retrieve a human-readable error text.
* @param pFile Path and filename of the file to be imported, * @param pFile Path and filename of the file to be imported,
* expected to be a null-terminated c-string. NULL is not a valid value. * expected to be a null-terminated c-string. NULL is not a valid value.
* @param pFlags Optional post processing steps to be executed after * @param pFlags Optional post processing steps to be executed after
* a successful import. Provide a bitwise combination of the * a successful import. Provide a bitwise combination of the
* #aiPostProcessSteps flags. * #aiPostProcessSteps flags.
* @param pFS aiFileIO structure. Will be used to open the model file itself * @param pFS aiFileIO structure. Will be used to open the model file itself
* and any other files the loader needs to open. * and any other files the loader needs to open.
* @return Pointer to the imported data or NULL if the import failed. * @return Pointer to the imported data or NULL if the import failed.
*/ * @note Include <aiFileIO.h> for the definition of #aiFioeIO.
// --------------------------------------------------------------------------- */
ASSIMP_API const C_STRUCT aiScene* aiImportFileEx( ASSIMP_API const C_STRUCT aiScene* aiImportFileEx(
const char* pFile, const char* pFile,
unsigned int pFlags, unsigned int pFlags,
C_STRUCT aiFileIO* pFS); C_STRUCT aiFileIO* pFS);
// --------------------------------------------------------------------------------
/** Apply post-processing to an already-imported scene.
*
* This is strictly equivalent to calling #aiImportFile()/#aiImportFileEx with the
* same flags. However, you can use this separate function to inspect the imported
* scene first to fine-tune your post-processing setup.
* @param pScene Scene to work on.
* @param pFlags Provide a bitwise combination of the #aiPostProcessSteps flags.
* @return A pointer to the post-processed data. Post processing is done in-place,
* meaning this is still the same #aiScene which you passed for pScene. However,
* _if_ post-processing failed, the scene could now be NULL. That's quite a rare
* case, post processing steps are not really designed to 'fail'. To be exact,
* the #aiProcess_ValidateDS flag is currently the only post processing step
* which can actually cause the scene to be reset to NULL.
*/
ASSIMP_API const C_STRUCT aiScene* aiApplyPostProcessing(
const C_STRUCT aiScene* pScene,
unsigned int pFlags);
// --------------------------------------------------------------------------- // --------------------------------------------------------------------------------
/** Get one of the predefine log streams. This is the quick'n'easy solution to
* access Assimp's log system. Attaching a log stream can slightly reduce Assimp's
* overall import performance.
*
* Usage is rather simple:
* @code
* aiLogStreamCallback c = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"log.txt",NULL);
* if (NULL != c) {
* aiAttachLogStream(c);
* }
* @endcode
*
* @param One of the #aiDefaultLogStream enumerated values.
* @param file Solely for the #aiDefaultLogStream_FILE flag: specifies the file to write to.
* Pass NULL for all other flags.
* @return The log stream. callback is set to NULL if something went wrong.
*/
ASSIMP_API C_STRUCT aiLogStream aiGetPredefinedLogStream(
C_ENUM aiDefaultLogStream pStreams,
const char* file);
// --------------------------------------------------------------------------------
/** Attach a custom log stream to the libraries' logging system.
*
* Attaching a log stream can slightly reduce Assimp's overall import
* performance. Multiple log-streams can be attached.
* @param stream Describes the new log stream.
* @note To ensure proepr destruction of the logging system, you need to manually
* call aiDetachLogStream() on every single log stream you attach.
* Alternatively (for the lazy folks) #aiDetachAllLogStreams is provided.
*/
ASSIMP_API void aiAttachLogStream(
const C_STRUCT aiLogStream* stream);
// --------------------------------------------------------------------------------
/** Enable verbose logging. Verbose logging includes debug-related stuff and
* detailed import statistics. This can have severe impact on import performance
* and memory consumption. However, it might be useful to find out why a file
* didn't read correctly.
* @param d AI_TRUE or AI_FALSE, your decision.
*/
ASSIMP_API void aiEnableVerboseLogging(aiBool d);
// --------------------------------------------------------------------------------
/** Detach a custom log stream from the libraries' logging system.
*
* This is the counterpart of #aiAttachPredefinedLogStream. If you attached a stream,
* don't forget to detach it again.
* @param stream The log stream to be detached.
* @return AI_SUCCESS if the log stream has been detached successfully.
* @see aiDetachAllLogStreams
*/
ASSIMP_API C_ENUM aiReturn aiDetachLogStream(
const C_STRUCT aiLogStream* stream);
// --------------------------------------------------------------------------------
/** Detach all active log streams from the libraries' logging system.
* This ensures that the logging system is terminated properly and all
* resources allocated by it are actually freed. If you attached a stream,
* don't forget to detach it again.
* @see aiAttachLogStream
* @see aiDetachLogStream
*/
ASSIMP_API void aiDetachAllLogStreams(void);
// --------------------------------------------------------------------------------
/** Releases all resources associated with the given import process. /** Releases all resources associated with the given import process.
* *
* Call this function after you're done with the imported data. * Call this function after you're done with the imported data.
* @param pScene The imported data to release. NULL is a valid value. * @param pScene The imported data to release. NULL is a valid value.
*/ */
// --------------------------------------------------------------------------- ASSIMP_API void aiReleaseImport(
ASSIMP_API void aiReleaseImport( const C_STRUCT aiScene* pScene); const C_STRUCT aiScene* pScene);
// --------------------------------------------------------------------------------
// ---------------------------------------------------------------------------
/** Returns the error text of the last failed import process. /** Returns the error text of the last failed import process.
* *
* @return A textual description of the error that occurred at the last * @return A textual description of the error that occurred at the last
* import process. NULL if there was no error. * import process. NULL if there was no error. There can't be an error if you
*/ * got a non-NULL #aiScene from #aiImportFile/#aiImportFileEx/#aiApplyPostProcessing.
// --------------------------------------------------------------------------- */
ASSIMP_API const char* aiGetErrorString(); ASSIMP_API const char* aiGetErrorString();
// --------------------------------------------------------------------------------
// ---------------------------------------------------------------------------
/** Returns whether a given file extension is supported by ASSIMP /** Returns whether a given file extension is supported by ASSIMP
* *
* @param szExtension Extension for which the function queries support. * @param szExtension Extension for which the function queries support for.
* Must include a leading dot '.'. Example: ".3ds", ".md3" * Must include a leading dot '.'. Example: ".3ds", ".md3"
* @return 1 if the extension is supported, 0 otherwise * @return AI_TRUE if the file extension is supported.
*/ */
// --------------------------------------------------------------------------- ASSIMP_API aiBool aiIsExtensionSupported(
ASSIMP_API int aiIsExtensionSupported(const char* szExtension); const char* szExtension);
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------- /** Get a list of all file extensions supported by ASSIMP.
/** Get a full list of all file extensions generally supported by ASSIMP.
* *
* If a file extension is contained in the list this does, of course, not * If a file extension is contained in the list this does, of course, not
* mean that ASSIMP is able to load all files with this extension. * mean that ASSIMP is able to load all files with this extension.
* @param szOut String to receive the extension list. * @param szOut String to receive the extension list.
* Format of the list: "*.3ds;*.obj;*.dae". NULL is not a valid parameter. * Format of the list: "*.3ds;*.obj;*.dae". NULL is not a valid parameter.
*/ */
// --------------------------------------------------------------------------- ASSIMP_API void aiGetExtensionList(
ASSIMP_API void aiGetExtensionList(C_STRUCT aiString* szOut); C_STRUCT aiString* szOut);
// --------------------------------------------------------------------------------
// ---------------------------------------------------------------------------
/** Get the storage required by an imported asset /** Get the storage required by an imported asset
* @param pIn Input asset. * @param pIn Input asset.
* @param in Data structure to be filled. * @param in Data structure to be filled.
*/ */
// --------------------------------------------------------------------------- ASSIMP_API void aiGetMemoryRequirements(
ASSIMP_API void aiGetMemoryRequirements(const C_STRUCT aiScene* pIn, const C_STRUCT aiScene* pIn,
C_STRUCT aiMemoryInfo* in); C_STRUCT aiMemoryInfo* in);
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------- /** Set an integer property.
/** Set an integer property. This is the C-version of
* #Assimp::Importer::SetPropertyInteger(). In the C-API properties are shared by
* all imports. It is not possible to specify them per asset.
* *
* @param szName Name of the configuration property to be set. All constants * This is the C-version of #Assimp::Importer::SetPropertyInteger(). In the C
* are defined in the aiConfig.h header file. * interface, properties are always shared by all imports. It is not possible to
* specify them per import.
*
* @param szName Name of the configuration property to be set. All supported
* public properties are defined in the aiConfig.h header file (#AI_CONFIG_XXX).
* @param value New value for the property * @param value New value for the property
*/ */
// --------------------------------------------------------------------------- ASSIMP_API void aiSetImportPropertyInteger(
ASSIMP_API void aiSetImportPropertyInteger(const char* szName, int value); const char* szName,
int value);
// --------------------------------------------------------------------------- // --------------------------------------------------------------------------------
/** @see aiSetImportPropertyInteger() /** Set a floating-point property.
*
* This is the C-version of #Assimp::Importer::SetPropertyFloat(). In the C
* interface, properties are always shared by all imports. It is not possible to
* specify them per import.
*
* @param szName Name of the configuration property to be set. All supported
* public properties are defined in the aiConfig.h header file (#AI_CONFIG_XXX).
* @param value New value for the property
*/ */
ASSIMP_API void aiSetImportPropertyFloat(const char* szName, float value); ASSIMP_API void aiSetImportPropertyFloat(
const char* szName,
float value);
// --------------------------------------------------------------------------- // --------------------------------------------------------------------------------
/** @see aiSetImportPropertyInteger() /** Set a string property.
*
* This is the C-version of #Assimp::Importer::SetPropertyString(). In the C
* interface, properties are always shared by all imports. It is not possible to
* specify them per import.
*
* @param szName Name of the configuration property to be set. All supported
* public properties are defined in the aiConfig.h header file (#AI_CONFIG_XXX).
* @param value New value for the property
*/ */
ASSIMP_API void aiSetImportPropertyString(const char* szName, ASSIMP_API void aiSetImportPropertyString(
const char* szName,
const C_STRUCT aiString* st); const C_STRUCT aiString* st);
// --------------------------------------------------------------------------- // --------------------------------------------------------------------------------
/** @see aiQuaternion(const aiMatrix3x3& pRotMatrix) /** Construct a quaternion from a 3x3 rotation matrix.
* @param quat Receives the output quaternion.
* @param mat Matrix to 'quaternionize'.
* @see aiQuaternion(const aiMatrix3x3& pRotMatrix)
*/ */
ASSIMP_API void aiCreateQuaternionFromMatrix(C_STRUCT aiQuaternion* quat,const C_STRUCT aiMatrix3x3* mat); ASSIMP_API void aiCreateQuaternionFromMatrix(
C_STRUCT aiQuaternion* quat,
const C_STRUCT aiMatrix3x3* mat);
// --------------------------------------------------------------------------- // --------------------------------------------------------------------------------
/** @see aiMatrix4x4::Decompose (aiVector3D&, aiQuaternion&, aiVector3D&) const; /** Decompose a transformation matrix into its rotational, translational and
* scaling components.
*
* @param mat Matrix to decompose
* @param scaling Receives the scaling component
* @param rotation Receives the rotational component
* @param position Receives the translational component.
* @see aiMatrix4x4::Decompose (aiVector3D&, aiQuaternion&, aiVector3D&) const;
*/ */
ASSIMP_API void aiDecomposeMatrix(const C_STRUCT aiMatrix4x4* mat, ASSIMP_API void aiDecomposeMatrix(
const C_STRUCT aiMatrix4x4* mat,
C_STRUCT aiVector3D* scaling, C_STRUCT aiVector3D* scaling,
C_STRUCT aiQuaternion* rotation, C_STRUCT aiQuaternion* rotation,
C_STRUCT aiVector3D* position); C_STRUCT aiVector3D* position);

View File

@ -336,7 +336,7 @@ public:
* #aiPostProcessSteps flags. * #aiPostProcessSteps flags.
* @return A pointer to the post-processed data. This is still the * @return A pointer to the post-processed data. This is still the
* same as the pointer returned by #ReadFile(). However, if * same as the pointer returned by #ReadFile(). However, if
* post-processing fails severly the scene could now be NULL. * post-processing fails, the scene could now be NULL.
* That's quite a rare case, post processing steps are not really * That's quite a rare case, post processing steps are not really
* designed to 'fail'. To be exact, the #aiProcess_ValidateDS * designed to 'fail'. To be exact, the #aiProcess_ValidateDS
* flag is currently the only post processing step which can actually * flag is currently the only post processing step which can actually

View File

@ -1 +1 @@
#define SVNRevision 412 #define SVNRevision 423

View File

@ -13,8 +13,6 @@ rem FIRSTUTNA - if the test wasn't found, receives the test name
rem FIRSTUTFAILUR - if the test failed, receives the test name rem FIRSTUTFAILUR - if the test failed, receives the test name
rem rem
rem ------------------------------------------------------------------------------ rem ------------------------------------------------------------------------------
rem Check whether the
IF NOT EXIST %BINDIR%\%1\unit.exe ( IF NOT EXIST %BINDIR%\%1\unit.exe (
echo NOT AVAILABLE. Please rebuild this configuration echo NOT AVAILABLE. Please rebuild this configuration

View File

@ -85,7 +85,7 @@ IF %FIRSTUTNA% == nil (
) )
IF %FIRSTUTFAILURE% == nil ( IF %FIRSTUTFAILURE% == nil (
echo All tests have been successful. Everything is fine. echo All tests have been successful.
) ELSE ( ) ELSE (
echo One or more tests failed. echo One or more tests failed.
) )

View File

@ -18,9 +18,19 @@ int main (int argc, char* argv[])
time_t t;time(&t); time_t t;time(&t);
srand((unsigned int)t); srand((unsigned int)t);
// create a logger // ............................................................................
Assimp::DefaultLogger::create("AssimpLog.txt",Assimp::Logger::VERBOSE,
Assimp::DLS_DEBUGGER | Assimp::DLS_FILE); // create a logger from both CPP
Assimp::DefaultLogger::create("AssimpLog_Cpp.txt",Assimp::Logger::VERBOSE,
aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE);
// .. and C. They should smoothly work together
aiEnableVerboseLogging(AI_TRUE);
aiAttachLogStream(&aiGetPredefinedLogStream(
aiDefaultLogStream_FILE,
"AssimpLog_C.txt"));
// ............................................................................
// Informiert Test-Listener ueber Testresultate // Informiert Test-Listener ueber Testresultate
CPPUNIT_NS :: TestResult testresult; CPPUNIT_NS :: TestResult testresult;
@ -49,8 +59,13 @@ int main (int argc, char* argv[])
xml.write (); xml.write ();
#endif #endif
// kill the logger again // ............................................................................
Assimp::DefaultLogger::kill(); // but shutdown must be done from C to ensure proper deallocation
aiDetachAllLogStreams();
if (!Assimp::DefaultLogger::isNullLogger()) {
return 1;
}
// ............................................................................
// Rueckmeldung, ob Tests erfolgreich waren // Rueckmeldung, ob Tests erfolgreich waren
return collectedresults.wasSuccessful () ? 0 : 1; return collectedresults.wasSuccessful () ? 0 : 1;

View File

@ -6,6 +6,7 @@
// We need to be sure to have the same STL settings as Assimp // We need to be sure to have the same STL settings as Assimp
#include <AssimpPCH.h> #include <AssimpPCH.h>
#include "assimp.h"
// CPPUNIT // CPPUNIT
#include <cppunit/TestFixture.h> #include <cppunit/TestFixture.h>

View File

@ -50,6 +50,7 @@ void RemoveVCProcessTest :: setUp (void)
// COMPILE TEST: MaterialHelper may no add any extra members, // COMPILE TEST: MaterialHelper may no add any extra members,
// so we don't need a virtual destructor // so we don't need a virtual destructor
char check[sizeof(MaterialHelper) == sizeof(aiMaterial) ? 10 : -1]; char check[sizeof(MaterialHelper) == sizeof(aiMaterial) ? 10 : -1];
check[0] = 0;
} }
void RemoveVCProcessTest :: tearDown (void) void RemoveVCProcessTest :: tearDown (void)

View File

@ -38,8 +38,8 @@ void TriangulateProcessTest :: setUp (void)
// construct fully convex input data in ccw winding, xy plane // construct fully convex input data in ccw winding, xy plane
aiVector3D& v = pcMesh->mVertices[pcMesh->mNumVertices++]; aiVector3D& v = pcMesh->mVertices[pcMesh->mNumVertices++];
v.z = 0.f; v.z = 0.f;
v.x = cos (p * AI_MATH_TWO_PI/face.mNumIndices); v.x = cos (p * (float)(AI_MATH_TWO_PI)/face.mNumIndices);
v.y = sin (p * AI_MATH_TWO_PI/face.mNumIndices); v.y = sin (p * (float)(AI_MATH_TWO_PI)/face.mNumIndices);
} }
} }
} }

View File

@ -129,9 +129,9 @@ const aiScene* ImportModel(const ImportData& imp, const std::string& path)
unsigned int flags = 0; unsigned int flags = 0;
if (imp.logFile.length()) if (imp.logFile.length())
flags |= DLS_FILE; flags |= aiDefaultLogStream_FILE;
if (imp.showLog) if (imp.showLog)
flags |= DLS_CERR; flags |= aiDefaultLogStream_STDERR;
DefaultLogger::create(imp.logFile.c_str(),imp.verbose ? Logger::VERBOSE : Logger::NORMAL,flags); DefaultLogger::create(imp.logFile.c_str(),imp.verbose ? Logger::VERBOSE : Logger::NORMAL,flags);
} }

View File

@ -1132,130 +1132,6 @@
<Filter <Filter
Name="include" Name="include"
> >
<File
RelativePath="..\..\include\aiAnim.h"
>
</File>
<File
RelativePath="..\..\include\aiAssert.h"
>
</File>
<File
RelativePath="..\..\include\aiCamera.h"
>
</File>
<File
RelativePath="..\..\include\aiConfig.h"
>
</File>
<File
RelativePath="..\..\include\aiDefines.h"
>
</File>
<File
RelativePath="..\..\include\aiFileIO.h"
>
</File>
<File
RelativePath="..\..\include\aiLight.h"
>
</File>
<File
RelativePath="..\..\include\aiMaterial.h"
>
</File>
<File
RelativePath="..\..\include\aiMaterial.inl"
>
</File>
<File
RelativePath="..\..\include\aiMatrix3x3.h"
>
</File>
<File
RelativePath="..\..\include\aiMatrix3x3.inl"
>
</File>
<File
RelativePath="..\..\include\aiMatrix4x4.h"
>
</File>
<File
RelativePath="..\..\include\aiMatrix4x4.inl"
>
</File>
<File
RelativePath="..\..\include\aiMesh.h"
>
</File>
<File
RelativePath="..\..\include\aiPostProcess.h"
>
</File>
<File
RelativePath="..\..\include\aiQuaternion.h"
>
</File>
<File
RelativePath="..\..\include\aiScene.h"
>
</File>
<File
RelativePath="..\..\include\aiTexture.h"
>
</File>
<File
RelativePath="..\..\include\aiTypes.h"
>
</File>
<File
RelativePath="..\..\include\aiVector2D.h"
>
</File>
<File
RelativePath="..\..\include\aiVector3D.h"
>
</File>
<File
RelativePath="..\..\include\aiVector3D.inl"
>
</File>
<File
RelativePath="..\..\include\aiVersion.h"
>
</File>
<File
RelativePath="..\..\include\assimp.h"
>
</File>
<File
RelativePath="..\..\include\assimp.hpp"
>
</File>
<File
RelativePath="..\..\include\DefaultLogger.h"
>
</File>
<File
RelativePath="..\..\include\IOStream.h"
>
</File>
<File
RelativePath="..\..\include\IOSystem.h"
>
</File>
<File
RelativePath="..\..\include\Logger.h"
>
</File>
<File
RelativePath="..\..\include\LogStream.h"
>
</File>
<File
RelativePath="..\..\include\NullLogger.h"
>
</File>
<Filter <Filter
Name="Compiler" Name="Compiler"
> >
@ -1324,6 +1200,142 @@
</File> </File>
</Filter> </Filter>
</Filter> </Filter>
<Filter
Name="C"
>
<File
RelativePath="..\..\include\aiFileIO.h"
>
</File>
<File
RelativePath="..\..\include\assimp.h"
>
</File>
</Filter>
<Filter
Name="Cpp"
>
<File
RelativePath="..\..\include\assimp.hpp"
>
</File>
<File
RelativePath="..\..\include\DefaultLogger.h"
>
</File>
<File
RelativePath="..\..\include\IOStream.h"
>
</File>
<File
RelativePath="..\..\include\IOSystem.h"
>
</File>
<File
RelativePath="..\..\include\Logger.h"
>
</File>
<File
RelativePath="..\..\include\LogStream.h"
>
</File>
<File
RelativePath="..\..\include\NullLogger.h"
>
</File>
</Filter>
<Filter
Name="Common"
>
<File
RelativePath="..\..\include\aiAnim.h"
>
</File>
<File
RelativePath="..\..\include\aiAssert.h"
>
</File>
<File
RelativePath="..\..\include\aiCamera.h"
>
</File>
<File
RelativePath="..\..\include\aiConfig.h"
>
</File>
<File
RelativePath="..\..\include\aiDefines.h"
>
</File>
<File
RelativePath="..\..\include\aiLight.h"
>
</File>
<File
RelativePath="..\..\include\aiMaterial.h"
>
</File>
<File
RelativePath="..\..\include\aiMaterial.inl"
>
</File>
<File
RelativePath="..\..\include\aiMatrix3x3.h"
>
</File>
<File
RelativePath="..\..\include\aiMatrix3x3.inl"
>
</File>
<File
RelativePath="..\..\include\aiMatrix4x4.h"
>
</File>
<File
RelativePath="..\..\include\aiMatrix4x4.inl"
>
</File>
<File
RelativePath="..\..\include\aiMesh.h"
>
</File>
<File
RelativePath="..\..\include\aiPostProcess.h"
>
</File>
<File
RelativePath="..\..\include\aiQuaternion.h"
>
</File>
<File
RelativePath="..\..\include\aiScene.h"
>
</File>
<File
RelativePath="..\..\include\aiTexture.h"
>
</File>
<File
RelativePath="..\..\include\aiTypes.h"
>
</File>
<File
RelativePath="..\..\include\aiVector2D.h"
>
</File>
<File
RelativePath="..\..\include\aiVector3D.h"
>
</File>
<File
RelativePath="..\..\include\aiVector3D.inl"
>
</File>
<File
RelativePath="..\..\include\aiVersion.h"
>
</File>
</Filter>
</Filter> </Filter>
<Filter <Filter
Name="sources" Name="sources"

View File

@ -1104,130 +1104,6 @@
<Filter <Filter
Name="include" Name="include"
> >
<File
RelativePath="..\..\include\aiAnim.h"
>
</File>
<File
RelativePath="..\..\include\aiAssert.h"
>
</File>
<File
RelativePath="..\..\include\aiCamera.h"
>
</File>
<File
RelativePath="..\..\include\aiConfig.h"
>
</File>
<File
RelativePath="..\..\include\aiDefines.h"
>
</File>
<File
RelativePath="..\..\include\aiFileIO.h"
>
</File>
<File
RelativePath="..\..\include\aiLight.h"
>
</File>
<File
RelativePath="..\..\include\aiMaterial.h"
>
</File>
<File
RelativePath="..\..\include\aiMaterial.inl"
>
</File>
<File
RelativePath="..\..\include\aiMatrix3x3.h"
>
</File>
<File
RelativePath="..\..\include\aiMatrix3x3.inl"
>
</File>
<File
RelativePath="..\..\include\aiMatrix4x4.h"
>
</File>
<File
RelativePath="..\..\include\aiMatrix4x4.inl"
>
</File>
<File
RelativePath="..\..\include\aiMesh.h"
>
</File>
<File
RelativePath="..\..\include\aiPostProcess.h"
>
</File>
<File
RelativePath="..\..\include\aiQuaternion.h"
>
</File>
<File
RelativePath="..\..\include\aiScene.h"
>
</File>
<File
RelativePath="..\..\include\aiTexture.h"
>
</File>
<File
RelativePath="..\..\include\aiTypes.h"
>
</File>
<File
RelativePath="..\..\include\aiVector2D.h"
>
</File>
<File
RelativePath="..\..\include\aiVector3D.h"
>
</File>
<File
RelativePath="..\..\include\aiVector3D.inl"
>
</File>
<File
RelativePath="..\..\include\aiVersion.h"
>
</File>
<File
RelativePath="..\..\include\assimp.h"
>
</File>
<File
RelativePath="..\..\include\assimp.hpp"
>
</File>
<File
RelativePath="..\..\include\DefaultLogger.h"
>
</File>
<File
RelativePath="..\..\include\IOStream.h"
>
</File>
<File
RelativePath="..\..\include\IOSystem.h"
>
</File>
<File
RelativePath="..\..\include\Logger.h"
>
</File>
<File
RelativePath="..\..\include\LogStream.h"
>
</File>
<File
RelativePath="..\..\include\NullLogger.h"
>
</File>
<Filter <Filter
Name="Compiler" Name="Compiler"
> >
@ -1296,6 +1172,142 @@
</File> </File>
</Filter> </Filter>
</Filter> </Filter>
<Filter
Name="Cpp"
>
<File
RelativePath="..\..\include\aiAssert.h"
>
</File>
<File
RelativePath="..\..\include\assimp.hpp"
>
</File>
<File
RelativePath="..\..\include\DefaultLogger.h"
>
</File>
<File
RelativePath="..\..\include\IOStream.h"
>
</File>
<File
RelativePath="..\..\include\IOSystem.h"
>
</File>
<File
RelativePath="..\..\include\Logger.h"
>
</File>
<File
RelativePath="..\..\include\LogStream.h"
>
</File>
<File
RelativePath="..\..\include\NullLogger.h"
>
</File>
</Filter>
<Filter
Name="C"
>
<File
RelativePath="..\..\include\aiFileIO.h"
>
</File>
<File
RelativePath="..\..\include\aiVersion.h"
>
</File>
<File
RelativePath="..\..\include\assimp.h"
>
</File>
</Filter>
<Filter
Name="Common"
>
<File
RelativePath="..\..\include\aiAnim.h"
>
</File>
<File
RelativePath="..\..\include\aiCamera.h"
>
</File>
<File
RelativePath="..\..\include\aiConfig.h"
>
</File>
<File
RelativePath="..\..\include\aiDefines.h"
>
</File>
<File
RelativePath="..\..\include\aiLight.h"
>
</File>
<File
RelativePath="..\..\include\aiMaterial.h"
>
</File>
<File
RelativePath="..\..\include\aiMaterial.inl"
>
</File>
<File
RelativePath="..\..\include\aiMatrix3x3.h"
>
</File>
<File
RelativePath="..\..\include\aiMatrix3x3.inl"
>
</File>
<File
RelativePath="..\..\include\aiMatrix4x4.h"
>
</File>
<File
RelativePath="..\..\include\aiMatrix4x4.inl"
>
</File>
<File
RelativePath="..\..\include\aiMesh.h"
>
</File>
<File
RelativePath="..\..\include\aiPostProcess.h"
>
</File>
<File
RelativePath="..\..\include\aiQuaternion.h"
>
</File>
<File
RelativePath="..\..\include\aiScene.h"
>
</File>
<File
RelativePath="..\..\include\aiTexture.h"
>
</File>
<File
RelativePath="..\..\include\aiTypes.h"
>
</File>
<File
RelativePath="..\..\include\aiVector2D.h"
>
</File>
<File
RelativePath="..\..\include\aiVector3D.h"
>
</File>
<File
RelativePath="..\..\include\aiVector3D.inl"
>
</File>
</Filter>
</Filter> </Filter>
<Filter <Filter
Name="sources" Name="sources"