Merge pull request #261 from terziman/master

Improvement of collada exporter & bug fixes
pull/265/head
Kim Kulling 2014-04-28 23:54:10 +02:00
commit 562dd01655
80 changed files with 2284 additions and 735 deletions

2
.gitignore vendored
View File

@ -1 +1,3 @@
build build
.project
*.kdev4*

View File

@ -18,7 +18,7 @@ set(LIBASSIMP-DEV_COMPONENT "libassimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_M
set(CPACK_COMPONENTS_ALL assimp-bin ${LIBASSIMP_COMPONENT} ${LIBASSIMP-DEV_COMPONENT} assimp-dev) set(CPACK_COMPONENTS_ALL assimp-bin ${LIBASSIMP_COMPONENT} ${LIBASSIMP-DEV_COMPONENT} assimp-dev)
set(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names") set(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names")
if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX AND NOT MINGW ) if((CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) AND NOT CMAKE_COMPILER_IS_MINGW)
add_definitions(-fPIC) # this is a very important switch and some libraries seem now to have it.... add_definitions(-fPIC) # this is a very important switch and some libraries seem now to have it....
# hide all not-exported symbols # hide all not-exported symbols
add_definitions( -fvisibility=hidden -Wall ) add_definitions( -fvisibility=hidden -Wall )

View File

@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Importer.h" #include "Importer.h"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#ifdef AI_C_THREADSAFE #ifndef ASSIMP_BUILD_SINGLETHREADED
# include <boost/thread/thread.hpp> # include <boost/thread/thread.hpp>
# include <boost/thread/mutex.hpp> # include <boost/thread/mutex.hpp>
#endif #endif
@ -87,7 +87,7 @@ namespace Assimp
} }
#ifdef AI_C_THREADSAFE #ifndef ASSIMP_BUILD_SINGLETHREADED
/** Global mutex to manage the access to the logstream map */ /** Global mutex to manage the access to the logstream map */
static boost::mutex gLogStreamMutex; static boost::mutex gLogStreamMutex;
#endif #endif
@ -104,7 +104,7 @@ public:
} }
~LogToCallbackRedirector() { ~LogToCallbackRedirector() {
#ifdef AI_C_THREADSAFE #ifndef ASSIMP_BUILD_SINGLETHREADED
boost::mutex::scoped_lock lock(gLogStreamMutex); boost::mutex::scoped_lock lock(gLogStreamMutex);
#endif #endif
// (HACK) Check whether the 'stream.user' pointer points to a // (HACK) Check whether the 'stream.user' pointer points to a
@ -172,6 +172,7 @@ const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFl
pimpl->mIntProperties = pp->ints; pimpl->mIntProperties = pp->ints;
pimpl->mFloatProperties = pp->floats; pimpl->mFloatProperties = pp->floats;
pimpl->mStringProperties = pp->strings; pimpl->mStringProperties = pp->strings;
pimpl->mMatrixProperties = pp->matrices;
} }
// setup a custom IO system if necessary // setup a custom IO system if necessary
if (pFS) { if (pFS) {
@ -230,6 +231,7 @@ const aiScene* aiImportFileFromMemoryWithProperties(
pimpl->mIntProperties = pp->ints; pimpl->mIntProperties = pp->ints;
pimpl->mFloatProperties = pp->floats; pimpl->mFloatProperties = pp->floats;
pimpl->mStringProperties = pp->strings; pimpl->mStringProperties = pp->strings;
pimpl->mMatrixProperties = pp->matrices;
} }
// and have it read the file from the memory buffer // and have it read the file from the memory buffer
@ -337,7 +339,7 @@ ASSIMP_API void aiAttachLogStream( const aiLogStream* stream )
{ {
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
#ifdef AI_C_THREADSAFE #ifndef ASSIMP_BUILD_SINGLETHREADED
boost::mutex::scoped_lock lock(gLogStreamMutex); boost::mutex::scoped_lock lock(gLogStreamMutex);
#endif #endif
@ -356,7 +358,7 @@ ASSIMP_API aiReturn aiDetachLogStream( const aiLogStream* stream)
{ {
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
#ifdef AI_C_THREADSAFE #ifndef ASSIMP_BUILD_SINGLETHREADED
boost::mutex::scoped_lock lock(gLogStreamMutex); boost::mutex::scoped_lock lock(gLogStreamMutex);
#endif #endif
// find the logstream associated with this data // find the logstream associated with this data
@ -381,7 +383,7 @@ ASSIMP_API aiReturn aiDetachLogStream( const aiLogStream* stream)
ASSIMP_API void aiDetachAllLogStreams(void) ASSIMP_API void aiDetachAllLogStreams(void)
{ {
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
#ifdef AI_C_THREADSAFE #ifndef ASSIMP_BUILD_SINGLETHREADED
boost::mutex::scoped_lock lock(gLogStreamMutex); boost::mutex::scoped_lock lock(gLogStreamMutex);
#endif #endif
for (LogStreamMap::iterator it = gActiveLogStreams.begin(); it != gActiveLogStreams.end(); ++it) { for (LogStreamMap::iterator it = gActiveLogStreams.begin(); it != gActiveLogStreams.end(); ++it) {
@ -504,6 +506,20 @@ ASSIMP_API void aiSetImportPropertyString(aiPropertyStore* p, const char* szName
ASSIMP_END_EXCEPTION_REGION(void); ASSIMP_END_EXCEPTION_REGION(void);
} }
// ------------------------------------------------------------------------------------------------
// Importer::SetPropertyMatrix
ASSIMP_API void aiSetImportPropertyMatrix(aiPropertyStore* p, const char* szName,
const C_STRUCT aiMatrix4x4* mat)
{
if (!mat) {
return;
}
ASSIMP_BEGIN_EXCEPTION_REGION();
PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
SetGenericProperty<aiMatrix4x4>(pp->matrices,szName,*mat,NULL);
ASSIMP_END_EXCEPTION_REGION(void);
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Rotation matrix to quaternion // Rotation matrix to quaternion
ASSIMP_API void aiCreateQuaternionFromMatrix(aiQuaternion* quat,const aiMatrix3x3* mat) ASSIMP_API void aiCreateQuaternionFromMatrix(aiQuaternion* quat,const aiMatrix3x3* mat)

View File

@ -69,27 +69,27 @@ ASSIMP_API unsigned int aiGetVersionRevision ()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiScene::aiScene() ASSIMP_API aiScene::aiScene()
: mFlags() : mFlags(0)
, mRootNode() , mRootNode(NULL)
, mNumMeshes() , mNumMeshes(0)
, mMeshes() , mMeshes(NULL)
, mNumMaterials() , mNumMaterials(0)
, mMaterials() , mMaterials(NULL)
, mNumAnimations() , mNumAnimations(0)
, mAnimations() , mAnimations(NULL)
, mNumTextures() , mNumTextures(0)
, mTextures() , mTextures(NULL)
, mNumLights() , mNumLights(0)
, mLights() , mLights(NULL)
, mNumCameras() , mNumCameras(0)
, mCameras() , mCameras(NULL)
, mPrivate(new Assimp::ScenePrivateData()) , mPrivate(new Assimp::ScenePrivateData())
{ {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiScene::~aiScene() ASSIMP_API aiScene::~aiScene()
{ {
// delete all sub-objects recursively // delete all sub-objects recursively
delete mRootNode; delete mRootNode;

View File

@ -74,7 +74,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/* Helper macro to set a pointer to NULL in debug builds /* Helper macro to set a pointer to NULL in debug builds
*/ */
#if (defined _DEBUG) #if (defined ASSIMP_BUILD_DEBUG)
# define AI_DEBUG_INVALIDATE_PTR(x) x = NULL; # define AI_DEBUG_INVALIDATE_PTR(x) x = NULL;
#else #else
# define AI_DEBUG_INVALIDATE_PTR(x) # define AI_DEBUG_INVALIDATE_PTR(x)

View File

@ -379,6 +379,43 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
} }
} }
// ------------------------------------------------------------------------------------------------
// Convert to UTF8 data to ISO-8859-1
void BaseImporter::ConvertUTF8toISO8859_1(std::string& data)
{
unsigned int size = data.size();
unsigned int i = 0, j = 0;
while(i < size) {
if((unsigned char) data[i] < 0x80) {
data[j] = data[i];
} else if(i < size - 1) {
if((unsigned char) data[i] == 0xC2) {
data[j] = data[++i];
} else if((unsigned char) data[i] == 0xC3) {
data[j] = ((unsigned char) data[++i] + 0x40);
} else {
std::stringstream stream;
stream << "UTF8 code " << std::hex << data[i] << data[i + 1] << " can not be converted into ISA-8859-1.";
DefaultLogger::get()->error(stream.str());
data[j++] = data[i++];
data[j] = data[i];
}
} else {
DefaultLogger::get()->error("UTF8 code but only one character remaining");
data[j] = data[i];
}
i++; j++;
}
data.resize(j);
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BaseImporter::TextFileToBuffer(IOStream* stream, void BaseImporter::TextFileToBuffer(IOStream* stream,
std::vector<char>& data) std::vector<char>& data)
@ -533,7 +570,7 @@ void BatchLoader::LoadAll()
for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) { for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) {
// force validation in debug builds // force validation in debug builds
unsigned int pp = (*it).flags; unsigned int pp = (*it).flags;
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
pp |= aiProcess_ValidateDataStructure; pp |= aiProcess_ValidateDataStructure;
#endif #endif
// setup config properties if necessary // setup config properties if necessary
@ -541,6 +578,7 @@ void BatchLoader::LoadAll()
pimpl->mFloatProperties = (*it).map.floats; pimpl->mFloatProperties = (*it).map.floats;
pimpl->mIntProperties = (*it).map.ints; pimpl->mIntProperties = (*it).map.ints;
pimpl->mStringProperties = (*it).map.strings; pimpl->mStringProperties = (*it).map.strings;
pimpl->mMatrixProperties = (*it).map.matrices;
if (!DefaultLogger::isNullLogger()) if (!DefaultLogger::isNullLogger())
{ {

View File

@ -331,6 +331,15 @@ public: // static utilities
static void ConvertToUTF8( static void ConvertToUTF8(
std::vector<char>& data); std::vector<char>& data);
// -------------------------------------------------------------------
/** An utility for all text file loaders. It converts a file from our
* UTF8 character set back to ISO-8859-1. Errors are reported, but ignored.
*
* @param data File buffer to be converted from UTF8 to ISO-8859-1. The buffer
* is resized as appropriate. */
static void ConvertUTF8toISO8859_1(
std::string& data);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Utility for text file loaders which copies the contents of the /** Utility for text file loaders which copies the contents of the
* file into a memory buffer and converts it to our UTF8 * file into a memory buffer and converts it to our UTF8

145
code/Bitmap.cpp 100644
View File

@ -0,0 +1,145 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2012, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file Bitmap.cpp
* @brief Defines bitmap format helper for textures
*
* Used for file formats which embed their textures into the model file.
*/
#include "AssimpPCH.h"
#include "Bitmap.h"
namespace Assimp {
void Bitmap::Save(aiTexture* texture, IOStream* file) {
if(file != NULL) {
Header header;
DIB dib;
dib.size = DIB::dib_size;
dib.width = texture->mWidth;
dib.height = texture->mHeight;
dib.planes = 1;
dib.bits_per_pixel = 8 * mBytesPerPixel;
dib.compression = 0;
dib.image_size = (((dib.width * mBytesPerPixel) + 3) & 0x0000FFFC) * dib.height;
dib.x_resolution = 0;
dib.y_resolution = 0;
dib.nb_colors = 0;
dib.nb_important_colors = 0;
header.type = 0x4D42; // 'BM'
header.offset = Header::header_size + DIB::dib_size;
header.size = header.offset + dib.image_size;
header.reserved1 = 0;
header.reserved2 = 0;
WriteHeader(header, file);
WriteDIB(dib, file);
WriteData(texture, file);
}
}
template<typename T>
inline std::size_t Copy(uint8_t* data, T& field) {
std::memcpy(data, &AI_BE(field), sizeof(field)); return sizeof(field);
}
void Bitmap::WriteHeader(Header& header, IOStream* file) {
uint8_t data[Header::header_size];
std::size_t offset = 0;
offset += Copy(&data[offset], header.type);
offset += Copy(&data[offset], header.size);
offset += Copy(&data[offset], header.reserved1);
offset += Copy(&data[offset], header.reserved2);
offset += Copy(&data[offset], header.offset);
file->Write(data, Header::header_size, 1);
}
void Bitmap::WriteDIB(DIB& dib, IOStream* file) {
uint8_t data[DIB::dib_size];
std::size_t offset = 0;
offset += Copy(&data[offset], dib.size);
offset += Copy(&data[offset], dib.width);
offset += Copy(&data[offset], dib.height);
offset += Copy(&data[offset], dib.planes);
offset += Copy(&data[offset], dib.bits_per_pixel);
offset += Copy(&data[offset], dib.compression);
offset += Copy(&data[offset], dib.image_size);
offset += Copy(&data[offset], dib.x_resolution);
offset += Copy(&data[offset], dib.y_resolution);
offset += Copy(&data[offset], dib.nb_colors);
offset += Copy(&data[offset], dib.nb_important_colors);
file->Write(data, DIB::dib_size, 1);
}
void Bitmap::WriteData(aiTexture* texture, IOStream* file) {
static const std::size_t padding_offset = 4;
static const uint8_t padding_data[padding_offset] = {0x0, 0x0, 0x0, 0x0};
unsigned int padding = (padding_offset - ((mBytesPerPixel * texture->mWidth) % padding_offset)) % padding_offset;
uint8_t pixel[mBytesPerPixel];
for(std::size_t i = 0; i < texture->mHeight; ++i) {
for(std::size_t j = 0; j < texture->mWidth; ++j) {
const aiTexel& texel = texture->pcData[(texture->mHeight - i - 1) * texture->mWidth + j]; // Bitmap files are stored in bottom-up format
pixel[0] = texel.r;
pixel[1] = texel.g;
pixel[2] = texel.b;
pixel[3] = texel.a;
file->Write(pixel, mBytesPerPixel, 1);
}
file->Write(padding_data, padding, 1);
}
}
}

139
code/Bitmap.h 100644
View File

@ -0,0 +1,139 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2012, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file Bitmap.h
* @brief Defines bitmap format helper for textures
*
* Used for file formats which embed their textures into the model file.
*/
#ifndef AI_BITMAP_H_INC
#define AI_BITMAP_H_INC
namespace Assimp {
class Bitmap {
protected:
struct Header {
uint16_t type;
uint32_t size;
uint16_t reserved1;
uint16_t reserved2;
uint32_t offset;
// We define the struct size because sizeof(Header) might return a wrong result because of structure padding.
// Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field).
static const std::size_t header_size =
sizeof(uint16_t) + // type
sizeof(uint32_t) + // size
sizeof(uint16_t) + // reserved1
sizeof(uint16_t) + // reserved2
sizeof(uint32_t); // offset
};
struct DIB {
uint32_t size;
int32_t width;
int32_t height;
uint16_t planes;
uint16_t bits_per_pixel;
uint32_t compression;
uint32_t image_size;
int32_t x_resolution;
int32_t y_resolution;
uint32_t nb_colors;
uint32_t nb_important_colors;
// We define the struct size because sizeof(DIB) might return a wrong result because of structure padding.
// Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field).
static const std::size_t dib_size =
sizeof(uint32_t) + // size
sizeof(int32_t) + // width
sizeof(int32_t) + // height
sizeof(uint16_t) + // planes
sizeof(uint16_t) + // bits_per_pixel
sizeof(uint32_t) + // compression
sizeof(uint32_t) + // image_size
sizeof(int32_t) + // x_resolution
sizeof(int32_t) + // y_resolution
sizeof(uint32_t) + // nb_colors
sizeof(uint32_t); // nb_important_colors
};
static const std::size_t mBytesPerPixel = 4;
public:
static void Save(aiTexture* texture, IOStream* file);
protected:
static void WriteHeader(Header& header, IOStream* file);
static void WriteDIB(DIB& dib, IOStream* file);
static void WriteData(aiTexture* texture, IOStream* file);
};
}
#endif // AI_BITMAP_H_INC

View File

@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "TinyFormatter.h" #include "TinyFormatter.h"
// enable verbose log output. really verbose, so be careful. // enable verbose log output. really verbose, so be careful.
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
# define ASSIMP_BUILD_BLENDER_DEBUG # define ASSIMP_BUILD_BLENDER_DEBUG
#endif #endif

View File

@ -76,13 +76,13 @@ SOURCE_GROUP(Boost FILES ${Boost_SRCS})
SET( Logging_SRCS SET( Logging_SRCS
${HEADER_PATH}/DefaultLogger.hpp ${HEADER_PATH}/DefaultLogger.hpp
${HEADER_PATH}/IOStream.hpp
${HEADER_PATH}/LogStream.hpp ${HEADER_PATH}/LogStream.hpp
${HEADER_PATH}/Logger.hpp ${HEADER_PATH}/Logger.hpp
${HEADER_PATH}/NullLogger.hpp ${HEADER_PATH}/NullLogger.hpp
Win32DebugLogStream.h Win32DebugLogStream.h
DefaultLogger.cpp DefaultLogger.cpp
FileLogStream.h FileLogStream.h
StdOStreamLogStream.h
) )
SOURCE_GROUP(Logging FILES ${Logging_SRCS}) SOURCE_GROUP(Logging FILES ${Logging_SRCS})
@ -107,8 +107,8 @@ SET( Common_SRCS
Hash.h Hash.h
Importer.cpp Importer.cpp
IFF.h IFF.h
MemoryIOWrapper.h
ParsingUtils.h ParsingUtils.h
StdOStreamLogStream.h
StreamReader.h StreamReader.h
StringComparison.h StringComparison.h
SGSpatialSort.cpp SGSpatialSort.cpp
@ -140,6 +140,8 @@ SET( Common_SRCS
TinyFormatter.h TinyFormatter.h
Profiler.h Profiler.h
LogAux.h LogAux.h
Bitmap.cpp
Bitmap.h
) )
SOURCE_GROUP(Common FILES ${Common_SRCS}) SOURCE_GROUP(Common FILES ${Common_SRCS})
@ -461,8 +463,6 @@ SET( PostProcessing_SRCS
SortByPTypeProcess.h SortByPTypeProcess.h
SplitLargeMeshes.cpp SplitLargeMeshes.cpp
SplitLargeMeshes.h SplitLargeMeshes.h
TerragenLoader.cpp
TerragenLoader.h
TextureTransform.cpp TextureTransform.cpp
TextureTransform.h TextureTransform.h
TriangulateProcess.cpp TriangulateProcess.cpp
@ -520,6 +520,12 @@ SET( STL_SRCS
) )
SOURCE_GROUP( STL FILES ${STL_SRCS}) SOURCE_GROUP( STL FILES ${STL_SRCS})
SET( Terragen_SRCS
TerragenLoader.cpp
TerragenLoader.h
)
SOURCE_GROUP( Terragen FILES ${Terragen_SRCS})
SET( Unreal_SRCS SET( Unreal_SRCS
UnrealLoader.cpp UnrealLoader.cpp
UnrealLoader.h UnrealLoader.h
@ -655,6 +661,7 @@ SET( assimp_src
${Raw_SRCS} ${Raw_SRCS}
${SMD_SRCS} ${SMD_SRCS}
${STL_SRCS} ${STL_SRCS}
${Terragen_SRCS}
${Unreal_SRCS} ${Unreal_SRCS}
${XFile_SRCS} ${XFile_SRCS}
${Extra_SRCS} ${Extra_SRCS}
@ -677,9 +684,14 @@ SET( assimp_src
${PUBLIC_HEADERS} ${PUBLIC_HEADERS}
${COMPILER_HEADERS} ${COMPILER_HEADERS}
# Old precompiled header
# (removed because the precompiled header is not updated when visual studio switch configuration which leads to failed compilation.
# Moreover it's a drag to recompile assimp entirely each time a modification is made to one of the included header, which is definitely counter-productive.)
AssimpPCH.cpp
) )
ADD_MSVC_PRECOMPILED_HEADER("AssimpPCH.h" "AssimpPCH.cpp" assimp_src) #ADD_MSVC_PRECOMPILED_HEADER("AssimpPCH.h" "AssimpPCH.cpp" assimp_src)
ADD_LIBRARY( assimp ${assimp_src} ) ADD_LIBRARY( assimp ${assimp_src} )

View File

@ -44,6 +44,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER #ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
#include "ColladaExporter.h" #include "ColladaExporter.h"
#include "Bitmap.h"
#include "fast_atof.h"
#include "SceneCombiner.h"
#include <ctime>
#include <set>
using namespace Assimp; using namespace Assimp;
namespace Assimp namespace Assimp
@ -53,8 +60,25 @@ namespace Assimp
// Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp // Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
void ExportSceneCollada(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene) void ExportSceneCollada(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
{ {
std::string path = "";
std::string file = pFile;
// We need to test both types of folder separators because pIOSystem->getOsSeparator() is not reliable.
// Moreover, the path given by some applications is not even consistent with the OS specific type of separator.
const char* end_path = std::max(strrchr(pFile, '\\'), strrchr(pFile, '/'));
if(end_path != NULL) {
path = std::string(pFile, end_path + 1 - pFile);
file = file.substr(end_path + 1 - pFile, file.npos);
std::size_t pos = file.find_last_of('.');
if(pos != file.npos) {
file = file.substr(0, pos);
}
}
// invoke the exporter // invoke the exporter
ColladaExporter iDoTheExportThing( pScene); ColladaExporter iDoTheExportThing( pScene, pIOSystem, path, file);
// we're still here - export successfully completed. Write result to the given IOSYstem // we're still here - export successfully completed. Write result to the given IOSYstem
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt")); boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
@ -71,12 +95,13 @@ void ExportSceneCollada(const char* pFile,IOSystem* pIOSystem, const aiScene* pS
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor for a specific scene to export // Constructor for a specific scene to export
ColladaExporter::ColladaExporter( const aiScene* pScene) ColladaExporter::ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file) : mIOSystem(pIOSystem), mPath(path), mFile(file)
{ {
// make sure that all formatting happens using the standard, C locale and not the user's current locale // make sure that all formatting happens using the standard, C locale and not the user's current locale
mOutput.imbue( std::locale("C") ); mOutput.imbue( std::locale("C") );
mScene = pScene; mScene = pScene;
mSceneOwned = false;
// set up strings // set up strings
endstr = "\n"; endstr = "\n";
@ -85,6 +110,15 @@ ColladaExporter::ColladaExporter( const aiScene* pScene)
WriteFile(); WriteFile();
} }
// ------------------------------------------------------------------------------------------------
// Destructor
ColladaExporter::~ColladaExporter()
{
if(mSceneOwned) {
delete mScene;
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Starts writing the contents // Starts writing the contents
void ColladaExporter::WriteFile() void ColladaExporter::WriteFile()
@ -95,9 +129,10 @@ void ColladaExporter::WriteFile()
mOutput << "<COLLADA xmlns=\"http://www.collada.org/2005/11/COLLADASchema\" version=\"1.4.1\">" << endstr; mOutput << "<COLLADA xmlns=\"http://www.collada.org/2005/11/COLLADASchema\" version=\"1.4.1\">" << endstr;
PushTag(); PushTag();
WriteTextures();
WriteHeader(); WriteHeader();
WriteMaterials(); WriteMaterials();
WriteGeometryLibrary(); WriteGeometryLibrary();
WriteSceneLibrary(); WriteSceneLibrary();
@ -105,7 +140,7 @@ void ColladaExporter::WriteFile()
// useless Collada fu at the end, just in case we haven't had enough indirections, yet. // useless Collada fu at the end, just in case we haven't had enough indirections, yet.
mOutput << startstr << "<scene>" << endstr; mOutput << startstr << "<scene>" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<instance_visual_scene url=\"#myScene\" />" << endstr; mOutput << startstr << "<instance_visual_scene url=\"#" + std::string(mScene->mRootNode->mName.C_Str()) + "\" />" << endstr;
PopTag(); PopTag();
mOutput << startstr << "</scene>" << endstr; mOutput << startstr << "</scene>" << endstr;
PopTag(); PopTag();
@ -116,23 +151,131 @@ void ColladaExporter::WriteFile()
// Writes the asset header // Writes the asset header
void ColladaExporter::WriteHeader() void ColladaExporter::WriteHeader()
{ {
// Dummy stuff. Nobody actually cares for it anyways static const float epsilon = 0.000001f;
static const aiQuaternion x_rot(aiMatrix3x3(
0, -1, 0,
1, 0, 0,
0, 0, 1));
static const aiQuaternion y_rot(aiMatrix3x3(
1, 0, 0,
0, 1, 0,
0, 0, 1));
static const aiQuaternion z_rot(aiMatrix3x3(
1, 0, 0,
0, 0, 1,
0, -1, 0));
static const unsigned int date_nb_chars = 20;
char date_str[date_nb_chars];
std::time_t date = std::time(NULL);
std::strftime(date_str, date_nb_chars, "%Y-%m-%dT%H:%M:%S", std::localtime(&date));
std::string scene_name = mScene->mRootNode->mName.C_Str();
aiVector3D scaling;
aiQuaternion rotation;
aiVector3D position;
mScene->mRootNode->mTransformation.Decompose(scaling, rotation, position);
bool add_root_node = false;
float scale = 1.0;
if(std::abs(scaling.x - scaling.y) <= epsilon && std::abs(scaling.x - scaling.z) <= epsilon && std::abs(scaling.y - scaling.z) <= epsilon) {
scale = (float) ((((double) scaling.x) + ((double) scaling.y) + ((double) scaling.z)) / 3.0);
} else {
add_root_node = true;
}
std::string up_axis = "Y_UP";
if(rotation.Equal(x_rot, epsilon)) {
up_axis = "X_UP";
} else if(rotation.Equal(y_rot, epsilon)) {
up_axis = "Y_UP";
} else if(rotation.Equal(z_rot, epsilon)) {
up_axis = "Z_UP";
} else {
add_root_node = true;
}
if(! position.Equal(aiVector3D(0, 0, 0))) {
add_root_node = true;
}
if(mScene->mRootNode->mNumChildren == 0) {
add_root_node = true;
}
if(add_root_node) {
aiScene* scene;
SceneCombiner::CopyScene(&scene, mScene);
aiNode* root = new aiNode("Scene");
root->mNumChildren = 1;
root->mChildren = new aiNode*[root->mNumChildren];
root->mChildren[0] = scene->mRootNode;
scene->mRootNode->mParent = root;
scene->mRootNode = root;
mScene = scene;
mSceneOwned = true;
up_axis = "Y_UP";
scale = 1.0;
}
mOutput << startstr << "<asset>" << endstr; mOutput << startstr << "<asset>" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<contributor>" << endstr; mOutput << startstr << "<contributor>" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<author>Someone</author>" << endstr; mOutput << startstr << "<author>Assimp</author>" << endstr;
mOutput << startstr << "<authoring_tool>Assimp Collada Exporter</authoring_tool>" << endstr; mOutput << startstr << "<authoring_tool>Assimp Collada Exporter</authoring_tool>" << endstr;
PopTag(); PopTag();
mOutput << startstr << "</contributor>" << endstr; mOutput << startstr << "</contributor>" << endstr;
mOutput << startstr << "<created>2000-01-01T23:59:59</created>" << endstr; mOutput << startstr << "<created>" << date_str << "</created>" << endstr;
mOutput << startstr << "<modified>2000-01-01T23:59:59</modified>" << endstr; mOutput << startstr << "<modified>" << date_str << "</modified>" << endstr;
mOutput << startstr << "<unit name=\"centimeter\" meter=\"0.01\" />" << endstr; mOutput << startstr << "<unit name=\"meter\" meter=\"" << scale << "\" />" << endstr;
mOutput << startstr << "<up_axis>Y_UP</up_axis>" << endstr; mOutput << startstr << "<up_axis>" << up_axis << "</up_axis>" << endstr;
PopTag(); PopTag();
mOutput << startstr << "</asset>" << endstr; mOutput << startstr << "</asset>" << endstr;
} }
// ------------------------------------------------------------------------------------------------
// Write the embedded textures
void ColladaExporter::WriteTextures() {
static const unsigned int buffer_size = 1024;
char str[buffer_size];
if(mScene->HasTextures()) {
for(unsigned int i = 0; i < mScene->mNumTextures; i++) {
// It would be great to be able to create a directory in portable standard C++, but it's not the case,
// so we just write the textures in the current directory.
aiTexture* texture = mScene->mTextures[i];
ASSIMP_itoa10(str, buffer_size, i + 1);
std::string name = mFile + "_texture_" + (i < 1000 ? "0" : "") + (i < 100 ? "0" : "") + (i < 10 ? "0" : "") + str + "." + ((const char*) texture->achFormatHint);
boost::scoped_ptr<IOStream> outfile(mIOSystem->Open(mPath + name, "wb"));
if(outfile == NULL) {
throw DeadlyExportError("could not open output texture file: " + mPath + name);
}
if(texture->mHeight == 0) {
outfile->Write((void*) texture->pcData, texture->mWidth, 1);
} else {
Bitmap::Save(texture, outfile.get());
}
outfile->Flush();
textures.insert(std::make_pair(i, name));
}
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a single surface entry from the given material keys // Reads a single surface entry from the given material keys
void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex) void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex)
@ -142,12 +285,39 @@ void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial*
aiString texfile; aiString texfile;
unsigned int uvChannel = 0; unsigned int uvChannel = 0;
pSrcMat->GetTexture( pTexture, 0, &texfile, NULL, &uvChannel); pSrcMat->GetTexture( pTexture, 0, &texfile, NULL, &uvChannel);
poSurface.texture = texfile.C_Str();
std::string index_str(texfile.C_Str());
if(index_str.size() != 0 && index_str[0] == '*')
{
unsigned int index;
index_str = index_str.substr(1, std::string::npos);
try {
index = (unsigned int) strtoul10_64(index_str.c_str());
} catch(std::exception& error) {
throw DeadlyExportError(error.what());
}
std::map<unsigned int, std::string>::const_iterator name = textures.find(index);
if(name != textures.end()) {
poSurface.texture = name->second;
} else {
throw DeadlyExportError("could not find embedded texture at index " + index_str);
}
} else
{
poSurface.texture = texfile.C_Str();
}
poSurface.channel = uvChannel; poSurface.channel = uvChannel;
poSurface.exist = true;
} else } else
{ {
if( pKey ) if( pKey )
pSrcMat->Get( pKey, pType, pIndex, poSurface.color); poSurface.exist = pSrcMat->Get( pKey, pType, pIndex, poSurface.color) == aiReturn_SUCCESS;
} }
} }
@ -177,17 +347,19 @@ void ColladaExporter::WriteImageEntry( const Surface& pSurface, const std::strin
// Writes a color-or-texture entry into an effect definition // Writes a color-or-texture entry into an effect definition
void ColladaExporter::WriteTextureColorEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pImageName) void ColladaExporter::WriteTextureColorEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pImageName)
{ {
mOutput << startstr << "<" << pTypeName << ">" << endstr; if(pSurface.exist) {
PushTag(); mOutput << startstr << "<" << pTypeName << ">" << endstr;
if( pSurface.texture.empty() ) PushTag();
{ if( pSurface.texture.empty() )
mOutput << startstr << "<color sid=\"" << pTypeName << "\">" << pSurface.color.r << " " << pSurface.color.g << " " << pSurface.color.b << " " << pSurface.color.a << "</color>" << endstr; {
} else mOutput << startstr << "<color sid=\"" << pTypeName << "\">" << pSurface.color.r << " " << pSurface.color.g << " " << pSurface.color.b << " " << pSurface.color.a << "</color>" << endstr;
{ } else
mOutput << startstr << "<texture texture=\"" << pImageName << "\" texcoord=\"CHANNEL" << pSurface.channel << "\" />" << endstr; {
mOutput << startstr << "<texture texture=\"" << pImageName << "\" texcoord=\"CHANNEL" << pSurface.channel << "\" />" << endstr;
}
PopTag();
mOutput << startstr << "</" << pTypeName << ">" << endstr;
} }
PopTag();
mOutput << startstr << "</" << pTypeName << ">" << endstr;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -219,12 +391,27 @@ void ColladaExporter::WriteTextureParamEntry( const Surface& pSurface, const std
} }
} }
// ------------------------------------------------------------------------------------------------
// Writes a scalar property
void ColladaExporter::WriteFloatEntry( const Property& pProperty, const std::string& pTypeName)
{
if(pProperty.exist) {
mOutput << startstr << "<" << pTypeName << ">" << endstr;
PushTag();
mOutput << startstr << "<float sid=\"" << pTypeName << "\">" << pProperty.value << "</float>" << endstr;
PopTag();
mOutput << startstr << "</" << pTypeName << ">" << endstr;
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Writes the material setup // Writes the material setup
void ColladaExporter::WriteMaterials() void ColladaExporter::WriteMaterials()
{ {
materials.resize( mScene->mNumMaterials); materials.resize( mScene->mNumMaterials);
std::set<std::string> material_names;
/// collect all materials from the scene /// collect all materials from the scene
size_t numTextures = 0; size_t numTextures = 0;
for( size_t a = 0; a < mScene->mNumMaterials; ++a ) for( size_t a = 0; a < mScene->mNumMaterials; ++a )
@ -243,6 +430,20 @@ void ColladaExporter::WriteMaterials()
} }
} }
aiShadingMode shading;
materials[a].shading_model = "phong";
if(mat->Get( AI_MATKEY_SHADING_MODEL, shading) == aiReturn_SUCCESS) {
if(shading == aiShadingMode_Phong) {
materials[a].shading_model = "phong";
} else if(shading == aiShadingMode_Blinn) {
materials[a].shading_model = "blinn";
} else if(shading == aiShadingMode_NoShading) {
materials[a].shading_model = "constant";
} else if(shading == aiShadingMode_Gouraud) {
materials[a].shading_model = "lambert";
}
}
ReadMaterialSurface( materials[a].ambient, mat, aiTextureType_AMBIENT, AI_MATKEY_COLOR_AMBIENT); ReadMaterialSurface( materials[a].ambient, mat, aiTextureType_AMBIENT, AI_MATKEY_COLOR_AMBIENT);
if( !materials[a].ambient.texture.empty() ) numTextures++; if( !materials[a].ambient.texture.empty() ) numTextures++;
ReadMaterialSurface( materials[a].diffuse, mat, aiTextureType_DIFFUSE, AI_MATKEY_COLOR_DIFFUSE); ReadMaterialSurface( materials[a].diffuse, mat, aiTextureType_DIFFUSE, AI_MATKEY_COLOR_DIFFUSE);
@ -253,10 +454,15 @@ void ColladaExporter::WriteMaterials()
if( !materials[a].emissive.texture.empty() ) numTextures++; if( !materials[a].emissive.texture.empty() ) numTextures++;
ReadMaterialSurface( materials[a].reflective, mat, aiTextureType_REFLECTION, AI_MATKEY_COLOR_REFLECTIVE); ReadMaterialSurface( materials[a].reflective, mat, aiTextureType_REFLECTION, AI_MATKEY_COLOR_REFLECTIVE);
if( !materials[a].reflective.texture.empty() ) numTextures++; if( !materials[a].reflective.texture.empty() ) numTextures++;
ReadMaterialSurface( materials[a].transparent, mat, aiTextureType_OPACITY, AI_MATKEY_COLOR_TRANSPARENT);
if( !materials[a].transparent.texture.empty() ) numTextures++;
ReadMaterialSurface( materials[a].normal, mat, aiTextureType_NORMALS, NULL, 0, 0); ReadMaterialSurface( materials[a].normal, mat, aiTextureType_NORMALS, NULL, 0, 0);
if( !materials[a].normal.texture.empty() ) numTextures++; if( !materials[a].normal.texture.empty() ) numTextures++;
mat->Get( AI_MATKEY_SHININESS, materials[a].shininess); materials[a].shininess.exist = mat->Get( AI_MATKEY_SHININESS, materials[a].shininess.value) == aiReturn_SUCCESS;
materials[a].transparency.exist = mat->Get( AI_MATKEY_OPACITY, materials[a].transparency.value) == aiReturn_SUCCESS;
materials[a].transparency.value = 1 - materials[a].transparency.value;
materials[a].index_refraction.exist = mat->Get( AI_MATKEY_REFRACTI, materials[a].index_refraction.value) == aiReturn_SUCCESS;
} }
// output textures if present // output textures if present
@ -270,8 +476,9 @@ void ColladaExporter::WriteMaterials()
WriteImageEntry( mat.ambient, mat.name + "-ambient-image"); WriteImageEntry( mat.ambient, mat.name + "-ambient-image");
WriteImageEntry( mat.diffuse, mat.name + "-diffuse-image"); WriteImageEntry( mat.diffuse, mat.name + "-diffuse-image");
WriteImageEntry( mat.specular, mat.name + "-specular-image"); WriteImageEntry( mat.specular, mat.name + "-specular-image");
WriteImageEntry( mat.emissive, mat.name + "-emissive-image"); WriteImageEntry( mat.emissive, mat.name + "-emission-image");
WriteImageEntry( mat.reflective, mat.name + "-reflective-image"); WriteImageEntry( mat.reflective, mat.name + "-reflective-image");
WriteImageEntry( mat.transparent, mat.name + "-transparent-image");
WriteImageEntry( mat.normal, mat.name + "-normal-image"); WriteImageEntry( mat.normal, mat.name + "-normal-image");
} }
PopTag(); PopTag();
@ -293,37 +500,35 @@ void ColladaExporter::WriteMaterials()
PushTag(); PushTag();
// write sampler- and surface params for the texture entries // write sampler- and surface params for the texture entries
WriteTextureParamEntry( mat.emissive, "emissive", mat.name); WriteTextureParamEntry( mat.emissive, "emission", mat.name);
WriteTextureParamEntry( mat.ambient, "ambient", mat.name); WriteTextureParamEntry( mat.ambient, "ambient", mat.name);
WriteTextureParamEntry( mat.diffuse, "diffuse", mat.name); WriteTextureParamEntry( mat.diffuse, "diffuse", mat.name);
WriteTextureParamEntry( mat.specular, "specular", mat.name); WriteTextureParamEntry( mat.specular, "specular", mat.name);
WriteTextureParamEntry( mat.reflective, "reflective", mat.name); WriteTextureParamEntry( mat.reflective, "reflective", mat.name);
WriteTextureParamEntry( mat.transparent, "transparent", mat.name);
WriteTextureParamEntry( mat.normal, "normal", mat.name);
mOutput << startstr << "<technique sid=\"standard\">" << endstr; mOutput << startstr << "<technique sid=\"standard\">" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<phong>" << endstr; mOutput << startstr << "<" << mat.shading_model << ">" << endstr;
PushTag(); PushTag();
WriteTextureColorEntry( mat.emissive, "emission", mat.name + "-emissive-sampler"); WriteTextureColorEntry( mat.emissive, "emission", mat.name + "-emission-sampler");
WriteTextureColorEntry( mat.ambient, "ambient", mat.name + "-ambient-sampler"); WriteTextureColorEntry( mat.ambient, "ambient", mat.name + "-ambient-sampler");
WriteTextureColorEntry( mat.diffuse, "diffuse", mat.name + "-diffuse-sampler"); WriteTextureColorEntry( mat.diffuse, "diffuse", mat.name + "-diffuse-sampler");
WriteTextureColorEntry( mat.specular, "specular", mat.name + "-specular-sampler"); WriteTextureColorEntry( mat.specular, "specular", mat.name + "-specular-sampler");
WriteFloatEntry(mat.shininess, "shininess");
mOutput << startstr << "<shininess>" << endstr;
PushTag();
mOutput << startstr << "<float sid=\"shininess\">" << mat.shininess << "</float>" << endstr;
PopTag();
mOutput << startstr << "</shininess>" << endstr;
WriteTextureColorEntry( mat.reflective, "reflective", mat.name + "-reflective-sampler"); WriteTextureColorEntry( mat.reflective, "reflective", mat.name + "-reflective-sampler");
WriteTextureColorEntry( mat.transparent, "transparent", mat.name + "-transparent-sampler");
WriteFloatEntry(mat.transparency, "transparency");
WriteFloatEntry(mat.index_refraction, "index_of_refraction");
// deactivated because the Collada spec PHONG model does not allow other textures. if(! mat.normal.texture.empty()) {
// if( !mat.normal.texture.empty() ) WriteTextureColorEntry( mat.normal, "bump", mat.name + "-normal-sampler");
// WriteTextureColorEntry( mat.normal, "bump", mat.name + "-normal-sampler"); }
PopTag(); PopTag();
mOutput << startstr << "</phong>" << endstr; mOutput << startstr << "</" << mat.shading_model << ">" << endstr;
PopTag(); PopTag();
mOutput << startstr << "</technique>" << endstr; mOutput << startstr << "</technique>" << endstr;
PopTag(); PopTag();
@ -546,13 +751,16 @@ void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataTy
// Writes the scene library // Writes the scene library
void ColladaExporter::WriteSceneLibrary() void ColladaExporter::WriteSceneLibrary()
{ {
std::string scene_name = mScene->mRootNode->mName.C_Str();
mOutput << startstr << "<library_visual_scenes>" << endstr; mOutput << startstr << "<library_visual_scenes>" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<visual_scene id=\"myScene\" name=\"myScene\">" << endstr; mOutput << startstr << "<visual_scene id=\"" + scene_name + "\" name=\"" + scene_name + "\">" << endstr;
PushTag(); PushTag();
// start recursive write at the root node // start recursive write at the root node
WriteNode( mScene->mRootNode); for( size_t a = 0; a < mScene->mRootNode->mNumChildren; ++a )
WriteNode( mScene->mRootNode->mChildren[a]);
PopTag(); PopTag();
mOutput << startstr << "</visual_scene>" << endstr; mOutput << startstr << "</visual_scene>" << endstr;
@ -581,22 +789,22 @@ void ColladaExporter::WriteNode( const aiNode* pNode)
for( size_t a = 0; a < pNode->mNumMeshes; ++a ) for( size_t a = 0; a < pNode->mNumMeshes; ++a )
{ {
const aiMesh* mesh = mScene->mMeshes[pNode->mMeshes[a]]; const aiMesh* mesh = mScene->mMeshes[pNode->mMeshes[a]];
// do not instanciate mesh if empty. I wonder how this could happen // do not instanciate mesh if empty. I wonder how this could happen
if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 ) if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
continue; continue;
mOutput << startstr << "<instance_geometry url=\"#" << GetMeshId( pNode->mMeshes[a]) << "\">" << endstr; mOutput << startstr << "<instance_geometry url=\"#" << GetMeshId( pNode->mMeshes[a]) << "\">" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<bind_material>" << endstr; mOutput << startstr << "<bind_material>" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<technique_common>" << endstr; mOutput << startstr << "<technique_common>" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<instance_material symbol=\"theresonlyone\" target=\"#" << materials[mesh->mMaterialIndex].name << "\" />" << endstr; mOutput << startstr << "<instance_material symbol=\"theresonlyone\" target=\"#" << materials[mesh->mMaterialIndex].name << "\" />" << endstr;
PopTag(); PopTag();
mOutput << startstr << "</technique_common>" << endstr; mOutput << startstr << "</technique_common>" << endstr;
PopTag(); PopTag();
mOutput << startstr << "</bind_material>" << endstr; mOutput << startstr << "</bind_material>" << endstr;
PopTag(); PopTag();
mOutput << startstr << "</instance_geometry>" << endstr; mOutput << startstr << "</instance_geometry>" << endstr;
} }

View File

@ -59,7 +59,10 @@ class ColladaExporter
{ {
public: public:
/// Constructor for a specific scene to export /// Constructor for a specific scene to export
ColladaExporter( const aiScene* pScene); ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file);
/// Destructor
virtual ~ColladaExporter();
protected: protected:
/// Starts writing the contents /// Starts writing the contents
@ -68,8 +71,11 @@ protected:
/// Writes the asset header /// Writes the asset header
void WriteHeader(); void WriteHeader();
/// Writes the material setup /// Writes the embedded textures
void WriteMaterials(); void WriteTextures();
/// Writes the material setup
void WriteMaterials();
/// Writes the geometry library /// Writes the geometry library
void WriteGeometryLibrary(); void WriteGeometryLibrary();
@ -101,8 +107,18 @@ public:
std::stringstream mOutput; std::stringstream mOutput;
protected: protected:
/// The IOSystem for output
IOSystem* mIOSystem;
/// Path of the directory where the scene will be exported
const std::string mPath;
/// Name of the file (without extension) where the scene will be exported
const std::string mFile;
/// The scene to be written /// The scene to be written
const aiScene* mScene; const aiScene* mScene;
bool mSceneOwned;
/// current line start string, contains the current indentation for simple stream insertion /// current line start string, contains the current indentation for simple stream insertion
std::string startstr; std::string startstr;
@ -112,24 +128,35 @@ protected:
// pair of color and texture - texture precedences color // pair of color and texture - texture precedences color
struct Surface struct Surface
{ {
bool exist;
aiColor4D color; aiColor4D color;
std::string texture; std::string texture;
size_t channel; size_t channel;
Surface() { channel = 0; } Surface() { exist = false; channel = 0; }
};
struct Property
{
bool exist;
float value;
Property() { exist = false; }
}; };
// summarize a material in an convinient way. // summarize a material in an convinient way.
struct Material struct Material
{ {
std::string name; std::string name;
Surface ambient, diffuse, specular, emissive, reflective, normal; std::string shading_model;
float shininess; /// specular exponent Surface ambient, diffuse, specular, emissive, reflective, transparent, normal;
Property shininess, transparency, index_refraction;
Material() { shininess = 16.0f; } Material() {}
}; };
std::vector<Material> materials; std::vector<Material> materials;
std::map<unsigned int, std::string> textures;
protected: protected:
/// Dammit C++ - y u no compile two-pass? No I have to add all methods below the struct definitions /// Dammit C++ - y u no compile two-pass? No I have to add all methods below the struct definitions
/// Reads a single surface entry from the given material keys /// Reads a single surface entry from the given material keys
@ -140,6 +167,8 @@ protected:
void WriteTextureParamEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pMatName); void WriteTextureParamEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pMatName);
/// Writes a color-or-texture entry into an effect definition /// Writes a color-or-texture entry into an effect definition
void WriteTextureColorEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pImageName); void WriteTextureColorEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pImageName);
/// Writes a scalar property
void WriteFloatEntry( const Property& pProperty, const std::string& pTypeName);
}; };
} }

View File

@ -253,7 +253,7 @@ void DefaultLogger::OnDebug( const char* message )
if ( m_Severity == Logger::NORMAL ) if ( m_Severity == Logger::NORMAL )
return; return;
char msg[MAX_LOG_MESSAGE_LENGTH*2]; char msg[MAX_LOG_MESSAGE_LENGTH + 16];
::sprintf(msg,"Debug, T%i: %s", GetThreadID(), message ); ::sprintf(msg,"Debug, T%i: %s", GetThreadID(), message );
WriteToStreams( msg, Logger::Debugging ); WriteToStreams( msg, Logger::Debugging );
@ -263,7 +263,7 @@ void DefaultLogger::OnDebug( const char* message )
// Logs an info // Logs an info
void DefaultLogger::OnInfo( const char* message ) void DefaultLogger::OnInfo( const char* message )
{ {
char msg[MAX_LOG_MESSAGE_LENGTH*2]; char msg[MAX_LOG_MESSAGE_LENGTH + 16];
::sprintf(msg,"Info, T%i: %s", GetThreadID(), message ); ::sprintf(msg,"Info, T%i: %s", GetThreadID(), message );
WriteToStreams( msg , Logger::Info ); WriteToStreams( msg , Logger::Info );
@ -273,7 +273,7 @@ void DefaultLogger::OnInfo( const char* message )
// Logs a warning // Logs a warning
void DefaultLogger::OnWarn( const char* message ) void DefaultLogger::OnWarn( const char* message )
{ {
char msg[MAX_LOG_MESSAGE_LENGTH*2]; char msg[MAX_LOG_MESSAGE_LENGTH + 16];
::sprintf(msg,"Warn, T%i: %s", GetThreadID(), message ); ::sprintf(msg,"Warn, T%i: %s", GetThreadID(), message );
WriteToStreams( msg, Logger::Warn ); WriteToStreams( msg, Logger::Warn );
@ -283,7 +283,7 @@ void DefaultLogger::OnWarn( const char* message )
// Logs an error // Logs an error
void DefaultLogger::OnError( const char* message ) void DefaultLogger::OnError( const char* message )
{ {
char msg[MAX_LOG_MESSAGE_LENGTH*2]; char msg[MAX_LOG_MESSAGE_LENGTH + 16];
::sprintf(msg,"Error, T%i: %s", GetThreadID(), message ); ::sprintf(msg,"Error, T%i: %s", GetThreadID(), message );
WriteToStreams( msg, Logger::Err ); WriteToStreams( msg, Logger::Err );

View File

@ -176,6 +176,8 @@ Exporter :: Exporter()
Exporter :: ~Exporter() Exporter :: ~Exporter()
{ {
FreeBlob(); FreeBlob();
delete pimpl;
} }

View File

@ -2014,7 +2014,7 @@ private:
ai_assert(curves.size()); ai_assert(curves.size());
// sanity check whether the input is ok // sanity check whether the input is ok
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
{ const Object* target = NULL; { const Object* target = NULL;
BOOST_FOREACH(const AnimationCurveNode* node, curves) { BOOST_FOREACH(const AnimationCurveNode* node, curves) {
if(!target) { if(!target) {

View File

@ -565,7 +565,7 @@ void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const cha
// terminate zlib // terminate zlib
inflateEnd(&zstream); inflateEnd(&zstream);
} }
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
else { else {
// runtime check for this happens at tokenization stage // runtime check for this happens at tokenization stage
ai_assert(false); ai_assert(false);

View File

@ -221,7 +221,7 @@ bool IntersectsBoundaryProfile( const IfcVector3& e0, const IfcVector3& e1, cons
const IfcFloat s = (x*e.y - e.x*y)/det; const IfcFloat s = (x*e.y - e.x*y)/det;
const IfcFloat t = (x*b.y - b.x*y)/det; const IfcFloat t = (x*b.y - b.x*y)/det;
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
const IfcVector3 check = b0 + b*s - (e0 + e*t); const IfcVector3 check = b0 + b*s - (e0 + e*t);
ai_assert((IfcVector2(check.x,check.y)).SquareLength() < 1e-5); ai_assert((IfcVector2(check.x,check.y)).SquareLength() < 1e-5);
#endif #endif
@ -417,7 +417,7 @@ void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const IfcPolygonalBounded
IfcVector3 isectpos; IfcVector3 isectpos;
const Intersect isect = extra_point_flag ? Intersect_No : IntersectSegmentPlane(p,n,e0,e1,isectpos); const Intersect isect = extra_point_flag ? Intersect_No : IntersectSegmentPlane(p,n,e0,e1,isectpos);
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
if (isect == Intersect_Yes) { if (isect == Intersect_Yes) {
const IfcFloat f = fabs((isectpos - p)*n); const IfcFloat f = fabs((isectpos - p)*n);
ai_assert(f < 1e-5); ai_assert(f < 1e-5);

View File

@ -550,7 +550,7 @@ Curve* Curve :: Convert(const IFC::IfcCurve& curve,ConversionData& conv)
return NULL; return NULL;
} }
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool Curve :: InRange(IfcFloat u) const bool Curve :: InRange(IfcFloat u) const
{ {

View File

@ -192,24 +192,17 @@ void IFCImporter::InternReadFile( const std::string& pFile,
} }
// search file (same name as the IFCZIP except for the file extension) and place file pointer there // search file (same name as the IFCZIP except for the file extension) and place file pointer there
if(UNZ_OK == unzGoToFirstFile(zip)) { if(UNZ_OK == unzGoToFirstFile(zip)) {
do { do {
//
// get file size, etc. // get file size, etc.
unz_file_info fileInfo; unz_file_info fileInfo;
char filename[256]; char filename[256];
unzGetCurrentFileInfo( zip , &fileInfo, filename, sizeof(filename), 0, 0, 0, 0 ); unzGetCurrentFileInfo( zip , &fileInfo, filename, sizeof(filename), 0, 0, 0, 0 );
if (GetExtension(filename) != "ifc") { if (GetExtension(filename) != "ifc") {
continue; continue;
} }
uint8_t* buff = new uint8_t[fileInfo.uncompressed_size]; uint8_t* buff = new uint8_t[fileInfo.uncompressed_size];
LogInfo("Decompressing IFCZIP file"); LogInfo("Decompressing IFCZIP file");
unzOpenCurrentFile( zip ); unzOpenCurrentFile( zip );
const int ret = unzReadCurrentFile( zip, buff, fileInfo.uncompressed_size); const int ret = unzReadCurrentFile( zip, buff, fileInfo.uncompressed_size);
size_t filesize = fileInfo.uncompressed_size; size_t filesize = fileInfo.uncompressed_size;
@ -271,7 +264,6 @@ void IFCImporter::InternReadFile( const std::string& pFile,
// feed the IFC schema into the reader and pre-parse all lines // feed the IFC schema into the reader and pre-parse all lines
STEP::ReadFile(*db, schema, types_to_track, inverse_indices_to_track); STEP::ReadFile(*db, schema, types_to_track, inverse_indices_to_track);
const STEP::LazyObject* proj = db->GetObject("ifcproject"); const STEP::LazyObject* proj = db->GetObject("ifcproject");
if (!proj) { if (!proj) {
ThrowException("missing IfcProject entity"); ThrowException("missing IfcProject entity");
@ -287,9 +279,9 @@ void IFCImporter::InternReadFile( const std::string& pFile,
// in a build with no entities disabled. See // in a build with no entities disabled. See
// scripts/IFCImporter/CPPGenerator.py // scripts/IFCImporter/CPPGenerator.py
// for more information. // for more information.
#ifdef ASSIMP_IFC_TEST #ifdef ASSIMP_IFC_TEST
db->EvaluateAll(); db->EvaluateAll();
#endif #endif
// do final data copying // do final data copying
if (conv.meshes.size()) { if (conv.meshes.size()) {
@ -565,21 +557,16 @@ void ProcessProductRepresentation(const IfcProduct& el, aiNode* nd, std::vector<
if(!el.Representation) { if(!el.Representation) {
return; return;
} }
std::vector<unsigned int> meshes; std::vector<unsigned int> meshes;
// we want only one representation type, so bring them in a suitable order (i.e try those // we want only one representation type, so bring them in a suitable order (i.e try those
// that look as if we could read them quickly at first). This way of reading // that look as if we could read them quickly at first). This way of reading
// representation is relatively generic and allows the concrete implementations // representation is relatively generic and allows the concrete implementations
// for the different representation types to make some sensible choices what // for the different representation types to make some sensible choices what
// to load and what not to load. // to load and what not to load.
const STEP::ListOf< STEP::Lazy< IfcRepresentation >, 1, 0 >& src = el.Representation.Get()->Representations; const STEP::ListOf< STEP::Lazy< IfcRepresentation >, 1, 0 >& src = el.Representation.Get()->Representations;
std::vector<const IfcRepresentation*> repr_ordered(src.size()); std::vector<const IfcRepresentation*> repr_ordered(src.size());
std::copy(src.begin(),src.end(),repr_ordered.begin()); std::copy(src.begin(),src.end(),repr_ordered.begin());
std::sort(repr_ordered.begin(),repr_ordered.end(),RateRepresentationPredicate()); std::sort(repr_ordered.begin(),repr_ordered.end(),RateRepresentationPredicate());
BOOST_FOREACH(const IfcRepresentation* repr, repr_ordered) { BOOST_FOREACH(const IfcRepresentation* repr, repr_ordered) {
bool res = false; bool res = false;
BOOST_FOREACH(const IfcRepresentationItem& item, repr->Items) { BOOST_FOREACH(const IfcRepresentationItem& item, repr->Items) {
@ -595,7 +582,6 @@ void ProcessProductRepresentation(const IfcProduct& el, aiNode* nd, std::vector<
break; break;
} }
} }
AssignAddedMeshes(meshes,nd,conv); AssignAddedMeshes(meshes,nd,conv);
} }

View File

@ -1063,7 +1063,7 @@ IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh
if(!ok) { if(!ok) {
return IfcMatrix4(); return IfcMatrix4();
} }
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
const IfcFloat det = m.Determinant(); const IfcFloat det = m.Determinant();
ai_assert(fabs(det-1) < 1e-5); ai_assert(fabs(det-1) < 1e-5);
#endif #endif
@ -1119,7 +1119,7 @@ IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh
m = mult * m; m = mult * m;
// debug code to verify correctness // debug code to verify correctness
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
std::vector<IfcVector2> out_contour2; std::vector<IfcVector2> out_contour2;
BOOST_FOREACH(const IfcVector3& x, in_verts) { BOOST_FOREACH(const IfcVector3& x, in_verts) {
const IfcVector3& vv = m * x; const IfcVector3& vv = m * x;

View File

@ -193,7 +193,7 @@ void TempMesh::ComputePolygonNormals(std::vector<IfcVector3>& normals,
temp[cnt++] = v.x; temp[cnt++] = v.x;
temp[cnt++] = v.y; temp[cnt++] = v.y;
temp[cnt++] = v.z; temp[cnt++] = v.z;
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
temp[cnt] = std::numeric_limits<IfcFloat>::quiet_NaN(); temp[cnt] = std::numeric_limits<IfcFloat>::quiet_NaN();
#endif #endif
++cnt; ++cnt;

View File

@ -365,7 +365,7 @@ public:
// and append the result to the mesh // and append the result to the mesh
virtual void SampleDiscrete(TempMesh& out,IfcFloat start,IfcFloat end) const; virtual void SampleDiscrete(TempMesh& out,IfcFloat start,IfcFloat end) const;
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
// check if a particular parameter value lies within the well-defined range // check if a particular parameter value lies within the well-defined range
bool InRange(IfcFloat) const; bool InRange(IfcFloat) const;
#endif #endif

View File

@ -197,6 +197,7 @@ Importer::Importer(const Importer &other)
pimpl->mIntProperties = other.pimpl->mIntProperties; pimpl->mIntProperties = other.pimpl->mIntProperties;
pimpl->mFloatProperties = other.pimpl->mFloatProperties; pimpl->mFloatProperties = other.pimpl->mFloatProperties;
pimpl->mStringProperties = other.pimpl->mStringProperties; pimpl->mStringProperties = other.pimpl->mStringProperties;
pimpl->mMatrixProperties = other.pimpl->mMatrixProperties;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -232,7 +233,7 @@ aiReturn Importer::RegisterLoader(BaseImporter* pImp)
for(std::set<std::string>::const_iterator it = st.begin(); it != st.end(); ++it) { for(std::set<std::string>::const_iterator it = st.begin(); it != st.end(); ++it) {
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
if (IsExtensionSupported(*it)) { if (IsExtensionSupported(*it)) {
DefaultLogger::get()->warn("The file extension " + *it + " is already in use"); DefaultLogger::get()->warn("The file extension " + *it + " is already in use");
} }
@ -558,7 +559,7 @@ void WriteLogOpening(const std::string& file)
<< "<unknown compiler>" << "<unknown compiler>"
#endif #endif
#ifndef NDEBUG #ifdef ASSIMP_BUILD_DEBUG
<< " debug" << " debug"
#endif #endif
@ -749,10 +750,10 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags)
} }
} }
#endif // no validation #endif // no validation
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
if (pimpl->bExtraVerbose) if (pimpl->bExtraVerbose)
{ {
#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS #ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
DefaultLogger::get()->error("Verbose Import is not available due to build settings"); DefaultLogger::get()->error("Verbose Import is not available due to build settings");
#endif // no validation #endif // no validation
pFlags |= aiProcess_ValidateDataStructure; pFlags |= aiProcess_ValidateDataStructure;
@ -783,9 +784,9 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags)
if( !pimpl->mScene) { if( !pimpl->mScene) {
break; break;
} }
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS #ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
continue; continue;
#endif // no validation #endif // no validation
@ -937,6 +938,16 @@ void Importer::SetPropertyString(const char* szName, const std::string& value,
ASSIMP_END_EXCEPTION_REGION(void); ASSIMP_END_EXCEPTION_REGION(void);
} }
// ------------------------------------------------------------------------------------------------
// Set a configuration property
void Importer::SetPropertyMatrix(const char* szName, const aiMatrix4x4& value,
bool* bWasExisting /*= NULL*/)
{
ASSIMP_BEGIN_EXCEPTION_REGION();
SetGenericProperty<aiMatrix4x4>(pimpl->mMatrixProperties, szName,value,bWasExisting);
ASSIMP_END_EXCEPTION_REGION(void);
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get a configuration property // Get a configuration property
int Importer::GetPropertyInteger(const char* szName, int Importer::GetPropertyInteger(const char* szName,
@ -955,12 +966,20 @@ float Importer::GetPropertyFloat(const char* szName,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get a configuration property // Get a configuration property
const std::string& Importer::GetPropertyString(const char* szName, const std::string Importer::GetPropertyString(const char* szName,
const std::string& iErrorReturn /*= ""*/) const const std::string& iErrorReturn /*= ""*/) const
{ {
return GetGenericProperty<std::string>(pimpl->mStringProperties,szName,iErrorReturn); return GetGenericProperty<std::string>(pimpl->mStringProperties,szName,iErrorReturn);
} }
// ------------------------------------------------------------------------------------------------
// Get a configuration property
const aiMatrix4x4 Importer::GetPropertyMatrix(const char* szName,
const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const
{
return GetGenericProperty<aiMatrix4x4>(pimpl->mMatrixProperties,szName,iErrorReturn);
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get the memory requirements of a single node // Get the memory requirements of a single node
inline void AddNodeWeight(unsigned int& iScene,const aiNode* pcNode) inline void AddNodeWeight(unsigned int& iScene,const aiNode* pcNode)

View File

@ -63,11 +63,12 @@ public:
// Data type to store the key hash // Data type to store the key hash
typedef unsigned int KeyType; typedef unsigned int KeyType;
// typedefs for our three configuration maps. // typedefs for our four configuration maps.
// We don't need more, so there is no need for a generic solution // We don't need more, so there is no need for a generic solution
typedef std::map<KeyType, int> IntPropertyMap; typedef std::map<KeyType, int> IntPropertyMap;
typedef std::map<KeyType, float> FloatPropertyMap; typedef std::map<KeyType, float> FloatPropertyMap;
typedef std::map<KeyType, std::string> StringPropertyMap; typedef std::map<KeyType, std::string> StringPropertyMap;
typedef std::map<KeyType, aiMatrix4x4> MatrixPropertyMap;
public: public:
@ -100,6 +101,9 @@ public:
/** List of string properties */ /** List of string properties */
StringPropertyMap mStringProperties; StringPropertyMap mStringProperties;
/** List of Matrix properties */
MatrixPropertyMap mMatrixProperties;
/** Used for testing - extra verbose mode causes the ValidateDataStructure-Step /** Used for testing - extra verbose mode causes the ValidateDataStructure-Step
* to be executed before and after every single postprocess step */ * to be executed before and after every single postprocess step */
bool bExtraVerbose; bool bExtraVerbose;
@ -135,14 +139,15 @@ public:
ImporterPimpl::IntPropertyMap ints; ImporterPimpl::IntPropertyMap ints;
ImporterPimpl::FloatPropertyMap floats; ImporterPimpl::FloatPropertyMap floats;
ImporterPimpl::StringPropertyMap strings; ImporterPimpl::StringPropertyMap strings;
ImporterPimpl::MatrixPropertyMap matrices;
bool operator == (const PropertyMap& prop) const { bool operator == (const PropertyMap& prop) const {
// fixme: really isocpp? gcc complains // fixme: really isocpp? gcc complains
return ints == prop.ints && floats == prop.floats && strings == prop.strings; return ints == prop.ints && floats == prop.floats && strings == prop.strings && matrices == prop.matrices;
} }
bool empty () const { bool empty () const {
return ints.empty() && floats.empty() && strings.empty(); return ints.empty() && floats.empty() && strings.empty() && matrices.empty();
} }
}; };
//! @endcond //! @endcond

View File

@ -294,7 +294,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
unsigned int vUVChannelIndices[AI_MAX_NUMBER_OF_TEXTURECOORDS]; unsigned int vUVChannelIndices[AI_MAX_NUMBER_OF_TEXTURECOORDS];
unsigned int vVColorIndices[AI_MAX_NUMBER_OF_COLOR_SETS]; unsigned int vVColorIndices[AI_MAX_NUMBER_OF_COLOR_SETS];
#if _DEBUG #ifdef ASSIMP_BUILD_DEBUG
for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_TEXTURECOORDS;++mui ) { for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_TEXTURECOORDS;++mui ) {
vUVChannelIndices[mui] = UINT_MAX; vUVChannelIndices[mui] = UINT_MAX;
} }

View File

@ -103,13 +103,10 @@ public:
swallow = false; swallow = false;
return *this; return *this;
} }
if (!*this) { if (!*this) {
throw std::logic_error("End of file, no more lines to be retrieved."); throw std::logic_error("End of file, no more lines to be retrieved.");
} }
char s; char s;
cur.clear(); cur.clear();
while(stream.GetRemainingSize() && (s = stream.GetI1(),1)) { while(stream.GetRemainingSize() && (s = stream.GetI1(),1)) {
if (s == '\n' || s == '\r') { if (s == '\n' || s == '\r') {
@ -124,7 +121,6 @@ public:
if (stream.GetRemainingSize() && (s == '\r' && stream.GetI1() != '\n')) { if (stream.GetRemainingSize() && (s == '\r' && stream.GetI1() != '\n')) {
stream.IncPtr(-1); stream.IncPtr(-1);
} }
if (trim) { if (trim) {
while (stream.GetRemainingSize() && ((s = stream.GetI1()) == ' ' || s == '\t')); while (stream.GetRemainingSize() && ((s = stream.GetI1()) == ' ' || s == '\t'));
if (stream.GetRemainingSize()) { if (stream.GetRemainingSize()) {
@ -132,12 +128,10 @@ public:
} }
} }
} }
break; break;
} }
cur += s; cur += s;
} }
++idx; ++idx;
return *this; return *this;
} }
@ -174,7 +168,9 @@ public:
SkipSpaces(&s); SkipSpaces(&s);
for(size_t i = 0; i < N; ++i) { for(size_t i = 0; i < N; ++i) {
if(IsLineEnd(*s)) { if(IsLineEnd(*s)) {
throw std::range_error("Token count out of range, EOL reached"); throw std::range_error("Token count out of range, EOL reached");
} }
tokens[i] = s; tokens[i] = s;

View File

@ -247,6 +247,18 @@ aiReturn aiGetMaterialColor(const aiMaterial* pMat,
return eRet; return eRet;
} }
// ------------------------------------------------------------------------------------------------
// Get a aiUVTransform (4 floats) from the material
aiReturn aiGetMaterialUVTransform(const aiMaterial* pMat,
const char* pKey,
unsigned int type,
unsigned int index,
aiUVTransform* pOut)
{
unsigned int iMax = 4;
return aiGetMaterialFloatArray(pMat,pKey,type,index,(float*)pOut,&iMax);
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get a string from the material // Get a string from the material
aiReturn aiGetMaterialString(const aiMaterial* pMat, aiReturn aiGetMaterialString(const aiMaterial* pMat,

View File

@ -115,7 +115,7 @@ AI_FORCE_INLINE bool SkipSpaces( const char_t** inout)
} }
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
template <class char_t> template <class char_t>
inline bool SkipLine( const char_t* in, const char_t** out) AI_FORCE_INLINE bool SkipLine( const char_t* in, const char_t** out)
{ {
while (*in != (char_t)'\r' && *in != (char_t)'\n' && *in != (char_t)'\0')in++; while (*in != (char_t)'\r' && *in != (char_t)'\n' && *in != (char_t)'\0')in++;
@ -126,13 +126,13 @@ inline bool SkipLine( const char_t* in, const char_t** out)
} }
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
template <class char_t> template <class char_t>
inline bool SkipLine( const char_t** inout) AI_FORCE_INLINE bool SkipLine( const char_t** inout)
{ {
return SkipLine<char_t>(*inout,inout); return SkipLine<char_t>(*inout,inout);
} }
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
template <class char_t> template <class char_t>
inline bool SkipSpacesAndLineEnd( const char_t* in, const char_t** out) AI_FORCE_INLINE bool SkipSpacesAndLineEnd( const char_t* in, const char_t** out)
{ {
while (*in == (char_t)' ' || *in == (char_t)'\t' || while (*in == (char_t)' ' || *in == (char_t)'\t' ||
*in == (char_t)'\r' || *in == (char_t)'\n')in++; *in == (char_t)'\r' || *in == (char_t)'\n')in++;
@ -141,13 +141,13 @@ inline bool SkipSpacesAndLineEnd( const char_t* in, const char_t** out)
} }
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
template <class char_t> template <class char_t>
inline bool SkipSpacesAndLineEnd( const char_t** inout) AI_FORCE_INLINE bool SkipSpacesAndLineEnd( const char_t** inout)
{ {
return SkipSpacesAndLineEnd<char_t>(*inout,inout); return SkipSpacesAndLineEnd<char_t>(*inout,inout);
} }
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
template <class char_t> template <class char_t>
inline bool GetNextLine(const char_t*& buffer, char_t out[4096]) AI_FORCE_INLINE bool GetNextLine(const char_t*& buffer, char_t out[4096])
{ {
if ((char_t)'\0' == *buffer)return false; if ((char_t)'\0' == *buffer)return false;

View File

@ -133,6 +133,15 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
// validated - as RegisterPPStep() does - all dependencies must be given. // validated - as RegisterPPStep() does - all dependencies must be given.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
out.reserve(25); out.reserve(25);
#if (!defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS)
out.push_back( new MakeLeftHandedProcess());
#endif
#if (!defined ASSIMP_BUILD_NO_FLIPUVS_PROCESS)
out.push_back( new FlipUVsProcess());
#endif
#if (!defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS)
out.push_back( new FlipWindingOrderProcess());
#endif
#if (!defined ASSIMP_BUILD_NO_REMOVEVC_PROCESS) #if (!defined ASSIMP_BUILD_NO_REMOVEVC_PROCESS)
out.push_back( new RemoveVCProcess()); out.push_back( new RemoveVCProcess());
#endif #endif
@ -207,15 +216,6 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
#if (!defined ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS) #if (!defined ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS)
out.push_back( new SplitLargeMeshesProcess_Vertex()); out.push_back( new SplitLargeMeshesProcess_Vertex());
#endif #endif
#if (!defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS)
out.push_back( new MakeLeftHandedProcess());
#endif
#if (!defined ASSIMP_BUILD_NO_FLIPUVS_PROCESS)
out.push_back( new FlipUVsProcess());
#endif
#if (!defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS)
out.push_back( new FlipWindingOrderProcess());
#endif
#if (!defined ASSIMP_BUILD_NO_DEBONE_PROCESS) #if (!defined ASSIMP_BUILD_NO_DEBONE_PROCESS)
out.push_back( new DeboneProcess()); out.push_back( new DeboneProcess());
#endif #endif

View File

@ -57,7 +57,7 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
PretransformVertices::PretransformVertices() PretransformVertices::PretransformVertices()
: configKeepHierarchy (false) : configKeepHierarchy (false), configNormalize(false), configTransform(false), configTransformation()
{ {
} }
@ -79,9 +79,13 @@ bool PretransformVertices::IsActive( unsigned int pFlags) const
// Setup import configuration // Setup import configuration
void PretransformVertices::SetupProperties(const Importer* pImp) void PretransformVertices::SetupProperties(const Importer* pImp)
{ {
// Get the current value of AI_CONFIG_PP_PTV_KEEP_HIERARCHY and AI_CONFIG_PP_PTV_NORMALIZE // Get the current value of AI_CONFIG_PP_PTV_KEEP_HIERARCHY, AI_CONFIG_PP_PTV_NORMALIZE,
// AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION and AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION
configKeepHierarchy = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_KEEP_HIERARCHY,0)); configKeepHierarchy = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_KEEP_HIERARCHY,0));
configNormalize = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_NORMALIZE,0)); configNormalize = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_NORMALIZE,0));
configTransform = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION,0));
configTransformation = pImp->GetPropertyMatrix(AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION, aiMatrix4x4());
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -391,6 +395,8 @@ void PretransformVertices::BuildWCSMeshes(std::vector<aiMesh*>& out, aiMesh** in
ntz->mBones = reinterpret_cast<aiBone**> (&node->mTransformation); ntz->mBones = reinterpret_cast<aiBone**> (&node->mTransformation);
out.push_back(ntz); out.push_back(ntz);
node->mMeshes[i] = numIn + out.size() - 1;
} }
} }
} }
@ -437,6 +443,10 @@ void PretransformVertices::Execute( aiScene* pScene)
const unsigned int iOldAnimationChannels = pScene->mNumAnimations; const unsigned int iOldAnimationChannels = pScene->mNumAnimations;
const unsigned int iOldNodes = CountNodes(pScene->mRootNode); const unsigned int iOldNodes = CountNodes(pScene->mRootNode);
if(configTransform) {
pScene->mRootNode->mTransformation = configTransformation;
}
// first compute absolute transformation matrices for all nodes // first compute absolute transformation matrices for all nodes
ComputeAbsoluteTransform(pScene->mRootNode); ComputeAbsoluteTransform(pScene->mRootNode);

View File

@ -152,8 +152,10 @@ private:
//! Configuration option: keep scene hierarchy as long as possible //! Configuration option: keep scene hierarchy as long as possible
bool configKeepHierarchy, configNormalize; bool configKeepHierarchy;
bool configNormalize;
bool configTransform;
aiMatrix4x4 configTransformation;
}; };
} // end of namespace Assimp } // end of namespace Assimp

View File

@ -185,9 +185,9 @@ const aiImporterDesc* Q3BSPFileImporter::GetInfo () const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Import method. // Import method.
void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene* pScene, IOSystem* /*pIOHandler*/) void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene* pScene, IOSystem* pIOHandler)
{ {
Q3BSPZipArchive Archive( rFile ); Q3BSPZipArchive Archive( pIOHandler, rFile );
if ( !Archive.isOpen() ) if ( !Archive.isOpen() )
{ {
throw DeadlyImportError( "Failed to open file " + rFile + "." ); throw DeadlyImportError( "Failed to open file " + rFile + "." );

View File

@ -46,23 +46,144 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
namespace Assimp namespace Assimp {
{ namespace Q3BSP {
namespace Q3BSP
{ voidpf IOSystem2Unzip::open(voidpf opaque, const char* filename, int mode) {
IOSystem* io_system = (IOSystem*) opaque;
const char* mode_fopen = NULL;
if((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) {
mode_fopen = "rb";
} else {
if(mode & ZLIB_FILEFUNC_MODE_EXISTING) {
mode_fopen = "r+b";
} else {
if(mode & ZLIB_FILEFUNC_MODE_CREATE) {
mode_fopen = "wb";
}
}
}
return (voidpf) io_system->Open(filename, mode_fopen);
}
uLong IOSystem2Unzip::read(voidpf opaque, voidpf stream, void* buf, uLong size) {
IOStream* io_stream = (IOStream*) stream;
return io_stream->Read(buf, 1, size);
}
uLong IOSystem2Unzip::write(voidpf opaque, voidpf stream, const void* buf, uLong size) {
IOStream* io_stream = (IOStream*) stream;
return io_stream->Write(buf, 1, size);
}
long IOSystem2Unzip::tell(voidpf opaque, voidpf stream) {
IOStream* io_stream = (IOStream*) stream;
return io_stream->Tell();
}
long IOSystem2Unzip::seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
IOStream* io_stream = (IOStream*) stream;
aiOrigin assimp_origin;
switch (origin) {
default:
case ZLIB_FILEFUNC_SEEK_CUR:
assimp_origin = aiOrigin_CUR;
break;
case ZLIB_FILEFUNC_SEEK_END:
assimp_origin = aiOrigin_END;
break;
case ZLIB_FILEFUNC_SEEK_SET:
assimp_origin = aiOrigin_SET;
break;
}
return (io_stream->Seek(offset, assimp_origin) == aiReturn_SUCCESS ? 0 : -1);
}
int IOSystem2Unzip::close(voidpf opaque, voidpf stream) {
IOSystem* io_system = (IOSystem*) opaque;
IOStream* io_stream = (IOStream*) stream;
io_system->Close(io_stream);
return 0;
}
int IOSystem2Unzip::testerror(voidpf opaque, voidpf stream) {
return 0;
}
zlib_filefunc_def IOSystem2Unzip::get(IOSystem* pIOHandler) {
zlib_filefunc_def mapping;
mapping.zopen_file = open;
mapping.zread_file = read;
mapping.zwrite_file = write;
mapping.ztell_file = tell;
mapping.zseek_file = seek;
mapping.zclose_file = close;
mapping.zerror_file = testerror;
mapping.opaque = (voidpf) pIOHandler;
return mapping;
}
// ------------------------------------------------------------------------------------------------
ZipFile::ZipFile(size_t size) : m_Size(size) {
ai_assert(m_Size != 0);
m_Buffer = std::malloc(m_Size);
}
ZipFile::~ZipFile() {
std::free(m_Buffer);
m_Buffer = NULL;
}
size_t ZipFile::Read(void* pvBuffer, size_t pSize, size_t pCount) {
const size_t size = pSize * pCount;
assert(size <= m_Size);
std::memcpy(pvBuffer, m_Buffer, size);
return size;
}
size_t ZipFile::Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) {
return 0;
}
size_t ZipFile::FileSize() const {
return m_Size;
}
aiReturn ZipFile::Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) {
return aiReturn_FAILURE;
}
size_t ZipFile::Tell() const {
return 0;
}
void ZipFile::Flush() {
// empty
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor. // Constructor.
Q3BSPZipArchive::Q3BSPZipArchive( const std::string& rFile ) : Q3BSPZipArchive::Q3BSPZipArchive(IOSystem* pIOHandler, const std::string& rFile) : m_ZipFileHandle(NULL), m_ArchiveMap() {
m_ZipFileHandle( NULL ), if (! rFile.empty()) {
m_FileList(), zlib_filefunc_def mapping = IOSystem2Unzip::get(pIOHandler);
m_bDirty( true )
{ m_ZipFileHandle = unzOpen2(rFile.c_str(), &mapping);
if ( !rFile.empty() )
{ if(m_ZipFileHandle != NULL) {
m_ZipFileHandle = unzOpen( rFile.c_str() );
if ( NULL != m_ZipFileHandle )
{
mapArchive(); mapArchive();
} }
} }
@ -70,127 +191,122 @@ Q3BSPZipArchive::Q3BSPZipArchive( const std::string& rFile ) :
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor. // Destructor.
Q3BSPZipArchive::~Q3BSPZipArchive() Q3BSPZipArchive::~Q3BSPZipArchive() {
{ for( std::map<std::string, ZipFile*>::iterator it(m_ArchiveMap.begin()), end(m_ArchiveMap.end()); it != end; ++it ) {
if ( NULL != m_ZipFileHandle ) delete it->second;
{ }
unzClose( m_ZipFileHandle ); m_ArchiveMap.clear();
if(m_ZipFileHandle != NULL) {
unzClose(m_ZipFileHandle);
m_ZipFileHandle = NULL;
} }
m_ZipFileHandle = NULL;
m_FileList.clear();
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns true, if the archive is already open. // Returns true, if the archive is already open.
bool Q3BSPZipArchive::isOpen() const bool Q3BSPZipArchive::isOpen() const {
{ return (m_ZipFileHandle != NULL);
return ( NULL != m_ZipFileHandle );
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns true, if the filename is part of the archive. // Returns true, if the filename is part of the archive.
bool Q3BSPZipArchive::Exists( const char* pFile ) const bool Q3BSPZipArchive::Exists(const char* pFile) const {
{ ai_assert(pFile != NULL);
ai_assert( NULL != pFile );
if ( NULL == pFile ) bool exist = false;
{
return false; if (pFile != NULL) {
std::string rFile(pFile);
std::map<std::string, ZipFile*>::const_iterator it = m_ArchiveMap.find(rFile);
if(it != m_ArchiveMap.end()) {
exist = true;
}
} }
std::string rFile( pFile ); return exist;
std::vector<std::string>::const_iterator it = std::find( m_FileList.begin(), m_FileList.end(), rFile );
if ( m_FileList.end() == it )
{
return false;
}
return true;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns the separator delimiter. // Returns the separator delimiter.
char Q3BSPZipArchive::getOsSeparator() const char Q3BSPZipArchive::getOsSeparator() const {
{ #ifndef _WIN32
return '/'; return '/';
#else
return '\\';
#endif
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Opens a file, which is part of the archive. // Opens a file, which is part of the archive.
IOStream *Q3BSPZipArchive::Open( const char* pFile, const char* /*pMode*/ ) IOStream *Q3BSPZipArchive::Open(const char* pFile, const char* /*pMode*/) {
{ ai_assert(pFile != NULL);
ai_assert( NULL != pFile );
std::string rItem( pFile ); IOStream* result = NULL;
std::vector<std::string>::iterator it = std::find( m_FileList.begin(), m_FileList.end(), rItem );
if ( m_FileList.end() == it )
return NULL;
ZipFile *pZipFile = new ZipFile( *it, m_ZipFileHandle ); std::map<std::string, ZipFile*>::iterator it = m_ArchiveMap.find(pFile);
m_ArchiveMap[ rItem ] = pZipFile;
return pZipFile; if(it != m_ArchiveMap.end()) {
result = (IOStream*) it->second;
}
return result;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Close a filestream. // Close a filestream.
void Q3BSPZipArchive::Close( IOStream *pFile ) void Q3BSPZipArchive::Close(IOStream *pFile) {
{ ai_assert(pFile != NULL);
ai_assert( NULL != pFile );
std::map<std::string, IOStream*>::iterator it; // We don't do anything in case the file would be opened again in the future
for ( it = m_ArchiveMap.begin(); it != m_ArchiveMap.end(); ++it )
{
if ( (*it).second == pFile )
{
ZipFile *pZipFile = reinterpret_cast<ZipFile*>( (*it).second );
delete pZipFile;
m_ArchiveMap.erase( it );
break;
}
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns the file-list of the archive. // Returns the file-list of the archive.
void Q3BSPZipArchive::getFileList( std::vector<std::string> &rFileList ) void Q3BSPZipArchive::getFileList(std::vector<std::string> &rFileList) {
{ rFileList.clear();
rFileList = m_FileList;
for(std::map<std::string, ZipFile*>::iterator it(m_ArchiveMap.begin()), end(m_ArchiveMap.end()); it != end; ++it) {
rFileList.push_back(it->first);
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Maps the archive content. // Maps the archive content.
bool Q3BSPZipArchive::mapArchive() bool Q3BSPZipArchive::mapArchive() {
{ bool success = false;
if ( NULL == m_ZipFileHandle )
return false;
if ( !m_bDirty ) if(m_ZipFileHandle != NULL) {
return true; if(m_ArchiveMap.empty()) {
// At first ensure file is already open
if(unzGoToFirstFile(m_ZipFileHandle) == UNZ_OK) {
// Loop over all files
do {
char filename[FileNameSize];
unz_file_info fileInfo;
if ( !m_FileList.empty() ) if(unzGetCurrentFileInfo(m_ZipFileHandle, &fileInfo, filename, FileNameSize, NULL, 0, NULL, 0) == UNZ_OK) {
m_FileList.resize( 0 ); // The file has EXACTLY the size of uncompressed_size. In C
// you need to mark the last character with '\0', so add
// another character
if(unzOpenCurrentFile(m_ZipFileHandle) == UNZ_OK) {
std::pair<std::map<std::string, ZipFile*>::iterator, bool> result = m_ArchiveMap.insert(std::make_pair(filename, new ZipFile(fileInfo.uncompressed_size)));
// At first ensure file is already open if(unzReadCurrentFile(m_ZipFileHandle, result.first->second->m_Buffer, fileInfo.uncompressed_size) == (long int) fileInfo.uncompressed_size) {
if ( UNZ_OK == unzGoToFirstFile( m_ZipFileHandle ) ) if(unzCloseCurrentFile(m_ZipFileHandle) == UNZ_OK) {
{ // Nothing to do anymore...
char filename[ FileNameSize ]; }
unzGetCurrentFileInfo( m_ZipFileHandle, NULL, filename, FileNameSize, NULL, 0, NULL, 0 ); }
m_FileList.push_back( filename ); }
unzCloseCurrentFile( m_ZipFileHandle ); }
} while(unzGoToNextFile(m_ZipFileHandle) != UNZ_END_OF_LIST_OF_FILE);
// Loop over all files }
while ( unzGoToNextFile( m_ZipFileHandle ) != UNZ_END_OF_LIST_OF_FILE )
{
char filename[ FileNameSize ];
unzGetCurrentFileInfo( m_ZipFileHandle, NULL, filename, FileNameSize, NULL, 0, NULL, 0 );
m_FileList.push_back( filename );
unzCloseCurrentFile( m_ZipFileHandle );
} }
success = true;
} }
std::sort( m_FileList.begin(), m_FileList.end() ); return success;
m_bDirty = false;
return true;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -48,10 +48,35 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <map> #include <map>
#include <cassert> #include <cassert>
namespace Assimp namespace Assimp {
{ namespace Q3BSP {
namespace Q3BSP
{ // ------------------------------------------------------------------------------------------------
/// \class IOSystem2Unzip
/// \ingroup Assimp::Q3BSP
///
/// \brief
// ------------------------------------------------------------------------------------------------
class IOSystem2Unzip {
public:
static voidpf open(voidpf opaque, const char* filename, int mode);
static uLong read(voidpf opaque, voidpf stream, void* buf, uLong size);
static uLong write(voidpf opaque, voidpf stream, const void* buf, uLong size);
static long tell(voidpf opaque, voidpf stream);
static long seek(voidpf opaque, voidpf stream, uLong offset, int origin);
static int close(voidpf opaque, voidpf stream);
static int testerror(voidpf opaque, voidpf stream);
static zlib_filefunc_def get(IOSystem* pIOHandler);
};
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
/// \class ZipFile /// \class ZipFile
@ -59,88 +84,33 @@ namespace Q3BSP
/// ///
/// \brief /// \brief
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
class ZipFile : public IOStream class ZipFile : public IOStream {
{
public:
ZipFile( const std::string &rFileName, unzFile zipFile ) :
m_Name( rFileName ),
m_zipFile( zipFile )
{
ai_assert( NULL != m_zipFile );
}
~ZipFile() friend class Q3BSPZipArchive;
{
m_zipFile = NULL;
}
size_t Read(void* pvBuffer, size_t pSize, size_t pCount ) public:
{
size_t bytes_read = 0;
if ( NULL == m_zipFile )
return bytes_read;
// search file and place file pointer there ZipFile(size_t size);
if ( unzLocateFile( m_zipFile, m_Name.c_str(), 0 ) == UNZ_OK )
{
// get file size, etc.
unz_file_info fileInfo;
unzGetCurrentFileInfo( m_zipFile, &fileInfo, 0, 0, 0, 0, 0, 0 );
const size_t size = pSize * pCount;
assert( size <= fileInfo.uncompressed_size );
// The file has EXACTLY the size of uncompressed_size. In C ~ZipFile();
// you need to mark the last character with '\0', so add
// another character
unzOpenCurrentFile( m_zipFile );
const int ret = unzReadCurrentFile( m_zipFile, pvBuffer, fileInfo.uncompressed_size);
size_t filesize = fileInfo.uncompressed_size;
if ( ret < 0 || size_t(ret) != filesize )
{
return 0;
}
bytes_read = ret;
unzCloseCurrentFile( m_zipFile );
}
return bytes_read;
}
size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) size_t Read(void* pvBuffer, size_t pSize, size_t pCount );
{
return 0;
}
size_t FileSize() const size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/);
{
if ( NULL == m_zipFile )
return 0;
if ( unzLocateFile( m_zipFile, m_Name.c_str(), 0 ) == UNZ_OK )
{
unz_file_info fileInfo;
unzGetCurrentFileInfo( m_zipFile, &fileInfo, 0, 0, 0, 0, 0, 0 );
return fileInfo.uncompressed_size;
}
return 0;
}
aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) size_t FileSize() const;
{
return aiReturn_FAILURE;
}
size_t Tell() const aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/);
{
return 0;
}
void Flush() size_t Tell() const;
{
// empty
}
private: void Flush();
std::string m_Name;
unzFile m_zipFile; private:
void* m_Buffer;
size_t m_Size;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -150,29 +120,40 @@ private:
/// \brief IMplements a zip archive like the WinZip archives. Will be also used to import data /// \brief IMplements a zip archive like the WinZip archives. Will be also used to import data
/// from a P3K archive ( Quake level format ). /// from a P3K archive ( Quake level format ).
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
class Q3BSPZipArchive : public Assimp::IOSystem class Q3BSPZipArchive : public Assimp::IOSystem {
{
public:
static const unsigned int FileNameSize = 256;
public: public:
Q3BSPZipArchive( const std::string & rFile );
~Q3BSPZipArchive();
bool Exists( const char* pFile) const;
char getOsSeparator() const;
IOStream* Open(const char* pFile, const char* pMode = "rb");
void Close( IOStream* pFile);
bool isOpen() const;
void getFileList( std::vector<std::string> &rFileList );
private: static const unsigned int FileNameSize = 256;
bool mapArchive();
public:
Q3BSPZipArchive(IOSystem* pIOHandler, const std::string & rFile);
~Q3BSPZipArchive();
bool Exists(const char* pFile) const;
char getOsSeparator() const;
IOStream* Open(const char* pFile, const char* pMode = "rb");
void Close(IOStream* pFile);
bool isOpen() const;
void getFileList(std::vector<std::string> &rFileList);
private:
bool mapArchive();
private:
unzFile m_ZipFileHandle;
std::map<std::string, ZipFile*> m_ArchiveMap;
private:
unzFile m_ZipFileHandle;
std::map<std::string, IOStream*> m_ArchiveMap;
std::vector<std::string> m_FileList;
bool m_bDirty;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -142,6 +142,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
// if the material is not referenced ... remove it // if the material is not referenced ... remove it
if (!abReferenced[i]) { if (!abReferenced[i]) {
++unreferenced; ++unreferenced;
delete pScene->mMaterials[i];
continue; continue;
} }

View File

@ -175,7 +175,7 @@ bool IsEntityDef(const std::string& snext)
if (*it == '=') { if (*it == '=') {
return true; return true;
} }
if (*it < '0' || *it > '9') { if ((*it < '0' || *it > '9') && *it != ' ') {
break; break;
} }
} }
@ -197,16 +197,17 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
const DB::ObjectMap& map = db.GetObjects(); const DB::ObjectMap& map = db.GetObjects();
LineSplitter& splitter = db.GetSplitter(); LineSplitter& splitter = db.GetSplitter();
while (splitter) { while (splitter) {
bool has_next = false; bool has_next = false;
std::string s = *splitter; std::string s = *splitter;
if (s == "ENDSEC;") { if (s == "ENDSEC;") {
break; break;
} }
s.erase(std::remove(s.begin(), s.end(), ' '), s.end());
// want one-based line numbers for human readers, so +1 // want one-based line numbers for human readers, so +1
const uint64_t line = splitter.get_index()+1; const uint64_t line = splitter.get_index()+1;
// LineSplitter already ignores empty lines // LineSplitter already ignores empty lines
ai_assert(s.length()); ai_assert(s.length());
if (s[0] != '#') { if (s[0] != '#') {
@ -214,12 +215,10 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
++splitter; ++splitter;
continue; continue;
} }
// --- // ---
// extract id, entity class name and argument string, // extract id, entity class name and argument string,
// but don't create the actual object yet. // but don't create the actual object yet.
// --- // ---
const std::string::size_type n0 = s.find_first_of('='); const std::string::size_type n0 = s.find_first_of('=');
if (n0 == std::string::npos) { if (n0 == std::string::npos) {
DefaultLogger::get()->warn(AddLineNumber("expected token \'=\'",line)); DefaultLogger::get()->warn(AddLineNumber("expected token \'=\'",line));
@ -233,13 +232,10 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
++splitter; ++splitter;
continue; continue;
} }
std::string::size_type n1 = s.find_first_of('(',n0); std::string::size_type n1 = s.find_first_of('(',n0);
if (n1 == std::string::npos) { if (n1 == std::string::npos) {
has_next = true; has_next = true;
bool ok = false; bool ok = false;
for( ++splitter; splitter; ++splitter) { for( ++splitter; splitter; ++splitter) {
const std::string& snext = *splitter; const std::string& snext = *splitter;
if (snext.empty()) { if (snext.empty()) {
@ -269,13 +265,11 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
has_next = true; has_next = true;
bool ok = false; bool ok = false;
for( ++splitter; splitter; ++splitter) { for( ++splitter; splitter; ++splitter) {
const std::string& snext = *splitter; const std::string& snext = *splitter;
if (snext.empty()) { if (snext.empty()) {
continue; continue;
} }
// the next line doesn't start an entity, so maybe it is // the next line doesn't start an entity, so maybe it is
// just a continuation for this line, keep going // just a continuation for this line, keep going
if (!IsEntityDef(snext)) { if (!IsEntityDef(snext)) {
@ -287,7 +281,6 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
break; break;
} }
} }
if(!ok) { if(!ok) {
DefaultLogger::get()->warn(AddLineNumber("expected token \')\'",line)); DefaultLogger::get()->warn(AddLineNumber("expected token \')\'",line));
continue; continue;
@ -300,24 +293,18 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
std::string::size_type ns = n0; std::string::size_type ns = n0;
do ++ns; while( IsSpace(s.at(ns))); do ++ns; while( IsSpace(s.at(ns)));
std::string::size_type ne = n1; std::string::size_type ne = n1;
do --ne; while( IsSpace(s.at(ne))); do --ne; while( IsSpace(s.at(ne)));
std::string type = s.substr(ns,ne-ns+1); std::string type = s.substr(ns,ne-ns+1);
std::transform( type.begin(), type.end(), type.begin(), &Assimp::ToLower<char> ); std::transform( type.begin(), type.end(), type.begin(), &Assimp::ToLower<char> );
const char* sz = scheme.GetStaticStringForToken(type); const char* sz = scheme.GetStaticStringForToken(type);
if(sz) { if(sz) {
const std::string::size_type len = n2-n1+1; const std::string::size_type len = n2-n1+1;
char* const copysz = new char[len+1]; char* const copysz = new char[len+1];
std::copy(s.c_str()+n1,s.c_str()+n2+1,copysz); std::copy(s.c_str()+n1,s.c_str()+n2+1,copysz);
copysz[len] = '\0'; copysz[len] = '\0';
db.InternInsert(new LazyObject(db,id,line,sz,copysz)); db.InternInsert(new LazyObject(db,id,line,sz,copysz));
} }
if(!has_next) { if(!has_next) {
++splitter; ++splitter;
} }
@ -327,7 +314,7 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
DefaultLogger::get()->warn("STEP: ignoring unexpected EOF"); DefaultLogger::get()->warn("STEP: ignoring unexpected EOF");
} }
if ( !DefaultLogger::isNullLogger() ){ if ( !DefaultLogger::isNullLogger()){
DefaultLogger::get()->debug((Formatter::format(),"STEP: got ",map.size()," object records with ", DefaultLogger::get()->debug((Formatter::format(),"STEP: got ",map.size()," object records with ",
db.GetRefs().size()," inverse index entries")); db.GetRefs().size()," inverse index entries"));
} }
@ -338,7 +325,6 @@ boost::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*&
{ {
const char* cur = inout; const char* cur = inout;
SkipSpaces(&cur); SkipSpaces(&cur);
if (*cur == ',' || IsSpaceOrNewLine(*cur)) { if (*cur == ',' || IsSpaceOrNewLine(*cur)) {
throw STEP::SyntaxError("unexpected token, expected parameter",line); throw STEP::SyntaxError("unexpected token, expected parameter",line);
} }

View File

@ -47,12 +47,10 @@ namespace Assimp {
namespace STEP { namespace STEP {
// ### Parsing a STEP file is a twofold procedure ### // ### Parsing a STEP file is a twofold procedure ###
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// 1) read file header and return to caller, who checks if the // 1) read file header and return to caller, who checks if the
// file is of a supported schema .. // file is of a supported schema ..
DB* ReadFileHeader(boost::shared_ptr<IOStream> stream); DB* ReadFileHeader(boost::shared_ptr<IOStream> stream);
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// 2) read the actual file contents using a user-supplied set of // 2) read the actual file contents using a user-supplied set of
// conversion functions to interpret the data. // conversion functions to interpret the data.
@ -60,8 +58,6 @@ namespace STEP {
template <size_t N, size_t N2> inline void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const (&arr)[N], const char* const (&arr2)[N2]) { template <size_t N, size_t N2> inline void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const (&arr)[N], const char* const (&arr2)[N2]) {
return ReadFile(db,scheme,arr,N,arr2,N2); return ReadFile(db,scheme,arr,N,arr2,N2);
} }
} // ! STEP } // ! STEP
} // ! Assimp } // ! Assimp

View File

@ -880,6 +880,59 @@ void SceneCombiner::MergeMeshes(aiMesh** _out,unsigned int /*flags*/,
delete *it; delete *it;
} }
// ------------------------------------------------------------------------------------------------
void SceneCombiner::MergeMaterials(aiMaterial** dest,
std::vector<aiMaterial*>::const_iterator begin,
std::vector<aiMaterial*>::const_iterator end)
{
ai_assert(NULL != dest);
if (begin == end) {
*dest = NULL; // no materials ...
return;
}
// Allocate the output material
aiMaterial* out = *dest = new aiMaterial();
// Get the maximal number of properties
unsigned int size = 0;
for (std::vector<aiMaterial*>::const_iterator it = begin; it != end; ++it) {
size += (*it)->mNumProperties;
}
out->Clear();
delete[] out->mProperties;
out->mNumAllocated = size;
out->mNumProperties = 0;
out->mProperties = new aiMaterialProperty*[out->mNumAllocated];
for (std::vector<aiMaterial*>::const_iterator it = begin; it != end; ++it) {
for(unsigned int i = 0; i < (*it)->mNumProperties; ++i) {
aiMaterialProperty* sprop = (*it)->mProperties[i];
// Test if we already have a matching property
const aiMaterialProperty* prop_exist;
if(aiGetMaterialProperty(out, sprop->mKey.C_Str(), sprop->mType, sprop->mIndex, &prop_exist) != AI_SUCCESS) {
// If not, we add it to the new material
aiMaterialProperty* prop = out->mProperties[out->mNumProperties] = new aiMaterialProperty();
prop->mDataLength = sprop->mDataLength;
prop->mData = new char[prop->mDataLength];
::memcpy(prop->mData, sprop->mData, prop->mDataLength);
prop->mIndex = sprop->mIndex;
prop->mSemantic = sprop->mSemantic;
prop->mKey = sprop->mKey;
prop->mType = sprop->mType;
out->mNumProperties++;
}
}
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <typename Type> template <typename Type>
inline void CopyPtrArray (Type**& dest, const Type* const * src, unsigned int num) inline void CopyPtrArray (Type**& dest, const Type* const * src, unsigned int num)
@ -1012,6 +1065,10 @@ void SceneCombiner::Copy (aiMaterial** _dest, const aiMaterial* src)
ai_assert(NULL != _dest && NULL != src); ai_assert(NULL != _dest && NULL != src);
aiMaterial* dest = (aiMaterial*) ( *_dest = new aiMaterial() ); aiMaterial* dest = (aiMaterial*) ( *_dest = new aiMaterial() );
dest->Clear();
delete[] dest->mProperties;
dest->mNumAllocated = src->mNumAllocated; dest->mNumAllocated = src->mNumAllocated;
dest->mNumProperties = src->mNumProperties; dest->mNumProperties = src->mNumProperties;
dest->mProperties = new aiMaterialProperty* [dest->mNumAllocated]; dest->mProperties = new aiMaterialProperty* [dest->mNumAllocated];

View File

@ -248,6 +248,20 @@ public:
static void MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator it, static void MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator it,
std::vector<aiMesh*>::const_iterator end); std::vector<aiMesh*>::const_iterator end);
// -------------------------------------------------------------------
/** Merges two or more materials
*
* The materials should be complementary as much as possible. In case
* of a property present in different materials, the first occurence
* is used.
*
* @param dest Destination material. Must be empty.
* @param begin First material to be processed
* @param end Points to the material after the last material to be processed
*/
static void MergeMaterials(aiMaterial** dest,
std::vector<aiMaterial*>::const_iterator begin,
std::vector<aiMaterial*>::const_iterator end);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Builds a list of uniquely named bones in a mesh list /** Builds a list of uniquely named bones in a mesh list

View File

@ -72,7 +72,7 @@ void ScenePreprocessor::ProcessScene ()
aiColor3D clr(0.6f,0.6f,0.6f); aiColor3D clr(0.6f,0.6f,0.6f);
helper->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE); helper->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
// setup the default name to make this material identifyable // setup the default name to make this material identifiable
name.Set(AI_DEFAULT_MATERIAL_NAME); name.Set(AI_DEFAULT_MATERIAL_NAME);
helper->AddProperty(&name,AI_MATKEY_NAME); helper->AddProperty(&name,AI_MATKEY_NAME);

View File

@ -52,7 +52,7 @@ struct FaceWithSmoothingGroup
{ {
// let the rest uninitialized for performance - in release builds. // let the rest uninitialized for performance - in release builds.
// in debug builds set all indices to a common magic value // in debug builds set all indices to a common magic value
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
this->mIndices[0] = 0xffffffff; this->mIndices[0] = 0xffffffff;
this->mIndices[1] = 0xffffffff; this->mIndices[1] = 0xffffffff;
this->mIndices[2] = 0xffffffff; this->mIndices[2] = 0xffffffff;

View File

@ -329,7 +329,7 @@ unsigned int SpatialSort::GenerateMappingTable(std::vector<unsigned int>& fill,f
++t; ++t;
} }
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
// debug invariant: mPositions[i].mIndex values must range from 0 to mPositions.size()-1 // debug invariant: mPositions[i].mIndex values must range from 0 to mPositions.size()-1
for (size_t i = 0; i < fill.size(); ++i) { for (size_t i = 0; i < fill.size(); ++i) {

View File

@ -383,7 +383,7 @@ void CatmullClarkSubdivider::InternSubdivide (
} }
// check the other way round for consistency // check the other way round for consistency
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
for (size_t t = 0; t < ofsadjvec.size()-1; ++t) { for (size_t t = 0; t < ofsadjvec.size()-1; ++t) {
for (unsigned int m = 0; m < cntadjfac[t]; ++m) { for (unsigned int m = 0; m < cntadjfac[t]; ++m) {
@ -530,7 +530,7 @@ void CatmullClarkSubdivider::InternSubdivide (
ai_assert(adj[o]-moffsets[nidx].first < mp->mNumFaces); ai_assert(adj[o]-moffsets[nidx].first < mp->mNumFaces);
const aiFace& f = mp->mFaces[adj[o]-moffsets[nidx].first]; const aiFace& f = mp->mFaces[adj[o]-moffsets[nidx].first];
# ifdef _DEBUG # ifdef ASSIMP_BUILD_DEBUG
bool haveit = false; bool haveit = false;
# endif # endif
@ -553,7 +553,7 @@ void CatmullClarkSubdivider::InternSubdivide (
// fixme: replace with mod face.mNumIndices? // fixme: replace with mod face.mNumIndices?
R += c0.midpoint+c1.midpoint; R += c0.midpoint+c1.midpoint;
# ifdef _DEBUG # ifdef ASSIMP_BUILD_DEBUG
haveit = true; haveit = true;
# endif # endif
break; break;

View File

@ -86,7 +86,7 @@ AI_WONT_RETURN void ValidateDSProcess::ReportError(const char* msg,...)
ai_assert(iLen > 0); ai_assert(iLen > 0);
va_end(args); va_end(args);
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
ai_assert( false ); ai_assert( false );
#endif #endif
throw DeadlyImportError("Validation failed: " + std::string(szBuffer,iLen)); throw DeadlyImportError("Validation failed: " + std::string(szBuffer,iLen));

View File

@ -21,23 +21,23 @@
namespace Assimp namespace Assimp
{ {
const float fast_atof_table[16] = { // we write [16] here instead of [] to work around a swig bug const double fast_atof_table[16] = { // we write [16] here instead of [] to work around a swig bug
0.f, 0.0,
0.1f, 0.1,
0.01f, 0.01,
0.001f, 0.001,
0.0001f, 0.0001,
0.00001f, 0.00001,
0.000001f, 0.000001,
0.0000001f, 0.0000001,
0.00000001f, 0.00000001,
0.000000001f, 0.000000001,
0.0000000001f, 0.0000000001,
0.00000000001f, 0.00000000001,
0.000000000001f, 0.000000000001,
0.0000000000001f, 0.0000000000001,
0.00000000000001f, 0.00000000000001,
0.000000000000001f 0.000000000000001
}; };
@ -179,6 +179,9 @@ inline uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int*
unsigned int cur = 0; unsigned int cur = 0;
uint64_t value = 0; uint64_t value = 0;
if ( *in < '0' || *in > '9' )
throw std::invalid_argument(std::string("The string \"") + in + "\" cannot be converted into a value.");
bool running = true; bool running = true;
while ( running ) while ( running )
{ {
@ -188,7 +191,7 @@ inline uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int*
const uint64_t new_value = ( value * 10 ) + ( *in - '0' ); const uint64_t new_value = ( value * 10 ) + ( *in - '0' );
if (new_value < value) /* numeric overflow, we rely on you */ if (new_value < value) /* numeric overflow, we rely on you */
return value; throw std::overflow_error(std::string("Converting the string \"") + in + "\" into a value resulted in overflow.");
value = new_value; value = new_value;
@ -224,7 +227,7 @@ inline uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int*
// If you find any bugs, please send them to me, niko (at) irrlicht3d.org. // If you find any bugs, please send them to me, niko (at) irrlicht3d.org.
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
template <typename Real> template <typename Real>
inline const char* fast_atoreal_move( const char* c, Real& out) inline const char* fast_atoreal_move( const char* c, Real& out, bool check_comma = true)
{ {
Real f; Real f;
@ -234,7 +237,7 @@ inline const char* fast_atoreal_move( const char* c, Real& out)
} }
f = static_cast<Real>( strtoul10_64 ( c, &c) ); f = static_cast<Real>( strtoul10_64 ( c, &c) );
if (*c == '.' || (c[0] == ',' && c[1] >= '0' && c[1] <= '9')) // allow for commas, too if (*c == '.' || (check_comma && c[0] == ',' && c[1] >= '0' && c[1] <= '9')) // allow for commas, too
{ {
++c; ++c;
@ -270,7 +273,7 @@ inline const char* fast_atoreal_move( const char* c, Real& out)
if (einv) { if (einv) {
exp = -exp; exp = -exp;
} }
f *= pow(static_cast<Real>(10.0f), exp); f *= pow(static_cast<Real>(10.0), exp);
} }
if (inv) { if (inv) {

View File

@ -81,12 +81,22 @@ public:
// Map the buffer into memory and convert it to UTF8. IrrXML provides its // Map the buffer into memory and convert it to UTF8. IrrXML provides its
// own conversion, which is merely a cast from uintNN_t to uint8_t. Thus, // own conversion, which is merely a cast from uintNN_t to uint8_t. Thus,
// it is not suitable for our purposes and we have to do it BEFORE IrrXML // it is not suitable for our purposes and we have to do it BEFORE IrrXML
// gets the buffer. Sadly, this forces as to map the whole file into // gets the buffer. Sadly, this forces us to map the whole file into
// memory. // memory.
data.resize(stream->FileSize()); data.resize(stream->FileSize());
stream->Read(&data[0],data.size(),1); stream->Read(&data[0],data.size(),1);
// Remove null characters from the input sequence otherwise the parsing will utterly fail
unsigned int size = 0;
unsigned int size_max = data.size();
for(unsigned int i = 0; i < size_max; i++) {
if(data[i] != '\0') {
data[size++] = data[i];
}
}
data.resize(size);
BaseImporter::ConvertToUTF8(data); BaseImporter::ConvertToUTF8(data);
} }

View File

@ -215,7 +215,7 @@ private:
{ {
char_type* start = P; char_type* start = P;
// more forward until '<' found // move forward until '<' found
while(*P != L'<' && *P) while(*P != L'<' && *P)
++P; ++P;

View File

@ -0,0 +1,513 @@
/* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-2013 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#ifndef ZCONF_H
#define ZCONF_H
/* #undef Z_PREFIX */
/* #undef Z_HAVE_UNISTD_H */
/*
* If you *really* need a unique prefix for all types and library functions,
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
* Even better than compiling with -DZ_PREFIX would be to use configure to set
* this permanently in zconf.h using "./configure --zprefix".
*/
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
# define Z_PREFIX_SET
/* all linked symbols */
# define _dist_code z__dist_code
# define _length_code z__length_code
# define _tr_align z__tr_align
# define _tr_flush_bits z__tr_flush_bits
# define _tr_flush_block z__tr_flush_block
# define _tr_init z__tr_init
# define _tr_stored_block z__tr_stored_block
# define _tr_tally z__tr_tally
# define adler32 z_adler32
# define adler32_combine z_adler32_combine
# define adler32_combine64 z_adler32_combine64
# ifndef Z_SOLO
# define compress z_compress
# define compress2 z_compress2
# define compressBound z_compressBound
# endif
# define crc32 z_crc32
# define crc32_combine z_crc32_combine
# define crc32_combine64 z_crc32_combine64
# define deflate z_deflate
# define deflateBound z_deflateBound
# define deflateCopy z_deflateCopy
# define deflateEnd z_deflateEnd
# define deflateInit2_ z_deflateInit2_
# define deflateInit_ z_deflateInit_
# define deflateParams z_deflateParams
# define deflatePending z_deflatePending
# define deflatePrime z_deflatePrime
# define deflateReset z_deflateReset
# define deflateResetKeep z_deflateResetKeep
# define deflateSetDictionary z_deflateSetDictionary
# define deflateSetHeader z_deflateSetHeader
# define deflateTune z_deflateTune
# define deflate_copyright z_deflate_copyright
# define get_crc_table z_get_crc_table
# ifndef Z_SOLO
# define gz_error z_gz_error
# define gz_intmax z_gz_intmax
# define gz_strwinerror z_gz_strwinerror
# define gzbuffer z_gzbuffer
# define gzclearerr z_gzclearerr
# define gzclose z_gzclose
# define gzclose_r z_gzclose_r
# define gzclose_w z_gzclose_w
# define gzdirect z_gzdirect
# define gzdopen z_gzdopen
# define gzeof z_gzeof
# define gzerror z_gzerror
# define gzflush z_gzflush
# define gzgetc z_gzgetc
# define gzgetc_ z_gzgetc_
# define gzgets z_gzgets
# define gzoffset z_gzoffset
# define gzoffset64 z_gzoffset64
# define gzopen z_gzopen
# define gzopen64 z_gzopen64
# ifdef _WIN32
# define gzopen_w z_gzopen_w
# endif
# define gzprintf z_gzprintf
# define gzvprintf z_gzvprintf
# define gzputc z_gzputc
# define gzputs z_gzputs
# define gzread z_gzread
# define gzrewind z_gzrewind
# define gzseek z_gzseek
# define gzseek64 z_gzseek64
# define gzsetparams z_gzsetparams
# define gztell z_gztell
# define gztell64 z_gztell64
# define gzungetc z_gzungetc
# define gzwrite z_gzwrite
# endif
# define inflate z_inflate
# define inflateBack z_inflateBack
# define inflateBackEnd z_inflateBackEnd
# define inflateBackInit_ z_inflateBackInit_
# define inflateCopy z_inflateCopy
# define inflateEnd z_inflateEnd
# define inflateGetHeader z_inflateGetHeader
# define inflateInit2_ z_inflateInit2_
# define inflateInit_ z_inflateInit_
# define inflateMark z_inflateMark
# define inflatePrime z_inflatePrime
# define inflateReset z_inflateReset
# define inflateReset2 z_inflateReset2
# define inflateSetDictionary z_inflateSetDictionary
# define inflateGetDictionary z_inflateGetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateUndermine z_inflateUndermine
# define inflateResetKeep z_inflateResetKeep
# define inflate_copyright z_inflate_copyright
# define inflate_fast z_inflate_fast
# define inflate_table z_inflate_table
# ifndef Z_SOLO
# define uncompress z_uncompress
# endif
# define zError z_zError
# ifndef Z_SOLO
# define zcalloc z_zcalloc
# define zcfree z_zcfree
# endif
# define zlibCompileFlags z_zlibCompileFlags
# define zlibVersion z_zlibVersion
/* all zlib typedefs in zlib.h and zconf.h */
# define Byte z_Byte
# define Bytef z_Bytef
# define alloc_func z_alloc_func
# define charf z_charf
# define free_func z_free_func
# ifndef Z_SOLO
# define gzFile z_gzFile
# endif
# define gz_header z_gz_header
# define gz_headerp z_gz_headerp
# define in_func z_in_func
# define intf z_intf
# define out_func z_out_func
# define uInt z_uInt
# define uIntf z_uIntf
# define uLong z_uLong
# define uLongf z_uLongf
# define voidp z_voidp
# define voidpc z_voidpc
# define voidpf z_voidpf
/* all zlib structs in zlib.h and zconf.h */
# define gz_header_s z_gz_header_s
# define internal_state z_internal_state
#endif
#if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS
#endif
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
# define OS2
#endif
#if defined(_WINDOWS) && !defined(WINDOWS)
# define WINDOWS
#endif
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
# ifndef WIN32
# define WIN32
# endif
#endif
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
# ifndef SYS16BIT
# define SYS16BIT
# endif
# endif
#endif
/*
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
* than 64k bytes at a time (needed on systems with 16-bit int).
*/
#ifdef SYS16BIT
# define MAXSEG_64K
#endif
#ifdef MSDOS
# define UNALIGNED_OK
#endif
#ifdef __STDC_VERSION__
# ifndef STDC
# define STDC
# endif
# if __STDC_VERSION__ >= 199901L
# ifndef STDC99
# define STDC99
# endif
# endif
#endif
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
# define STDC
#endif
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
# define STDC
#endif
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
# define STDC
#endif
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
# define STDC
#endif
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
# define STDC
#endif
#ifndef STDC
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
# define const /* note: need a more gentle solution here */
# endif
#endif
#if defined(ZLIB_CONST) && !defined(z_const)
# define z_const const
#else
# define z_const
#endif
/* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
# define NO_DUMMY_DECL
#endif
/* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL
# ifdef MAXSEG_64K
# define MAX_MEM_LEVEL 8
# else
# define MAX_MEM_LEVEL 9
# endif
#endif
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
* created by gzip. (Files created by minigzip can still be extracted by
* gzip.)
*/
#ifndef MAX_WBITS
# define MAX_WBITS 15 /* 32K LZ77 window */
#endif
/* The memory requirements for deflate are (in bytes):
(1 << (windowBits+2)) + (1 << (memLevel+9))
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
plus a few kilobytes for small objects. For example, if you want to reduce
the default memory requirements from 256K to 128K, compile with
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
Of course this will generally degrade compression (there's no free lunch).
The memory requirements for inflate are (in bytes) 1 << windowBits
that is, 32K for windowBits=15 (default value) plus a few kilobytes
for small objects.
*/
/* Type declarations */
#ifndef OF /* function prototypes */
# ifdef STDC
# define OF(args) args
# else
# define OF(args) ()
# endif
#endif
#ifndef Z_ARG /* function prototypes for stdarg */
# if defined(STDC) || defined(Z_HAVE_STDARG_H)
# define Z_ARG(args) args
# else
# define Z_ARG(args) ()
# endif
#endif
/* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations).
* This was tested only with MSC; for other MSDOS compilers you may have
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
* just define FAR to be empty.
*/
#ifdef SYS16BIT
# if defined(M_I86SM) || defined(M_I86MM)
/* MSC small or medium model */
# define SMALL_MEDIUM
# ifdef _MSC_VER
# define FAR _far
# else
# define FAR far
# endif
# endif
# if (defined(__SMALL__) || defined(__MEDIUM__))
/* Turbo C small or medium model */
# define SMALL_MEDIUM
# ifdef __BORLANDC__
# define FAR _far
# else
# define FAR far
# endif
# endif
#endif
#if defined(WINDOWS) || defined(WIN32)
/* If building or using zlib as a DLL, define ZLIB_DLL.
* This is not mandatory, but it offers a little performance increase.
*/
# ifdef ZLIB_DLL
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
# ifdef ZLIB_INTERNAL
# define ZEXTERN extern __declspec(dllexport)
# else
# define ZEXTERN extern __declspec(dllimport)
# endif
# endif
# endif /* ZLIB_DLL */
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
* define ZLIB_WINAPI.
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
*/
# ifdef ZLIB_WINAPI
# ifdef FAR
# undef FAR
# endif
# include <windows.h>
/* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
# define ZEXPORT WINAPI
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# else
# define ZEXPORTVA FAR CDECL
# endif
# endif
#endif
#if defined (__BEOS__)
# ifdef ZLIB_DLL
# ifdef ZLIB_INTERNAL
# define ZEXPORT __declspec(dllexport)
# define ZEXPORTVA __declspec(dllexport)
# else
# define ZEXPORT __declspec(dllimport)
# define ZEXPORTVA __declspec(dllimport)
# endif
# endif
#endif
#ifndef ZEXTERN
# define ZEXTERN extern
#endif
#ifndef ZEXPORT
# define ZEXPORT
#endif
#ifndef ZEXPORTVA
# define ZEXPORTVA
#endif
#ifndef FAR
# define FAR
#endif
#if !defined(__MACTYPES__)
typedef unsigned char Byte; /* 8 bits */
#endif
typedef unsigned int uInt; /* 16 bits or more */
typedef unsigned long uLong; /* 32 bits or more */
#ifdef SMALL_MEDIUM
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
# define Bytef Byte FAR
#else
typedef Byte FAR Bytef;
#endif
typedef char FAR charf;
typedef int FAR intf;
typedef uInt FAR uIntf;
typedef uLong FAR uLongf;
#ifdef STDC
typedef void const *voidpc;
typedef void FAR *voidpf;
typedef void *voidp;
#else
typedef Byte const *voidpc;
typedef Byte FAR *voidpf;
typedef Byte *voidp;
#endif
#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
# include <limits.h>
# if (UINT_MAX == 0xffffffffUL)
# define Z_U4 unsigned
# elif (ULONG_MAX == 0xffffffffUL)
# define Z_U4 unsigned long
# elif (USHRT_MAX == 0xffffffffUL)
# define Z_U4 unsigned short
# endif
#endif
#ifdef Z_U4
typedef Z_U4 z_crc_t;
#else
typedef unsigned long z_crc_t;
#endif
#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
# define Z_HAVE_UNISTD_H
#endif
#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
# define Z_HAVE_STDARG_H
#endif
#ifdef STDC
# ifndef Z_SOLO
# include <sys/types.h> /* for off_t */
# endif
#endif
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
# ifndef Z_SOLO
# include <stdarg.h> /* for va_list */
# endif
#endif
#ifdef _WIN32
# ifndef Z_SOLO
# include <stddef.h> /* for wchar_t */
# endif
#endif
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
* "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
* though the former does not conform to the LFS document), but considering
* both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
* equivalently requesting no 64-bit operations
*/
#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
# undef _LARGEFILE64_SOURCE
#endif
#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
# define Z_HAVE_UNISTD_H
#endif
#ifndef Z_SOLO
# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
# ifdef VMS
# include <unixio.h> /* for off_t */
# endif
# ifndef z_off_t
# define z_off_t off_t
# endif
# endif
#endif
#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
# define Z_LFS64
#endif
#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
# define Z_LARGE64
#endif
#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
# define Z_WANT64
#endif
#if !defined(SEEK_SET) && !defined(Z_SOLO)
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
#endif
#ifndef z_off_t
# define z_off_t long
#endif
#if !defined(_WIN32) && defined(Z_LARGE64)
# define z_off64_t off64_t
#else
# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
# define z_off64_t __int64
# else
# define z_off64_t z_off_t
# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */
#if defined(__MVS__)
#pragma map(deflateInit_,"DEIN")
#pragma map(deflateInit2_,"DEIN2")
#pragma map(deflateEnd,"DEEND")
#pragma map(deflateBound,"DEBND")
#pragma map(inflateInit_,"ININ")
#pragma map(inflateInit2_,"ININ2")
#pragma map(inflateEnd,"INEND")
#pragma map(inflateSync,"INSY")
#pragma map(inflateSetDictionary,"INSEDI")
#pragma map(compressBound,"CMBND")
#pragma map(inflate_table,"INTABL")
#pragma map(inflate_fast,"INFA")
#pragma map(inflate_copyright,"INCOPY")
#endif
#endif /* ZCONF_H */

View File

@ -61,7 +61,10 @@ namespace Assimp {
* to the Importer. If you implement this interface, be sure to also provide an * to the Importer. If you implement this interface, be sure to also provide an
* implementation for IOSystem that creates instances of your custom IO class. * implementation for IOSystem that creates instances of your custom IO class.
*/ */
class ASSIMP_API IOStream : public Intern::AllocateFromAssimpHeap class ASSIMP_API IOStream
#ifndef SWIG
: public Intern::AllocateFromAssimpHeap
#endif
{ {
protected: protected:
/** Constructor protected, use IOSystem::Open() to create an instance. */ /** Constructor protected, use IOSystem::Open() to create an instance. */

View File

@ -64,7 +64,10 @@ class IOStream;
* supply a custom implementation for IOStream. * supply a custom implementation for IOStream.
* *
* @see Importer::SetIOHandler() */ * @see Importer::SetIOHandler() */
class ASSIMP_API IOSystem : public Intern::AllocateFromAssimpHeap class ASSIMP_API IOSystem
#ifndef SWIG
: public Intern::AllocateFromAssimpHeap
#endif
{ {
public: public:

View File

@ -230,6 +230,13 @@ public:
void SetPropertyString(const char* szName, const std::string& sValue, void SetPropertyString(const char* szName, const std::string& sValue,
bool* bWasExisting = NULL); bool* bWasExisting = NULL);
// -------------------------------------------------------------------
/** Set a matrix configuration property.
* @see SetPropertyInteger()
*/
void SetPropertyMatrix(const char* szName, const aiMatrix4x4& sValue,
bool* bWasExisting = NULL);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Get a configuration property. /** Get a configuration property.
* @param szName Name of the property. All supported properties * @param szName Name of the property. All supported properties
@ -270,9 +277,18 @@ public:
* The return value remains valid until the property is modified. * The return value remains valid until the property is modified.
* @see GetPropertyInteger() * @see GetPropertyInteger()
*/ */
const std::string& GetPropertyString(const char* szName, const std::string GetPropertyString(const char* szName,
const std::string& sErrorReturn = "") const; const std::string& sErrorReturn = "") const;
// -------------------------------------------------------------------
/** Get a matrix configuration property
*
* The return value remains valid until the property is modified.
* @see GetPropertyInteger()
*/
const aiMatrix4x4 GetPropertyMatrix(const char* szName,
const aiMatrix4x4& sErrorReturn = aiMatrix4x4()) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Supplies a custom IO handler to the importer to use to open and /** Supplies a custom IO handler to the importer to use to open and
* access files. If you need the importer to use custion IO logic to * access files. If you need the importer to use custion IO logic to

View File

@ -54,7 +54,10 @@ class IOSystem;
* details. Writing your own implementation of LogStream is just necessary if these * details. Writing your own implementation of LogStream is just necessary if these
* are not enough for your purpose. */ * are not enough for your purpose. */
class ASSIMP_API LogStream class ASSIMP_API LogStream
: public Intern::AllocateFromAssimpHeap { #ifndef SWIG
: public Intern::AllocateFromAssimpHeap
#endif
{
protected: protected:
/** @brief Default constructor */ /** @brief Default constructor */
LogStream() { LogStream() {

View File

@ -57,7 +57,10 @@ class LogStream;
* logging stuff ('DefaultLogger'). This class defines just basic logging * logging stuff ('DefaultLogger'). This class defines just basic logging
* behaviour and is not of interest for you. Instead, take a look at #DefaultLogger. */ * behaviour and is not of interest for you. Instead, take a look at #DefaultLogger. */
class ASSIMP_API Logger class ASSIMP_API Logger
: public Intern::AllocateFromAssimpHeap { #ifndef SWIG
: public Intern::AllocateFromAssimpHeap
#endif
{
public: public:
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------

View File

@ -52,7 +52,10 @@ namespace Assimp {
* Each #Importer instance maintains its own #ProgressHandler. The default * Each #Importer instance maintains its own #ProgressHandler. The default
* implementation provided by Assimp doesn't do anything at all. */ * implementation provided by Assimp doesn't do anything at all. */
class ASSIMP_API ProgressHandler class ASSIMP_API ProgressHandler
: public Intern::AllocateFromAssimpHeap { #ifndef SWIG
: public Intern::AllocateFromAssimpHeap
#endif
{
protected: protected:
/** @brief Default constructor */ /** @brief Default constructor */
ProgressHandler () { ProgressHandler () {

View File

@ -3,7 +3,7 @@
#ifndef AI_DEBUG_H_INC #ifndef AI_DEBUG_H_INC
#define AI_DEBUG_H_INC #define AI_DEBUG_H_INC
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
# include <assert.h> # include <assert.h>
# define ai_assert(expression) assert(expression) # define ai_assert(expression) assert(expression)
#else #else

View File

@ -79,6 +79,7 @@ struct aiLogStream
* @see aiSetPropertyInteger * @see aiSetPropertyInteger
* @see aiSetPropertyFloat * @see aiSetPropertyFloat
* @see aiSetPropertyString * @see aiSetPropertyString
* @see aiSetPropertyMatrix
*/ */
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
struct aiPropertyStore { char sentinel; }; struct aiPropertyStore { char sentinel; };
@ -397,6 +398,23 @@ ASSIMP_API void aiSetImportPropertyString(
const char* szName, const char* szName,
const C_STRUCT aiString* st); const C_STRUCT aiString* st);
// --------------------------------------------------------------------------------
/** Set a matrix property.
*
* This is the C-version of #Assimp::Importer::SetPropertyMatrix(). In the C
* interface, properties are always shared by all imports. It is not possible to
* specify them per import.
*
* @param property store to modify. Use #aiCreatePropertyStore to obtain a store.
* @param szName Name of the configuration property to be set. All supported
* public properties are defined in the config.h header file (#AI_CONFIG_XXX).
* @param value New value for the property
*/
ASSIMP_API void aiSetImportPropertyMatrix(
C_STRUCT aiPropertyStore* store,
const char* szName,
const C_STRUCT aiMatrix4x4* mat);
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
/** Construct a quaternion from a 3x3 rotation matrix. /** Construct a quaternion from a 3x3 rotation matrix.
* @param quat Receives the output quaternion. * @param quat Receives the output quaternion.

View File

@ -74,6 +74,7 @@ public:
// comparison // comparison
bool operator == (const aiColor4t& other) const; bool operator == (const aiColor4t& other) const;
bool operator != (const aiColor4t& other) const; bool operator != (const aiColor4t& other) const;
bool operator < (const aiColor4t& other) const;
// color tuple access, rgba order // color tuple access, rgba order
inline TReal operator[](unsigned int i) const; inline TReal operator[](unsigned int i) const;

View File

@ -94,6 +94,23 @@ AI_FORCE_INLINE bool aiColor4t<TReal>::operator!= (const aiColor4t<TReal>& other
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <typename TReal> template <typename TReal>
AI_FORCE_INLINE bool aiColor4t<TReal>::operator< (const aiColor4t<TReal>& other) const {
return r < other.r || (
r == other.r && (
g < other.g || (
g == other.g && (
b < other.b || (
b == other.b && (
a < other.a
)
)
)
)
)
);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
AI_FORCE_INLINE aiColor4t<TReal> operator + (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) { AI_FORCE_INLINE aiColor4t<TReal> operator + (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) {
return aiColor4t<TReal>( v1.r + v2.r, v1.g + v2.g, v1.b + v2.b, v1.a + v2.a); return aiColor4t<TReal>( v1.r + v2.r, v1.g + v2.g, v1.b + v2.b, v1.a + v2.a);
} }

View File

@ -233,6 +233,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONFIG_PP_PTV_NORMALIZE \ #define AI_CONFIG_PP_PTV_NORMALIZE \
"PP_PTV_NORMALIZE" "PP_PTV_NORMALIZE"
// ---------------------------------------------------------------------------
/** @brief Configures the #aiProcess_PretransformVertices step to use
* a users defined matrix as the scene root node transformation before
* transforming vertices.
* Property type: bool. Default value: false.
*/
#define AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION \
"PP_PTV_ADD_ROOT_TRANSFORMATION"
// ---------------------------------------------------------------------------
/** @brief Configures the #aiProcess_PretransformVertices step to use
* a users defined matrix as the scene root node transformation before
* transforming vertices. This property correspond to the 'a1' component
* of the transformation matrix.
* Property type: aiMatrix4x4.
*/
#define AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION \
"PP_PTV_ROOT_TRANSFORMATION"
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief Configures the #aiProcess_FindDegenerates step to /** @brief Configures the #aiProcess_FindDegenerates step to
* remove degenerated primitives from the import - immediately. * remove degenerated primitives from the import - immediately.

View File

@ -238,11 +238,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# define ASSIMP_BUILD_SINGLETHREADED # define ASSIMP_BUILD_SINGLETHREADED
#endif #endif
#ifndef ASSIMP_BUILD_SINGLETHREADED #if defined(_DEBUG) || ! defined(NDEBUG)
# define AI_C_THREADSAFE
#endif // !! ASSIMP_BUILD_SINGLETHREADED
#ifdef _DEBUG
# define ASSIMP_BUILD_DEBUG # define ASSIMP_BUILD_DEBUG
#endif #endif

View File

@ -1473,6 +1473,18 @@ ASSIMP_API C_ENUM aiReturn aiGetMaterialColor(const C_STRUCT aiMaterial* pMat,
C_STRUCT aiColor4D* pOut); C_STRUCT aiColor4D* pOut);
// ---------------------------------------------------------------------------
/** @brief Retrieve a aiUVTransform value from the material property table
*
* See the sample for aiGetMaterialFloat for more information*/
// ---------------------------------------------------------------------------
ASSIMP_API C_ENUM aiReturn aiGetMaterialUVTransform(const C_STRUCT aiMaterial* pMat,
const char* pKey,
unsigned int type,
unsigned int index,
C_STRUCT aiUVTransform* pOut);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief Retrieve a string from the material property table /** @brief Retrieve a string from the material property table
* *

View File

@ -167,6 +167,12 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
{ {
return aiGetMaterialString(this,pKey,type,idx,&pOut); return aiGetMaterialString(this,pKey,type,idx,&pOut);
} }
// ---------------------------------------------------------------------------
inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
unsigned int idx,aiUVTransform& pOut) const
{
return aiGetMaterialUVTransform(this,pKey,type,idx,&pOut);
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -90,8 +90,10 @@ public:
const TReal* operator[] (unsigned int p_iIndex) const; const TReal* operator[] (unsigned int p_iIndex) const;
// comparison operators // comparison operators
bool operator== (const aiMatrix4x4t<TReal> m) const; bool operator== (const aiMatrix4x4t<TReal>& m) const;
bool operator!= (const aiMatrix4x4t<TReal> m) const; bool operator!= (const aiMatrix4x4t<TReal>& m) const;
bool Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon = 1e-6) const;
template <typename TOther> template <typename TOther>
operator aiMatrix3x3t<TOther> () const; operator aiMatrix3x3t<TOther> () const;

View File

@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "matrix4x4.h" #include "matrix4x4.h"
#include <algorithm> #include <algorithm>
#include <cmath>
#include <limits> #include <limits>
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -113,7 +114,7 @@ inline const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) cons
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <typename TReal> template <typename TReal>
inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal> m) const inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const
{ {
return a1 == m.a1 && a2 == m.a2 && a3 == m.a3 && return a1 == m.a1 && a2 == m.a2 && a3 == m.a3 &&
b1 == m.b1 && b2 == m.b2 && b3 == m.b3 && b1 == m.b1 && b2 == m.b2 && b3 == m.b3 &&
@ -122,11 +123,26 @@ inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal> m) const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <typename TReal> template <typename TReal>
inline bool aiMatrix3x3t<TReal>::operator!= (const aiMatrix4x4t<TReal> m) const inline bool aiMatrix3x3t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const
{ {
return !(*this == m); return !(*this == m);
} }
// ---------------------------------------------------------------------------
template<typename TReal>
inline bool aiMatrix3x3t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const {
return
std::abs(a1 - m.a1) <= epsilon &&
std::abs(a2 - m.a2) <= epsilon &&
std::abs(a3 - m.a3) <= epsilon &&
std::abs(b1 - m.b1) <= epsilon &&
std::abs(b2 - m.b2) <= epsilon &&
std::abs(b3 - m.b3) <= epsilon &&
std::abs(c1 - m.c1) <= epsilon &&
std::abs(c2 - m.c2) <= epsilon &&
std::abs(c3 - m.c3) <= epsilon;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <typename TReal> template <typename TReal>
inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose() inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose()

View File

@ -79,6 +79,14 @@ public:
/** construction from 3x3 matrix, remaining elements are set to identity */ /** construction from 3x3 matrix, remaining elements are set to identity */
explicit aiMatrix4x4t( const aiMatrix3x3t<TReal>& m); explicit aiMatrix4x4t( const aiMatrix3x3t<TReal>& m);
/** construction from position, rotation and scaling components
* @param scaling The scaling for the x,y,z axes
* @param rotation The rotation as a hamilton quaternion
* @param position The position for the x,y,z axes
*/
aiMatrix4x4t(aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation,
aiVector3t<TReal>& position);
public: public:
// array access operators // array access operators
@ -86,8 +94,10 @@ public:
const TReal* operator[] (unsigned int p_iIndex) const; const TReal* operator[] (unsigned int p_iIndex) const;
// comparison operators // comparison operators
bool operator== (const aiMatrix4x4t m) const; bool operator== (const aiMatrix4x4t& m) const;
bool operator!= (const aiMatrix4x4t m) const; bool operator!= (const aiMatrix4x4t& m) const;
bool Equal(const aiMatrix4x4t& m, TReal epsilon = 1e-6) const;
// matrix multiplication. // matrix multiplication.
aiMatrix4x4t& operator *= (const aiMatrix4x4t& m); aiMatrix4x4t& operator *= (const aiMatrix4x4t& m);

View File

@ -107,6 +107,34 @@ inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m)
d1 = static_cast<TReal>(0.0); d2 = static_cast<TReal>(0.0); d3 = static_cast<TReal>(0.0); d4 = static_cast<TReal>(1.0); d1 = static_cast<TReal>(0.0); d2 = static_cast<TReal>(0.0); d3 = static_cast<TReal>(0.0); d4 = static_cast<TReal>(1.0);
} }
// ----------------------------------------------------------------------------------------
template <typename TReal>
inline aiMatrix4x4t<TReal>::aiMatrix4x4t (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation, aiVector3t<TReal>& position)
{
// build a 3x3 rotation matrix
aiMatrix3x3t<TReal> m = rotation.GetMatrix();
a1 = m.a1 * scaling.x;
a2 = m.a2 * scaling.x;
a3 = m.a3 * scaling.x;
a4 = position.x;
b1 = m.b1 * scaling.y;
b2 = m.b2 * scaling.y;
b3 = m.b3 * scaling.y;
b4 = position.y;
c1 = m.c1 * scaling.z;
c2 = m.c2 * scaling.z;
c3 = m.c3 * scaling.z;
c4= position.z;
d1 = static_cast<TReal>(0.0);
d2 = static_cast<TReal>(0.0);
d3 = static_cast<TReal>(0.0);
d4 = static_cast<TReal>(1.0);
}
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename TReal> template <typename TReal>
inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t<TReal>& m) inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t<TReal>& m)
@ -231,7 +259,7 @@ inline const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename TReal> template <typename TReal>
inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal> m) const inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const
{ {
return (a1 == m.a1 && a2 == m.a2 && a3 == m.a3 && a4 == m.a4 && return (a1 == m.a1 && a2 == m.a2 && a3 == m.a3 && a4 == m.a4 &&
b1 == m.b1 && b2 == m.b2 && b3 == m.b3 && b4 == m.b4 && b1 == m.b1 && b2 == m.b2 && b3 == m.b3 && b4 == m.b4 &&
@ -241,11 +269,33 @@ inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal> m) const
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename TReal> template <typename TReal>
inline bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal> m) const inline bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const
{ {
return !(*this == m); return !(*this == m);
} }
// ---------------------------------------------------------------------------
template<typename TReal>
inline bool aiMatrix4x4t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const {
return
std::abs(a1 - m.a1) <= epsilon &&
std::abs(a2 - m.a2) <= epsilon &&
std::abs(a3 - m.a3) <= epsilon &&
std::abs(a4 - m.a4) <= epsilon &&
std::abs(b1 - m.b1) <= epsilon &&
std::abs(b2 - m.b2) <= epsilon &&
std::abs(b3 - m.b3) <= epsilon &&
std::abs(b4 - m.b4) <= epsilon &&
std::abs(c1 - m.c1) <= epsilon &&
std::abs(c2 - m.c2) <= epsilon &&
std::abs(c3 - m.c3) <= epsilon &&
std::abs(c4 - m.c4) <= epsilon &&
std::abs(d1 - m.d1) <= epsilon &&
std::abs(d2 - m.d2) <= epsilon &&
std::abs(d3 - m.d3) <= epsilon &&
std::abs(d4 - m.d4) <= epsilon;
}
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename TReal> template <typename TReal>
inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation, inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation,

View File

@ -620,7 +620,7 @@ struct aiMesh
, mBitangents( NULL ) , mBitangents( NULL )
, mFaces( NULL ) , mFaces( NULL )
, mNumBones( 0 ) , mNumBones( 0 )
, mBones( 0 ) , mBones( NULL )
, mMaterialIndex( 0 ) , mMaterialIndex( 0 )
, mNumAnimMeshes( 0 ) , mNumAnimMeshes( 0 )
, mAnimMeshes( NULL ) , mAnimMeshes( NULL )

View File

@ -64,7 +64,9 @@ enum aiMetadataType
AI_AISTRING = 4, AI_AISTRING = 4,
AI_AIVECTOR3D = 5, AI_AIVECTOR3D = 5,
#ifndef SWIG
FORCE_32BIT = INT_MAX FORCE_32BIT = INT_MAX
#endif
}; };

View File

@ -79,6 +79,8 @@ public:
bool operator== (const aiQuaterniont& o) const; bool operator== (const aiQuaterniont& o) const;
bool operator!= (const aiQuaterniont& o) const; bool operator!= (const aiQuaterniont& o) const;
bool Equal(const aiQuaterniont& o, TReal epsilon = 1e-6) const;
public: public:
/** Normalize the quaternion */ /** Normalize the quaternion */

View File

@ -48,6 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifdef __cplusplus #ifdef __cplusplus
#include "quaternion.h" #include "quaternion.h"
#include <cmath>
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
template<typename TReal> template<typename TReal>
bool aiQuaterniont<TReal>::operator== (const aiQuaterniont& o) const bool aiQuaterniont<TReal>::operator== (const aiQuaterniont& o) const
@ -62,7 +64,15 @@ bool aiQuaterniont<TReal>::operator!= (const aiQuaterniont& o) const
return !(*this == o); return !(*this == o);
} }
// ---------------------------------------------------------------------------
template<typename TReal>
inline bool aiQuaterniont<TReal>::Equal(const aiQuaterniont& o, TReal epsilon) const {
return
std::abs(x - o.x) <= epsilon &&
std::abs(y - o.y) <= epsilon &&
std::abs(z - o.z) <= epsilon &&
std::abs(w - o.w) <= epsilon;
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Constructs a quaternion from a rotation matrix // Constructs a quaternion from a rotation matrix

View File

@ -123,13 +123,13 @@ struct aiNode
/** Constructor */ /** Constructor */
aiNode() aiNode()
// set all members to zero by default // set all members to zero by default
: mName() : mName("")
, mParent() , mParent(NULL)
, mNumChildren() , mNumChildren(0)
, mChildren() , mChildren(NULL)
, mNumMeshes() , mNumMeshes(0)
, mMeshes() , mMeshes(NULL)
, mMetaData() , mMetaData(NULL)
{ {
} }
@ -138,12 +138,12 @@ struct aiNode
aiNode(const std::string& name) aiNode(const std::string& name)
// set all members to zero by default // set all members to zero by default
: mName(name) : mName(name)
, mParent() , mParent(NULL)
, mNumChildren() , mNumChildren(0)
, mChildren() , mChildren(NULL)
, mNumMeshes() , mNumMeshes(0)
, mMeshes() , mMeshes(NULL)
, mMetaData() , mMetaData(NULL)
{ {
} }
@ -378,10 +378,10 @@ struct aiScene
#ifdef __cplusplus #ifdef __cplusplus
//! Default constructor - set everything to 0/NULL //! Default constructor - set everything to 0/NULL
aiScene(); ASSIMP_API aiScene();
//! Destructor //! Destructor
~aiScene(); ASSIMP_API ~aiScene();
//! Check whether the scene contains meshes //! Check whether the scene contains meshes
//! Unless no special scene flags are set this will always be true. //! Unless no special scene flags are set this will always be true.

View File

@ -174,6 +174,16 @@ struct aiColor3D
bool operator != (const aiColor3D& other) const bool operator != (const aiColor3D& other) const
{return r != other.r || g != other.g || b != other.b;} {return r != other.r || g != other.g || b != other.b;}
/** Component-wise comparison */
// TODO: add epsilon?
bool operator < (const aiColor3D& other) const {
return r < other.r || (
r == other.r && (g < other.g ||
(g == other.g && b < other.b)
)
);
}
/** Component-wise addition */ /** Component-wise addition */
aiColor3D operator+(const aiColor3D& c) const { aiColor3D operator+(const aiColor3D& c) const {
return aiColor3D(r+c.r,g+c.g,b+c.b); return aiColor3D(r+c.r,g+c.g,b+c.b);
@ -247,7 +257,7 @@ struct aiString
{ {
data[0] = '\0'; data[0] = '\0';
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
// Debug build: overwrite the string on its full length with ESC (27) // Debug build: overwrite the string on its full length with ESC (27)
memset(data+1,27,MAXLEN-1); memset(data+1,27,MAXLEN-1);
#endif #endif
@ -334,7 +344,7 @@ struct aiString
length = 0; length = 0;
data[0] = '\0'; data[0] = '\0';
#ifdef _DEBUG #ifdef ASSIMP_BUILD_DEBUG
// Debug build: overwrite the string on its full length with ESC (27) // Debug build: overwrite the string on its full length with ESC (27)
memset(data+1,27,MAXLEN-1); memset(data+1,27,MAXLEN-1);
#endif #endif

View File

@ -87,6 +87,8 @@ public:
bool operator== (const aiVector2t& other) const; bool operator== (const aiVector2t& other) const;
bool operator!= (const aiVector2t& other) const; bool operator!= (const aiVector2t& other) const;
bool Equal(const aiVector2t& other, TReal epsilon = 1e-6) const;
aiVector2t& operator= (TReal f); aiVector2t& operator= (TReal f);
const aiVector2t SymMul(const aiVector2t& o); const aiVector2t SymMul(const aiVector2t& o);

View File

@ -48,6 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifdef __cplusplus #ifdef __cplusplus
#include "vector2.h" #include "vector2.h"
#include <cmath>
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <typename TReal> template <typename TReal>
template <typename TOther> template <typename TOther>
@ -131,6 +133,14 @@ bool aiVector2t<TReal>::operator!= (const aiVector2t& other) const {
return x != other.x || y != other.y; return x != other.x || y != other.y;
} }
// ---------------------------------------------------------------------------
template<typename TReal>
bool aiVector2t<TReal>::Equal(const aiVector2t& other, TReal epsilon) const {
return
std::abs(x - other.x) <= epsilon &&
std::abs(y - other.y) <= epsilon;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <typename TReal> template <typename TReal>
aiVector2t<TReal>& aiVector2t<TReal>::operator= (TReal f) { aiVector2t<TReal>& aiVector2t<TReal>::operator= (TReal f) {

View File

@ -89,6 +89,8 @@ public:
bool operator== (const aiVector3t& other) const; bool operator== (const aiVector3t& other) const;
bool operator!= (const aiVector3t& other) const; bool operator!= (const aiVector3t& other) const;
bool Equal(const aiVector3t& other, TReal epsilon = 1e-6) const;
template <typename TOther> template <typename TOther>
operator aiVector3t<TOther> () const; operator aiVector3t<TOther> () const;

View File

@ -48,6 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifdef __cplusplus #ifdef __cplusplus
#include "vector3.h" #include "vector3.h"
#include <cmath>
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
/** Transformation of a vector by a 3x3 matrix */ /** Transformation of a vector by a 3x3 matrix */
template <typename TReal> template <typename TReal>
@ -147,6 +149,14 @@ template <typename TReal>
AI_FORCE_INLINE bool aiVector3t<TReal>::operator!= (const aiVector3t<TReal>& other) const { AI_FORCE_INLINE bool aiVector3t<TReal>::operator!= (const aiVector3t<TReal>& other) const {
return x != other.x || y != other.y || z != other.z; return x != other.x || y != other.y || z != other.z;
} }
// ---------------------------------------------------------------------------
template<typename TReal>
AI_FORCE_INLINE bool aiVector3t<TReal>::Equal(const aiVector3t<TReal>& other, TReal epsilon) const {
return
std::abs(x - other.x) <= epsilon &&
std::abs(y - other.y) <= epsilon &&
std::abs(z - other.z) <= epsilon;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <typename TReal> template <typename TReal>
AI_FORCE_INLINE const aiVector3t<TReal> aiVector3t<TReal>::SymMul(const aiVector3t<TReal>& o) { AI_FORCE_INLINE const aiVector3t<TReal> aiVector3t<TReal>::SymMul(const aiVector3t<TReal>& o) {

View File

@ -51,7 +51,7 @@ const char* AICMD_MSG_ABOUT =
" -- Commandline toolchain --\n" " -- Commandline toolchain --\n"
"------------------------------------------------------ \n\n" "------------------------------------------------------ \n\n"
"Version %i.%i-%s%s%s%s%s (SVNREV %i)\n\n"; "Version %i.%i %s%s%s%s%s(SVNREV %i)\n\n";
const char* AICMD_MSG_HELP = const char* AICMD_MSG_HELP =
"assimp <verb> <parameters>\n\n" "assimp <verb> <parameters>\n\n"

View File

@ -1041,27 +1041,35 @@ void DoExport(size_t formatId)
char szFileName[MAX_PATH*2]; char szFileName[MAX_PATH*2];
DWORD dwTemp; DWORD dwTemp;
if(ERROR_SUCCESS == RegQueryValueEx(g_hRegistry,"ModelExportDest",NULL,NULL,(BYTE*)szFileName,&dwTemp)) { if(ERROR_SUCCESS == RegQueryValueEx(g_hRegistry,"ModelExportDest",NULL,NULL,(BYTE*)szFileName,&dwTemp)) {
ai_assert(dwTemp == MAX_PATH + 1);
ai_assert(strlen(szFileName) <= MAX_PATH);
// invent a nice default file name // invent a nice default file name
char* sz = std::max(strrchr(szFileName,'\\'),strrchr(szFileName,'/')); char* sz = std::max(strrchr(szFileName,'\\'),strrchr(szFileName,'/'));
if (sz) { if (sz) {
strcpy(sz,std::max(strrchr(g_szFileName,'\\'),strrchr(g_szFileName,'/'))); strncpy(sz,std::max(strrchr(g_szFileName,'\\'),strrchr(g_szFileName,'/')),MAX_PATH);
} }
} }
else { else {
// Key was not found. Use the folder where the asset comes from // Key was not found. Use the folder where the asset comes from
strcpy(szFileName,g_szFileName); strncpy(szFileName,g_szFileName,MAX_PATH);
} }
// fix file extension // fix file extension
{ char * const sz = strrchr(szFileName,'.'); { char * const sz = strrchr(szFileName,'.');
if(sz) strcpy(sz+1,e->fileExtension); if(sz) {
ai_assert((sz - &szFileName[0]) + strlen(e->fileExtension) + 1 <= MAX_PATH);
strcpy(sz+1,e->fileExtension);
}
} }
// build the stupid info string for GetSaveFileName() - can't use sprintf() because the string must contain binary zeros. // build the stupid info string for GetSaveFileName() - can't use sprintf() because the string must contain binary zeros.
char desc[256] = {0}; char desc[256] = {0};
char* c = strcpy(desc,e->description) + strlen(e->description)+1; char* c = strcpy(desc,e->description) + strlen(e->description)+1;
c += sprintf(c,"*.%s",e->fileExtension)+1; c += sprintf(c,"*.%s",e->fileExtension)+1;
strcpy(c, "*.*\0"); strcpy(c, "*.*\0"); c += 4;
ai_assert(c - &desc[0] <= 256);
const std::string ext = "."+std::string(e->fileExtension); const std::string ext = "."+std::string(e->fileExtension);
OPENFILENAME sFilename1 = { OPENFILENAME sFilename1 = {
@ -1084,7 +1092,15 @@ void DoExport(size_t formatId)
} }
// export the file // export the file
const aiReturn res = exp.Export(g_pcAsset->pcScene,e->id,sFinal.c_str()); const aiReturn res = exp.Export(g_pcAsset->pcScene,e->id,sFinal.c_str(),
ppsteps | /* configurable pp steps */
aiProcess_GenSmoothNormals | // generate smooth normal vectors if not existing
aiProcess_SplitLargeMeshes | // split large, unrenderable meshes into submeshes
aiProcess_Triangulate | // triangulate polygons with more than 3 edges
aiProcess_ConvertToLeftHanded | // convert everything to D3D left handed space
aiProcess_SortByPType | // make 'clean' meshes which consist of a single typ of primitives
0
);
if (res == aiReturn_SUCCESS) { if (res == aiReturn_SUCCESS) {
CLogDisplay::Instance().AddEntry("[INFO] Exported file " + sFinal,D3DCOLOR_ARGB(0xFF,0x00,0xFF,0x00)); CLogDisplay::Instance().AddEntry("[INFO] Exported file " + sFinal,D3DCOLOR_ARGB(0xFF,0x00,0xFF,0x00));
return; return;