Major API cleanup. Unified formatting & doxygen tags in the public API.

Added factory provider for default log streams.
Added default log streams to std::out and std::cerr.
Updated VC8 project config, boost workarounds is now working for the viewer.
Updated unit test suite.
Fixed some minor issues in the postprocessing-framework.

BROKEN: DebugDLL build.




git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@292 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
This commit is contained in:
aramis_acg
2009-01-12 22:06:54 +00:00
parent bba8dee77d
commit 58eb786d62
102 changed files with 5278 additions and 1657 deletions

View File

@@ -264,7 +264,7 @@ void Discreet3DSImporter::ParseEditorChunk()
{
// print the version number
char buff[10];
itoa10(buff,stream->GetI2());
ASSIMP_itoa10(buff,stream->GetI2());
DefaultLogger::get()->info(std::string("3DS file format version: ") + buff);
}
break;

View File

@@ -734,7 +734,7 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
// print the file format version to the console
unsigned int version = HexDigitToDecimal( buffer[4] );
char msg[3];
itoa10(msg,3,version);
ASSIMP_itoa10(msg,3,version);
DefaultLogger::get()->info(std::string("AC3D file format version: ") + msg);
std::vector<Material> materials;

View File

@@ -50,7 +50,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "GenericProperty.h"
#if (defined AI_C_THREADSAFE)
# include <boost/thread/thread.hpp>
# include <boost/thread/mutex.hpp>
@@ -92,7 +91,7 @@ public:
{}
// -------------------------------------------------------------------
size_t Read(void* pvBuffer,
size_t Read(void* pvBuffer,
size_t pSize,
size_t pCount)
{
@@ -100,16 +99,14 @@ public:
return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount);
}
// -------------------------------------------------------------------
size_t Write(const void* pvBuffer,
size_t Write(const void* pvBuffer,
size_t pSize,
size_t pCount)
{
// need to typecast here as C has no void*
return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount);
}
{
// need to typecast here as C has no void*
return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount);
}
// -------------------------------------------------------------------
aiReturn Seek(size_t pOffset,
@@ -118,20 +115,24 @@ public:
return mFile->SeekProc(mFile,pOffset,pOrigin);
}
// -------------------------------------------------------------------
size_t Tell(void) const
size_t Tell(void) const
{
return mFile->TellProc(mFile);
}
// -------------------------------------------------------------------
size_t FileSize() const
{
return mFile->FileSizeProc(mFile);
}
// -------------------------------------------------------------------
void Flush ()
{
return mFile->FlushProc(mFile);
}
private:
aiFile* mFile;
};
@@ -152,13 +153,17 @@ public:
{
CIOSystemWrapper* pip = const_cast<CIOSystemWrapper*>(this);
IOStream* p = pip->Open(pFile);
if (p){pip->Close(p);return true;}
if (p){
pip->Close(p);
return true;
}
return false;
}
// -------------------------------------------------------------------
std::string getOsSeparator() const
{
// FIXME
return "/";
}
@@ -179,6 +184,7 @@ public:
delete pFile;
}
private:
aiFileIO* mFileSystem;

View File

@@ -44,17 +44,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define ASSIMP_INTERNAL_BUILD
// *******************************************************************
// If we have at least VC8 some C string manipulation functions
// are mapped to their safe _s counterparts (e.g. _itoa_s).
// *******************************************************************
#if _MSC_VER >= 1400 && !(defined _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES)
# define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
#endif
// Compile config
#include "../include/aiDefines.h"
// *******************************************************************
// STL headers - we need quite a lot of them
// *******************************************************************
// ===================================================================
// Runtime/STL headers
// ===================================================================
#include <vector>
#include <list>
#include <map>
@@ -67,10 +62,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <iostream>
#include <algorithm>
#include <numeric>
#include <new>
// *******************************************************************
// public ASSIMP headers
// *******************************************************************
// ===================================================================
// Public ASSIMP headers
// ===================================================================
#include "../include/DefaultLogger.h"
#include "../include/IOStream.h"
#include "../include/IOSystem.h"
@@ -78,18 +74,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../include/aiPostProcess.h"
#include "../include/assimp.hpp"
// *******************************************************************
// internal headers that are nearly always required
// *******************************************************************
// ===================================================================
// Internal utility headers
// ===================================================================
#include "BaseImporter.h"
#include "MaterialSystem.h"
#include "StringComparison.h"
#include "StreamReader.h"
#include "qnan.h"
// *******************************************************************
// ===================================================================
// boost headers - take them from the workaround dir if possible
// *******************************************************************
// ===================================================================
#ifdef ASSIMP_BUILD_BOOST_WORKAROUND
# include "../include/BoostWorkaround/boost/scoped_ptr.hpp"
@@ -104,8 +100,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# include <boost/format.hpp>
# include <boost/foreach.hpp>
#endif
#endif // ! ASSIMP_BUILD_BOOST_WORKAROUND
#endif // !! ASSIMP_PCH_INCLUDED

View File

@@ -169,7 +169,7 @@ struct LoadRequest
// ------------------------------------------------------------------------------------------------
// BatchLoader::pimpl data structure
struct BatchData
struct Assimp::BatchData
{
// IO system to be used for all imports
IOSystem* pIOSystem;
@@ -189,8 +189,7 @@ BatchLoader::BatchLoader(IOSystem* pIO)
{
ai_assert(NULL != pIO);
pimpl = new BatchData();
BatchData* data = ( BatchData* )pimpl;
data = new BatchData();
data->pIOSystem = pIO;
data->pImporter = new Importer();
}
@@ -199,7 +198,6 @@ BatchLoader::BatchLoader(IOSystem* pIO)
BatchLoader::~BatchLoader()
{
// delete all scenes wthat have not been polled by the user
BatchData* data = ( BatchData* )pimpl;
for (std::list<LoadRequest>::iterator it = data->requests.begin();
it != data->requests.end(); ++it)
{
@@ -212,7 +210,6 @@ BatchLoader::~BatchLoader()
// ------------------------------------------------------------------------------------------------
void BatchLoader::SetBasePath (const std::string& pBase)
{
BatchData* data = ( BatchData* )pimpl;
data->pathBase = pBase;
// file name? we just need the directory
@@ -241,8 +238,6 @@ void BatchLoader::AddLoadRequest (const std::string& file,
ai_assert(!file.empty());
// no threaded implementation for the moment
BatchData* data = ( BatchData* )pimpl;
std::string real;
// build a full path if this is a relative path and
@@ -273,7 +268,6 @@ void BatchLoader::AddLoadRequest (const std::string& file,
aiScene* BatchLoader::GetImport (const std::string& file)
{
// no threaded implementation for the moment
BatchData* data = ( BatchData* )pimpl;
std::string real;
// build a full path if this is a relative path and
@@ -302,8 +296,6 @@ aiScene* BatchLoader::GetImport (const std::string& file)
// ------------------------------------------------------------------------------------------------
void BatchLoader::LoadAll()
{
BatchData* data = ( BatchData* )pimpl;
// no threaded implementation for the moment
for (std::list<LoadRequest>::iterator it = data->requests.begin();
it != data->requests.end(); ++it)

View File

@@ -39,8 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file Definition of the base class for all importer worker classes. */
#ifndef AI_BASEIMPORTER_H_INC
#define AI_BASEIMPORTER_H_INC
#ifndef INCLUDED_AI_BASEIMPORTER_H
#define INCLUDED_AI_BASEIMPORTER_H
#include <string>
#include "./../include/aiTypes.h"
@@ -203,7 +203,7 @@ protected:
*
* The function searches the header of a file for a specific token
* and returns true if this token is found. This works for text
* files only. There is a rudimentary handling if UNICODE files.
* files only. There is a rudimentary handling of UNICODE files.
* The comparison is case independent.
*
* @param pIOSystem IO System to work with
@@ -239,6 +239,8 @@ protected:
std::string mErrorText;
};
struct BatchData;
// ---------------------------------------------------------------------------
/** A helper class that can be used by importers which need to load many
* extern meshes recursively.
@@ -316,7 +318,7 @@ public:
private:
// No need to have that in the public API ...
void* pimpl;
BatchData* data;
};

View File

@@ -39,8 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file Base class of all import post processing steps */
#ifndef AI_BASEPROCESS_H_INC
#define AI_BASEPROCESS_H_INC
#ifndef INCLUDED_AI_BASEPROCESS_H
#define INCLUDED_AI_BASEPROCESS_H
#include <map>
@@ -155,20 +155,17 @@ public:
return true;
}
inline void RemoveProperty( const char* name)
{
inline void RemoveProperty( const char* name) {
SetGenericPropertyPtr<Base>(pmap,name,NULL);
}
private:
inline void AddProperty( const char* name, Base* data)
{
inline void AddProperty( const char* name, Base* data) {
SetGenericPropertyPtr<Base>(pmap,name,data);
}
inline void GetProperty( const char* name, Base*& data) const
{
inline void GetProperty( const char* name, Base*& data) const {
data = GetGenericProperty<Base*>(pmap,name,NULL);
}
@@ -239,16 +236,14 @@ public:
* allows multiple postprocess steps to share data.
* @param sh May be NULL
*/
inline void SetSharedData(SharedPostProcessInfo* sh)
{
inline void SetSharedData(SharedPostProcessInfo* sh) {
shared = sh;
}
// -------------------------------------------------------------------
/** Get the shared data that is assigned to the step.
*/
inline SharedPostProcessInfo* GetSharedData()
{
inline SharedPostProcessInfo* GetSharedData() {
return shared;
}

View File

@@ -43,70 +43,71 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AssimpPCH.h"
#include "DefaultIOStream.h"
#include "../include/aiAssert.h"
#include <sys/types.h>
#include <sys/stat.h>
using namespace Assimp;
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
DefaultIOStream::~DefaultIOStream()
{
if (this->mFile)
{
::fclose(this->mFile);
}
if (mFile)
::fclose(mFile);
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
size_t DefaultIOStream::Read(void* pvBuffer,
size_t pSize,
size_t pCount)
size_t pSize,
size_t pCount)
{
ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount);
if (!this->mFile)
return 0;
return ::fread(pvBuffer, pSize, pCount, this->mFile);
return (mFile ? ::fread(pvBuffer, pSize, pCount, mFile) : 0);
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
size_t DefaultIOStream::Write(const void* pvBuffer,
size_t pSize,
size_t pCount)
size_t pSize,
size_t pCount)
{
ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount);
if (!this->mFile)return 0;
::fseek(mFile, 0, SEEK_SET);
return ::fwrite(pvBuffer, pSize, pCount, this->mFile);
return (mFile ? ::fwrite(pvBuffer, pSize, pCount, mFile) : 0);
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
aiReturn DefaultIOStream::Seek(size_t pOffset,
aiOrigin pOrigin)
aiOrigin pOrigin)
{
if (!this->mFile)return AI_FAILURE;
if (!mFile)return AI_FAILURE;
return (0 == ::fseek(this->mFile, (long)pOffset,
(aiOrigin_CUR == pOrigin ? SEEK_CUR :
(aiOrigin_END == pOrigin ? SEEK_END : SEEK_SET)))
? AI_SUCCESS : AI_FAILURE);
// Just to check whether our enum maps one to one with the CRT constants
ai_assert(aiOrigin_CUR == SEEK_CUR && aiOrigin_END == SEEK_END
&& aiOrigin_SET == SEEK_SET);
// do the seek
return (0 == ::fseek(mFile, (long)pOffset,(int)pOrigin) ? AI_SUCCESS : AI_FAILURE);
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
size_t DefaultIOStream::Tell() const
{
if (!this->mFile)return 0;
return ::ftell(this->mFile);
if (!mFile)return 0;
return ::ftell(mFile);
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
size_t DefaultIOStream::FileSize() const
{
ai_assert (!mFilename.empty());
if (NULL == mFile)
if (! mFile)
return 0;
// TODO: Is that really faster if we have already opened the file?
#if defined _WIN32 && !defined __GNUC__
struct __stat64 fileStat;
int err = _stat64( mFilename.c_str(), &fileStat );
@@ -121,4 +122,12 @@ size_t DefaultIOStream::FileSize() const
return (size_t) (fileStat.st_size);
#endif
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
void DefaultIOStream::Flush()
{
if (mFile)
::fflush(mFile);
}
// ----------------------------------------------------------------------------------

View File

@@ -42,17 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_DEFAULTIOSTREAM_H_INC
#define AI_DEFAULTIOSTREAM_H_INC
#include <string>
#include <stdio.h>
#include "../include/IOStream.h"
namespace Assimp
{
namespace Assimp {
// ---------------------------------------------------------------------------
//! \class DefaultIOStream
//! \brief Default IO implementation, use standard IO operations
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
//! @class DefaultIOStream
//! @brief Default IO implementation, use standard IO operations
class DefaultIOStream : public IOStream
{
friend class DefaultIOSystem;
@@ -66,39 +63,39 @@ public:
~DefaultIOStream ();
// -------------------------------------------------------------------
// -------------------------------------------------------------------
size_t Read(void* pvBuffer,
size_t pSize,
size_t pCount);
// -------------------------------------------------------------------
// -------------------------------------------------------------------
size_t Write(const void* pvBuffer,
size_t pSize,
size_t pCount);
// -------------------------------------------------------------------
// -------------------------------------------------------------------
aiReturn Seek(size_t pOffset,
aiOrigin pOrigin);
// -------------------------------------------------------------------
// -------------------------------------------------------------------
size_t Tell() const;
//! Returns filesize
// -------------------------------------------------------------------
size_t FileSize() const;
// -------------------------------------------------------------------
void Flush();
private:
//! File datastructure, using clib
FILE* mFile;
//! Filename
std::string mFilename;
};
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
inline DefaultIOStream::DefaultIOStream () :
mFile(NULL),
mFilename("")
@@ -106,7 +103,8 @@ inline DefaultIOStream::DefaultIOStream () :
// empty
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
inline DefaultIOStream::DefaultIOStream (FILE* pFile,
const std::string &strFilename) :
mFile(pFile),
@@ -114,8 +112,7 @@ inline DefaultIOStream::DefaultIOStream (FILE* pFile,
{
// empty
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
} // ns assimp

View File

@@ -40,18 +40,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "AssimpPCH.h"
#include "DefaultIOSystem.h"
// Default log streams
#include "Win32DebugLogStream.h"
#include "StdOStreamLogStream.h"
#include "FileLogStream.h"
namespace Assimp
{
// ---------------------------------------------------------------------------
namespace Assimp {
// ----------------------------------------------------------------------------------
NullLogger DefaultLogger::s_pNullLogger;
Logger *DefaultLogger::m_pLogger = &DefaultLogger::s_pNullLogger;
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
//
struct LogStreamInfo
{
@@ -72,17 +74,73 @@ struct LogStreamInfo
// empty
}
};
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
// Construct a default log stream
LogStream* LogStream::createDefaultStream(DefaultLogStreams streams,
const std::string& name /*= "AssimpLog.txt"*/,
IOSystem* io /*= NULL*/)
{
switch (streams)
{
// This is a platform-specific feature
case DLS_DEBUGGER:
#ifdef WIN32
return new Win32DebugLogStream();
#else
return NULL;
#endif
// Platform-independent default streams
case DLS_CERR:
return new StdOStreamLogStream(std::cerr);
case DLS_COUT:
return new StdOStreamLogStream(std::cout);
case DLS_FILE:
return (name.size() ? new FileLogStream(name,io) : NULL);
default:
// We don't know this default log stream, so raise an assertion
ai_assert(false);
};
// For compilers without dead code path detection
return NULL;
}
// ----------------------------------------------------------------------------------
// Creates the only singleton instance
Logger *DefaultLogger::create(const std::string &name, LogSeverity severity)
Logger *DefaultLogger::create(const std::string &name /*= "AssimpLog.txt"*/,
LogSeverity severity /*= NORMAL*/,
unsigned int defStreams /*= DLS_DEBUGGER | DLS_FILE*/,
IOSystem* io /*= NULL*/)
{
if (m_pLogger && !isNullLogger() )
delete m_pLogger;
m_pLogger = new DefaultLogger( name, severity );
m_pLogger = new DefaultLogger( severity );
// Attach default log streams
// Stream the log to the MSVC debugger?
if (defStreams & DLS_DEBUGGER)
m_pLogger->attachStream( LogStream::createDefaultStream(DLS_DEBUGGER));
// Stream the log to COUT?
if (defStreams & DLS_COUT)
m_pLogger->attachStream( LogStream::createDefaultStream(DLS_COUT));
// Stream the log to CERR?
if (defStreams & DLS_CERR)
m_pLogger->attachStream( LogStream::createDefaultStream(DLS_CERR));
// Stream the log to a file
if (defStreams & DLS_FILE && !name.empty())
m_pLogger->attachStream( LogStream::createDefaultStream(DLS_FILE,name,io));
return m_pLogger;
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
void DefaultLogger::set( Logger *logger )
{
if (!logger)logger = &s_pNullLogger;
@@ -91,19 +149,21 @@ void DefaultLogger::set( Logger *logger )
DefaultLogger::m_pLogger = logger;
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
bool DefaultLogger::isNullLogger()
{
return m_pLogger == &s_pNullLogger;
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
// Singleton getter
Logger *DefaultLogger::get()
{
return m_pLogger;
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
// Kills the only instance
void DefaultLogger::kill()
{
@@ -112,7 +172,7 @@ void DefaultLogger::kill()
m_pLogger = &s_pNullLogger;
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
// Debug message
void DefaultLogger::debug( const std::string &message )
{
@@ -123,7 +183,7 @@ void DefaultLogger::debug( const std::string &message )
writeToStreams( msg, Logger::DEBUGGING );
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
// Logs an info
void DefaultLogger::info( const std::string &message )
{
@@ -131,7 +191,7 @@ void DefaultLogger::info( const std::string &message )
writeToStreams( msg , Logger::INFO );
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
// Logs a warning
void DefaultLogger::warn( const std::string &message )
{
@@ -139,7 +199,7 @@ void DefaultLogger::warn( const std::string &message )
writeToStreams( msg, Logger::WARN );
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
// Logs an error
void DefaultLogger::error( const std::string &message )
{
@@ -147,18 +207,19 @@ void DefaultLogger::error( const std::string &message )
writeToStreams( msg, Logger::ERR );
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
// Severity setter
void DefaultLogger::setLogSeverity( LogSeverity log_severity )
{
m_Severity = log_severity;
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
// Attachs a new stream
void DefaultLogger::attachStream( LogStream *pStream, unsigned int severity )
{
ai_assert ( NULL != pStream );
if (!pStream)
return;
// fix (Aramis)
if (0 == severity)
@@ -181,11 +242,12 @@ void DefaultLogger::attachStream( LogStream *pStream, unsigned int severity )
m_StreamArray.push_back( pInfo );
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
// Detatch a stream
void DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
{
ai_assert ( NULL != pStream );
if (!pStream)
return;
// fix (Aramis)
if (0 == severity)
@@ -199,79 +261,49 @@ void DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
{
if ( (*it)->m_pStream == pStream )
{
unsigned int uiSev = (*it)->m_uiErrorSeverity;
if ( severity & Logger::INFO )
uiSev &= ( ~Logger::INFO );
if ( severity & Logger::WARN )
uiSev &= ( ~Logger::WARN );
if ( severity & Logger::ERR )
uiSev &= ( ~Logger::ERR );
// fix (Aramis)
if ( severity & Logger::DEBUGGING )
uiSev &= ( ~Logger::DEBUGGING );
(*it)->m_uiErrorSeverity = uiSev;
(*it)->m_uiErrorSeverity &= ~severity;
if ( (*it)->m_uiErrorSeverity == 0 )
{
it = m_StreamArray.erase( it );
m_StreamArray.erase( it );
break;
}
}
}
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
// Constructor
DefaultLogger::DefaultLogger( const std::string &name, LogSeverity severity ) :
m_Severity( severity )
{
#ifdef WIN32
m_Streams.push_back( new Win32DebugLogStream() );
#endif
if (name.empty())
return;
m_Streams.push_back( new FileLogStream( name ) );
DefaultLogger::DefaultLogger(LogSeverity severity)
noRepeatMsg = false;
}
: m_Severity ( severity )
, noRepeatMsg (false)
{}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
// Destructor
DefaultLogger::~DefaultLogger()
{
for ( StreamIt it = m_StreamArray.begin();
it != m_StreamArray.end();
++it )
{
for ( StreamIt it = m_StreamArray.begin(); it != m_StreamArray.end(); ++it )
delete *it;
}
for (std::vector<LogStream*>::iterator it = m_Streams.begin();
it != m_Streams.end();
++it)
{
delete *it;
}
m_Streams.clear();
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
// Writes message to stream
void DefaultLogger::writeToStreams(const std::string &message,
ErrorSeverity ErrorSev )
ErrorSeverity ErrorSev )
{
if ( message.empty() )
return;
std::string s;
// Check whether this is a repeated message
if (message == lastMsg)
{
if (!noRepeatMsg)
{
noRepeatMsg = true;
s = "Skipping one or more lines with the same contents";
s = "Skipping one or more lines with the same contents\n";
}
else return;
}
@@ -279,32 +311,25 @@ void DefaultLogger::writeToStreams(const std::string &message,
{
lastMsg = s = message;
noRepeatMsg = false;
}
s.append("\n");
}
for ( ConstStreamIt it = m_StreamArray.begin();
it != m_StreamArray.end();
++it)
{
if ( ErrorSev & (*it)->m_uiErrorSeverity )
{
(*it)->m_pStream->write( s);
}
}
for (std::vector<LogStream*>::iterator it = m_Streams.begin();
it != m_Streams.end();
++it)
{
(*it)->write( s + std::string("\n"));
}
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
// Returns thread id, if not supported only a zero will be returned.
std::string DefaultLogger::getThreadID()
{
std::string thread_id( "0" );
#ifdef WIN32
HANDLE hThread = GetCurrentThread();
HANDLE hThread = ::GetCurrentThread();
if ( hThread )
{
std::stringstream thread_msg;
@@ -318,6 +343,6 @@ std::string DefaultLogger::getThreadID()
#endif
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
} // Namespace Assimp
} // !namespace Assimp

View File

@@ -4,10 +4,10 @@
#include "../include/LogStream.h"
#include "../include/IOStream.h"
namespace Assimp
{
namespace Assimp {
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
/** @class FileLogStream
* @brief Logstream to write into a file.
*/
@@ -15,52 +15,57 @@ class FileLogStream :
public LogStream
{
public:
FileLogStream( const std::string &strFileName );
FileLogStream( const std::string &strFileName, IOSystem* io = NULL );
~FileLogStream();
void write( const std::string &message );
private:
IOStream *m_pStream;
};
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
// Constructor
inline FileLogStream::FileLogStream( const std::string &strFileName ) :
inline FileLogStream::FileLogStream( const std::string &strFileName, IOSystem* io ) :
m_pStream(NULL)
{
if ( strFileName.empty() )
return;
DefaultIOSystem FileSystem;
const std::string mode = "w";
m_pStream = FileSystem.Open( strFileName, mode );
const static std::string mode = "wt";
// If no IOSystem is specified: take a default one
if (!io)
{
DefaultIOSystem FileSystem;
m_pStream = FileSystem.Open( strFileName, mode );
}
else m_pStream = io->Open( strFileName, mode );
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
// Destructor
inline FileLogStream::~FileLogStream()
{
if (NULL != m_pStream)
{
DefaultIOSystem FileSystem;
FileSystem.Close( m_pStream );
}
// The virtual d'tor should destroy the underlying file
delete m_pStream;
}
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
// Write method
inline void FileLogStream::write( const std::string &message )
{
if (m_pStream != NULL)
{
m_pStream->Write(message.c_str(), sizeof(char),
message.size());
/*int i=0;
i++;*/
m_pStream->Write(message.c_str(), sizeof(char), message.size());
m_pStream->Flush();
}
}
// ---------------------------------------------------------------------------
} // Namespace Assimp
// ----------------------------------------------------------------------------------
#endif
} // !Namespace Assimp
#endif // !! ASSIMP_FILELOGSTREAM_H_INC

View File

@@ -145,7 +145,7 @@ void FindDegeneratesProcess::Execute( aiScene* pScene)
if (deg && !DefaultLogger::isNullLogger())
{
char s[64];
itoa10(s,deg);
ASSIMP_itoa10(s,deg);
DefaultLogger::get()->warn(std::string("Found ") + s + " degenerated primitives");
}
}

View File

@@ -171,9 +171,11 @@ inline const char* ValidateArrayContents<aiVector3D>(const aiVector3D* arr, unsi
const std::vector<bool>& dirtyMask, bool mayBeIdentical , bool mayBeZero )
{
bool b = false;
unsigned int cnt = 0;
for (unsigned int i = 0; i < size;++i)
{
if (dirtyMask.size() && dirtyMask[i])continue;
++cnt;
const aiVector3D& v = arr[i];
if (is_special_float(v.x) || is_special_float(v.y) || is_special_float(v.z))
@@ -186,7 +188,7 @@ inline const char* ValidateArrayContents<aiVector3D>(const aiVector3D* arr, unsi
}
if (i && v != arr[i-1])b = true;
}
if (!b && !mayBeIdentical)
if (cnt > 1 && !b && !mayBeIdentical)
return "All vectors are identical";
return NULL;
}
@@ -284,7 +286,7 @@ void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim)
int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh)
{
bool ret = false;
std::vector<bool> dirtyMask(pMesh->mNumVertices,true);
std::vector<bool> dirtyMask(pMesh->mNumVertices,(pMesh->mNumFaces ? true : false));
// Ignore elements that are not referenced by vertices.
// (they are, for example, caused by the FindDegenerates step)
@@ -295,7 +297,7 @@ int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh)
dirtyMask[f.mIndices[i]] = false;
}
// process vertex positions
// Process vertex positions
if(pMesh->mVertices && ProcessArray(pMesh->mVertices,pMesh->mNumVertices,"positions",dirtyMask))
{
DefaultLogger::get()->error("Deleting mesh: Unable to continue without vertex positions");
@@ -333,11 +335,13 @@ int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh)
for (unsigned int m = 0; m < pMesh->mNumFaces;++m)
{
const aiFace& f = pMesh->mFaces[m];
if (2 == f.mNumIndices)
if (f.mNumIndices < 3)
{
dirtyMask[f.mIndices[0]] = dirtyMask[f.mIndices[1]] = true;
dirtyMask[f.mIndices[0]] = true;
if (f.mNumIndices == 2)
dirtyMask[f.mIndices[1]] = true;
}
else if (1 == f.mNumIndices)dirtyMask[f.mIndices[0]] = true;
}
}
// Normals, tangents and bitangents are undefined for
@@ -354,7 +358,7 @@ int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh)
if (pMesh->mTangents && ProcessArray(pMesh->mTangents,pMesh->mNumVertices,
"tangents",dirtyMask))
{
delete[] pMesh->mTangents; pMesh->mTangents = NULL;
delete[] pMesh->mBitangents; pMesh->mBitangents = NULL;
ret = true;
}
@@ -362,7 +366,7 @@ int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh)
if (pMesh->mBitangents && ProcessArray(pMesh->mBitangents,pMesh->mNumVertices,
"bitangents",dirtyMask))
{
delete[] pMesh->mBitangents; pMesh->mBitangents = NULL;
delete[] pMesh->mTangents; pMesh->mTangents = NULL;
ret = true;
}
}

View File

@@ -123,11 +123,11 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int
return false;
}
// allocate an array to hold the output normals
// Allocate the array to hold the output normals
const float qnan = std::numeric_limits<float>::quiet_NaN();
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
// compute per-face normals but store them per-vertex
// Compute per-face normals but store them per-vertex
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
{
const aiFace& face = pMesh->mFaces[a];
@@ -148,7 +148,7 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int
pMesh->mNormals[face.mIndices[i]] = vNor;
}
// set up a SpatialSort to quickly find all vertices close to a given position
// Set up a SpatialSort to quickly find all vertices close to a given position
// check whether we can reuse the SpatialSort of a previous step.
SpatialSort* vertexFinder = NULL;
SpatialSort _vertexFinder;
@@ -176,16 +176,15 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int
if (configMaxAngle >= AI_DEG_TO_RAD( 175.f ))
{
// there is no angle limit. Thus all vertices with positions close
// There is no angle limit. Thus all vertices with positions close
// to each other will receive the same vertex normal. This allows us
// to optimize the whole algorithm a little bit ...
std::vector<bool> abHad(pMesh->mNumVertices,false);
for (unsigned int i = 0; i < pMesh->mNumVertices;++i)
{
if (abHad[i])continue;
// get all vertices that share this one ...
// Get all vertices that share this one ...
vertexFinder->FindPositions( pMesh->mVertices[i], posEpsilon, verticesFound);
aiVector3D pcNor;
@@ -194,10 +193,9 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int
const aiVector3D& v = pMesh->mNormals[verticesFound[a]];
if (is_not_qnan(v.x))pcNor += v;
}
pcNor.Normalize();
// write the smoothed normal back to all affected normals
// Write the smoothed normal back to all affected normals
for (unsigned int a = 0; a < verticesFound.size(); ++a)
{
register unsigned int vidx = verticesFound[a];
@@ -211,7 +209,7 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int
const float fLimit = ::cos(configMaxAngle);
for (unsigned int i = 0; i < pMesh->mNumVertices;++i)
{
// get all vertices that share this one ...
// Get all vertices that share this one ...
vertexFinder->FindPositions( pMesh->mVertices[i] , posEpsilon, verticesFound);
aiVector3D pcNor;
@@ -222,7 +220,7 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int
// check whether the angle between the two normals is not too large
// HACK: if v.x is qnan the dot product will become qnan, too
// therefore the comparison against fLimit should be false
// in every case. Contact me if you disagree with this assumption
// in every case.
if (v * pMesh->mNormals[i] < fLimit)
continue;

View File

@@ -43,8 +43,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AssimpPCH.h"
// internal headers
// =======================================================================================
// Internal headers
// =======================================================================================
#include "BaseImporter.h"
#include "BaseProcess.h"
#include "DefaultIOStream.h"
@@ -53,7 +54,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ProcessHelper.h"
#include "ScenePreprocessor.h"
// =======================================================================================
// Importers
// =======================================================================================
#ifndef AI_BUILD_NO_X_IMPORTER
# include "XFileImporter.h"
#endif
@@ -133,7 +136,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# include "TerragenLoader.h"
#endif
// =======================================================================================
// PostProcess-Steps
// =======================================================================================
#ifndef AI_BUILD_NO_CALCTANGENTS_PROCESS
# include "CalcTangentsProcess.h"
#endif
@@ -196,22 +201,50 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
using namespace Assimp;
using namespace Assimp::Intern;
// =======================================================================================
// Intern::AllocateFromAssimpHeap serves as abstract base class. It overrides
// new and delete (and their array counterparts) of public API classes (e.g. Logger) to
// utilize our DLL heap
// =======================================================================================
void* AllocateFromAssimpHeap::operator new ( size_t num_bytes)
{
return ::operator new(num_bytes);
}
void AllocateFromAssimpHeap::operator delete ( void* data)
{
return ::operator delete(data);
}
void* AllocateFromAssimpHeap::operator new[] ( size_t num_bytes)
{
return ::operator new[](num_bytes);
}
void AllocateFromAssimpHeap::operator delete[] ( void* data)
{
return ::operator delete[](data);
}
// ------------------------------------------------------------------------------------------------
// Constructor.
Importer::Importer() :
mIOHandler(NULL),
mScene(NULL),
mErrorString("")
// Importer Constructor.
Importer::Importer()
: mIOHandler (NULL)
, mScene (NULL)
, mErrorString ("")
{
// Allocate a default IO handler
mIOHandler = new DefaultIOSystem;
mIsDefaultHandler = true;
bExtraVerbose = false; // disable extra verbose mode by default
// ======================================================================
// Add an instance of each worker class here
// the order doesn't really care, however file formats that are
// The order doesn't really care, however file formats that are
// used more frequently than others should be at the beginning.
// ======================================================================
mImporter.reserve(25);
#if (!defined AI_BUILD_NO_X_IMPORTER)
@@ -293,9 +326,11 @@ Importer::Importer() :
mImporter.push_back( new TerragenImporter());
#endif
// ======================================================================
// Add an instance of each post processing step here in the order
// of sequence it is executed. steps that are added here are not validated -
// as RegisterPPStep() does - all dependencies must be there.
// of sequence it is executed. Steps that are added here are not
// validated - as RegisterPPStep() does - all dependencies must be there.
// ======================================================================
mPostProcessingSteps.reserve(25);
#if (!defined AI_BUILD_NO_VALIDATEDS_PROCESS)
@@ -386,9 +421,7 @@ Importer::Importer() :
#endif
// allocate a SharedPostProcessInfo object and store pointers to it
// Allocate a SharedPostProcessInfo object and store pointers to it
// in all post-process steps in the list.
mPPShared = new SharedPostProcessInfo();
for (std::vector<BaseProcess*>::iterator it = mPostProcessingSteps.begin(),
@@ -402,37 +435,47 @@ Importer::Importer() :
// Destructor.
Importer::~Importer()
{
// Delete all import plugins
for( unsigned int a = 0; a < mImporter.size(); a++)
delete mImporter[a];
// Delete all post-processing plug-ins
for( unsigned int a = 0; a < mPostProcessingSteps.size(); a++)
delete mPostProcessingSteps[a];
// delete the assigned IO handler
// Delete the assigned IO handler
delete mIOHandler;
// kill imported scene. Destructors should do that recursivly
// Kill imported scene. Destructors should do that recursivly
delete mScene;
// delete shared post-processing data
// Delete shared post-processing data
delete mPPShared;
}
// ------------------------------------------------------------------------------------------------
// Empty and private copy constructor
// Copy constructor - copies the config of another Importer, not the scene
Importer::Importer(const Importer &other)
{
// empty
// Call the default constructor
new(this) Importer();
// Copy the property table
mIntProperties = other.mIntProperties;
mFloatProperties = other.mFloatProperties;
mStringProperties = other.mStringProperties;
}
// ------------------------------------------------------------------------------------------------
// Register a custom loader plugin
aiReturn Importer::RegisterLoader(BaseImporter* pImp)
{
ai_assert(NULL != pImp);
// Check whether we would have two loaders for the same file extension now
// ======================================================================
// Check whether we would have two loaders for the same file extension
// This is absolutely OK, but we should warn the developer of the new
// loader that his code will propably never be called.
// ======================================================================
std::string st;
pImp->GetExtensionList(st);
@@ -441,9 +484,8 @@ aiReturn Importer::RegisterLoader(BaseImporter* pImp)
while (sz)
{
if (IsExtensionSupported(std::string(sz)))
{
DefaultLogger::get()->warn(std::string( "The file extension " ) + sz + " is already in use");
}
sz = ::strtok(NULL,";");
}
#endif
@@ -455,10 +497,10 @@ aiReturn Importer::RegisterLoader(BaseImporter* pImp)
}
// ------------------------------------------------------------------------------------------------
// Unregister a custom loader
aiReturn Importer::UnregisterLoader(BaseImporter* pImp)
{
ai_assert(NULL != pImp);
for (std::vector<BaseImporter*>::iterator
it = mImporter.begin(),end = mImporter.end();
it != end;++it)
@@ -481,12 +523,14 @@ aiReturn Importer::UnregisterLoader(BaseImporter* pImp)
// Supplies a custom IO handler to the importer to open and access files.
void Importer::SetIOHandler( IOSystem* pIOHandler)
{
// If the new handler is zero, allocate a default IO implementation.
if (!pIOHandler)
{
delete mIOHandler;
mIOHandler = new DefaultIOSystem();
mIsDefaultHandler = true;
}
// Otherwise register the custom handler
else if (mIOHandler != pIOHandler)
{
delete mIOHandler;
@@ -533,28 +577,37 @@ bool ValidateFlags(unsigned int pFlags)
}
#endif // ! DEBUG
// ------------------------------------------------------------------------------------------------
// Free the current scene
void Importer::FreeScene( )
{
delete mScene;
mScene = NULL;
}
// ------------------------------------------------------------------------------------------------
// Reads the given file and returns its contents if successful.
const aiScene* Importer::ReadFile( const std::string& pFile, unsigned int pFlags)
{
// validate the flags
// Validate the flags
ai_assert(ValidateFlags(pFlags));
// put a large try block around everything to catch all std::exception's
// ======================================================================
// Put a large try block around everything to catch all std::exception's
// that might be thrown by STL containers or by new().
// ImportErrorException's are throw by ourselves and caught elsewhere.
// ======================================================================
try
{
// check whether this Importer instance has already loaded
// Check whether this Importer instance has already loaded
// a scene. In this case we need to delete the old one
if (this->mScene)
if (mScene)
{
DefaultLogger::get()->debug("The previous scene has been deleted");
delete mScene;
this->mScene = NULL;
DefaultLogger::get()->debug("Deleting previous scene");
FreeScene();
}
// first check if the file is accessable at all
// First check if the file is accessable at all
if( !mIOHandler->Exists( pFile))
{
mErrorString = "Unable to open file \"" + pFile + "\".";
@@ -562,7 +615,7 @@ const aiScene* Importer::ReadFile( const std::string& pFile, unsigned int pFlags
return NULL;
}
// find an worker class which can handle the file
// Find an worker class which can handle the file
BaseImporter* imp = NULL;
for( unsigned int a = 0; a < mImporter.size(); a++)
{
@@ -573,7 +626,7 @@ const aiScene* Importer::ReadFile( const std::string& pFile, unsigned int pFlags
}
}
// put a proper error message if no suitable importer was found
// Put a proper error message if no suitable importer was found
if( !imp)
{
mErrorString = "No suitable reader found for the file format of file \"" + pFile + "\".";
@@ -581,17 +634,17 @@ const aiScene* Importer::ReadFile( const std::string& pFile, unsigned int pFlags
return NULL;
}
// dispatch the reading to the worker class for this format
// Dispatch the reading to the worker class for this format
DefaultLogger::get()->info("Found a matching importer for this file format");
imp->SetupProperties( this );
mScene = imp->ReadFile( pFile, mIOHandler);
// if successful, apply all active post processing steps to the imported data
// If successful, apply all active post processing steps to the imported data
if( mScene)
{
// FIRST of all - preprocess the scene
ScenePreprocessor pre;
pre.ProcessScene(mScene);
ScenePreprocessor pre(mScene);
pre.ProcessScene();
DefaultLogger::get()->info("Import successful, entering postprocessing-steps");
#ifdef _DEBUG
@@ -648,7 +701,6 @@ const aiScene* Importer::ReadFile( const std::string& pFile, unsigned int pFlags
catch (std::exception &e)
{
#if (defined _MSC_VER) && (defined _CPPRTTI)
// if we have RTTI get the full name of the exception that occured
mErrorString = std::string(typeid( e ).name()) + ": " + e.what();
#else
@@ -710,6 +762,7 @@ void Importer::SetPropertyInteger(const char* szName, int iValue,
}
// ------------------------------------------------------------------------------------------------
// Set a configuration property
void Importer::SetPropertyFloat(const char* szName, float iValue,
bool* bWasExisting /*= NULL*/)
{
@@ -717,6 +770,7 @@ void Importer::SetPropertyFloat(const char* szName, float iValue,
}
// ------------------------------------------------------------------------------------------------
// Set a configuration property
void Importer::SetPropertyString(const char* szName, const std::string& value,
bool* bWasExisting /*= NULL*/)
{
@@ -732,6 +786,7 @@ int Importer::GetPropertyInteger(const char* szName,
}
// ------------------------------------------------------------------------------------------------
// Get a configuration property
float Importer::GetPropertyFloat(const char* szName,
float iErrorReturn /*= 10e10*/) const
{
@@ -739,6 +794,7 @@ float Importer::GetPropertyFloat(const char* szName,
}
// ------------------------------------------------------------------------------------------------
// Get a configuration property
const std::string& Importer::GetPropertyString(const char* szName,
const std::string& iErrorReturn /*= ""*/) const
{
@@ -746,6 +802,7 @@ const std::string& Importer::GetPropertyString(const char* szName,
}
// ------------------------------------------------------------------------------------------------
// Get the memory requirements of a single node
inline void AddNodeWeight(unsigned int& iScene,const aiNode* pcNode)
{
iScene += sizeof(aiNode);
@@ -760,8 +817,9 @@ inline void AddNodeWeight(unsigned int& iScene,const aiNode* pcNode)
void Importer::GetMemoryRequirements(aiMemoryInfo& in) const
{
in = aiMemoryInfo();
if (!this->mScene)return;
// return if we have no scene loaded
if (!this->mScene)return;
in.total = sizeof(aiScene);
// add all meshes

View File

@@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Get a specific property from a material
aiReturn aiGetMaterialProperty(const aiMaterial* pMat,
const char* pKey,
unsigned int type,
@@ -70,6 +71,7 @@ aiReturn aiGetMaterialProperty(const aiMaterial* pMat,
}
// ------------------------------------------------------------------------------------------------
// Get an array of floating-point values from the material.
aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
const char* pKey,
unsigned int type,
@@ -124,6 +126,7 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
}
// ------------------------------------------------------------------------------------------------
// Get an array if integers from the material
aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat,
const char* pKey,
unsigned int type,
@@ -177,6 +180,7 @@ aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat,
}
// ------------------------------------------------------------------------------------------------
// Get a color (3 or 4 floats) from the material
aiReturn aiGetMaterialColor(const aiMaterial* pMat,
const char* pKey,
unsigned int type,
@@ -192,6 +196,7 @@ aiReturn aiGetMaterialColor(const aiMaterial* pMat,
}
// ------------------------------------------------------------------------------------------------
// Get a string from the material
aiReturn aiGetMaterialString(const aiMaterial* pMat,
const char* pKey,
unsigned int type,
@@ -223,6 +228,7 @@ aiReturn aiGetMaterialString(const aiMaterial* pMat,
}
// ------------------------------------------------------------------------------------------------
// Construction. Actually the one and only way to get an aiMaterial instance
MaterialHelper::MaterialHelper()
{
// Allocate 5 entries by default
@@ -234,7 +240,30 @@ MaterialHelper::MaterialHelper()
// ------------------------------------------------------------------------------------------------
MaterialHelper::~MaterialHelper()
{
_InternDestruct();
}
// ------------------------------------------------------------------------------------------------
aiMaterial::~aiMaterial()
{
// This is safe: aiMaterial has a private constructor,
// so instances must be created indirectly via MaterialHelper.
((MaterialHelper*)this)->_InternDestruct();
}
// ------------------------------------------------------------------------------------------------
// Manual destructor
void MaterialHelper::_InternDestruct()
{
// First clean up all properties
Clear();
// Then delete the array that stored them
delete[] mProperties;
AI_DEBUG_INVALIDATE_PTR(mProperties);
// Update members
mNumAllocated = 0;
}
// ------------------------------------------------------------------------------------------------
@@ -244,36 +273,38 @@ void MaterialHelper::Clear()
{
// delete this entry
delete mProperties[i];
AI_DEBUG_INVALIDATE_PTR(mProperties[i]);
}
mNumProperties = 0;
// The array remains
// The array remains allocated, we just invalidated its contents
}
// ------------------------------------------------------------------------------------------------
uint32_t MaterialHelper::ComputeHash()
uint32_t MaterialHelper::ComputeHash(bool includeMatName /*= false*/)
{
uint32_t hash = 1503; // magic start value, choosen to be my birthday :-)
for (unsigned int i = 0; i < this->mNumProperties;++i)
{
aiMaterialProperty* prop;
// NOTE: We need to exclude the material name from the hash
if ((prop = this->mProperties[i]) && ::strcmp(prop->mKey.data,"$mat.name"))
// If specified, exclude the material name from the hash
if ((prop = mProperties[i]) && (includeMatName || ::strcmp(prop->mKey.data,"$mat.name")))
{
hash = SuperFastHash(prop->mKey.data,(unsigned int)prop->mKey.length,hash);
hash = SuperFastHash(prop->mData,prop->mDataLength,hash);
// Combine the semantic and the index with the hash
// We print them to a string to make sure the quality
// of the hash isn't decreased.
// of the hashing state isn't affected (our hashing
// procedure was originally intended for plaintest).
char buff[32];
unsigned int len;
len = itoa10(buff,prop->mSemantic);
len = ASSIMP_itoa10(buff,prop->mSemantic);
hash = SuperFastHash(buff,len-1,hash);
len = itoa10(buff,prop->mIndex);
len = ASSIMP_itoa10(buff,prop->mIndex);
hash = SuperFastHash(buff,len-1,hash);
}
}
@@ -359,11 +390,11 @@ aiReturn MaterialHelper::AddBinaryProperty (const void* pInput,
return AI_SUCCESS;
}
// resize the array ... allocate storage for 5 other properties
// resize the array ... double the storage
if (mNumProperties == mNumAllocated)
{
unsigned int iOld = mNumAllocated;
mNumAllocated += 5;
mNumAllocated *= 2;
aiMaterialProperty** ppTemp = new aiMaterialProperty*[mNumAllocated];
if (NULL == ppTemp)return AI_OUTOFMEMORY;

View File

@@ -43,13 +43,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_MATERIALSYSTEM_H_INC
#include "../include/aiMaterial.h"
namespace Assimp
{
namespace Assimp {
// ---------------------------------------------------------------------------
/** Internal material helper class. Can be used to fill an aiMaterial
// ----------------------------------------------------------------------------------------
/** Internal material helper class. Intended to be used to fill an aiMaterial
structure easily. */
class ASSIMP_API MaterialHelper : public ::aiMaterial
{
@@ -58,95 +56,102 @@ public:
MaterialHelper();
~MaterialHelper();
// -------------------------------------------------------------------
/** Add a property with a given key and type info to the material
// ------------------------------------------------------------------------------
/** @brief Add a property with a given key and type info to the material
* structure
*
* \param pInput Pointer to input data
* \param pSizeInBytes Size of input data
* \param pKey Key/Usage of the property (AI_MATKEY_XXX)
* \param type Set by the AI_MATKEY_XXX macro
* \param index Set by the AI_MATKEY_XXX macro
* \param pType Type information hint
* @param pInput Pointer to input data
* @param pSizeInBytes Size of input data
* @param pKey Key/Usage of the property (AI_MATKEY_XXX)
* @param type Set by the AI_MATKEY_XXX macro
* @param index Set by the AI_MATKEY_XXX macro
* @param pType Type information hint
*/
aiReturn AddBinaryProperty (const void* pInput,
unsigned int pSizeInBytes,
const char* pKey,
unsigned int type,
unsigned int index,
unsigned int type ,
unsigned int index ,
aiPropertyTypeInfo pType);
// -------------------------------------------------------------------
/** Add a string property with a given key and type info to the
// ------------------------------------------------------------------------------
/** @brief Add a string property with a given key and type info to the
* material structure
*
* \param pInput Input string
* \param pKey Key/Usage of the property (AI_MATKEY_XXX)
* \param type Set by the AI_MATKEY_XXX macro
* \param index Set by the AI_MATKEY_XXX macro
* @param pInput Input string
* @param pKey Key/Usage of the property (AI_MATKEY_XXX)
* @param type Set by the AI_MATKEY_XXX macro
* @param index Set by the AI_MATKEY_XXX macro
*/
aiReturn AddProperty (const aiString* pInput,
const char* pKey,
unsigned int type,
unsigned int index);
unsigned int type = 0,
unsigned int index = 0);
// -------------------------------------------------------------------
/** Add a property with a given key to the material structure
* \param pInput Pointer to the input data
* \param pNumValues Number of values in the array
* \param pKey Key/Usage of the property (AI_MATKEY_XXX)
* \param type Set by the AI_MATKEY_XXX macro
* \param index Set by the AI_MATKEY_XXX macro
// ------------------------------------------------------------------------------
/** @brief Add a property with a given key to the material structure
* @param pInput Pointer to the input data
* @param pNumValues Number of values in the array
* @param pKey Key/Usage of the property (AI_MATKEY_XXX)
* @param type Set by the AI_MATKEY_XXX macro
* @param index Set by the AI_MATKEY_XXX macro
*/
template<class TYPE>
aiReturn AddProperty (const TYPE* pInput,
unsigned int pNumValues,
const char* pKey,
unsigned int type,
unsigned int index);
unsigned int type = 0,
unsigned int index = 0);
// -------------------------------------------------------------------
/** Remove a given key from the list
* The function fails if the key isn't found
// ------------------------------------------------------------------------------
/** @brief Remove a given key from the list.
*
* \param pKey Key to be deleted
* The function fails if the key isn't found
* @param pKey Key to be deleted
*/
aiReturn RemoveProperty (const char* pKey,
unsigned int type,
unsigned int index);
unsigned int type = 0,
unsigned int index = 0);
// -------------------------------------------------------------------
/** Removes all properties from the material
// ------------------------------------------------------------------------------
/** @brief Removes all properties from the material.
*
* The array remains allocated, so adding new properties is quite fast.
*/
void Clear();
// -------------------------------------------------------------------
// ------------------------------------------------------------------------------
/** Computes a hash (hopefully unique) from all material properties
* The hash value must be updated after material properties have
* been changed.
* The hash value reflects the current property state, so if you add any
* proprty and call this method again, the resulting hash value will be
* different.
*
* \return Unique hash
* @param includeMatName Set to 'true' to take the #AI_MATKEY_NAME property
* into account. The default value is false.
* @return Unique hash
*/
uint32_t ComputeHash();
uint32_t ComputeHash(bool includeMatName = false);
// -------------------------------------------------------------------
// ------------------------------------------------------------------------------
/** Copy the property list of a material
* \param pcDest Destination material
* \param pcSrc Source material
*/
static void CopyPropertyList(MaterialHelper* pcDest,
const MaterialHelper* pcSrc);
// For internal use
void _InternDestruct();
};
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template<class TYPE>
aiReturn MaterialHelper::AddProperty (const TYPE* pInput,
const unsigned int pNumValues,
@@ -154,14 +159,12 @@ aiReturn MaterialHelper::AddProperty (const TYPE* pInput,
unsigned int type,
unsigned int index)
{
return this->AddBinaryProperty((const void*)pInput,
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(TYPE),
pKey,type,index,aiPTI_Buffer);
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template<>
inline aiReturn MaterialHelper::AddProperty<float> (const float* pInput,
const unsigned int pNumValues,
@@ -169,14 +172,12 @@ inline aiReturn MaterialHelper::AddProperty<float> (const float* pInput,
unsigned int type,
unsigned int index)
{
return this->AddBinaryProperty((const void*)pInput,
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(float),
pKey,type,index,aiPTI_Float);
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template<>
inline aiReturn MaterialHelper::AddProperty<aiColor4D> (const aiColor4D* pInput,
const unsigned int pNumValues,
@@ -184,14 +185,12 @@ inline aiReturn MaterialHelper::AddProperty<aiColor4D> (const aiColor4D* pInput,
unsigned int type,
unsigned int index)
{
return this->AddBinaryProperty((const void*)pInput,
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiColor4D),
pKey,type,index,aiPTI_Float);
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template<>
inline aiReturn MaterialHelper::AddProperty<aiColor3D> (const aiColor3D* pInput,
const unsigned int pNumValues,
@@ -199,14 +198,12 @@ inline aiReturn MaterialHelper::AddProperty<aiColor3D> (const aiColor3D* pInput,
unsigned int type,
unsigned int index)
{
return this->AddBinaryProperty((const void*)pInput,
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiColor3D),
pKey,type,index,aiPTI_Float);
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template<>
inline aiReturn MaterialHelper::AddProperty<int> (const int* pInput,
const unsigned int pNumValues,
@@ -214,11 +211,10 @@ inline aiReturn MaterialHelper::AddProperty<int> (const int* pInput,
unsigned int type,
unsigned int index)
{
return this->AddBinaryProperty((const void*)pInput,
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(int),
pKey,type,index,aiPTI_Integer);
}
}
} // ! namespace Assimp
#endif //!! AI_MATERIALSYSTEM_H_INC

View File

@@ -612,7 +612,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
if (objectName.length())
{
::strcpy(mesh->name,objectName.c_str());
itoa10(&mesh->name[objectName.length()],30,subMeshIdx++);
ASSIMP_itoa10(&mesh->name[objectName.length()],30,subMeshIdx++);
}
// copy the shader to the mesh.

View File

@@ -45,25 +45,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ---------------------------------------------------------------------------------
template <class char_t>
inline bool IsSpace( const char_t in)
AI_FORCE_INLINE bool IsSpace( const char_t in)
{
return (in == (char_t)' ' || in == (char_t)'\t');
}
// ---------------------------------------------------------------------------------
template <class char_t>
inline bool IsLineEnd( const char_t in)
AI_FORCE_INLINE bool IsLineEnd( const char_t in)
{
return (in == (char_t)'\r' || in == (char_t)'\n' || in == (char_t)'\0');
}
// ---------------------------------------------------------------------------------
template <class char_t>
inline bool IsSpaceOrNewLine( const char_t in)
AI_FORCE_INLINE bool IsSpaceOrNewLine( const char_t in)
{
return IsSpace<char_t>(in) || IsLineEnd<char_t>(in);
}
// ---------------------------------------------------------------------------------
template <class char_t>
inline bool SkipSpaces( const char_t* in, const char_t** out)
AI_FORCE_INLINE bool SkipSpaces( const char_t* in, const char_t** out)
{
while (*in == (char_t)' ' || *in == (char_t)'\t')in++;
*out = in;
@@ -71,7 +71,7 @@ inline bool SkipSpaces( const char_t* in, const char_t** out)
}
// ---------------------------------------------------------------------------------
template <class char_t>
inline bool SkipSpaces( const char_t** inout)
AI_FORCE_INLINE bool SkipSpaces( const char_t** inout)
{
return SkipSpaces<char_t>(*inout,inout);
}
@@ -109,7 +109,7 @@ inline bool SkipSpacesAndLineEnd( const char_t** inout)
}
// ---------------------------------------------------------------------------------
template <class char_t>
bool GetNextLine(const char_t*& buffer, char_t out[4096])
inline bool GetNextLine(const char_t*& buffer, char_t out[4096])
{
if ((char_t)'\0' == *buffer)return false;
@@ -124,7 +124,7 @@ bool GetNextLine(const char_t*& buffer, char_t out[4096])
}
// ---------------------------------------------------------------------------------
template <class char_t>
inline bool IsNumeric( char_t in)
AI_FORCE_INLINE bool IsNumeric( char_t in)
{
return in >= '0' && in <= '9' || '-' == in || '+' == in;
}

View File

@@ -164,7 +164,6 @@ class ComputeSpatialSortProcess : public BaseProcess
aiMesh* mesh = pScene->mMeshes[i];
_Type& blubb = *it;
blubb.first.Fill(mesh->mVertices,mesh->mNumVertices,sizeof(aiVector3D));
blubb.second = ComputePositionEpsilon(mesh);
}

View File

@@ -458,7 +458,7 @@ outer:
if (srcMat.texIdx < pScene->mNumTextures || real < pScene->mNumTextures)
{
srcMat.name.data[0] = '*';
srcMat.name.length = itoa10(&srcMat.name.data[1],1000,
srcMat.name.length = ASSIMP_itoa10(&srcMat.name.data[1],1000,
(srcMat.texIdx < pScene->mNumTextures ? srcMat.texIdx : real));
mat->AddProperty(&srcMat.name,AI_MATKEY_TEXTURE_DIFFUSE(0));
}

View File

@@ -81,60 +81,62 @@ inline void ArrayDelete(T**& in, unsigned int& num)
num = 0;
}
//// ------------------------------------------------------------------------------------------------
//// Updates the node graph - removes all nodes which have the "remove" flag set and the
//// "don't remove" flag not set. Nodes with meshes are never deleted.
//bool UpdateNodeGraph(aiNode* node,std::list<aiNode*>& childsOfParent,bool root)
//{
// register bool b = false;
//
// std::list<aiNode*> mine;
// for (unsigned int i = 0; i < node->mNumChildren;++i)
// {
// if(UpdateNodeGraph(node->mChildren[i],mine,false))
// b = true;
// }
//
// // somewhat tricky ... mNumMeshes must be originally 0 and MSB2 may not be set,
// // so we can do a simple comparison against MSB here
// if (!root && AI_RC_UINT_MSB == node->mNumMeshes )
// {
// // this node needs to be removed
// if(node->mNumChildren)
// {
// childsOfParent.insert(childsOfParent.end(),mine.begin(),mine.end());
//
// // set all children to NULL to make sure they are not deleted when we delete ourself
// for (unsigned int i = 0; i < node->mNumChildren;++i)
// node->mChildren[i] = NULL;
// }
// b = true;
// delete node;
// }
// else
// {
// AI_RC_UNMASK(node->mNumMeshes);
// childsOfParent.push_back(node);
//
// if (b)
// {
// // reallocate the array of our children here
// node->mNumChildren = (unsigned int)mine.size();
// aiNode** const children = new aiNode*[mine.size()];
// aiNode** ptr = children;
//
// for (std::list<aiNode*>::iterator it = mine.begin(), end = mine.end();
// it != end; ++it)
// {
// *ptr++ = *it;
// }
// delete[] node->mChildren;
// node->mChildren = children;
// return false;
// }
// }
// return b;
//}
#if 0
// ------------------------------------------------------------------------------------------------
// Updates the node graph - removes all nodes which have the "remove" flag set and the
// "don't remove" flag not set. Nodes with meshes are never deleted.
bool UpdateNodeGraph(aiNode* node,std::list<aiNode*>& childsOfParent,bool root)
{
register bool b = false;
std::list<aiNode*> mine;
for (unsigned int i = 0; i < node->mNumChildren;++i)
{
if(UpdateNodeGraph(node->mChildren[i],mine,false))
b = true;
}
// somewhat tricky ... mNumMeshes must be originally 0 and MSB2 may not be set,
// so we can do a simple comparison against MSB here
if (!root && AI_RC_UINT_MSB == node->mNumMeshes )
{
// this node needs to be removed
if(node->mNumChildren)
{
childsOfParent.insert(childsOfParent.end(),mine.begin(),mine.end());
// set all children to NULL to make sure they are not deleted when we delete ourself
for (unsigned int i = 0; i < node->mNumChildren;++i)
node->mChildren[i] = NULL;
}
b = true;
delete node;
}
else
{
AI_RC_UNMASK(node->mNumMeshes);
childsOfParent.push_back(node);
if (b)
{
// reallocate the array of our children here
node->mNumChildren = (unsigned int)mine.size();
aiNode** const children = new aiNode*[mine.size()];
aiNode** ptr = children;
for (std::list<aiNode*>::iterator it = mine.begin(), end = mine.end();
it != end; ++it)
{
*ptr++ = *it;
}
delete[] node->mChildren;
node->mChildren = children;
return false;
}
}
return b;
}
#endif
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
@@ -167,7 +169,9 @@ void RemoveVCProcess::Execute( aiScene* pScene)
for (unsigned int i = 1;i < pScene->mNumMaterials;++i)
delete pScene->mMaterials[i];
pScene->mNumMaterials = 1;
MaterialHelper* helper = (MaterialHelper*) pScene->mMaterials[0];
ai_assert(NULL != helper);
helper->Clear();
// gray
@@ -218,6 +222,10 @@ void RemoveVCProcess::Execute( aiScene* pScene)
{
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
DefaultLogger::get()->debug("Setting AI_SCENE_FLAGS_INCOMPLETE flag");
// If we have no meshes anymore we should also clear another flag ...
if (!pScene->mNumMeshes)
pScene->mFlags &= ~AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
}
if (bHas)DefaultLogger::get()->info("RemoveVCProcess finished. Data structure cleanup has been done.");
@@ -267,10 +275,10 @@ bool RemoveVCProcess::ProcessMesh(aiMesh* pMesh)
// handle texture coordinates
register bool b = (0 != (configDeleteFlags & aiComponent_TEXCOORDS));
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i)
for (unsigned int i = 0, real = 0; real < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++real)
{
if (!pMesh->mTextureCoords[i])break;
if (configDeleteFlags & aiComponent_TEXCOORDSn(i) || b)
if (configDeleteFlags & aiComponent_TEXCOORDSn(real) || b)
{
delete pMesh->mTextureCoords[i];
pMesh->mTextureCoords[i] = NULL;
@@ -279,19 +287,19 @@ bool RemoveVCProcess::ProcessMesh(aiMesh* pMesh)
if (!b)
{
// collapse the rest of the array
unsigned int a;
for (a = i+1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a)
{
for (unsigned int a = i+1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a)
pMesh->mTextureCoords[a-1] = pMesh->mTextureCoords[a];
}
pMesh->mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS-1] = NULL;
continue;
}
}
++i;
}
// handle vertex colors
b = (0 != (configDeleteFlags & aiComponent_COLORS));
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i)
for (unsigned int i = 0, real = 0; real < AI_MAX_NUMBER_OF_COLOR_SETS; ++real)
{
if (!pMesh->mColors[i])break;
if (configDeleteFlags & aiComponent_COLORSn(i) || b)
@@ -303,14 +311,14 @@ bool RemoveVCProcess::ProcessMesh(aiMesh* pMesh)
if (!b)
{
// collapse the rest of the array
unsigned int a;
for (a = i+1; a < AI_MAX_NUMBER_OF_COLOR_SETS;++a)
{
for (unsigned int a = i+1; a < AI_MAX_NUMBER_OF_COLOR_SETS;++a)
pMesh->mColors[a-1] = pMesh->mColors[a];
}
pMesh->mColors[AI_MAX_NUMBER_OF_COLOR_SETS-1] = NULL;
continue;
}
}
++i;
}
// handle bones

View File

@@ -38,19 +38,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file Defines a post processing step to kill all loaded normals */
#ifndef AI_KILLNORMALPROCESS_H_INC
#define AI_KILLNORMALPROCESS_H_INC
/** @file Defines a post processing step to remove specific parts of the scene */
#ifndef AI_REMOVEVCPROCESS_H_INCLUDED
#define AI_REMOVEVCPROCESS_H_INCLUDED
#include "BaseProcess.h"
#include "../include/aiMesh.h"
class RemoveVCProcessTest;
namespace Assimp
{
namespace Assimp {
// ---------------------------------------------------------------------------
/** RemoveVCProcess: Class to kill all normals loaded
/** RemoveVCProcess: Class to exclude specific parts of the data structure
* from further processing by removing them,
*/
class ASSIMP_API RemoveVCProcess : public BaseProcess
{
@@ -80,7 +80,6 @@ public:
*/
void Execute( aiScene* pScene);
// -------------------------------------------------------------------
/** Called prior to ExecuteOnScene().
* The function is a request to the process to update its configuration
@@ -88,20 +87,37 @@ public:
*/
virtual void SetupProperties(const Importer* pImp);
// -------------------------------------------------------------------
/** Manually setup the configuration flags for the step
*
* @param Bitwise combintion of the #aiComponent enumerated values.
*/
void SetDeleteFlags(unsigned int f)
{
configDeleteFlags = f;
}
// -------------------------------------------------------------------
/** Query the current configuration.
*/
unsigned int GetDeleteFlags() const
{
return configDeleteFlags;
}
private:
bool ProcessMesh (aiMesh* pcMesh);
/** Configuration
/** Configuration flag
*/
unsigned int configDeleteFlags;
/** The scene the instance is currently operating on
/** The scene we're working with
*/
aiScene* mScene;
};
} // end of namespace Assimp
#endif // !!AI_KILLNORMALPROCESS_H_INC
#endif // !!AI_REMOVEVCPROCESS_H_INCLUDED

View File

@@ -397,7 +397,7 @@ void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master,
{
// Offset the index and write it back ..
const unsigned int idx = strtol10(&s.data[1]) + offset[n];
itoa10(&s.data[1],sizeof(s.data)-1,idx);
ASSIMP_itoa10(&s.data[1],sizeof(s.data)-1,idx);
}
}

View File

@@ -43,10 +43,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
// ---------------------------------------------------------------------------
void ScenePreprocessor::ProcessScene (aiScene* _scene)
// ---------------------------------------------------------------------------------------------
void ScenePreprocessor::ProcessScene ()
{
scene = _scene;
ai_assert(scene != NULL);
// Process all meshes
for (unsigned int i = 0; i < scene->mNumMeshes;++i)
@@ -87,7 +87,7 @@ void ScenePreprocessor::ProcessScene (aiScene* _scene)
}
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------
void ScenePreprocessor::ProcessMesh (aiMesh* mesh)
{
// If aiMesh::mNumUVComponents is *not* set assign the default value of 2
@@ -129,7 +129,7 @@ void ScenePreprocessor::ProcessMesh (aiMesh* mesh)
}
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------
void ScenePreprocessor::ProcessAnimation (aiAnimation* anim)
{
double first = 10e10, last = -10e10;

View File

@@ -43,27 +43,65 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_SCENE_PREPROCESSOR_H_INC
#define AI_SCENE_PREPROCESSOR_H_INC
class ScenePreprocessorTest;
namespace Assimp {
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
/** ScenePreprocessor: Preprocess a scene before any post-processing
* steps are executed.
*
* The step computes data that needn't necessarily be provided by the
* importer, such as aiMesh::mPrimitiveTypes.
*/
// ----------------------------------------------------------------------------------
class ASSIMP_API ScenePreprocessor
{
// Make ourselves a friend of the corresponding test unit.
friend class ::ScenePreprocessorTest;
public:
/** Preprocess a given scene.
*
* @param _scene Scene to be preprocessed
// ----------------------------------------------------------------
/** Default c'tpr. Use SetScene() to assign a scene to the object.
*/
void ProcessScene (aiScene* _scene);
ScenePreprocessor()
: scene (NULL)
{}
/** Constructs the object and assigns a specific scene to it
*/
ScenePreprocessor(aiScene* _scene)
: scene (_scene)
{}
// ----------------------------------------------------------------
/** Assign a (new) scene to the object.
*
* One 'SceneProcessor' can be used for multiple scenes.
* Call ProcessScene to have the scene preprocessed.
* @param sc Scene to be processed.
*/
void SetScene (aiScene* sc) {
scene = sc;
}
// ----------------------------------------------------------------
/** Preprocess the current scene
*/
void ProcessScene ();
protected:
// ----------------------------------------------------------------
/** Preprocess an animation in the scene
* @param anim Anim to be preprocessed.
*/
void ProcessAnimation (aiAnimation* anim);
// ----------------------------------------------------------------
/** Preprocess a mesh in the scene
* @param mesh Mesh to be preprocessed.
*/
void ProcessMesh (aiMesh* mesh);
protected:

View File

@@ -70,9 +70,8 @@ void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups<T>& sMesh)
aiVector3D pDelta2 = *pV3 - *pV1;
aiVector3D vNor = pDelta1 ^ pDelta2;
sMesh.mNormals[face.mIndices[0]] = vNor;
sMesh.mNormals[face.mIndices[1]] = vNor;
sMesh.mNormals[face.mIndices[2]] = vNor;
for (unsigned int c = 0; c < 3;++c)
sMesh.mNormals[face.mIndices[c]] = vNor;
}
// calculate the position bounds so we have a reliable epsilon to check position differences against
@@ -95,9 +94,8 @@ void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups<T>& sMesh)
for( typename std::vector<T>::iterator i = sMesh.mFaces.begin();
i != sMesh.mFaces.end();++i)
{
sSort.Add(sMesh.mPositions[(*i).mIndices[0]],(*i).mIndices[0],(*i).iSmoothGroup);
sSort.Add(sMesh.mPositions[(*i).mIndices[1]],(*i).mIndices[1],(*i).iSmoothGroup);
sSort.Add(sMesh.mPositions[(*i).mIndices[2]],(*i).mIndices[2],(*i).iSmoothGroup);
for (unsigned int c = 0; c < 3;++c)
sSort.Add(sMesh.mPositions[(*i).mIndices[c]],(*i).mIndices[c],(*i).iSmoothGroup);
}
sSort.Prepare();

View File

@@ -57,7 +57,7 @@ using namespace Assimp;
// Constructor to be privately used by Importer
SortByPTypeProcess::SortByPTypeProcess()
{
// nothing to do here
configRemoveMeshes = 0;
}
// ------------------------------------------------------------------------------------------------

View File

@@ -0,0 +1,52 @@
#ifndef AI_STROSTREAMLOGSTREAM_H_INC
#define AI_STROSTREAMLOGSTREAM_H_INC
#include "../include/LogStream.h"
#include <ostream>
namespace Assimp {
// ---------------------------------------------------------------------------
/** @class StdOStreamLogStream
* @brief Logs into a std::ostream
*/
class StdOStreamLogStream : public LogStream
{
public:
/** @brief Construction from an existing std::ostream
* @param _ostream Output stream to be used
*/
StdOStreamLogStream(std::ostream& _ostream);
/** @brief Destructor */
~StdOStreamLogStream();
/** @brief Writer */
void write(const std::string &messgae);
private:
std::ostream& ostream;
};
// ---------------------------------------------------------------------------
// Default constructor
inline StdOStreamLogStream::StdOStreamLogStream(std::ostream& _ostream)
: ostream (_ostream)
{}
// ---------------------------------------------------------------------------
// Default constructor
inline StdOStreamLogStream::~StdOStreamLogStream()
{}
// ---------------------------------------------------------------------------
// Write method
inline void StdOStreamLogStream::write(const std::string &message)
{
ostream << message.c_str();
ostream.flush();
}
// ---------------------------------------------------------------------------
} // Namespace Assimp
#endif // guard

View File

@@ -68,7 +68,7 @@ public:
* The stream will be deleted afterwards.
* @param stream Input stream
*/
inline StreamReader(IOStream* stream)
StreamReader(IOStream* stream)
{
ai_assert(NULL != stream);
this->stream = stream;
@@ -81,7 +81,7 @@ public:
end = limit = &buffer[s];
}
inline ~StreamReader()
~StreamReader()
{
delete[] buffer;
delete stream;
@@ -90,28 +90,28 @@ public:
/** Read a float from the stream
*/
inline float GetF4()
float GetF4()
{
return Get<float>();
}
/** Read a double from the stream
*/
inline double GetF8()
double GetF8()
{
return Get<double>();
}
/** Read a short from the stream
*/
inline int16_t GetI2()
int16_t GetI2()
{
return Get<int16_t>();
}
/** Read a char from the stream
*/
inline int8_t GetI1()
int8_t GetI1()
{
if (current >= end)
throw new ImportErrorException("End of file was reached");
@@ -121,21 +121,21 @@ public:
/** Read an int from the stream
*/
inline int32_t GetI4()
int32_t GetI4()
{
return Get<int32_t>();
}
/** Read a long from the stream
*/
inline int64_t GetI8()
int64_t GetI8()
{
return Get<int64_t>();
}
/** Get the remaining stream size (to the end of the srream)
*/
inline unsigned int GetRemainingSize()
unsigned int GetRemainingSize()
{
return (unsigned int)(end - current);
}
@@ -143,7 +143,7 @@ public:
/** Get the remaining stream size (to the current read limit)
*/
inline unsigned int GetRemainingSizeToLimit()
unsigned int GetRemainingSizeToLimit()
{
return (unsigned int)(limit - current);
}
@@ -151,7 +151,7 @@ public:
/** Increase the file pointer
*/
inline void IncPtr(unsigned int plus)
void IncPtr(unsigned int plus)
{
current += plus;
if (current > end)
@@ -162,14 +162,14 @@ public:
/** Get the current file pointer
*/
inline int8_t* GetPtr() const
int8_t* GetPtr() const
{
return current;
}
/** Set current file pointer
*/
inline void SetPtr(int8_t* p)
void SetPtr(int8_t* p)
{
current = p;
if (current > end || current < buffer)
@@ -180,7 +180,7 @@ public:
/** Get the current offset from the beginning of the file
*/
inline int GetCurrentPos() const
int GetCurrentPos() const
{
return (unsigned int)(current - buffer);
}
@@ -191,7 +191,7 @@ public:
* the beginning of the file. Passing 0xffffffff
* resets the limit.
*/
inline void SetReadLimit(unsigned int _limit)
void SetReadLimit(unsigned int _limit)
{
if (0xffffffff == _limit)
{
@@ -205,35 +205,35 @@ public:
/** Get the current read limit
*/
inline int GetReadLimit() const
int GetReadLimit() const
{
return (unsigned int)(limit - buffer);
}
/** Skip to the read limit
*/
inline void SkipToReadLimit()
void SkipToReadLimit()
{
current = limit;
}
// overload operator>> for those who prefer this way ...
inline void operator >> (float& f)
void operator >> (float& f)
{f = GetF4();}
inline void operator >> (double& f)
void operator >> (double& f)
{f = GetF8();}
inline void operator >> (int16_t& f)
void operator >> (int16_t& f)
{f = GetI2();}
inline void operator >> (int32_t& f)
void operator >> (int32_t& f)
{f = GetI4();}
inline void operator >> (int64_t& f)
void operator >> (int64_t& f)
{f = GetI8();}
inline void operator >> (int8_t& f)
void operator >> (int8_t& f)
{f = GetI1();}
private:
@@ -241,7 +241,7 @@ private:
/** Generic read method. ByteSwap::Swap(T*) must exist.
*/
template <typename T>
inline T Get()
T Get()
{
if (current + sizeof(T) > limit)
throw new ImportErrorException("End of file or stream limit was reached");

View File

@@ -38,23 +38,31 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file Definition of platform independent string comparison functions */
#ifndef AI_STRINGCOMPARISON_H_INC
#define AI_STRINGCOMPARISON_H_INC
/** @file Definition of platform independent string workers:
ASSIMP_itoa10
ASSIMP_stricmp
ASSIMP_strincmp
namespace Assimp
{
These functions are not consistently available on all platforms,
or the provided implementations behave too differently.
*/
#ifndef INCLUDED_AI_STRING_WORKERS_H
#define INCLUDED_AI_STRING_WORKERS_H
// ---------------------------------------------------------------------------
// itoa is not consistently available on all platforms so it is quite useful
// to have a small replacement function here. No need to use a full sprintf()
// if we just want to print a number ...
// @param out Output buffer
// @param max Maximum number of characters to be written, including '\0'
// @param number Number to be written
// @return Number of bytes written. Including '\0'.
inline unsigned int itoa10( char* out, unsigned int max, int32_t number)
namespace Assimp {
// -------------------------------------------------------------------------------
/** @brief itoa with a fixed base 10
* 'itoa' is not consistently available on all platforms so it is quite useful
* to have a small replacement function here. No need to use a full sprintf()
* if we just want to print a number ...
* @param out Output buffer
* @param max Maximum number of characters to be written, including '\0'
* @param number Number to be written
* @return Number of bytes written. Including the terminal zero.
*/
inline unsigned int ASSIMP_itoa10( char* out, unsigned int max, int32_t number)
{
ai_assert(NULL != out);
@@ -91,28 +99,32 @@ inline unsigned int itoa10( char* out, unsigned int max, int32_t number)
return written;
}
// ---------------------------------------------------------------------------
// Secure template overload
// The compiler should choose this function if he is able to determine the
// size of the array automatically.
// -------------------------------------------------------------------------------
/** @brief itoa with a fixed base 10 (Secure template overload)
* The compiler should choose this function if he is able to determine the
* size of the array automatically.
*/
template <unsigned int length>
inline unsigned int itoa10( char(& out)[length], int32_t number)
inline unsigned int ASSIMP_itoa10( char(& out)[length], int32_t number)
{
return itoa10(out,length,number);
return ASSIMP_itoa10(out,length,number);
}
// ---------------------------------------------------------------------------
/** \brief Helper function to do platform independent string comparison.
// -------------------------------------------------------------------------------
/** @brief Helper function to do platform independent string comparison.
*
* This is required since stricmp() is not consistently available on
* all platforms. Some platforms use the '_' prefix, others don't even
* have such a function.
*
* \param s1 First input string
* \param s2 Second input string
* @param s1 First input string
* @param s2 Second input string
* @return 0 if the given strings are identical
*/
inline int ASSIMP_stricmp(const char *s1, const char *s2)
{
ai_assert(NULL != s1 && NULL != s2);
#if (defined _MSC_VER)
return ::_stricmp(s1,s2);
@@ -134,8 +146,12 @@ inline int ASSIMP_stricmp(const char *s1, const char *s2)
#endif
}
// ---------------------------------------------------------------------------
/** \brief Case independent comparison of two std::strings
// -------------------------------------------------------------------------------
/** @brief Case independent comparison of two std::strings
*
* @param a First string
* @param b Second string
* @return 0 if a == b
*/
inline int ASSIMP_stricmp(const std::string& a, const std::string& b)
{
@@ -143,19 +159,23 @@ inline int ASSIMP_stricmp(const std::string& a, const std::string& b)
return (i ? i : ASSIMP_stricmp(a.c_str(),b.c_str()));
}
// ---------------------------------------------------------------------------
/** \brief Helper function to do platform independent string comparison.
// -------------------------------------------------------------------------------
/** @brief Helper function to do platform independent string comparison.
*
* This is required since strincmp() is not consistently available on
* all platforms. Some platforms use the '_' prefix, others don't even
* have such a function.
*
* \param s1 First input string
* \param s2 Second input string
* \param n Macimum number of characters to compare
* @param s1 First input string
* @param s2 Second input string
* @param n Macimum number of characters to compare
* @return 0 if the given strings are identical
*/
inline int ASSIMP_strincmp(const char *s1, const char *s2, unsigned int n)
{
ai_assert(NULL != s1 && NULL != s2);
if (!n)return 0;
#if (defined _MSC_VER)
return ::_strnicmp(s1,s2,n);
@@ -180,8 +200,11 @@ inline int ASSIMP_strincmp(const char *s1, const char *s2, unsigned int n)
}
// ---------------------------------------------------------------------------
// Evaluates an integer power.
// -------------------------------------------------------------------------------
/** @brief Evaluates an integer power
*
* todo: move somewhere where it fits better in than here
*/
inline unsigned int integer_pow (unsigned int base, unsigned int power)
{
unsigned int res = 1;

View File

@@ -227,14 +227,18 @@ void TargetAnimationHelper::Process(std::vector<aiVectorKey>* distanceTrack)
float f = diff.Length();
// output distance vector
if (fill)
if (f)
{
fill->push_back(aiVectorKey());
aiVectorKey& v = fill->back();
v.mTime = iter.GetCurTime();
v.mValue = aiVector3D (0.f,0.f,f);
v.mValue = diff;
diff /= f;
}
else
{
}
diff /= f;
// diff is now the vector in which our camera is pointing
}

View File

@@ -47,12 +47,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../include/aiAssert.h"
struct aiMesh;
namespace Assimp
{
namespace Assimp {
// ---------------------------------------------------------------------------
/** The VertexTriangleAdjacency class computes a vertex-triangle
/** @brief The VertexTriangleAdjacency class computes a vertex-triangle
* adjacency map from a given index buffer.
*
* @note The input data is expected to be triangulated.
@@ -62,30 +60,30 @@ class ASSIMP_API VertexTriangleAdjacency
public:
/** Construction from an existing index buffer
* @param pcFaces Index buffer
* @param iNumFaces Number of faces in the buffer
* @param iNumVertices Number of referenced vertices. This value
* is computed automatically if 0 is specified.
* @param bComputeNumTriangles If you want the class to compute
* a list which contains the number of referenced triangles
* per vertex - pass true.
/** @brief Construction from an existing index buffer
* @param pcFaces Index buffer
* @param iNumFaces Number of faces in the buffer
* @param iNumVertices Number of referenced vertices. This value
* is computed automatically if 0 is specified.
* @param bComputeNumTriangles If you want the class to compute
* a list which contains the number of referenced triangles
* per vertex - pass true.
*/
VertexTriangleAdjacency(aiFace* pcFaces,unsigned int iNumFaces,
unsigned int iNumVertices = 0,
bool bComputeNumTriangles = true);
/** Destructor
/** @brief Destructor
*/
~VertexTriangleAdjacency();
/** Get all triangles adjacent to a vertex
* @param iVertIndex Index of the vertex
* @return A pointer to the adjacency list
/** @brief Get all triangles adjacent to a vertex
* @param iVertIndex Index of the vertex
* @return A pointer to the adjacency list
*/
inline unsigned int* GetAdjacentTriangles(unsigned int iVertIndex) const
unsigned int* GetAdjacentTriangles(unsigned int iVertIndex) const
{
ai_assert(iVertIndex < iNumVertices);
@@ -94,12 +92,12 @@ public:
}
/** Get the number of triangles that are referenced by
* a vertex. This function returns a reference that can be modified
* @param iVertIndex Index of the vertex
* @return Number of referenced triangles
/** @brief Get the number of triangles that are referenced by
* a vertex. This function returns a reference that can be modified
* @param iVertIndex Index of the vertex
* @return Number of referenced triangles
*/
inline unsigned int& GetNumTrianglesPtr(unsigned int iVertIndex)
unsigned int& GetNumTrianglesPtr(unsigned int iVertIndex)
{
ai_assert(iVertIndex < iNumVertices && NULL != mLiveTriangles);
return mLiveTriangles[iVertIndex];

View File

@@ -1,17 +1,12 @@
#ifndef AI_WIN32DEBUGLOGSTREAM_H_INC
#define AI_WIN32DEBUGLOGSTREAM_H_INC
#ifdef WIN32
#include "../include/LogStream.h"
//#ifdef _MSC_VER
#ifdef WIN32
#include "Windows.h"
#endif
namespace Assimp
{
//#ifdef _MSC_VER
#ifdef WIN32
namespace Assimp {
// ---------------------------------------------------------------------------
/** @class Win32DebugLogStream
@@ -34,16 +29,12 @@ public:
// ---------------------------------------------------------------------------
// Default constructor
inline Win32DebugLogStream::Win32DebugLogStream()
{
// empty
}
{}
// ---------------------------------------------------------------------------
// Default constructor
inline Win32DebugLogStream::~Win32DebugLogStream()
{
// empty
}
{}
// ---------------------------------------------------------------------------
// Write method
@@ -53,9 +44,7 @@ inline void Win32DebugLogStream::write(const std::string &message)
}
// ---------------------------------------------------------------------------
#endif
} // Namespace Assimp
#endif
#endif // ! WIN32
#endif // guard