Pārlūkot izejas kodu

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

aramis_acg 16 gadi atpakaļ
vecāks
revīzija
d881a16402

+ 278 - 94
code/Assimp.cpp

@@ -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.
 ---------------------------------------------------------------------------
 */
-/** @file Implementation of the Plain-C API */
-
-
+/** @file  Assimp.cpp
+ *  @brief Implementation of the Plain-C API
+ */
 
 #include "AssimpPCH.h"
 #include "../include/assimp.h"
-
-// public ASSIMP headers
 #include "../include/aiFileIO.h"
 
 #include "GenericProperty.h"
 
-#if (defined AI_C_THREADSAFE)
+// ------------------------------------------------------------------------------------------------
+#ifdef AI_C_THREADSAFE
 #	include <boost/thread/thread.hpp>
 #	include <boost/thread/mutex.hpp>
 #endif
-
+// ------------------------------------------------------------------------------------------------
 using namespace Assimp;
-
 /** 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 */
 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 */
 static std::string gLastErrorString;
 
+/** Verbose logging active or not? */
+static aiBool gVerboseLogging = false;
+
 /** Configuration properties */
-static ImporterPimpl::IntPropertyMap		gIntProperties;
-static ImporterPimpl::FloatPropertyMap		gFloatProperties;
-static ImporterPimpl::StringPropertyMap		gStringProperties;
+static ImporterPimpl::IntPropertyMap gIntProperties;
+static ImporterPimpl::FloatPropertyMap gFloatProperties;
+static ImporterPimpl::StringPropertyMap	gStringProperties;
 
-#if (defined AI_C_THREADSAFE)
+#ifdef AI_C_THREADSAFE
 /** Global mutex to manage the access to the importer map */
 static boost::mutex gMutex;
+
+/** Global mutex to manage the access to the logstream map */
+static boost::mutex gLogStreamMutex;
 #endif
 
 class CIOSystemWrapper;
@@ -90,46 +111,43 @@ public:
 		: mFile(pFile)
 	{}
 
-	// -------------------------------------------------------------------
+	// ...................................................................
 	size_t Read(void* pvBuffer, 
 		size_t pSize, 
-		size_t pCount)
-	{
+		size_t pCount
+	){
 		// need to typecast here as C has no void*
 		return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount);
 	}
 
-	// -------------------------------------------------------------------
+	// ...................................................................
 	size_t Write(const void* pvBuffer, 
 		size_t pSize,
-		size_t pCount)
-	{
+		size_t pCount
+	){
 		// need to typecast here as C has no void*
 		return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount);
 	}
 
-	// -------------------------------------------------------------------
+	// ...................................................................
 	aiReturn Seek(size_t pOffset,
-		aiOrigin pOrigin)
-	{
+		aiOrigin pOrigin
+	){
 		return mFile->SeekProc(mFile,pOffset,pOrigin);
 	}
 
-	// -------------------------------------------------------------------
-	size_t Tell(void) const
-	{
+	// ...................................................................
+	size_t Tell(void) const {
 		return mFile->TellProc(mFile);
 	}
 
-	// -------------------------------------------------------------------
-	size_t	FileSize() const
-	{
+	// ...................................................................
+	size_t	FileSize() const {
 		return mFile->FileSizeProc(mFile);
 	}
 
-	// -------------------------------------------------------------------
-	void Flush ()
-	{
+	// ...................................................................
+	void Flush () {
 		return mFile->FlushProc(mFile);
 	}
 
@@ -137,20 +155,17 @@ private:
 	aiFile* mFile;
 };
 
-
 // ------------------------------------------------------------------------------------------------
 // Custom IOStream implementation for the C-API
 class CIOSystemWrapper : public IOSystem
 {
 public:
-
 	CIOSystemWrapper(aiFileIO* pFile)
 		: mFileSystem(pFile)
 	{}
 
-	// -------------------------------------------------------------------
-	bool Exists( const char* pFile) const
-	{
+	// ...................................................................
+	bool Exists( const char* pFile) const {
 		CIOSystemWrapper* pip = const_cast<CIOSystemWrapper*>(this);
 		IOStream* p = pip->Open(pFile);
 		if (p){
@@ -160,40 +175,80 @@ public:
 		return false;
 	}
 
-	// -------------------------------------------------------------------
-	char getOsSeparator() const
-	{
-		// FIXME
+	// ...................................................................
+	char getOsSeparator() const {
+#ifndef _WIN32
 		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);
-		if (!p)return NULL;
+		if (!p) {
+			return NULL;
+		}
 		return new CIOStreamWrapper(p);
 	}
 
-	// -------------------------------------------------------------------
-	void Close( IOStream* pFile)
-	{
-		if (!pFile)return;
+	// ...................................................................
+	void Close( IOStream* pFile) {
+		if (!pFile) {
+			return;
+		}
 		mFileSystem->CloseProc(mFileSystem,((CIOStreamWrapper*) pFile)->mFile);
 		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.
 
-private:
+		PredefLogStreamMap::iterator it = std::find(gPredefinedStreams.begin(), 
+			gPredefinedStreams.end(), (Assimp::LogStream*)stream.user);
 
-	aiFileIO* mFileSystem;
+		if (it != gPredefinedStreams.end()) {
+			delete *it;
+			gPredefinedStreams.erase(it);
+		}
+	}
+
+	/** @copydoc LogStream::write */
+	void write(const char* message)	{
+		stream.callback(message,stream.user);
+	}
+
+private:
+	aiLogStream stream;
 };
 
 // ------------------------------------------------------------------------------------------------
 void ReportSceneNotFoundError()
 {
-	DefaultLogger::get()->error("Unable to find the Importer instance for this scene. "
-		"Are you sure it has been created by aiImportFile(ex)(...)?");
+	DefaultLogger::get()->error("Unable to find the Assimp::Importer for this aiScene. "
+		"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)
 {
 	ai_assert(NULL != pFile);
-
 	// create an Importer for this file
 	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
-	// (we are a friend of Importer)
 	imp->pimpl->mIntProperties = gIntProperties;
 	imp->pimpl->mFloatProperties = gFloatProperties;
 	imp->pimpl->mStringProperties = gStringProperties;
 
+#ifdef AI_C_THREADSAFE
+	lock.unlock();
+#endif
+
 	// setup a custom IO system if necessary
-	if (pFS)
-	{
+	if (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);
 
 	// if succeeded, place it in the collection of active processes
-	if( scene)
-	{
-#if (defined AI_C_THREADSAFE)
-		boost::mutex::scoped_lock lock(gMutex);
+	if( scene)	{
+#ifdef AI_C_THREADSAFE
+		lock.lock();
 #endif
 		gActiveImports[scene] = imp;
 	} 
-	else
-	{
+	else	{
 		// if failed, extract error code and destroy the import
 		gLastErrorString = imp->GetErrorString();
 		delete imp;
@@ -250,18 +307,18 @@ const aiScene* aiImportFileEx( const char* pFile, unsigned int pFlags,
 // Releases all resources associated with the given import process. 
 void aiReleaseImport( const aiScene* pScene)
 {
-	if (!pScene)return;
+	if (!pScene) {
+		return;
+	}
 
-	// lock the mutex
-#if (defined AI_C_THREADSAFE)
+#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())
-	{
+	if( it == gActiveImports.end())	{
 		ReportSceneNotFoundError();
 		return;
 	}
@@ -271,6 +328,120 @@ void aiReleaseImport( const aiScene* pScene)
 	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. 
 const char* aiGetErrorString()
@@ -280,25 +451,20 @@ const char* aiGetErrorString()
 
 // ------------------------------------------------------------------------------------------------
 // Returns the error text of the last failed import process. 
-int aiIsExtensionSupported(const char* szExtension)
+aiBool aiIsExtensionSupported(const char* szExtension)
 {
 	ai_assert(NULL != szExtension);
-
-	// lock the mutex
-#if (defined AI_C_THREADSAFE)
+#ifdef AI_C_THREADSAFE
 	boost::mutex::scoped_lock lock(gMutex);
 #endif
 
 	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.
-	// TODO: Find a better solution ...
-	Assimp::Importer* pcTemp = new Assimp::Importer();
-	int i = (int)pcTemp->IsExtensionSupported(std::string(szExtension));
-	delete pcTemp;
-	return i;
+	// fixme: no need to create a temporary Importer instance just for that .. 
+	Assimp::Importer tmp;
+	return tmp.IsExtensionSupported(std::string(szExtension)) ? AI_TRUE : AI_FALSE;
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -306,9 +472,7 @@ int aiIsExtensionSupported(const char* szExtension)
 void aiGetExtensionList(aiString* szOut)
 {
 	ai_assert(NULL != szOut);
-
-	// lock the mutex
-#if (defined AI_C_THREADSAFE)
+#ifdef AI_C_THREADSAFE
 	boost::mutex::scoped_lock lock(gMutex);
 #endif
 
@@ -317,65 +481,85 @@ void aiGetExtensionList(aiString* szOut)
 		(*(gActiveImports.begin())).second->GetExtensionList(*szOut);
 		return;
 	}
-	// need to create a temporary Importer instance.
-	// TODO: Find a better solution ...
-	Assimp::Importer* pcTemp = new Assimp::Importer();
-	pcTemp->GetExtensionList(*szOut);
-	delete pcTemp;
+	// fixme: no need to create a temporary Importer instance just for that .. 
+	Assimp::Importer tmp;
+	tmp.GetExtensionList(*szOut);
 }
 
 // ------------------------------------------------------------------------------------------------
+// Get the memory requirements for a particular import.
 void aiGetMemoryRequirements(const C_STRUCT aiScene* pIn,
 	C_STRUCT aiMemoryInfo* in)
 {
-// lock the mutex
-#if (defined AI_C_THREADSAFE)
+#ifdef AI_C_THREADSAFE
 	boost::mutex::scoped_lock lock(gMutex);
 #endif
 
 	// find the importer associated with this data
 	ImporterMap::iterator it = gActiveImports.find( pIn);
 	// it should be there... else the user is playing fools with us
-	if( it == gActiveImports.end())
-	{
+	if( it == gActiveImports.end())	{
 		ReportSceneNotFoundError();
 		return;
 	}
 	// get memory statistics
+#ifdef AI_C_THREADSAFE
+	lock.unlock();
+#endif
 	it->second->GetMemoryRequirements(*in);
 }
 
 // ------------------------------------------------------------------------------------------------
+// Importer::SetPropertyInteger
 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);
 }
 
 // ------------------------------------------------------------------------------------------------
+// Importer::SetPropertyFloat
 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);
 }
 
 // ------------------------------------------------------------------------------------------------
+// Importer::SetPropertyString
 ASSIMP_API void aiSetImportPropertyString(const char* szName,
 	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,
 		std::string( st->data ),NULL);
 }
 
 // ------------------------------------------------------------------------------------------------
+// Rotation matrix to quaternion
 ASSIMP_API void aiCreateQuaternionFromMatrix(aiQuaternion* quat,const aiMatrix3x3* mat)
 {
+	ai_assert(NULL != quat && NULL != mat);
 	*quat = aiQuaternion(*mat);
 }
 
 // ------------------------------------------------------------------------------------------------
-ASSIMP_API void aiDecomposeMatrix(const aiMatrix4x4* mat, aiVector3D* scaling,
-	aiQuaternion* rotation,aiVector3D* position)
+// Affline matrix decomposition
+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);
 }
+
+

+ 14 - 14
code/DefaultLogger.cpp

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

+ 14 - 13
code/PlyLoader.cpp

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

BIN
doc/AssimpDoc_Html/AssimpDoc.chm


+ 74 - 48
include/DefaultLogger.h

@@ -37,7 +37,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 ----------------------------------------------------------------------
 */
-
 /** @file DefaultLogger.h
 */
 
@@ -54,100 +53,127 @@ namespace Assimp	{
 class IOStream;
 struct LogStreamInfo;
 
-//! Default log file name
+/** default name of logfile */
 #define ASSIMP_DEFAULT_LOG_NAME "AssimpLog.txt"
 
 // ------------------------------------------------------------------------------------
-/**  @class	DefaultLogger
- *	 @brief	Default logging implementation. 
+/** @class	DefaultLogger
+ *	@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 :
-	public Logger
-{
+	public Logger	{
 public:
 
-	/** @brief	Creates a default logging instance (DefaultLogger)
-	 *	@param	name		Name for log file. Only valid in combination
-	 *                      with the DLS_FILE flag. 
-	 *	@param	severity	Log severity, VERBOSE will activate debug messages
-	 *  @param  defStreams  Default log streams to be attached. Bitwise
-	 *                      combination of the DefaultLogStreams enumerated
-	 *                      values. If DLS_FILE is specified, but an empty
-	 *                      string is passed for 'name' no log file is created.
-	 *  @param  io          IOSystem to be used to open external files (such as the 
-	 *                      log file). Pass NULL for the default implementation.
+	// ----------------------------------------------------------------------
+	/** @brief Creates a logging instance.
+	 *  @param name Name for log file. Only valid in combination
+	 *    with the aiDefaultLogStream_FILE flag. 
+	 *  @param severity	Log severity, VERBOSE turns on debug messages
+	 *  @param defStreams  Default log streams to be attached. Any bitwise
+	 *    combination of the aiDefaultLogStream enumerated values. 
+	 *    If #aiDefaultLogStream_FILE is specified but an empty string is
+	 *    passed for 'name', no log file is created at all.
+	 *  @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,
 		LogSeverity severity    = NORMAL,
-		unsigned int defStreams = DLS_DEBUGGER | DLS_FILE,
+		unsigned int defStreams = aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE,
 		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,
-	 *  it is easier to use create() to create a DefaultLogger and to attach
-	 *  your own custom output streams to it than using this method.
+	 *  it's much easier to use #create() and to attach your own custom 
+	 *  output streams to it.
 	 *  @param logger Pass NULL to setup a default NullLogger
 	 */
 	static void set (Logger *logger);
 	
+	// ----------------------------------------------------------------------
 	/** @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.
 	 */
 	static Logger *get();
 
-	/** @brief  Return whether a default NullLogger is currently active
-	 *  @return true if the current logger is a NullLogger.
-	 *  Use create() or set() to setup a custom logger.
+	// ----------------------------------------------------------------------
+	/** @brief  Return whether a #NullLogger is currently active
+	 *  @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();
 	
-	/** @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();
 	
-	/**	@brief	Attach a stream to the logger. */
-	/* override */ bool attachStream(LogStream *pStream,
+	// ----------------------------------------------------------------------
+	/**	@copydoc Logger::attachStream  
+	 */
+	bool attachStream(LogStream *pStream,
 		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);
 
+
+private:
+
+	// ----------------------------------------------------------------------
+	/** @briefPrivate construction for internal use by create().
+	 *  @param severity Logging granularity
+	 */
+	DefaultLogger(LogSeverity severity);
+	
+	// ----------------------------------------------------------------------
+	/**	@briefDestructor	*/
+	~DefaultLogger();
+
 private:
 
 	/**	@brief	Logs debug infos, only been written when severity level VERBOSE is set */
-	/* override */ void OnDebug(const char* message);
+	void OnDebug(const char* message);
 
 	/**	@brief	Logs an info message */
-	/* override */ void OnInfo(const char*  message);
+	void OnInfo(const char*  message);
 
 	/**	@brief	Logs a warning message */
-	/* override */ void OnWarn(const char*  message);
+	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
-	 */
-	DefaultLogger(LogSeverity severity);
-	
-	/**	@brief	Destructor	*/
-	~DefaultLogger();
+	void OnError(const char* message);
 
+	// ----------------------------------------------------------------------
 	/**	@brief Writes a message to all streams */
 	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();
 

+ 20 - 55
include/LogStream.h

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

+ 47 - 34
include/Logger.h

@@ -41,31 +41,31 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 /** @file Logger.h
  *  @brief Abstract base class 'Logger', base of the logging system. 
  */
-
 #ifndef INCLUDED_AI_LOGGER_H
 #define INCLUDED_AI_LOGGER_H
 
 #include "aiTypes.h"
 namespace Assimp	{
-
 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
 
 // ----------------------------------------------------------------------------------
 /**	@class	Logger
  *	@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:
+
+	// ----------------------------------------------------------------------
 	/**	@enum	LogSeverity
 	 *	@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
 	{
@@ -73,6 +73,7 @@ public:
 		VERBOSE		//!< Debug infos will be logged, too
 	};
 
+	// ----------------------------------------------------------------------
 	/**	@enum	ErrorSeverity
 	 *	@brief	Description for severity of a log message.
 	 *
@@ -93,35 +94,42 @@ public:
 	/** @brief	Virtual destructor */
 	virtual ~Logger();
 
+	// ----------------------------------------------------------------------
 	/** @brief	Writes a debug message
-	 *	 @param	message		Debug message
+	 *	 @param	message	Debug message
 	 */
 	void debug(const std::string &message);
 
+	// ----------------------------------------------------------------------
 	/** @brief	Writes a info message
-	 *	@param	message		Info message
+	 *	@param	message Info message
 	 */
 	void info(const std::string &message);
 
+	// ----------------------------------------------------------------------
 	/** @brief	Writes a warning message
-	 *	@param	message		Warn message
+	 *	@param	message Warn message
 	 */
 	void warn(const std::string &message);
 
+	// ----------------------------------------------------------------------
 	/** @brief	Writes an error message
-	 *	@param	message		Error message
+	 *	@param	message	Error message
 	 */
 	void error(const std::string &message);
 
+	// ----------------------------------------------------------------------
 	/** @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);
 
-	/** @brief	Get the current log severity
+	// ----------------------------------------------------------------------
+	/** @brief Get the current log severity
 	 */
 	LogSeverity getLogSeverity() const;
 
+	// ----------------------------------------------------------------------
 	/** @brief	Attach a new logstream
 	 *
 	 *  The logger takes ownership of the stream and is responsible
@@ -137,6 +145,7 @@ public:
 	virtual bool attachStream(LogStream *pStream, 
 		unsigned int severity = DEBUGGING | ERR | WARN | INFO) = 0;
 
+	// ----------------------------------------------------------------------
 	/** @brief	Detach a still attached stream from the logger (or 
 	 *          modify the filter flags bits)
 	 *	 @param	pStream	Logstream instance for detaching
@@ -157,35 +166,39 @@ protected:
 	/** Construction with a given log severity */
 	Logger(LogSeverity severity);
 
-	/**  @brief Called as a request to write a specific debug message
-	 *	 @param	message		Debug message. Never longer than
-	 *     MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
-	 *   @note  The message string is only valid until the scope of
-	 *     the function is left.
+	// ----------------------------------------------------------------------
+	/** @brief Called as a request to write a specific debug message
+	 *	@param	message	Debug message. Never longer than
+	 *    MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
+	 *  @note  The message string is only valid until the scope of
+	 *    the function is left.
 	 */
 	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
-	 *     MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
-	 *   @note  The message string is only valid until the scope of
-	 *     the function is left.
+	// ----------------------------------------------------------------------
+	/** @brief Called as a request to write a specific info message
+	 *	@param	message	Info message. Never longer than
+	 *    MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
+	 *  @note  The message string is only valid until the scope of
+	 *    the function is left.
 	 */
 	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
-	 *     MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
-	 *   @note  The message string is only valid until the scope of
-	 *     the function is left.
+	// ----------------------------------------------------------------------
+	/** @brief Called as a request to write a specific warn message
+	 *	@param	message	Warn message. Never longer than
+	 *    MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
+	 *  @note  The message string is only valid until the scope of
+	 *    the function is left.
 	 */
 	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
-	 *     MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
-	 *   @note  The message string is only valid until the scope of
-	 *     the function is left.
+	// ----------------------------------------------------------------------
+	/** @brief Called as a request to write a specific error message
+	 *	@param	message Error message. Never longer than
+	 *    MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
+	 *  @note  The message string is only valid until the scope of
+	 *    the function is left.
 	 */
 	virtual void OnError(const char* message) = 0;
 

+ 5 - 8
include/NullLogger.h

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

+ 26 - 24
include/aiFileIO.h

@@ -40,18 +40,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
 /** @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
 #define AI_FILEIO_H_INC
 
 #include "aiTypes.h"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
-
 struct aiFileIO;
 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   (*aiFileTellProc)  (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
 typedef aiFile* (*aiFileOpenProc)  (C_STRUCT aiFileIO*, const char*, const char*);
 typedef void    (*aiFileCloseProc) (C_STRUCT aiFileIO*, C_STRUCT aiFile*);
 
-// represents user-defined data
+// Represents user-defined data
 typedef char* aiUserData;
 
 // ----------------------------------------------------------------------------------
@@ -79,13 +76,15 @@ typedef char* aiUserData;
 */
 struct aiFileIO
 {
-	//! Function used to open a new file
+	/** Function used to open a new file
+	 */
 	aiFileOpenProc OpenProc;
 
-	//! Function used to close an existing file
+	/** Function used to close an existing file
+	 */
 	aiFileCloseProc CloseProc;
 
-	//! User-defined data
+	/** User-defined, opaque data */
 	aiUserData UserData;
 };
 
@@ -93,44 +92,47 @@ struct aiFileIO
 /** @class aiFile
  *  @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
  *
  *  The default implementation of the functions utilizes the fXXX functions from 
  *  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, 
- *  such as ZIPs or memory locations.
+ *  delivering a custom aiFileIO. Use this to enable reading from other sources, 
+ *  such as ZIP archives or memory locations.
  */
 struct aiFile
 {
-	//! Function used to read from a file
+	/** Callback to read from a file */
 	aiFileReadProc ReadProc;
 
-	//! Function used to write to a file
+	/** Callback to write to a file */
 	aiFileWriteProc WriteProc;
 
-	//! Function used to retrieve the current
-	//! position of the file cursor (ftell())
+	/** Callback to retrieve the current position of 
+	 *  the file cursor (ftell())
+	 */
 	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;
 
-	//! Function used to set the current position
-	//! of the file cursor (fseek())
+	/** Callback to set the current position
+	 * of the file cursor (fseek())
+	 */
 	aiFileSeek SeekProc;
 
-	//! Function used to flush the file contents
+	/** Callback to flush the file contents
+	 */
 	aiFileFlushProc FlushProc;
 
-	//! User-defined data
+	/** User-defined, opaque data
+	 */
 	aiUserData UserData;
 };
 
-
 #ifdef __cplusplus
 }
 #endif
-
-
 #endif // AI_FILEIO_H_INC

+ 97 - 108
include/aiMaterial.h

@@ -56,47 +56,6 @@ extern "C" {
 #define AI_DEFAULT_MATERIAL_NAME          "DefaultMaterial"
 #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
  *  the result of all previous layers.
@@ -420,12 +379,11 @@ enum aiShadingMode
 // ---------------------------------------------------------------------------
 /** @brief Defines some mixed flags for a particular texture.
  *
- *  Usually you'll tell your cg artists how textures have to look like ...
- *  and hopefully the follow these rules. If they don't, restrict access
- *  to the coffee machine for them. That should help. 
- *  However, if you use Assimp for completely generic loading purposes you
- *  might also need to process these flags in order to display as many 
- *  'unknown' 3D models as possible correctly.
+ *  Usually you'll instruct your cg artists how textures have to look like ...
+ *  and how they will be processed in your application. However, if you use
+ *  Assimp for completely generic loading purposes you might also need to 
+ *  process these flags in order to display as many 'unknown' 3D models as 
+ *  possible correctly.
  *
  *  This corresponds to the #AI_MATKEY_TEXFLAGS property.
 */
@@ -435,7 +393,6 @@ enum aiTextureFlags
 	 */
 	aiTextureFlags_Invert = 0x1,
 
-
 	/** Explicit request to the application to process the alpha channel
 	 *  of the texture.
 	 *
@@ -450,11 +407,9 @@ enum aiTextureFlags
 	/** Explicit request to the application to ignore the alpha channel
 	 *  of the texture.
 	 *
-	 *  Mutually exclusive with #aiTextureFlags_IgnoreAlpha. 
+	 *  Mutually exclusive with #aiTextureFlags_UseAlpha. 
 	 */
 	aiTextureFlags_IgnoreAlpha = 0x4,
-
-
 	
 	 /** @cond never 
 	  *  This value is not used. It forces the compiler to use at least
@@ -560,6 +515,48 @@ struct aiUVTransform
 
 #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
  *
@@ -576,37 +573,30 @@ struct aiUVTransform
  *       2nd: Public, but ignored by the #aiProcess_RemoveRedundantMaterials 
  *       post-processing step.
  *    ~<name>
- *       A temporary property for internal use. If someone forgets to
- *       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. 
+ *       A temporary property for internal use. 
  *  @endcode
  *  @see aiMaterial
  */
 struct aiMaterialProperty
 {
     /** Specifies the name of the property (key)
-     *
-     *  Keys are case insensitive. 
+     *  Keys are generally  case insensitive. 
      */
     C_STRUCT aiString mKey;
 
-	/** Textures: Specifies the exact usage semantic.
-	 *  
-	 *  For non-texture properties, this member is always 0 
-	 *  or #aiTextureType_NONE.
+	/** Textures: Specifies their exact usage semantic.
+	 * For non-texture properties, this member is always 0 
+	 * (or, better-said, #aiTextureType_NONE).
 	 */
 	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.
 	 */
 	unsigned int mIndex;
 
     /**	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;
 
@@ -619,8 +609,7 @@ struct aiMaterialProperty
      */
     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.
      */
     char* mData;
@@ -638,6 +627,7 @@ struct aiMaterialProperty
 
 #endif
 };
+//! @endcond
 
 #ifdef __cplusplus
 } // 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
-*
-*  @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 type Specifies the type of the texture to be retrieved (
-*    e.g. diffuse, specular, height map ...)
-*  @param index Index of the texture to be retrieved.
-*  @param pPropOut Pointer to receive a pointer to a valid aiMaterialProperty
-*         structure or NULL if the key has not been found. 
-*/
+ *
+ * @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 type Specifies the type of the texture to be retrieved (
+ *    e.g. diffuse, specular, height map ...)
+ * @param index Index of the texture to be retrieved.
+ * @param pPropOut Pointer to receive a pointer to a valid aiMaterialProperty
+ *        structure or NULL if the key has not been found. 
+ */
 // ---------------------------------------------------------------------------
 ASSIMP_API C_ENUM aiReturn aiGetMaterialProperty(
 	 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 
-*  from the material
-*
-* 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)
-* @code
-* aiUVTransform trafo;
-* unsigned int max = sizeof(aiUVTransform);
-* if (AI_SUCCESS != aiGetMaterialFloatArray(mat, AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE,0),
-*    (float*)&trafo, &max) || sizeof(aiUVTransform) != max)
-* {
-*   // error handling 
-* }
-* @endcode
-*
-* @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 pOut Pointer to a buffer to receive the result. 
-* @param pMax Specifies the size of the given buffer, in float's.
-*        Receives the number of values (not bytes!) read. 
-* @param type (see the code sample above)
-* @param index (see the code sample above)
-* @return Specifies whether the key has been found. If not, the output
-*   arrays remains unmodified and pMax is set to 0.
-*/
+ *  from the material
+ *
+ * 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)
+ * @code
+ * aiUVTransform trafo;
+ * unsigned int max = sizeof(aiUVTransform);
+ * if (AI_SUCCESS != aiGetMaterialFloatArray(mat, AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE,0),
+ *    (float*)&trafo, &max) || sizeof(aiUVTransform) != max)
+ * {
+ *   // error handling 
+ * }
+ * @endcode
+ *
+ * @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 pOut Pointer to a buffer to receive the result. 
+ * @param pMax Specifies the size of the given buffer, in float's.
+ *        Receives the number of values (not bytes!) read. 
+ * @param type (see the code sample above)
+ * @param index (see the code sample above)
+ * @return Specifies whether the key has been found. If not, the output
+ *   arrays remains unmodified and pMax is set to 0.
+ */
 // ---------------------------------------------------------------------------
 ASSIMP_API C_ENUM aiReturn aiGetMaterialFloatArray(
 	 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 
-*  from a material
-*
-* See the sample for aiGetMaterialFloatArray for more information.
-*/
-// ---------------------------------------------------------------------------
+ *  from a material
+ *
+ * See the sample for aiGetMaterialFloatArray for more information.
+ */
 ASSIMP_API C_ENUM aiReturn aiGetMaterialIntegerArray(const C_STRUCT aiMaterial* pMat, 
     const char* pKey,
 	 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
-*
-* See the sample for aiGetMaterialFloat for more information.
-*/
+ *
+ * See the sample for aiGetMaterialFloat for more information.
+ */
 // ---------------------------------------------------------------------------
 inline aiReturn aiGetMaterialInteger(const C_STRUCT aiMaterial* pMat, 
 	const char* pKey,

+ 137 - 109
include/aiTypes.h

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

+ 234 - 99
include/assimp.h

@@ -39,154 +39,289 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
-/** @file assimp.h
-    @brief Defines the C-API to the Asset Import Library. */
+/** @file  assimp.h
+ *  @brief Defines the C-API to the Open Asset Import Library. 
+ */
 #ifndef AI_ASSIMP_H_INC
 #define AI_ASSIMP_H_INC
-
 #include "aiTypes.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-struct aiScene;
-struct aiFileIO;
-struct aiString;
+struct aiScene;  // aiScene.h
+struct aiFileIO; // aiFileIO.h
+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.
-* 
-* 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 
-* library and will be stable until aiReleaseImport() is called. After you're 
-* done with it, call aiReleaseImport() to free the resources associated with 
-* this file. If the import fails, NULL is returned instead. Call 
-* aiGetErrorString() to retrieve a human-readable error text.
-* @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.
-* @param pFlags Optional post processing steps to be executed after 
-*   a successful import. Provide a bitwise combination of the 
-*   #aiPostProcessSteps flags.
-* @return Pointer to the imported data or NULL if the import failed. 
-*/
-// ---------------------------------------------------------------------------
-ASSIMP_API const C_STRUCT aiScene* aiImportFile( const char* pFile, 
+ * 
+ * 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 
+ * library and will be stable until aiReleaseImport() is called. After you're 
+ * done with it, call aiReleaseImport() to free the resources associated with 
+ * this file. If the import fails, NULL is returned instead. Call 
+ * aiGetErrorString() to retrieve a human-readable error text.
+ * @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.
+ * @param pFlags Optional post processing steps to be executed after 
+ *   a successful import. Provide a bitwise combination of the 
+ *   #aiPostProcessSteps flags.
+ * @return Pointer to the imported data or NULL if the import failed. 
+ */
+ASSIMP_API const C_STRUCT aiScene* aiImportFile( 
+	const char* pFile, 
 	unsigned int pFlags);
 
-
-// ---------------------------------------------------------------------------
+// --------------------------------------------------------------------------------
 /** Reads the given file using user-defined I/O functions and returns 
-*   its content.
-* 
-* 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 
-* library and will be stable until aiReleaseImport() is called. After you're 
-* done with it, call aiReleaseImport() to free the resources associated with 
-* this file. If the import fails, NULL is returned instead. Call 
-* aiGetErrorString() to retrieve a human-readable error text.
-* @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.
-* @param pFlags Optional post processing steps to be executed after 
-*   a successful import. Provide a bitwise combination of the
-*   #aiPostProcessSteps flags.
-* @param pFS aiFileIO structure. Will be used to open the model file itself
-*   and any other files the loader needs to open.
-* @return Pointer to the imported data or NULL if the import failed.  
-*/
-// ---------------------------------------------------------------------------
+ *   its content.
+ * 
+ * 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 
+ * library and will be stable until aiReleaseImport() is called. After you're 
+ * done with it, call aiReleaseImport() to free the resources associated with 
+ * this file. If the import fails, NULL is returned instead. Call 
+ * aiGetErrorString() to retrieve a human-readable error text.
+ * @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.
+ * @param pFlags Optional post processing steps to be executed after 
+ *   a successful import. Provide a bitwise combination of the
+ *   #aiPostProcessSteps flags.
+ * @param pFS aiFileIO structure. Will be used to open the model file itself
+ *   and any other files the loader needs to open.
+ * @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( 
 	const char* pFile,
-    unsigned int pFlags,
+	unsigned int pFlags,
 	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);
 
-// ---------------------------------------------------------------------------
-/** Releases all resources associated with the given import process.
-*
-* Call this function after you're done with the imported data.
-* @param pScene The imported data to release. NULL is a valid value.
-*/
-// ---------------------------------------------------------------------------
-ASSIMP_API void aiReleaseImport( const C_STRUCT aiScene* pScene);
+// --------------------------------------------------------------------------------
+/** 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.
+ *
+ * Call this function after you're done with the imported data.
+ * @param pScene The imported data to release. NULL is a valid value.
+ */
+ASSIMP_API void aiReleaseImport( 
+	const C_STRUCT aiScene* pScene);
 
-// ---------------------------------------------------------------------------
+// --------------------------------------------------------------------------------
 /** Returns the error text of the last failed import process. 
-*
-* @return A textual description of the error that occurred at the last
-* import process. NULL if there was no error.
-*/
-// ---------------------------------------------------------------------------
+ *
+ * @return A textual description of the error that occurred at the last
+ * 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();
 
-
-// ---------------------------------------------------------------------------
+// --------------------------------------------------------------------------------
 /** Returns whether a given file extension is supported by ASSIMP
-*
-* @param szExtension Extension for which the function queries support.
-* Must include a leading dot '.'. Example: ".3ds", ".md3"
-* @return 1 if the extension is supported, 0 otherwise
-*/
-// ---------------------------------------------------------------------------
-ASSIMP_API int aiIsExtensionSupported(const char* szExtension);
-
+ *
+ * @param szExtension Extension for which the function queries support for.
+ * Must include a leading dot '.'. Example: ".3ds", ".md3"
+ * @return AI_TRUE if the file extension is supported.
+ */
+ASSIMP_API aiBool aiIsExtensionSupported(
+	const char* szExtension);
 
-// ---------------------------------------------------------------------------
-/** Get a full list of all file extensions generally supported by ASSIMP.
+// --------------------------------------------------------------------------------
+/** Get a list of all file extensions supported by ASSIMP.
  *
  * 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.
  * @param szOut String to receive the extension list.
  * Format of the list: "*.3ds;*.obj;*.dae". NULL is not a valid parameter.
-*/
-// ---------------------------------------------------------------------------
-ASSIMP_API void aiGetExtensionList(C_STRUCT aiString* szOut);
-
+ */
+ASSIMP_API void aiGetExtensionList(
+	C_STRUCT aiString* szOut);
 
-// ---------------------------------------------------------------------------
+// --------------------------------------------------------------------------------
 /** Get the storage required by an imported asset
  * @param pIn Input asset.
  * @param in Data structure to be filled. 
  */
-// ---------------------------------------------------------------------------
-ASSIMP_API void aiGetMemoryRequirements(const C_STRUCT aiScene* pIn,
+ASSIMP_API void aiGetMemoryRequirements(
+	const C_STRUCT aiScene* pIn,
 	C_STRUCT aiMemoryInfo* in);
 
-
-// ---------------------------------------------------------------------------
-/** 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.
+// --------------------------------------------------------------------------------
+/** Set an integer property. 
+ *
+ *  This is the C-version of #Assimp::Importer::SetPropertyInteger(). 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 constants
- *   are defined in the aiConfig.h header file.
+ * @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 aiSetImportPropertyInteger(const char* szName, int value);
+ASSIMP_API void aiSetImportPropertyInteger(
+	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);
 
-// ---------------------------------------------------------------------------
-/** @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);
-
-// ---------------------------------------------------------------------------
-/** @see aiMatrix4x4::Decompose (aiVector3D&, aiQuaternion&, aiVector3D&) const;
+ASSIMP_API void aiCreateQuaternionFromMatrix(
+	C_STRUCT aiQuaternion* quat,
+	const C_STRUCT aiMatrix3x3* mat);
+
+// --------------------------------------------------------------------------------
+/** 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 aiQuaternion* rotation,
 	C_STRUCT aiVector3D* position);

+ 1 - 1
include/assimp.hpp

@@ -336,7 +336,7 @@ public:
 	 *   #aiPostProcessSteps flags.
 	 *  @return A pointer to the post-processed data. This is still the
 	 *   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
 	 *   designed to 'fail'. To be exact, the #aiProcess_ValidateDS
 	 *   flag is currently the only post processing step which can actually

+ 1 - 1
mkutil/revision.h

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

+ 0 - 2
test/RunSingleUnitTestSuite.bat

@@ -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
 rem ------------------------------------------------------------------------------
-
-rem Check whether the 
 IF NOT EXIST %BINDIR%\%1\unit.exe (
 
    echo NOT AVAILABLE. Please rebuild this configuration

+ 1 - 1
test/RunUnitTestSuite.bat

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

+ 20 - 5
test/unit/Main.cpp

@@ -18,9 +18,19 @@ int main (int argc, char* argv[])
 	time_t t;time(&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
     CPPUNIT_NS :: TestResult testresult;
@@ -49,8 +59,13 @@ int main (int argc, char* argv[])
     xml.write ();
 #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
     return collectedresults.wasSuccessful () ? 0 : 1;

+ 1 - 0
test/unit/UnitTestPCH.h

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

+ 1 - 0
test/unit/utRemoveComponent.cpp

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

+ 2 - 2
test/unit/utTriangulate.cpp

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

+ 2 - 2
tools/assimp_cmd/Main.cpp

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

+ 136 - 124
workspaces/vc8/assimp.vcproj

@@ -1132,130 +1132,6 @@
 		<Filter
 			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
 				Name="Compiler"
 				>
@@ -1324,6 +1200,142 @@
 					</File>
 				</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
 			Name="sources"

+ 136 - 124
workspaces/vc9/assimp.vcproj

@@ -1104,130 +1104,6 @@
 		<Filter
 			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
 				Name="Compiler"
 				>
@@ -1296,6 +1172,142 @@
 					</File>
 				</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
 			Name="sources"