Merge branch 'master' into kimkulling-build-instructions

pull/2092/head
Kim Kulling 2018-09-18 20:40:56 +02:00 committed by GitHub
commit 62416122d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
64 changed files with 26021 additions and 1621 deletions

View File

@ -111,9 +111,9 @@ OPTION( INJECT_DEBUG_POSTFIX
) )
IF (IOS) IF (IOS)
IF (NOT CMAKE_BUILD_TYPE) IF (NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE "Release") SET(CMAKE_BUILD_TYPE "Release")
ENDIF (NOT CMAKE_BUILD_TYPE) ENDIF (NOT CMAKE_BUILD_TYPE)
ENDIF (IOS) ENDIF (IOS)
# Use subset of Windows.h # Use subset of Windows.h
@ -210,8 +210,8 @@ ENDIF( UNIX )
# Grouped compiler settings # Grouped compiler settings
IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW) IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
# hide all not-exported symbols # hide all not-exported symbols
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -std=c++0x") SET(CMAKE_CXX_FLAGS "-g -fvisibility=hidden -fPIC -fno-strict-aliasing -Wall -std=c++0x ${CMAKE_CXX_FLAGS}")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") SET(CMAKE_C_FLAGS "-fPIC -fno-strict-aliasing ${CMAKE_C_FLAGS}")
SET(LIBSTDC++_LIBRARIES -lstdc++) SET(LIBSTDC++_LIBRARIES -lstdc++)
ELSEIF(MSVC) ELSEIF(MSVC)
# enable multi-core compilation with MSVC # enable multi-core compilation with MSVC
@ -224,11 +224,11 @@ ELSEIF(MSVC)
ADD_COMPILE_OPTIONS(/wd4351) ADD_COMPILE_OPTIONS(/wd4351)
ENDIF() ENDIF()
ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" ) ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -Wno-long-long -std=c++11" ) SET(CMAKE_CXX_FLAGS "-g -fvisibility=hidden -fPIC -fno-strict-aliasing -Wall -Wno-long-long -std=c++11 ${CMAKE_CXX_FLAGS}" )
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") SET(CMAKE_C_FLAGS "-fPIC -fno-strict-aliasing ${CMAKE_C_FLAGS}")
ELSEIF( CMAKE_COMPILER_IS_MINGW ) ELSEIF( CMAKE_COMPILER_IS_MINGW )
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -std=c++11" ) SET( CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -std=c++11 -Wa,-mbig-obj ${CMAKE_CXX_FLAGS}" )
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") SET(CMAKE_C_FLAGS "-fPIC -fno-strict-aliasing ${CMAKE_C_FLAGS} ")
ADD_DEFINITIONS( -U__STRICT_ANSI__ ) ADD_DEFINITIONS( -U__STRICT_ANSI__ )
ENDIF() ENDIF()

View File

@ -30,6 +30,8 @@ One-off donations via PayPal:
Please check our Wiki as well: https://github.com/assimp/assimp/wiki Please check our Wiki as well: https://github.com/assimp/assimp/wiki
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
#### Supported file formats #### #### Supported file formats ####
__Importers__: __Importers__:

File diff suppressed because it is too large Load Diff

View File

@ -46,6 +46,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_ASSBINEXPORTER_H_INC #ifndef AI_ASSBINEXPORTER_H_INC
#define AI_ASSBINEXPORTER_H_INC #define AI_ASSBINEXPORTER_H_INC
// nothing really needed here - reserved for future use like properties #include <assimp/defs.h>
#endif // nothing really needed here - reserved for future use like properties
namespace Assimp {
void ASSIMP_API ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/);
}
#endif // AI_ASSBINEXPORTER_H_INC

View File

@ -79,16 +79,17 @@ static const aiImporterDesc desc = {
"assbin" "assbin"
}; };
const aiImporterDesc* AssbinImporter::GetInfo() const // -----------------------------------------------------------------------------------
{ const aiImporterDesc* AssbinImporter::GetInfo() const {
return &desc; return &desc;
} }
bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/ ) const // -----------------------------------------------------------------------------------
{ bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/ ) const {
IOStream * in = pIOHandler->Open(pFile); IOStream * in = pIOHandler->Open(pFile);
if (!in) if (nullptr == in) {
return false; return false;
}
char s[32]; char s[32];
in->Read( s, sizeof(char), 32 ); in->Read( s, sizeof(char), 32 );
@ -98,17 +99,17 @@ bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bo
return strncmp( s, "ASSIMP.binary-dump.", 19 ) == 0; return strncmp( s, "ASSIMP.binary-dump.", 19 ) == 0;
} }
// -----------------------------------------------------------------------------------
template <typename T> template <typename T>
T Read(IOStream * stream) T Read(IOStream * stream) {
{
T t; T t;
stream->Read( &t, sizeof(T), 1 ); stream->Read( &t, sizeof(T), 1 );
return t; return t;
} }
// -----------------------------------------------------------------------------------
template <> template <>
aiVector3D Read<aiVector3D>(IOStream * stream) aiVector3D Read<aiVector3D>(IOStream * stream) {
{
aiVector3D v; aiVector3D v;
v.x = Read<float>(stream); v.x = Read<float>(stream);
v.y = Read<float>(stream); v.y = Read<float>(stream);
@ -116,9 +117,9 @@ aiVector3D Read<aiVector3D>(IOStream * stream)
return v; return v;
} }
// -----------------------------------------------------------------------------------
template <> template <>
aiColor4D Read<aiColor4D>(IOStream * stream) aiColor4D Read<aiColor4D>(IOStream * stream) {
{
aiColor4D c; aiColor4D c;
c.r = Read<float>(stream); c.r = Read<float>(stream);
c.g = Read<float>(stream); c.g = Read<float>(stream);
@ -127,9 +128,9 @@ aiColor4D Read<aiColor4D>(IOStream * stream)
return c; return c;
} }
// -----------------------------------------------------------------------------------
template <> template <>
aiQuaternion Read<aiQuaternion>(IOStream * stream) aiQuaternion Read<aiQuaternion>(IOStream * stream) {
{
aiQuaternion v; aiQuaternion v;
v.w = Read<float>(stream); v.w = Read<float>(stream);
v.x = Read<float>(stream); v.x = Read<float>(stream);
@ -138,9 +139,9 @@ aiQuaternion Read<aiQuaternion>(IOStream * stream)
return v; return v;
} }
// -----------------------------------------------------------------------------------
template <> template <>
aiString Read<aiString>(IOStream * stream) aiString Read<aiString>(IOStream * stream) {
{
aiString s; aiString s;
stream->Read(&s.length,4,1); stream->Read(&s.length,4,1);
stream->Read(s.data,s.length,1); stream->Read(s.data,s.length,1);
@ -148,18 +149,18 @@ aiString Read<aiString>(IOStream * stream)
return s; return s;
} }
// -----------------------------------------------------------------------------------
template <> template <>
aiVertexWeight Read<aiVertexWeight>(IOStream * stream) aiVertexWeight Read<aiVertexWeight>(IOStream * stream) {
{
aiVertexWeight w; aiVertexWeight w;
w.mVertexId = Read<unsigned int>(stream); w.mVertexId = Read<unsigned int>(stream);
w.mWeight = Read<float>(stream); w.mWeight = Read<float>(stream);
return w; return w;
} }
// -----------------------------------------------------------------------------------
template <> template <>
aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream) aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream) {
{
aiMatrix4x4 m; aiMatrix4x4 m;
for (unsigned int i = 0; i < 4;++i) { for (unsigned int i = 0; i < 4;++i) {
for (unsigned int i2 = 0; i2 < 4;++i2) { for (unsigned int i2 = 0; i2 < 4;++i2) {
@ -169,36 +170,43 @@ aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream)
return m; return m;
} }
// -----------------------------------------------------------------------------------
template <> template <>
aiVectorKey Read<aiVectorKey>(IOStream * stream) aiVectorKey Read<aiVectorKey>(IOStream * stream) {
{
aiVectorKey v; aiVectorKey v;
v.mTime = Read<double>(stream); v.mTime = Read<double>(stream);
v.mValue = Read<aiVector3D>(stream); v.mValue = Read<aiVector3D>(stream);
return v; return v;
} }
// -----------------------------------------------------------------------------------
template <> template <>
aiQuatKey Read<aiQuatKey>(IOStream * stream) aiQuatKey Read<aiQuatKey>(IOStream * stream) {
{
aiQuatKey v; aiQuatKey v;
v.mTime = Read<double>(stream); v.mTime = Read<double>(stream);
v.mValue = Read<aiQuaternion>(stream); v.mValue = Read<aiQuaternion>(stream);
return v; return v;
} }
// -----------------------------------------------------------------------------------
template <typename T> template <typename T>
void ReadArray(IOStream * stream, T * out, unsigned int size) void ReadArray( IOStream *stream, T * out, unsigned int size) {
{ ai_assert( nullptr != stream );
for (unsigned int i=0; i<size; i++) out[i] = Read<T>(stream); ai_assert( nullptr != out );
for (unsigned int i=0; i<size; i++) {
out[i] = Read<T>(stream);
}
} }
template <typename T> void ReadBounds( IOStream * stream, T* /*p*/, unsigned int n ) // -----------------------------------------------------------------------------------
{ template <typename T>
void ReadBounds( IOStream * stream, T* /*p*/, unsigned int n ) {
// not sure what to do here, the data isn't really useful. // not sure what to do here, the data isn't really useful.
stream->Seek( sizeof(T) * n, aiOrigin_CUR ); stream->Seek( sizeof(T) * n, aiOrigin_CUR );
} }
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* parent ) { void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* parent ) {
uint32_t chunkID = Read<uint32_t>(stream); uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID); (void)(chunkID);
@ -273,8 +281,7 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* p
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) {
{
uint32_t chunkID = Read<uint32_t>(stream); uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID); (void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AIBONE); ai_assert(chunkID == ASSBIN_CHUNK_AIBONE);
@ -286,20 +293,22 @@ void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b )
// for the moment we write dumb min/max values for the bones, too. // for the moment we write dumb min/max values for the bones, too.
// maybe I'll add a better, hash-like solution later // maybe I'll add a better, hash-like solution later
if (shortened) if (shortened) {
{
ReadBounds(stream,b->mWeights,b->mNumWeights); ReadBounds(stream,b->mWeights,b->mNumWeights);
} // else write as usual } else {
else // else write as usual
{
b->mWeights = new aiVertexWeight[b->mNumWeights]; b->mWeights = new aiVertexWeight[b->mNumWeights];
ReadArray<aiVertexWeight>(stream,b->mWeights,b->mNumWeights); ReadArray<aiVertexWeight>(stream,b->mWeights,b->mNumWeights);
} }
} }
// -----------------------------------------------------------------------------------
static bool fitsIntoUI16(unsigned int mNumVertices) {
return ( mNumVertices < (1u<<16) );
}
void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) // -----------------------------------------------------------------------------------
{ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) {
uint32_t chunkID = Read<uint32_t>(stream); uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID); (void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AIMESH); ai_assert(chunkID == ASSBIN_CHUNK_AIMESH);
@ -314,70 +323,61 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
// first of all, write bits for all existent vertex components // first of all, write bits for all existent vertex components
unsigned int c = Read<unsigned int>(stream); unsigned int c = Read<unsigned int>(stream);
if (c & ASSBIN_MESH_HAS_POSITIONS) if (c & ASSBIN_MESH_HAS_POSITIONS) {
{
if (shortened) { if (shortened) {
ReadBounds(stream,mesh->mVertices,mesh->mNumVertices); ReadBounds(stream,mesh->mVertices,mesh->mNumVertices);
} // else write as usual } else {
else // else write as usual
{
mesh->mVertices = new aiVector3D[mesh->mNumVertices]; mesh->mVertices = new aiVector3D[mesh->mNumVertices];
ReadArray<aiVector3D>(stream,mesh->mVertices,mesh->mNumVertices); ReadArray<aiVector3D>(stream,mesh->mVertices,mesh->mNumVertices);
} }
} }
if (c & ASSBIN_MESH_HAS_NORMALS) if (c & ASSBIN_MESH_HAS_NORMALS) {
{
if (shortened) { if (shortened) {
ReadBounds(stream,mesh->mNormals,mesh->mNumVertices); ReadBounds(stream,mesh->mNormals,mesh->mNumVertices);
} // else write as usual } else {
else // else write as usual
{
mesh->mNormals = new aiVector3D[mesh->mNumVertices]; mesh->mNormals = new aiVector3D[mesh->mNumVertices];
ReadArray<aiVector3D>(stream,mesh->mNormals,mesh->mNumVertices); ReadArray<aiVector3D>(stream,mesh->mNormals,mesh->mNumVertices);
} }
} }
if (c & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS) if (c & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS) {
{
if (shortened) { if (shortened) {
ReadBounds(stream,mesh->mTangents,mesh->mNumVertices); ReadBounds(stream,mesh->mTangents,mesh->mNumVertices);
ReadBounds(stream,mesh->mBitangents,mesh->mNumVertices); ReadBounds(stream,mesh->mBitangents,mesh->mNumVertices);
} // else write as usual } else {
else // else write as usual
{
mesh->mTangents = new aiVector3D[mesh->mNumVertices]; mesh->mTangents = new aiVector3D[mesh->mNumVertices];
ReadArray<aiVector3D>(stream,mesh->mTangents,mesh->mNumVertices); ReadArray<aiVector3D>(stream,mesh->mTangents,mesh->mNumVertices);
mesh->mBitangents = new aiVector3D[mesh->mNumVertices]; mesh->mBitangents = new aiVector3D[mesh->mNumVertices];
ReadArray<aiVector3D>(stream,mesh->mBitangents,mesh->mNumVertices); ReadArray<aiVector3D>(stream,mesh->mBitangents,mesh->mNumVertices);
} }
} }
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) {
{ if (!(c & ASSBIN_MESH_HAS_COLOR(n))) {
if (!(c & ASSBIN_MESH_HAS_COLOR(n)))
break; break;
}
if (shortened) if (shortened) {
{
ReadBounds(stream,mesh->mColors[n],mesh->mNumVertices); ReadBounds(stream,mesh->mColors[n],mesh->mNumVertices);
} // else write as usual } else {
else // else write as usual
{
mesh->mColors[n] = new aiColor4D[mesh->mNumVertices]; mesh->mColors[n] = new aiColor4D[mesh->mNumVertices];
ReadArray<aiColor4D>(stream,mesh->mColors[n],mesh->mNumVertices); ReadArray<aiColor4D>(stream,mesh->mColors[n],mesh->mNumVertices);
} }
} }
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
{ if (!(c & ASSBIN_MESH_HAS_TEXCOORD(n))) {
if (!(c & ASSBIN_MESH_HAS_TEXCOORD(n)))
break; break;
}
// write number of UV components // write number of UV components
mesh->mNumUVComponents[n] = Read<unsigned int>(stream); mesh->mNumUVComponents[n] = Read<unsigned int>(stream);
if (shortened) { if (shortened) {
ReadBounds(stream,mesh->mTextureCoords[n],mesh->mNumVertices); ReadBounds(stream,mesh->mTextureCoords[n],mesh->mNumVertices);
} // else write as usual } else {
else // else write as usual
{
mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices]; mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices];
ReadArray<aiVector3D>(stream,mesh->mTextureCoords[n],mesh->mNumVertices); ReadArray<aiVector3D>(stream,mesh->mTextureCoords[n],mesh->mNumVertices);
} }
@ -389,9 +389,8 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
// using Assimp's standard hashing function. // using Assimp's standard hashing function.
if (shortened) { if (shortened) {
Read<unsigned int>(stream); Read<unsigned int>(stream);
} } else {
else // else write as usual // else write as usual
{
// if there are less than 2^16 vertices, we can simply use 16 bit integers ... // if there are less than 2^16 vertices, we can simply use 16 bit integers ...
mesh->mFaces = new aiFace[mesh->mNumFaces]; mesh->mFaces = new aiFace[mesh->mNumFaces];
for (unsigned int i = 0; i < mesh->mNumFaces;++i) { for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
@ -402,12 +401,10 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
f.mIndices = new unsigned int[f.mNumIndices]; f.mIndices = new unsigned int[f.mNumIndices];
for (unsigned int a = 0; a < f.mNumIndices;++a) { for (unsigned int a = 0; a < f.mNumIndices;++a) {
if (mesh->mNumVertices < (1u<<16)) // Check if unsigned short ( 16 bit ) are big enought for the indices
{ if ( fitsIntoUI16( mesh->mNumVertices ) ) {
f.mIndices[a] = Read<uint16_t>(stream); f.mIndices[a] = Read<uint16_t>(stream);
} } else {
else
{
f.mIndices[a] = Read<unsigned int>(stream); f.mIndices[a] = Read<unsigned int>(stream);
} }
} }
@ -424,8 +421,8 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
} }
} }
void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop) // -----------------------------------------------------------------------------------
{ void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop) {
uint32_t chunkID = Read<uint32_t>(stream); uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID); (void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIALPROPERTY); ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIALPROPERTY);
@ -442,8 +439,7 @@ void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialPro
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat) void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat) {
{
uint32_t chunkID = Read<uint32_t>(stream); uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID); (void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIAL); ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIAL);
@ -465,8 +461,7 @@ void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat)
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) {
{
uint32_t chunkID = Read<uint32_t>(stream); uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID); (void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AINODEANIM); ai_assert(chunkID == ASSBIN_CHUNK_AINODEANIM);
@ -493,9 +488,8 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
if (shortened) { if (shortened) {
ReadBounds(stream,nd->mRotationKeys,nd->mNumRotationKeys); ReadBounds(stream,nd->mRotationKeys,nd->mNumRotationKeys);
} // else write as usual } else {
else // else write as usual
{
nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys]; nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys];
ReadArray<aiQuatKey>(stream,nd->mRotationKeys,nd->mNumRotationKeys); ReadArray<aiQuatKey>(stream,nd->mRotationKeys,nd->mNumRotationKeys);
} }
@ -504,19 +498,16 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
if (shortened) { if (shortened) {
ReadBounds(stream,nd->mScalingKeys,nd->mNumScalingKeys); ReadBounds(stream,nd->mScalingKeys,nd->mNumScalingKeys);
} // else write as usual } else {
else // else write as usual
{
nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys]; nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys];
ReadArray<aiVectorKey>(stream,nd->mScalingKeys,nd->mNumScalingKeys); ReadArray<aiVectorKey>(stream,nd->mScalingKeys,nd->mNumScalingKeys);
} }
} }
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim ) void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim ) {
{
uint32_t chunkID = Read<uint32_t>(stream); uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID); (void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AIANIMATION); ai_assert(chunkID == ASSBIN_CHUNK_AIANIMATION);
@ -527,8 +518,7 @@ void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
anim->mTicksPerSecond = Read<double> (stream); anim->mTicksPerSecond = Read<double> (stream);
anim->mNumChannels = Read<unsigned int>(stream); anim->mNumChannels = Read<unsigned int>(stream);
if (anim->mNumChannels) if (anim->mNumChannels) {
{
anim->mChannels = new aiNodeAnim*[ anim->mNumChannels ]; anim->mChannels = new aiNodeAnim*[ anim->mNumChannels ];
for (unsigned int a = 0; a < anim->mNumChannels;++a) { for (unsigned int a = 0; a < anim->mNumChannels;++a) {
anim->mChannels[a] = new aiNodeAnim(); anim->mChannels[a] = new aiNodeAnim();
@ -537,8 +527,8 @@ void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
} }
} }
void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) // -----------------------------------------------------------------------------------
{ void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) {
uint32_t chunkID = Read<uint32_t>(stream); uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID); (void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AITEXTURE); ai_assert(chunkID == ASSBIN_CHUNK_AITEXTURE);
@ -552,18 +542,15 @@ void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex)
if (!tex->mHeight) { if (!tex->mHeight) {
tex->pcData = new aiTexel[ tex->mWidth ]; tex->pcData = new aiTexel[ tex->mWidth ];
stream->Read(tex->pcData,1,tex->mWidth); stream->Read(tex->pcData,1,tex->mWidth);
} } else {
else {
tex->pcData = new aiTexel[ tex->mWidth*tex->mHeight ]; tex->pcData = new aiTexel[ tex->mWidth*tex->mHeight ];
stream->Read(tex->pcData,1,tex->mWidth*tex->mHeight*4); stream->Read(tex->pcData,1,tex->mWidth*tex->mHeight*4);
} }
} }
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l ) void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l ) {
{
uint32_t chunkID = Read<uint32_t>(stream); uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID); (void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AILIGHT); ai_assert(chunkID == ASSBIN_CHUNK_AILIGHT);
@ -586,12 +573,10 @@ void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l )
l->mAngleInnerCone = Read<float>(stream); l->mAngleInnerCone = Read<float>(stream);
l->mAngleOuterCone = Read<float>(stream); l->mAngleOuterCone = Read<float>(stream);
} }
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam ) void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam ) {
{
uint32_t chunkID = Read<uint32_t>(stream); uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID); (void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AICAMERA); ai_assert(chunkID == ASSBIN_CHUNK_AICAMERA);
@ -607,8 +592,8 @@ void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam )
cam->mAspect = Read<float>(stream); cam->mAspect = Read<float>(stream);
} }
void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) // -----------------------------------------------------------------------------------
{ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) {
uint32_t chunkID = Read<uint32_t>(stream); uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID); (void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AISCENE); ai_assert(chunkID == ASSBIN_CHUNK_AISCENE);
@ -623,12 +608,11 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
scene->mNumCameras = Read<unsigned int>(stream); scene->mNumCameras = Read<unsigned int>(stream);
// Read node graph // Read node graph
scene->mRootNode = new aiNode[1]; //scene->mRootNode = new aiNode[1];
ReadBinaryNode( stream, &scene->mRootNode, (aiNode*)NULL ); ReadBinaryNode( stream, &scene->mRootNode, (aiNode*)NULL );
// Read all meshes // Read all meshes
if (scene->mNumMeshes) if (scene->mNumMeshes) {
{
scene->mMeshes = new aiMesh*[scene->mNumMeshes]; scene->mMeshes = new aiMesh*[scene->mNumMeshes];
for (unsigned int i = 0; i < scene->mNumMeshes;++i) { for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
scene->mMeshes[i] = new aiMesh(); scene->mMeshes[i] = new aiMesh();
@ -637,8 +621,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
} }
// Read materials // Read materials
if (scene->mNumMaterials) if (scene->mNumMaterials) {
{
scene->mMaterials = new aiMaterial*[scene->mNumMaterials]; scene->mMaterials = new aiMaterial*[scene->mNumMaterials];
for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
scene->mMaterials[i] = new aiMaterial(); scene->mMaterials[i] = new aiMaterial();
@ -647,8 +630,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
} }
// Read all animations // Read all animations
if (scene->mNumAnimations) if (scene->mNumAnimations) {
{
scene->mAnimations = new aiAnimation*[scene->mNumAnimations]; scene->mAnimations = new aiAnimation*[scene->mNumAnimations];
for (unsigned int i = 0; i < scene->mNumAnimations;++i) { for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
scene->mAnimations[i] = new aiAnimation(); scene->mAnimations[i] = new aiAnimation();
@ -657,8 +639,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
} }
// Read all textures // Read all textures
if (scene->mNumTextures) if (scene->mNumTextures) {
{
scene->mTextures = new aiTexture*[scene->mNumTextures]; scene->mTextures = new aiTexture*[scene->mNumTextures];
for (unsigned int i = 0; i < scene->mNumTextures;++i) { for (unsigned int i = 0; i < scene->mNumTextures;++i) {
scene->mTextures[i] = new aiTexture(); scene->mTextures[i] = new aiTexture();
@ -667,8 +648,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
} }
// Read lights // Read lights
if (scene->mNumLights) if (scene->mNumLights) {
{
scene->mLights = new aiLight*[scene->mNumLights]; scene->mLights = new aiLight*[scene->mNumLights];
for (unsigned int i = 0; i < scene->mNumLights;++i) { for (unsigned int i = 0; i < scene->mNumLights;++i) {
scene->mLights[i] = new aiLight(); scene->mLights[i] = new aiLight();
@ -677,8 +657,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
} }
// Read cameras // Read cameras
if (scene->mNumCameras) if (scene->mNumCameras) {
{
scene->mCameras = new aiCamera*[scene->mNumCameras]; scene->mCameras = new aiCamera*[scene->mNumCameras];
for (unsigned int i = 0; i < scene->mNumCameras;++i) { for (unsigned int i = 0; i < scene->mNumCameras;++i) {
scene->mCameras[i] = new aiCamera(); scene->mCameras[i] = new aiCamera();
@ -688,16 +667,22 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
} }
void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ) // -----------------------------------------------------------------------------------
{ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ) {
IOStream * stream = pIOHandler->Open(pFile,"rb"); IOStream * stream = pIOHandler->Open(pFile,"rb");
if (!stream) if (nullptr == stream) {
return; return;
}
stream->Seek( 44, aiOrigin_CUR ); // signature // signature
stream->Seek( 44, aiOrigin_CUR );
unsigned int versionMajor = Read<unsigned int>(stream);
unsigned int versionMinor = Read<unsigned int>(stream);
if (versionMinor != ASSBIN_VERSION_MINOR || versionMajor != ASSBIN_VERSION_MAJOR) {
throw DeadlyImportError( "Invalid version, data format not compatible!" );
}
/*unsigned int versionMajor =*/ Read<unsigned int>(stream);
/*unsigned int versionMinor =*/ Read<unsigned int>(stream);
/*unsigned int versionRevision =*/ Read<unsigned int>(stream); /*unsigned int versionRevision =*/ Read<unsigned int>(stream);
/*unsigned int compileFlags =*/ Read<unsigned int>(stream); /*unsigned int compileFlags =*/ Read<unsigned int>(stream);
@ -711,8 +696,7 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
stream->Seek( 128, aiOrigin_CUR ); // options stream->Seek( 128, aiOrigin_CUR ); // options
stream->Seek( 64, aiOrigin_CUR ); // padding stream->Seek( 64, aiOrigin_CUR ); // padding
if (compressed) if (compressed) {
{
uLongf uncompressedSize = Read<uint32_t>(stream); uLongf uncompressedSize = Read<uint32_t>(stream);
uLongf compressedSize = static_cast<uLongf>(stream->FileSize() - stream->Tell()); uLongf compressedSize = static_cast<uLongf>(stream->FileSize() - stream->Tell());
@ -729,9 +713,7 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
delete[] uncompressedData; delete[] uncompressedData;
delete[] compressedData; delete[] compressedData;
} } else {
else
{
ReadBinaryScene(stream,pScene); ReadBinaryScene(stream,pScene);
} }

View File

@ -70,32 +70,33 @@ namespace Assimp {
class AssbinImporter : public BaseImporter class AssbinImporter : public BaseImporter
{ {
private: private:
bool shortened; bool shortened;
bool compressed; bool compressed;
public: public:
virtual bool CanRead( virtual bool CanRead(
const std::string& pFile, const std::string& pFile,
IOSystem* pIOHandler, IOSystem* pIOHandler,
bool checkSig bool checkSig
) const; ) const;
virtual const aiImporterDesc* GetInfo() const; virtual const aiImporterDesc* GetInfo() const;
virtual void InternReadFile( virtual void InternReadFile(
const std::string& pFile, const std::string& pFile,
aiScene* pScene, aiScene* pScene,
IOSystem* pIOHandler IOSystem* pIOHandler
); );
void ReadBinaryScene( IOStream * stream, aiScene* pScene ); void ReadHeader();
void ReadBinaryNode( IOStream * stream, aiNode** mRootNode, aiNode* parent ); void ReadBinaryScene( IOStream * stream, aiScene* pScene );
void ReadBinaryMesh( IOStream * stream, aiMesh* mesh ); void ReadBinaryNode( IOStream * stream, aiNode** mRootNode, aiNode* parent );
void ReadBinaryBone( IOStream * stream, aiBone* bone ); void ReadBinaryMesh( IOStream * stream, aiMesh* mesh );
void ReadBinaryMaterial(IOStream * stream, aiMaterial* mat); void ReadBinaryBone( IOStream * stream, aiBone* bone );
void ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop); void ReadBinaryMaterial(IOStream * stream, aiMaterial* mat);
void ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd); void ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop);
void ReadBinaryAnim( IOStream * stream, aiAnimation* anim ); void ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd);
void ReadBinaryTexture(IOStream * stream, aiTexture* tex); void ReadBinaryAnim( IOStream * stream, aiAnimation* anim );
void ReadBinaryLight( IOStream * stream, aiLight* l ); void ReadBinaryTexture(IOStream * stream, aiTexture* tex);
void ReadBinaryCamera( IOStream * stream, aiCamera* cam ); void ReadBinaryLight( IOStream * stream, aiLight* l );
void ReadBinaryCamera( IOStream * stream, aiCamera* cam );
}; };
} // end of namespace Assimp } // end of namespace Assimp

View File

@ -272,8 +272,6 @@ void aiReleaseImport( const aiScene* pScene)
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
aiReleaseDefaultMaterial();
// find the importer associated with this data // find the importer associated with this data
const ScenePrivateData* priv = ScenePriv(pScene); const ScenePrivateData* priv = ScenePriv(pScene);
if( !priv || !priv->mOrigImporter) { if( !priv || !priv->mOrigImporter) {

View File

@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <map>
using namespace Assimp; using namespace Assimp;
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
@ -461,6 +462,13 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
aiNodeAnim* nodeAnim = new aiNodeAnim; aiNodeAnim* nodeAnim = new aiNodeAnim;
anim->mChannels[a] = nodeAnim; anim->mChannels[a] = nodeAnim;
nodeAnim->mNodeName.Set( nodeName); nodeAnim->mNodeName.Set( nodeName);
std::map<BVHLoader::ChannelType, int> channelMap;
//Build map of channels
for (unsigned int channel = 0; channel < node.mChannels.size(); ++channel)
{
channelMap[node.mChannels[channel]] = channel;
}
// translational part, if given // translational part, if given
if( node.mChannels.size() == 6) if( node.mChannels.size() == 6)
@ -472,16 +480,32 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
{ {
poskey->mTime = double( fr); poskey->mTime = double( fr);
// Now compute all translations in the right order // Now compute all translations
for( unsigned int channel = 0; channel < 3; ++channel) for(BVHLoader::ChannelType channel = Channel_PositionX; channel <= Channel_PositionZ; channel = (BVHLoader::ChannelType)(channel +1))
{ {
switch( node.mChannels[channel]) //Find channel in node
{ std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
case Channel_PositionX: poskey->mValue.x = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
case Channel_PositionY: poskey->mValue.y = node.mChannelValues[fr * node.mChannels.size() + channel]; break; if (mapIter == channelMap.end())
case Channel_PositionZ: poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channel]; break; throw DeadlyImportError("Missing position channel in node " + nodeName);
default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName ); else {
} int channelIdx = mapIter->second;
switch (channel) {
case Channel_PositionX:
poskey->mValue.x = node.mChannelValues[fr * node.mChannels.size() + channelIdx];
break;
case Channel_PositionY:
poskey->mValue.y = node.mChannelValues[fr * node.mChannels.size() + channelIdx];
break;
case Channel_PositionZ:
poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channelIdx];
break;
default:
break;
}
}
} }
++poskey; ++poskey;
} }
@ -497,12 +521,6 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
// rotation part. Always present. First find value offsets // rotation part. Always present. First find value offsets
{ {
unsigned int rotOffset = 0;
if( node.mChannels.size() == 6)
{
// Offset all further calculations
rotOffset = 3;
}
// Then create the number of rotation keys // Then create the number of rotation keys
nodeAnim->mNumRotationKeys = mAnimNumFrames; nodeAnim->mNumRotationKeys = mAnimNumFrames;
@ -512,20 +530,33 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
{ {
aiMatrix4x4 temp; aiMatrix4x4 temp;
aiMatrix3x3 rotMatrix; aiMatrix3x3 rotMatrix;
for (BVHLoader::ChannelType channel = Channel_RotationX; channel <= Channel_RotationZ; channel = (BVHLoader::ChannelType)(channel + 1))
{
//Find channel in node
std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
for( unsigned int channel = 0; channel < 3; ++channel) if (mapIter == channelMap.end())
{ throw DeadlyImportError("Missing rotation channel in node " + nodeName);
// translate ZXY euler angels into a quaternion else {
const float angle = node.mChannelValues[fr * node.mChannels.size() + rotOffset + channel] * float( AI_MATH_PI) / 180.0f; int channelIdx = mapIter->second;
// translate ZXY euler angels into a quaternion
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
// Compute rotation transformations in the right order // Compute rotation transformations in the right order
switch (node.mChannels[rotOffset+channel]) switch (channel)
{ {
case Channel_RotationX: aiMatrix4x4::RotationX( angle, temp); rotMatrix *= aiMatrix3x3( temp); break; case Channel_RotationX:
case Channel_RotationY: aiMatrix4x4::RotationY( angle, temp); rotMatrix *= aiMatrix3x3( temp); break; aiMatrix4x4::RotationX(angle, temp); rotMatrix *= aiMatrix3x3(temp);
case Channel_RotationZ: aiMatrix4x4::RotationZ( angle, temp); rotMatrix *= aiMatrix3x3( temp); break; break;
default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName ); case Channel_RotationY:
} aiMatrix4x4::RotationY(angle, temp); rotMatrix *= aiMatrix3x3(temp);
break;
case Channel_RotationZ: aiMatrix4x4::RotationZ(angle, temp); rotMatrix *= aiMatrix3x3(temp);
break;
default:
break;
}
}
} }
rotkey->mTime = double( fr); rotkey->mTime = double( fr);

View File

@ -297,8 +297,9 @@ private:
return false; return false;
} }
//format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
const size_t len( strlen( color ) ); const size_t len( strlen( color ) );
if ( 9 != len ) { if ( 9 != len && 7 != len) {
return false; return false;
} }
@ -313,26 +314,28 @@ private:
++buf; ++buf;
comp[ 1 ] = *buf; comp[ 1 ] = *buf;
++buf; ++buf;
diffuse.r = static_cast<ai_real>( strtol( comp, NULL, 16 ) ); diffuse.r = static_cast<ai_real>( strtol( comp, NULL, 16 ) ) / 255.0;
comp[ 0 ] = *buf; comp[ 0 ] = *buf;
++buf; ++buf;
comp[ 1 ] = *buf; comp[ 1 ] = *buf;
++buf; ++buf;
diffuse.g = static_cast< ai_real >( strtol( comp, NULL, 16 ) ); diffuse.g = static_cast< ai_real >( strtol( comp, NULL, 16 ) ) / 255.0;
comp[ 0 ] = *buf; comp[ 0 ] = *buf;
++buf; ++buf;
comp[ 1 ] = *buf; comp[ 1 ] = *buf;
++buf; ++buf;
diffuse.b = static_cast< ai_real >( strtol( comp, NULL, 16 ) ); diffuse.b = static_cast< ai_real >( strtol( comp, NULL, 16 ) ) / 255.0;
if(7 == len)
return true;
comp[ 0 ] = *buf; comp[ 0 ] = *buf;
++buf; ++buf;
comp[ 1 ] = *buf; comp[ 1 ] = *buf;
++buf; ++buf;
diffuse.a = static_cast< ai_real >( strtol( comp, NULL, 16 ) ); diffuse.a = static_cast< ai_real >( strtol( comp, NULL, 16 ) ) / 255.0;
return true; return true;
} }

View File

@ -185,12 +185,8 @@ void FBXConverter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4&
} }
if ( !name_carrier ) { if ( !name_carrier ) {
NodeNameCache::const_iterator it = mNodeNames.find(original_name); std::string old_original_name = original_name;
if ( it != mNodeNames.end() ) { GetUniqueName(old_original_name, original_name);
original_name = original_name + std::string( "001" );
}
mNodeNames.insert( original_name );
nodes_chain.push_back( new aiNode( original_name ) ); nodes_chain.push_back( new aiNode( original_name ) );
} else { } else {
original_name = nodes_chain.back()->mName.C_Str(); original_name = nodes_chain.back()->mName.C_Str();

View File

@ -437,7 +437,7 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
// deal with this more elegantly and with less redundancy, but right // deal with this more elegantly and with less redundancy, but right
// now it seems unavoidable. // now it seems unavoidable.
if (MappingInformationType == "ByVertice" && isDirect) { if (MappingInformationType == "ByVertice" && isDirect) {
if (!HasElement(source, indexDataElementName)) { if (!HasElement(source, dataElementName)) {
return; return;
} }
std::vector<T> tempData; std::vector<T> tempData;

View File

@ -178,7 +178,6 @@ Importer::~Importer()
{ {
// Delete all import plugins // Delete all import plugins
DeleteImporterInstanceList(pimpl->mImporter); DeleteImporterInstanceList(pimpl->mImporter);
aiReleaseDefaultMaterial();
// Delete all post-processing plug-ins // Delete all post-processing plug-ins
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++)
@ -385,7 +384,6 @@ void Importer::FreeScene( )
{ {
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
aiReleaseDefaultMaterial();
delete pimpl->mScene; delete pimpl->mScene;
pimpl->mScene = NULL; pimpl->mScene = NULL;

View File

@ -434,10 +434,12 @@ void MDCImporter::InternReadFile(
else if (1 == pScene->mNumMeshes) else if (1 == pScene->mNumMeshes)
{ {
pScene->mRootNode = new aiNode(); pScene->mRootNode = new aiNode();
pScene->mRootNode->mName = pScene->mMeshes[0]->mName; if ( nullptr != pScene->mMeshes[0] ) {
pScene->mRootNode->mNumMeshes = 1; pScene->mRootNode->mName = pScene->mMeshes[0]->mName;
pScene->mRootNode->mMeshes = new unsigned int[1]; pScene->mRootNode->mNumMeshes = 1;
pScene->mRootNode->mMeshes[0] = 0; pScene->mRootNode->mMeshes = new unsigned int[1];
pScene->mRootNode->mMeshes[0] = 0;
}
} }
else else
{ {

View File

@ -387,26 +387,6 @@ aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
return AI_SUCCESS; return AI_SUCCESS;
} }
static aiMaterial *DefaultMaterial = nullptr;
// ------------------------------------------------------------------------------------------------
// Will return the default material.
aiMaterial *aiCreateAndRegisterDefaultMaterial() {
if (nullptr == DefaultMaterial) {
DefaultMaterial = new aiMaterial;
aiString s;
s.Set(AI_DEFAULT_MATERIAL_NAME);
DefaultMaterial->AddProperty(&s, AI_MATKEY_NAME);
}
return DefaultMaterial;
}
// ------------------------------------------------------------------------------------------------
// Will return the default material.
void aiReleaseDefaultMaterial() {
DefaultMaterial = nullptr;
}
static const unsigned int DefaultNumAllocated = 5; static const unsigned int DefaultNumAllocated = 5;

View File

@ -210,22 +210,80 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
ai_assert(false); ai_assert(false);
} }
// Create nodes for the whole scene if (pModel->m_Objects.size() > 0) {
std::vector<aiMesh*> MeshArray;
for (size_t index = 0; index < pModel->m_Objects.size(); ++index ) {
createNodes(pModel, pModel->m_Objects[ index ], pScene->mRootNode, pScene, MeshArray);
}
// Create mesh pointer buffer for this scene unsigned int meshCount = 0;
if (pScene->mNumMeshes > 0) { unsigned int childCount = 0;
pScene->mMeshes = new aiMesh*[ MeshArray.size() ];
for (size_t index =0; index < MeshArray.size(); ++index ) { for(size_t index = 0; index < pModel->m_Objects.size(); ++index) {
pScene->mMeshes[ index ] = MeshArray[ index ]; if(pModel->m_Objects[index]) {
++childCount;
meshCount += (unsigned int)pModel->m_Objects[index]->m_Meshes.size();
}
} }
}
// Create all materials // Allocate space for the child nodes on the root node
createMaterials( pModel, pScene ); pScene->mRootNode->mChildren = new aiNode*[ childCount ];
// Create nodes for the whole scene
std::vector<aiMesh*> MeshArray;
MeshArray.reserve(meshCount);
for (size_t index = 0; index < pModel->m_Objects.size(); ++index) {
createNodes(pModel, pModel->m_Objects[index], pScene->mRootNode, pScene, MeshArray);
}
ai_assert(pScene->mRootNode->mNumChildren == childCount);
// Create mesh pointer buffer for this scene
if (pScene->mNumMeshes > 0) {
pScene->mMeshes = new aiMesh*[MeshArray.size()];
for (size_t index = 0; index < MeshArray.size(); ++index) {
pScene->mMeshes[index] = MeshArray[index];
}
}
// Create all materials
createMaterials(pModel, pScene);
}else {
if (pModel->m_Vertices.empty()){
return;
}
std::unique_ptr<aiMesh> mesh( new aiMesh );
mesh->mPrimitiveTypes = aiPrimitiveType_POINT;
unsigned int n = pModel->m_Vertices.size();
mesh->mNumVertices = n;
mesh->mVertices = new aiVector3D[n];
memcpy(mesh->mVertices, pModel->m_Vertices.data(), n*sizeof(aiVector3D) );
if ( !pModel->m_Normals.empty() ) {
mesh->mNormals = new aiVector3D[n];
if (pModel->m_Normals.size() < n) {
throw DeadlyImportError("OBJ: vertex normal index out of range");
}
memcpy(mesh->mNormals, pModel->m_Normals.data(), n*sizeof(aiVector3D));
}
if ( !pModel->m_VertexColors.empty() ){
mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
for (unsigned int i = 0; i < n; ++i) {
if (i < pModel->m_VertexColors.size() ) {
const aiVector3D& color = pModel->m_VertexColors[i];
mesh->mColors[0][i] = aiColor4D(color.x, color.y, color.z, 1.0);
}else {
throw DeadlyImportError("OBJ: vertex color index out of range");
}
}
}
pScene->mRootNode->mNumMeshes = 1;
pScene->mRootNode->mMeshes = new unsigned int[1];
pScene->mRootNode->mMeshes[0] = 0;
pScene->mMeshes = new aiMesh*[1];
pScene->mNumMeshes = 1;
pScene->mMeshes[0] = mesh.release();
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -246,9 +304,8 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile
pNode->mName = pObject->m_strObjName; pNode->mName = pObject->m_strObjName;
// If we have a parent node, store it // If we have a parent node, store it
if( pParent != NULL ) { ai_assert( NULL != pParent );
appendChildToParentNode( pParent, pNode ); appendChildToParentNode( pParent, pNode );
}
for ( size_t i=0; i< pObject->m_Meshes.size(); ++i ) { for ( size_t i=0; i< pObject->m_Meshes.size(); ++i ) {
unsigned int meshId = pObject->m_Meshes[ i ]; unsigned int meshId = pObject->m_Meshes[ i ];
@ -401,8 +458,8 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
pMesh->mNumVertices = numIndices; pMesh->mNumVertices = numIndices;
if (pMesh->mNumVertices == 0) { if (pMesh->mNumVertices == 0) {
throw DeadlyImportError( "OBJ: no vertices" ); throw DeadlyImportError( "OBJ: no vertices" );
} else if (pMesh->mNumVertices > AI_MAX_ALLOC(aiVector3D)) { } else if (pMesh->mNumVertices > AI_MAX_VERTICES) {
throw DeadlyImportError( "OBJ: Too many vertices, would run out of memory" ); throw DeadlyImportError( "OBJ: Too many vertices" );
} }
pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ]; pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ];
@ -452,7 +509,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
// Copy all vertex colors // Copy all vertex colors
if ( !pModel->m_VertexColors.empty()) if ( !pModel->m_VertexColors.empty())
{ {
const aiVector3D color = pModel->m_VertexColors[ vertex ]; const aiVector3D& color = pModel->m_VertexColors[ vertex ];
pMesh->mColors[0][ newIndex ] = aiColor4D(color.x, color.y, color.z, 1.0); pMesh->mColors[0][ newIndex ] = aiColor4D(color.x, color.y, color.z, 1.0);
} }
@ -729,25 +786,8 @@ void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild)
// Assign parent to child // Assign parent to child
pChild->mParent = pParent; pChild->mParent = pParent;
// If already children was assigned to the parent node, store them in a
std::vector<aiNode*> temp;
if (pParent->mChildren != NULL)
{
ai_assert( 0 != pParent->mNumChildren );
for (size_t index = 0; index < pParent->mNumChildren; index++)
{
temp.push_back(pParent->mChildren [ index ] );
}
delete [] pParent->mChildren;
}
// Copy node instances into parent node // Copy node instances into parent node
pParent->mNumChildren++; pParent->mNumChildren++;
pParent->mChildren = new aiNode*[ pParent->mNumChildren ];
for (size_t index = 0; index < pParent->mNumChildren-1; index++)
{
pParent->mChildren[ index ] = temp [ index ];
}
pParent->mChildren[ pParent->mNumChildren-1 ] = pChild; pParent->mChildren[ pParent->mNumChildren-1 ] = pChild;
} }

View File

@ -214,11 +214,10 @@ void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
// create a single default material, using a white diffuse color for consistency with // create a single default material, using a white diffuse color for consistency with
// other geometric types (e.g., PLY). // other geometric types (e.g., PLY).
aiMaterial* pcMat = aiCreateAndRegisterDefaultMaterial(); aiMaterial* pcMat = new aiMaterial();
/*aiMaterial* pcMat = new aiMaterial();
aiString s; aiString s;
s.Set(AI_DEFAULT_MATERIAL_NAME); s.Set(AI_DEFAULT_MATERIAL_NAME);
pcMat->AddProperty(&s, AI_MATKEY_NAME);*/ pcMat->AddProperty(&s, AI_MATKEY_NAME);
aiColor4D clrDiffuse(ai_real(1.0),ai_real(1.0),ai_real(1.0),ai_real(1.0)); aiColor4D clrDiffuse(ai_real(1.0),ai_real(1.0),ai_real(1.0),ai_real(1.0));
if (bMatClr) { if (bMatClr) {

View File

@ -393,7 +393,7 @@ void SplitByBoneCountProcess::UpdateNode( aiNode* pNode) const
newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end()); newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end());
} }
delete pNode->mMeshes; delete [] pNode->mMeshes;
pNode->mNumMeshes = static_cast<unsigned int>(newMeshList.size()); pNode->mNumMeshes = static_cast<unsigned int>(newMeshList.size());
pNode->mMeshes = new unsigned int[pNode->mNumMeshes]; pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes); std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes);

View File

@ -437,6 +437,12 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
} }
for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) { for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
if (attr.texcoord[tc]->count != aim->mNumVertices) {
DefaultLogger::get()->warn("Texcoord stream size in mesh \"" + mesh.name +
"\" does not match the vertex count");
continue;
}
attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]); attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);
aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents(); aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();

View File

@ -50,8 +50,7 @@ namespace Assimp {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Default implementation of IOSystem using the standard C file functions */ /** Default implementation of IOSystem using the standard C file functions */
class ASSIMP_API DefaultIOSystem : public IOSystem class ASSIMP_API DefaultIOSystem : public IOSystem {
{
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Tests for the existence of a file at the given path. */ /** Tests for the existence of a file at the given path. */

View File

@ -44,11 +44,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief LineSplitter, a helper class to iterate through all lines * @brief LineSplitter, a helper class to iterate through all lines
* of a file easily. Works with StreamReader. * of a file easily. Works with StreamReader.
*/ */
#pragma once
#ifndef INCLUDED_LINE_SPLITTER_H #ifndef INCLUDED_LINE_SPLITTER_H
#define INCLUDED_LINE_SPLITTER_H #define INCLUDED_LINE_SPLITTER_H
#include <stdexcept> #include <stdexcept>
#include "StreamReader.h" #include "StreamReader.h"
#include "ParsingUtils.h" #include "ParsingUtils.h"
@ -81,164 +81,205 @@ public:
/** construct from existing stream reader /** construct from existing stream reader
note: trim is *always* assumed true if skyp_empty_lines==true note: trim is *always* assumed true if skyp_empty_lines==true
*/ */
LineSplitter(StreamReaderLE& stream, bool skip_empty_lines = true, bool trim = true) LineSplitter(StreamReaderLE& stream, bool skip_empty_lines = true, bool trim = true);
: idx( 0 )
, stream(stream)
, swallow()
, skip_empty_lines(skip_empty_lines)
, trim(trim) {
cur.reserve(1024);
operator++();
idx = 0; ~LineSplitter();
}
~LineSplitter() {
// empty
}
public:
// ----------------------------------------- // -----------------------------------------
/** pseudo-iterator increment */ /** pseudo-iterator increment */
LineSplitter& operator++() { LineSplitter& operator++();
if(swallow) {
swallow = false;
return *this;
}
if (!*this) {
throw std::logic_error("End of file, no more lines to be retrieved.");
}
char s;
cur.clear();
while(stream.GetRemainingSize() && (s = stream.GetI1(),1)) {
if (s == '\n' || s == '\r') {
if (skip_empty_lines) {
while (stream.GetRemainingSize() && ((s = stream.GetI1()) == ' ' || s == '\r' || s == '\n'));
if (stream.GetRemainingSize()) {
stream.IncPtr(-1);
}
}
else {
// skip both potential line terminators but don't read past this line.
if (stream.GetRemainingSize() && (s == '\r' && stream.GetI1() != '\n')) {
stream.IncPtr(-1);
}
if (trim) {
while (stream.GetRemainingSize() && ((s = stream.GetI1()) == ' ' || s == '\t'));
if (stream.GetRemainingSize()) {
stream.IncPtr(-1);
}
}
}
break;
}
cur += s;
}
++idx;
return *this;
}
// ----------------------------------------- // -----------------------------------------
LineSplitter& operator++(int) { LineSplitter& operator++(int);
return ++(*this);
}
// ----------------------------------------- // -----------------------------------------
/** get a pointer to the beginning of a particular token */ /** get a pointer to the beginning of a particular token */
const char* operator[] (size_t idx) const { const char* operator[] (size_t idx) const;
const char* s = operator->()->c_str();
SkipSpaces(&s);
for(size_t i = 0; i < idx; ++i) {
for(;!IsSpace(*s); ++s) {
if(IsLineEnd(*s)) {
throw std::range_error("Token index out of range, EOL reached");
}
}
SkipSpaces(&s);
}
return s;
}
// ----------------------------------------- // -----------------------------------------
/** extract the start positions of N tokens from the current line*/ /** extract the start positions of N tokens from the current line*/
template <size_t N> template <size_t N>
void get_tokens(const char* (&tokens)[N]) const { void get_tokens(const char* (&tokens)[N]) const;
const char* s = operator->()->c_str();
SkipSpaces(&s);
for(size_t i = 0; i < N; ++i) {
if(IsLineEnd(*s)) {
throw std::range_error("Token count out of range, EOL reached");
}
tokens[i] = s;
for(;*s && !IsSpace(*s); ++s);
SkipSpaces(&s);
}
}
// ----------------------------------------- // -----------------------------------------
/** member access */ /** member access */
const std::string* operator -> () const { const std::string* operator -> () const;
return &cur;
}
std::string operator* () const { std::string operator* () const;
return cur;
}
// ----------------------------------------- // -----------------------------------------
/** boolean context */ /** boolean context */
operator bool() const { operator bool() const;
return stream.GetRemainingSize()>0;
}
// ----------------------------------------- // -----------------------------------------
/** line indices are zero-based, empty lines are included */ /** line indices are zero-based, empty lines are included */
operator line_idx() const { operator line_idx() const;
return idx;
}
line_idx get_index() const { line_idx get_index() const;
return idx;
}
// ----------------------------------------- // -----------------------------------------
/** access the underlying stream object */ /** access the underlying stream object */
StreamReaderLE& get_stream() { StreamReaderLE& get_stream();
return stream;
}
// ----------------------------------------- // -----------------------------------------
/** !strcmp((*this)->substr(0,strlen(check)),check) */ /** !strcmp((*this)->substr(0,strlen(check)),check) */
bool match_start(const char* check) { bool match_start(const char* check);
const size_t len = strlen(check);
return len <= cur.length() && std::equal(check,check+len,cur.begin());
}
// ----------------------------------------- // -----------------------------------------
/** swallow the next call to ++, return the previous value. */ /** swallow the next call to ++, return the previous value. */
void swallow_next_increment() { void swallow_next_increment();
swallow = true;
} LineSplitter( const LineSplitter & ) = delete;
LineSplitter(LineSplitter &&) = delete;
LineSplitter &operator = ( const LineSplitter & ) = delete;
private: private:
LineSplitter( const LineSplitter & ); line_idx mIdx;
LineSplitter &operator = ( const LineSplitter & ); std::string mCur;
StreamReaderLE& mStream;
private: bool mSwallow, mSkip_empty_lines, mTrim;
line_idx idx;
std::string cur;
StreamReaderLE& stream;
bool swallow, skip_empty_lines, trim;
}; };
inline
LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool trim )
: mIdx(0)
, mCur()
, mStream(stream)
, mSwallow()
, mSkip_empty_lines(skip_empty_lines)
, mTrim(trim) {
mCur.reserve(1024);
operator++();
mIdx = 0;
} }
inline
LineSplitter::~LineSplitter() {
// empty
}
inline
LineSplitter& LineSplitter::operator++() {
if (mSwallow) {
mSwallow = false;
return *this;
}
if (!*this) {
throw std::logic_error("End of file, no more lines to be retrieved.");
}
char s;
mCur.clear();
while (mStream.GetRemainingSize() && (s = mStream.GetI1(), 1)) {
if (s == '\n' || s == '\r') {
if (mSkip_empty_lines) {
while (mStream.GetRemainingSize() && ((s = mStream.GetI1()) == ' ' || s == '\r' || s == '\n'));
if (mStream.GetRemainingSize()) {
mStream.IncPtr(-1);
}
} else {
// skip both potential line terminators but don't read past this line.
if (mStream.GetRemainingSize() && (s == '\r' && mStream.GetI1() != '\n')) {
mStream.IncPtr(-1);
}
if (mTrim) {
while (mStream.GetRemainingSize() && ((s = mStream.GetI1()) == ' ' || s == '\t'));
if (mStream.GetRemainingSize()) {
mStream.IncPtr(-1);
}
}
}
break;
}
mCur += s;
}
++mIdx;
return *this;
}
inline
LineSplitter &LineSplitter::operator++(int) {
return ++(*this);
}
inline
const char *LineSplitter::operator[] (size_t idx) const {
const char* s = operator->()->c_str();
SkipSpaces(&s);
for (size_t i = 0; i < idx; ++i) {
for (; !IsSpace(*s); ++s) {
if (IsLineEnd(*s)) {
throw std::range_error("Token index out of range, EOL reached");
}
}
SkipSpaces(&s);
}
return s;
}
template <size_t N>
inline
void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
const char* s = operator->()->c_str();
SkipSpaces(&s);
for (size_t i = 0; i < N; ++i) {
if (IsLineEnd(*s)) {
throw std::range_error("Token count out of range, EOL reached");
}
tokens[i] = s;
for (; *s && !IsSpace(*s); ++s);
SkipSpaces(&s);
}
}
inline
const std::string* LineSplitter::operator -> () const {
return &mCur;
}
inline
std::string LineSplitter::operator* () const {
return mCur;
}
inline
LineSplitter::operator bool() const {
return mStream.GetRemainingSize() > 0;
}
inline
LineSplitter::operator line_idx() const {
return mIdx;
}
inline
LineSplitter::line_idx LineSplitter::get_index() const {
return mIdx;
}
inline
StreamReaderLE &LineSplitter::get_stream() {
return mStream;
}
inline
bool LineSplitter::match_start(const char* check) {
const size_t len = ::strlen(check);
return len <= mCur.length() && std::equal(check, check + len, mCur.begin());
}
inline
void LineSplitter::swallow_next_increment() {
mSwallow = true;
}
} // Namespace Assimp
#endif // INCLUDED_LINE_SPLITTER_H #endif // INCLUDED_LINE_SPLITTER_H

View File

@ -67,16 +67,13 @@ namespace Assimp {
* XXX switch from unsigned int for size types to size_t? or ptrdiff_t?*/ * XXX switch from unsigned int for size types to size_t? or ptrdiff_t?*/
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
template <bool SwapEndianess = false, bool RuntimeSwitch = false> template <bool SwapEndianess = false, bool RuntimeSwitch = false>
class StreamReader class StreamReader {
{
public: public:
// FIXME: use these data types throughout the whole library, // FIXME: use these data types throughout the whole library,
// then change them to 64 bit values :-) // then change them to 64 bit values :-)
using diff = int;
using pos = unsigned int;
typedef int diff;
typedef unsigned int pos;
public:
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
/** Construction from a given stream with a well-defined endianness. /** Construction from a given stream with a well-defined endianness.
* *
@ -111,8 +108,6 @@ public:
delete[] buffer; delete[] buffer;
} }
public:
// deprecated, use overloaded operator>> instead // deprecated, use overloaded operator>> instead
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@ -176,7 +171,6 @@ public:
return Get<uint64_t>(); return Get<uint64_t>();
} }
public:
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
/** Get the remaining stream size (to the end of the stream) */ /** Get the remaining stream size (to the end of the stream) */
unsigned int GetRemainingSize() const { unsigned int GetRemainingSize() const {

View File

@ -1565,26 +1565,6 @@ C_ENUM aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
unsigned int* flags /*= NULL*/); unsigned int* flags /*= NULL*/);
#endif // !#ifdef __cplusplus #endif // !#ifdef __cplusplus
// ---------------------------------------------------------------------------
/** @brief Helper function to get all values pertaining to a particular
* texture slot from a material structure.
*
* @return Pointer showing to the default material.
*/
// ---------------------------------------------------------------------------
#ifdef __cplusplus
ASSIMP_API aiMaterial *aiCreateAndRegisterDefaultMaterial(void);
#else
C_STRUCT aiMaterial *aiCreateAndRegisterDefaultMaterial(void);
#endif // !#ifdef __cplusplus
// ---------------------------------------------------------------------------
/**
* @brief Helper function to release the default material instance, the
* instance will not be destroyed.
*/
// ---------------------------------------------------------------------------
ASSIMP_API void aiReleaseDefaultMaterial();
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -66,6 +66,13 @@ def make_tuple(ai_obj, type = None):
return res return res
# Returns unicode object for Python 2, and str object for Python 3.
def _convert_assimp_string(assimp_string):
try:
return unicode(assimp_string.data, errors='ignore')
except:
return str(assimp_string.data, errors='ignore')
# It is faster and more correct to have an init function for each assimp class # It is faster and more correct to have an init function for each assimp class
def _init_face(aiFace): def _init_face(aiFace):
aiFace.indices = [aiFace.mIndices[i] for i in range(aiFace.mNumIndices)] aiFace.indices = [aiFace.mIndices[i] for i in range(aiFace.mNumIndices)]
@ -118,14 +125,9 @@ def _init(self, target = None, parent = None):
continue continue
if m == 'mName': if m == 'mName':
obj = self.mName target.name = str(_convert_assimp_string(self.mName))
try: target.__class__.__repr__ = lambda x: str(x.__class__) + "(" + getattr(x, 'name','') + ")"
uni = unicode(obj.data, errors='ignore') target.__class__.__str__ = lambda x: getattr(x, 'name', '')
except:
uni = str(obj.data, errors='ignore')
target.name = str( uni )
target.__class__.__repr__ = lambda x: str(x.__class__) + "(" + x.name + ")"
target.__class__.__str__ = lambda x: x.name
continue continue
name = m[1:].lower() name = m[1:].lower()
@ -220,6 +222,9 @@ def _init(self, target = None, parent = None):
if isinstance(self, structs.Texture): if isinstance(self, structs.Texture):
_finalize_texture(self, target) _finalize_texture(self, target)
if isinstance(self, structs.Metadata):
_finalize_metadata(self, target)
return self return self
@ -412,6 +417,43 @@ def _finalize_mesh(mesh, target):
faces = [f.indices for f in target.faces] faces = [f.indices for f in target.faces]
setattr(target, 'faces', faces) setattr(target, 'faces', faces)
def _init_metadata_entry(entry):
from ctypes import POINTER, c_bool, c_int32, c_uint64, c_float, c_double, cast
entry.type = entry.mType
if entry.type == structs.MetadataEntry.AI_BOOL:
entry.data = cast(entry.mData, POINTER(c_bool)).contents.value
elif entry.type == structs.MetadataEntry.AI_INT32:
entry.data = cast(entry.mData, POINTER(c_int32)).contents.value
elif entry.type == structs.MetadataEntry.AI_UINT64:
entry.data = cast(entry.mData, POINTER(c_uint64)).contents.value
elif entry.type == structs.MetadataEntry.AI_FLOAT:
entry.data = cast(entry.mData, POINTER(c_float)).contents.value
elif entry.type == structs.MetadataEntry.AI_DOUBLE:
entry.data = cast(entry.mData, POINTER(c_double)).contents.value
elif entry.type == structs.MetadataEntry.AI_AISTRING:
assimp_string = cast(entry.mData, POINTER(structs.String)).contents
entry.data = _convert_assimp_string(assimp_string)
elif entry.type == structs.MetadataEntry.AI_AIVECTOR3D:
assimp_vector = cast(entry.mData, POINTER(structs.Vector3D)).contents
entry.data = make_tuple(assimp_vector)
return entry
def _finalize_metadata(metadata, target):
""" Building the metadata object is a bit specific.
Firstly, there are two separate arrays: one with metadata keys and one
with metadata values, and there are no corresponding mNum* attributes,
so the C arrays are not converted to Python arrays using the generic
code in the _init function.
Secondly, a metadata entry value has to be cast according to declared
metadata entry type.
"""
length = metadata.mNumProperties
setattr(target, 'keys', [str(_convert_assimp_string(metadata.mKeys[i])) for i in range(length)])
setattr(target, 'values', [_init_metadata_entry(metadata.mValues[i]) for i in range(length)])
class PropertyGetter(dict): class PropertyGetter(dict):
def __getitem__(self, key): def __getitem__(self, key):
@ -443,11 +485,8 @@ def _get_properties(properties, length):
for p in [properties[i] for i in range(length)]: for p in [properties[i] for i in range(length)]:
#the name #the name
p = p.contents p = p.contents
try: key = str(_convert_assimp_string(p.mKey))
uni = unicode(p.mKey.data, errors='ignore') key = (key.split('.')[1], p.mSemantic)
except:
uni = str(p.mKey.data, errors='ignore')
key = (str(uni).split('.')[1], p.mSemantic)
#the data #the data
from ctypes import POINTER, cast, c_int, c_float, sizeof from ctypes import POINTER, cast, c_int, c_float, sizeof
@ -455,11 +494,7 @@ def _get_properties(properties, length):
arr = cast(p.mData, POINTER(c_float * int(p.mDataLength/sizeof(c_float)) )).contents arr = cast(p.mData, POINTER(c_float * int(p.mDataLength/sizeof(c_float)) )).contents
value = [x for x in arr] value = [x for x in arr]
elif p.mType == 3: #string can't be an array elif p.mType == 3: #string can't be an array
try: value = _convert_assimp_string(cast(p.mData, POINTER(structs.MaterialPropertyString)).contents)
uni = unicode(cast(p.mData, POINTER(structs.MaterialPropertyString)).contents.data, errors='ignore')
except:
uni = str(cast(p.mData, POINTER(structs.MaterialPropertyString)).contents.data, errors='ignore')
value = uni
elif p.mType == 4: elif p.mType == 4:
arr = cast(p.mData, POINTER(c_int * int(p.mDataLength/sizeof(c_int)) )).contents arr = cast(p.mData, POINTER(c_int * int(p.mDataLength/sizeof(c_int)) )).contents

View File

@ -5,7 +5,7 @@ from ctypes import POINTER, c_void_p, c_int, c_uint, c_char, c_float, Structure,
class Vector2D(Structure): class Vector2D(Structure):
""" """
See 'aiVector2D.h' for details. See 'vector2.h' for details.
""" """
@ -15,7 +15,7 @@ class Vector2D(Structure):
class Matrix3x3(Structure): class Matrix3x3(Structure):
""" """
See 'aiMatrix3x3.h' for details. See 'matrix3x3.h' for details.
""" """
@ -27,7 +27,7 @@ class Matrix3x3(Structure):
class Texel(Structure): class Texel(Structure):
""" """
See 'aiTexture.h' for details. See 'texture.h' for details.
""" """
_fields_ = [ _fields_ = [
@ -36,7 +36,7 @@ class Texel(Structure):
class Color4D(Structure): class Color4D(Structure):
""" """
See 'aiColor4D.h' for details. See 'color4.h' for details.
""" """
@ -47,7 +47,7 @@ class Color4D(Structure):
class Plane(Structure): class Plane(Structure):
""" """
See 'aiTypes.h' for details. See 'types.h' for details.
""" """
_fields_ = [ _fields_ = [
@ -57,7 +57,7 @@ class Plane(Structure):
class Color3D(Structure): class Color3D(Structure):
""" """
See 'aiTypes.h' for details. See 'types.h' for details.
""" """
_fields_ = [ _fields_ = [
@ -67,7 +67,7 @@ class Color3D(Structure):
class String(Structure): class String(Structure):
""" """
See 'aiTypes.h' for details. See 'types.h' for details.
""" """
MAXLEN = 1024 MAXLEN = 1024
@ -84,7 +84,7 @@ class String(Structure):
class MaterialPropertyString(Structure): class MaterialPropertyString(Structure):
""" """
See 'aiTypes.h' for details. See 'MaterialSystem.cpp' for details.
The size of length is truncated to 4 bytes on 64-bit platforms when used as a The size of length is truncated to 4 bytes on 64-bit platforms when used as a
material property (see MaterialSystem.cpp aiMaterial::AddProperty() for details). material property (see MaterialSystem.cpp aiMaterial::AddProperty() for details).
@ -104,7 +104,7 @@ class MaterialPropertyString(Structure):
class MemoryInfo(Structure): class MemoryInfo(Structure):
""" """
See 'aiTypes.h' for details. See 'types.h' for details.
""" """
_fields_ = [ _fields_ = [
@ -135,7 +135,7 @@ class MemoryInfo(Structure):
class Quaternion(Structure): class Quaternion(Structure):
""" """
See 'aiQuaternion.h' for details. See 'quaternion.h' for details.
""" """
@ -146,7 +146,7 @@ class Quaternion(Structure):
class Face(Structure): class Face(Structure):
""" """
See 'aiMesh.h' for details. See 'mesh.h' for details.
""" """
_fields_ = [ _fields_ = [
@ -161,7 +161,7 @@ class Face(Structure):
class VertexWeight(Structure): class VertexWeight(Structure):
""" """
See 'aiMesh.h' for details. See 'mesh.h' for details.
""" """
_fields_ = [ _fields_ = [
@ -175,7 +175,7 @@ class VertexWeight(Structure):
class Matrix4x4(Structure): class Matrix4x4(Structure):
""" """
See 'aiMatrix4x4.h' for details. See 'matrix4x4.h' for details.
""" """
@ -188,7 +188,7 @@ class Matrix4x4(Structure):
class Vector3D(Structure): class Vector3D(Structure):
""" """
See 'aiVector3D.h' for details. See 'vector3.h' for details.
""" """
@ -198,7 +198,7 @@ class Vector3D(Structure):
class MeshKey(Structure): class MeshKey(Structure):
""" """
See 'aiAnim.h' for details. See 'anim.h' for details.
""" """
_fields_ = [ _fields_ = [
@ -214,9 +214,44 @@ class MeshKey(Structure):
("mValue", c_uint), ("mValue", c_uint),
] ]
class MetadataEntry(Structure):
"""
See 'metadata.h' for details
"""
AI_BOOL = 0
AI_INT32 = 1
AI_UINT64 = 2
AI_FLOAT = 3
AI_DOUBLE = 4
AI_AISTRING = 5
AI_AIVECTOR3D = 6
AI_META_MAX = 7
_fields_ = [
# The type field uniquely identifies the underlying type of the data field
("mType", c_uint),
("mData", c_void_p),
]
class Metadata(Structure):
"""
See 'metadata.h' for details
"""
_fields_ = [
# Length of the mKeys and mValues arrays, respectively
("mNumProperties", c_uint),
# Arrays of keys, may not be NULL. Entries in this array may not be NULL
# as well.
("mKeys", POINTER(String)),
# Arrays of values, may not be NULL. Entries in this array may be NULL
# if the corresponding property key has no assigned value.
("mValues", POINTER(MetadataEntry)),
]
class Node(Structure): class Node(Structure):
""" """
See 'aiScene.h' for details. See 'scene.h' for details.
""" """
@ -253,11 +288,15 @@ Node._fields_ = [
# The meshes of this node. Each entry is an index into the mesh # The meshes of this node. Each entry is an index into the mesh
("mMeshes", POINTER(c_uint)), ("mMeshes", POINTER(c_uint)),
# Metadata associated with this node or NULL if there is no metadata.
# Whether any metadata is generated depends on the source file format.
("mMetadata", POINTER(Metadata)),
] ]
class Light(Structure): class Light(Structure):
""" """
See 'aiLight.h' for details. See 'light.h' for details.
""" """
@ -283,6 +322,13 @@ class Light(Structure):
# may be normalized, but it needn't. # may be normalized, but it needn't.
("mDirection", Vector3D), ("mDirection", Vector3D),
# Up direction of the light source in space. Relative to the
# transformation of the node corresponding to the light.
#
# The direction is undefined for point lights. The vector
# may be normalized, but it needn't.
("mUp", Vector3D),
# Constant light attenuation factor. # Constant light attenuation factor.
# The intensity of the light source at a given distance 'd' from # The intensity of the light source at a given distance 'd' from
# the light's position is # the light's position is
@ -354,11 +400,14 @@ class Light(Structure):
# interpolation between the inner and the outer cone of the # interpolation between the inner and the outer cone of the
# spot light. # spot light.
("mAngleOuterCone", c_float), ("mAngleOuterCone", c_float),
# Size of area light source.
("mSize", Vector2D),
] ]
class Texture(Structure): class Texture(Structure):
""" """
See 'aiTexture.h' for details. See 'texture.h' for details.
""" """
@ -375,16 +424,25 @@ class Texture(Structure):
("mHeight", c_uint), ("mHeight", c_uint),
# A hint from the loader to make it easier for applications # A hint from the loader to make it easier for applications
# to determine the type of embedded compressed textures. # to determine the type of embedded textures.
# If mHeight != 0 this member is undefined. Otherwise it #
# is set set to '\\0\\0\\0\\0' if the loader has no additional # If mHeight != 0 this member is show how data is packed. Hint will consist of
# two parts: channel order and channel bitness (count of the bits for every
# color channel). For simple parsing by the viewer it's better to not omit
# absent color channel and just use 0 for bitness. For example:
# 1. Image contain RGBA and 8 bit per channel, achFormatHint == "rgba8888";
# 2. Image contain ARGB and 8 bit per channel, achFormatHint == "argb8888";
# 3. Image contain RGB and 5 bit for R and B channels and 6 bit for G channel,
# achFormatHint == "rgba5650";
# 4. One color image with B channel and 1 bit for it, achFormatHint == "rgba0010";
# If mHeight == 0 then achFormatHint is set set to '\\0\\0\\0\\0' if the loader has no additional
# information about the texture file format used OR the # information about the texture file format used OR the
# file extension of the format without a trailing dot. If there # file extension of the format without a trailing dot. If there
# are multiple file extensions for a format, the shortest # are multiple file extensions for a format, the shortest
# extension is chosen (JPEG maps to 'jpg', not to 'jpeg'). # extension is chosen (JPEG maps to 'jpg', not to 'jpeg').
# E.g. 'dds\\0', 'pcx\\0', 'jpg\\0'. All characters are lower-case. # E.g. 'dds\\0', 'pcx\\0', 'jpg\\0'. All characters are lower-case.
# The fourth character will always be '\\0'. # The fourth character will always be '\\0'.
("achFormatHint", c_char*4), ("achFormatHint", c_char*9),
# Data of the texture. # Data of the texture.
# Points to an array of mWidth # Points to an array of mWidth
@ -395,11 +453,15 @@ class Texture(Structure):
# buffer of size mWidth containing the compressed texture # buffer of size mWidth containing the compressed texture
# data. Good luck, have fun! # data. Good luck, have fun!
("pcData", POINTER(Texel)), ("pcData", POINTER(Texel)),
# Texture original filename
# Used to get the texture reference
("mFilename", String),
] ]
class Ray(Structure): class Ray(Structure):
""" """
See 'aiTypes.h' for details. See 'types.h' for details.
""" """
_fields_ = [ _fields_ = [
@ -409,7 +471,7 @@ class Ray(Structure):
class UVTransform(Structure): class UVTransform(Structure):
""" """
See 'aiMaterial.h' for details. See 'material.h' for details.
""" """
_fields_ = [ _fields_ = [
@ -430,7 +492,7 @@ class UVTransform(Structure):
class MaterialProperty(Structure): class MaterialProperty(Structure):
""" """
See 'aiMaterial.h' for details. See 'material.h' for details.
""" """
_fields_ = [ _fields_ = [
@ -466,7 +528,7 @@ class MaterialProperty(Structure):
class Material(Structure): class Material(Structure):
""" """
See 'aiMaterial.h' for details. See 'material.h' for details.
""" """
_fields_ = [ _fields_ = [
@ -482,7 +544,7 @@ class Material(Structure):
class Bone(Structure): class Bone(Structure):
""" """
See 'aiMesh.h' for details. See 'mesh.h' for details.
""" """
_fields_ = [ _fields_ = [
@ -501,20 +563,66 @@ class Bone(Structure):
("mOffsetMatrix", Matrix4x4), ("mOffsetMatrix", Matrix4x4),
] ]
class Mesh(Structure):
class AnimMesh(Structure):
""" """
See 'aiMesh.h' for details. See 'mesh.h' for details.
""" """
AI_MAX_FACE_INDICES = 0x7fff AI_MAX_NUMBER_OF_TEXTURECOORDS = 0x8
AI_MAX_BONE_WEIGHTS = 0x7fffffff AI_MAX_NUMBER_OF_COLOR_SETS = 0x8
AI_MAX_VERTICES = 0x7fffffff
AI_MAX_FACES = 0x7fffffff
AI_MAX_NUMBER_OF_COLOR_SETS = 0x8
AI_MAX_NUMBER_OF_TEXTURECOORDS = 0x8
_fields_ = [ _fields_ = [
# Bitwise combination of the members of the # Replacement for aiMesh::mVertices. If this array is non-NULL,
# it *must* contain mNumVertices entries. The corresponding
# array in the host mesh must be non-NULL as well - animation
# meshes may neither add or nor remove vertex components (if
# a replacement array is NULL and the corresponding source
# array is not, the source data is taken instead)
("mVertices", POINTER(Vector3D)),
# Replacement for aiMesh::mNormals.
("mNormals", POINTER(Vector3D)),
# Replacement for aiMesh::mTangents.
("mTangents", POINTER(Vector3D)),
# Replacement for aiMesh::mBitangents.
("mBitangents", POINTER(Vector3D)),
# Replacement for aiMesh::mColors
("mColors", POINTER(Color4D) * AI_MAX_NUMBER_OF_COLOR_SETS),
# Replacement for aiMesh::mTextureCoords
("mTextureCoords", POINTER(Vector3D) * AI_MAX_NUMBER_OF_TEXTURECOORDS),
# The number of vertices in the aiAnimMesh, and thus the length of all
# the member arrays.
#
# This has always the same value as the mNumVertices property in the
# corresponding aiMesh. It is duplicated here merely to make the length
# of the member arrays accessible even if the aiMesh is not known, e.g.
# from language bindings.
("mNumVertices", c_uint),
# Weight of the AnimMesh.
("mWeight", c_float),
]
class Mesh(Structure):
"""
See 'mesh.h' for details.
"""
AI_MAX_FACE_INDICES = 0x7fff
AI_MAX_BONE_WEIGHTS = 0x7fffffff
AI_MAX_VERTICES = 0x7fffffff
AI_MAX_FACES = 0x7fffffff
AI_MAX_NUMBER_OF_COLOR_SETS = 0x8
AI_MAX_NUMBER_OF_TEXTURECOORDS = 0x8
_fields_ = [ # Bitwise combination of the members of the
#aiPrimitiveType enum. #aiPrimitiveType enum.
# This specifies which types of primitives are present in the mesh. # This specifies which types of primitives are present in the mesh.
# The "SortByPrimitiveType"-Step can be used to make sure the # The "SortByPrimitiveType"-Step can be used to make sure the
@ -637,17 +745,23 @@ class Mesh(Structure):
# - Vertex animations refer to meshes by their names. # - Vertex animations refer to meshes by their names.
("mName", String), ("mName", String),
# NOT CURRENTLY IN USE. The number of attachment meshes # The number of attachment meshes. Note! Currently only works with Collada loader.
("mNumAnimMeshes", c_uint), ("mNumAnimMeshes", c_uint),
# NOT CURRENTLY IN USE. Attachment meshes for this mesh, for vertex-based animation. # Attachment meshes for this mesh, for vertex-based animation.
# Attachment meshes carry replacement data for some of the # Attachment meshes carry replacement data for some of the
# mesh'es vertex components (usually positions, normals). # mesh'es vertex components (usually positions, normals).
# Note! Currently only works with Collada loader.
("mAnimMesh", POINTER(POINTER(AnimMesh))),
# Method of morphing when animeshes are specified.
("mMethod", c_uint),
] ]
class Camera(Structure): class Camera(Structure):
""" """
See 'aiCamera.h' for details. See 'camera.h' for details.
""" """
@ -707,7 +821,7 @@ class Camera(Structure):
class VectorKey(Structure): class VectorKey(Structure):
""" """
See 'aiAnim.h' for details. See 'anim.h' for details.
""" """
_fields_ = [ _fields_ = [
@ -720,7 +834,7 @@ class VectorKey(Structure):
class QuatKey(Structure): class QuatKey(Structure):
""" """
See 'aiAnim.h' for details. See 'anim.h' for details.
""" """
_fields_ = [ _fields_ = [
@ -731,9 +845,27 @@ class QuatKey(Structure):
("mValue", Quaternion), ("mValue", Quaternion),
] ]
class MeshMorphKey(Structure):
"""
See 'anim.h' for details.
"""
_fields_ = [
# The time of this key
("mTime", c_double),
# The values and weights at the time of this key
("mValues", POINTER(c_uint)),
("mWeights", POINTER(c_double)),
# The number of values and weights
("mNumValuesAndWeights", c_uint),
]
class NodeAnim(Structure): class NodeAnim(Structure):
""" """
See 'aiAnim.h' for details. See 'anim.h' for details.
""" """
_fields_ = [ _fields_ = [
@ -782,9 +914,48 @@ class NodeAnim(Structure):
("mPostState", c_uint), ("mPostState", c_uint),
] ]
class MeshAnim(Structure):
"""
See 'anim.h' for details.
"""
_fields_ = [
# Name of the mesh to be animated. An empty string is not allowed,
# animated meshes need to be named (not necessarily uniquely,
# the name can basically serve as wild-card to select a group
# of meshes with similar animation setup)
("mName", String),
# Size of the #mKeys array. Must be 1, at least.
("mNumKeys", c_uint),
# Key frames of the animation. May not be NULL.
("mKeys", POINTER(MeshKey)),
]
class MeshMorphAnim(Structure):
"""
See 'anim.h' for details.
"""
_fields_ = [
# Name of the mesh to be animated. An empty string is not allowed,
# animated meshes need to be named (not necessarily uniquely,
# the name can basically serve as wildcard to select a group
# of meshes with similar animation setup)
("mName", String),
# Size of the #mKeys array. Must be 1, at least.
("mNumKeys", c_uint),
# Key frames of the animation. May not be NULL.
("mKeys", POINTER(MeshMorphKey)),
]
class Animation(Structure): class Animation(Structure):
""" """
See 'aiAnim.h' for details. See 'anim.h' for details.
""" """
_fields_ = [ _fields_ = [
@ -813,6 +984,16 @@ class Animation(Structure):
# The mesh animation channels. Each channel affects a single mesh. # The mesh animation channels. Each channel affects a single mesh.
# The array is mNumMeshChannels in size. # The array is mNumMeshChannels in size.
("mMeshChannels", POINTER(POINTER(MeshAnim))),
# The number of mesh animation channels. Each channel affects
# a single mesh and defines morphing animation.
("mNumMorphMeshChannels", c_uint),
# The morph mesh animation channels. Each channel affects a single mesh.
# The array is mNumMorphMeshChannels in size.
("mMorphMeshChannels", POINTER(POINTER(MeshMorphAnim))),
] ]
class Scene(Structure): class Scene(Structure):
@ -820,11 +1001,12 @@ class Scene(Structure):
See 'aiScene.h' for details. See 'aiScene.h' for details.
""" """
AI_SCENE_FLAGS_INCOMPLETE = 0x1 AI_SCENE_FLAGS_INCOMPLETE = 0x1
AI_SCENE_FLAGS_VALIDATED = 0x2 AI_SCENE_FLAGS_VALIDATED = 0x2
AI_SCENE_FLAGS_VALIDATION_WARNING = 0x4 AI_SCENE_FLAGS_VALIDATION_WARNING = 0x4
AI_SCENE_FLAGS_NON_VERBOSE_FORMAT = 0x8 AI_SCENE_FLAGS_NON_VERBOSE_FORMAT = 0x8
AI_SCENE_FLAGS_TERRAIN = 0x10 AI_SCENE_FLAGS_TERRAIN = 0x10
AI_SCENE_FLAGS_ALLOW_SHARED = 0x20
_fields_ = [ _fields_ = [
# Any combination of the AI_SCENE_FLAGS_XXX flags. By default # Any combination of the AI_SCENE_FLAGS_XXX flags. By default
@ -896,6 +1078,14 @@ class Scene(Structure):
# array (if existing) is the default camera view into # array (if existing) is the default camera view into
# the scene. # the scene.
("mCameras", POINTER(POINTER(Camera))), ("mCameras", POINTER(POINTER(Camera))),
# This data contains global metadata which belongs to the scene like
# unit-conversions, versions, vendors or other model-specific data. This
# can be used to store format-specific metadata as well.
("mMetadata", POINTER(Metadata)),
# Internal data, do not touch
("mPrivate", c_char_p),
] ]
assimp_structs_as_tuple = (Matrix4x4, assimp_structs_as_tuple = (Matrix4x4,

File diff suppressed because it is too large Load Diff

View File

@ -40,8 +40,9 @@
cmake_minimum_required( VERSION 2.6 ) cmake_minimum_required( VERSION 2.6 )
INCLUDE_DIRECTORIES( INCLUDE_DIRECTORIES(
../contrib/gtest/include ${Assimp_SOURCE_DIR}/contrib/gtest/include
../contrib/gtest/ ${Assimp_SOURCE_DIR}/contrib/gtest/
${Assimp_SOURCE_DIR}/test/unit
${Assimp_SOURCE_DIR}/include ${Assimp_SOURCE_DIR}/include
${Assimp_SOURCE_DIR}/code ${Assimp_SOURCE_DIR}/code
) )
@ -74,6 +75,7 @@ SET( COMMON
unit/utProfiler.cpp unit/utProfiler.cpp
unit/utSharedPPData.cpp unit/utSharedPPData.cpp
unit/utStringUtils.cpp unit/utStringUtils.cpp
unit/Common/utLineSplitter.cpp
) )
SET( IMPORTERS SET( IMPORTERS
@ -113,6 +115,8 @@ SET( IMPORTERS
unit/utColladaImportExport.cpp unit/utColladaImportExport.cpp
unit/utCSMImportExport.cpp unit/utCSMImportExport.cpp
unit/utB3DImportExport.cpp unit/utB3DImportExport.cpp
unit/utMDCImportExport.cpp
unit/utAssbinImportExport.cpp
) )
SET( MATERIAL SET( MATERIAL

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,17 @@
####
#
# OBJ File Generated by Meshlab
#
####
# Object up.obj
#
# Vertices: 3
# Faces: 0
#
####
vn -0.281034 -0.057252 0.957989
v -0.207717 -0.953997 2.554110
vn -0.139126 -0.135672 0.980937
v -0.275607 -0.965401 2.541530
vn -0.163133 -0.131576 0.977791
v -0.270155 -0.963170 2.548000

View File

@ -0,0 +1,3 @@
TEST
the rest

View File

@ -0,0 +1,12 @@
#1= IFCORGANIZATION('GS','Graphisoft','Graphisoft',$,$);
#5= IFCAPPLICATION(#1,'14.0','ArchiCAD 14.0','ArchiCAD');
#6= IFCPERSON('','Haefele','Karl-Heinz',$,$,$,$,$);
#8= IFCORGANIZATION('','KIT / IAI','',$,$);
#12= IFCPERSONANDORGANIZATION(#6,#8,$);
#13= IFCOWNERHISTORY(#12,#5,$,.ADDED.,$,$,$,1286451639);
#14= IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);
#15= IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
#16= IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.);
#17= IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.);
#18= IFCMEASUREWITHUNIT(IFCPLANEANGLEMEASURE(0.017453293),#17);

View File

@ -0,0 +1,71 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2018, 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.
---------------------------------------------------------------------------
*/
#include "UnitTestPCH.h"
#include <assimp/LineSplitter.h>
#include <assimp/DefaultIOSystem.h>
#include <string>
using namespace Assimp;
class utLineSplitter : public ::testing::Test {
// empty
};
TEST_F(utLineSplitter, tokenizetest) {
DefaultIOSystem fs;
IOStream* file = fs.Open(ASSIMP_TEST_MODELS_DIR"/ParsingFiles/linesplitter_tokenizetest.txt", "rb");
StreamReaderLE stream(file);
LineSplitter myLineSplitter(stream);
}
TEST_F( utLineSplitter, issue212Test) {
DefaultIOSystem fs;
IOStream* file = fs.Open(ASSIMP_TEST_MODELS_DIR"/ParsingFiles/linesplitter_emptyline_test.txt", "rb");
StreamReaderLE stream(file);
LineSplitter myLineSplitter(stream);
myLineSplitter++;
EXPECT_THROW( myLineSplitter++, std::logic_error );
}

View File

@ -0,0 +1,78 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2018, 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.
---------------------------------------------------------------------------
*/
#include "UnitTestPCH.h"
#include "SceneDiffer.h"
#include "AbstractImportExportBase.h"
#include <assimp/Importer.hpp>
#include <assimp/Exporter.hpp>
#include <assimp/postprocess.h>
using namespace Assimp;
#ifndef ASSIMP_BUILD_NO_EXPORT
class utAssbinImportExport : public AbstractImportExportBase {
public:
virtual bool importerTest() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/OBJ/spider.obj", aiProcess_ValidateDataStructure );
Exporter exporter;
EXPECT_EQ( aiReturn_SUCCESS, exporter.Export( scene, "assbin", ASSIMP_TEST_MODELS_DIR "/OBJ/spider_test.assbin" ) );
const aiScene *newScene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/OBJ/spider_test.assbin", aiProcess_ValidateDataStructure );
return newScene != nullptr;
}
};
TEST_F( utAssbinImportExport, exportAssbin3DFromFileTest ) {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/OBJ/spider.obj", aiProcess_ValidateDataStructure );
EXPECT_NE( nullptr, scene );
}
TEST_F( utAssbinImportExport, import3ExportAssbinDFromFileTest ) {
EXPECT_TRUE( importerTest() );
}
#endif // #ifndef ASSIMP_BUILD_NO_EXPORT

View File

@ -0,0 +1,63 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2018, 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.
---------------------------------------------------------------------------
*/
#include "UnitTestPCH.h"
#include "AbstractImportExportBase.h"
#include <assimp/Importer.hpp>
#include <assimp/postprocess.h>
using namespace Assimp;
class utMDCImportExport : public AbstractImportExportBase {
public:
virtual bool importerTest() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/MDC/spider.mdc", 0);
return true;
return nullptr != scene;
}
};
TEST_F( utMDCImportExport, importMDCFromFileTest ) {
EXPECT_TRUE( importerTest() );
}

View File

@ -129,18 +129,10 @@ TEST_F(MaterialSystemTest, testStringProperty) {
EXPECT_STREQ("Hello, this is a small test", s.data); EXPECT_STREQ("Hello, this is a small test", s.data);
} }
// ------------------------------------------------------------------------------------------------
TEST_F(MaterialSystemTest, testDefaultMaterialAccess) {
aiMaterial *mat = aiCreateAndRegisterDefaultMaterial();
EXPECT_NE(nullptr, mat);
aiReleaseDefaultMaterial();
delete mat;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
TEST_F(MaterialSystemTest, testMaterialNameAccess) { TEST_F(MaterialSystemTest, testMaterialNameAccess) {
aiMaterial *mat = aiCreateAndRegisterDefaultMaterial(); aiMaterial *mat = new aiMaterial();
EXPECT_NE(nullptr, mat); EXPECT_NE(nullptr, mat);
aiString name = mat->GetName(); aiString name = mat->GetName();

View File

@ -389,3 +389,10 @@ TEST_F( utObjImportExport, mtllib_after_g ) {
ASSERT_EQ(aiReturn_SUCCESS, mat->Get(AI_MATKEY_NAME, name)); ASSERT_EQ(aiReturn_SUCCESS, mat->Get(AI_MATKEY_NAME, name));
EXPECT_STREQ("MyMaterial", name.C_Str()); EXPECT_STREQ("MyMaterial", name.C_Str());
} }
TEST_F(utObjImportExport, import_point_cloud) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/OBJ/point_cloud.obj", 0 );
ASSERT_NE(nullptr, scene);
}

View File

@ -67,6 +67,20 @@ TEST_F( utSTLImporterExporter, importSTLFromFileTest ) {
EXPECT_TRUE( importerTest() ); EXPECT_TRUE( importerTest() );
} }
TEST_F(utSTLImporterExporter, test_multiple) {
// import same file twice, each with its own importer
// must work both times and not crash
Assimp::Importer importer1;
const aiScene *scene1 = importer1.ReadFile( ASSIMP_TEST_MODELS_DIR "/STL/Spider_ascii.stl", aiProcess_ValidateDataStructure );
EXPECT_NE(nullptr, scene1);
Assimp::Importer importer2;
const aiScene *scene2 = importer2.ReadFile( ASSIMP_TEST_MODELS_DIR "/STL/Spider_ascii.stl", aiProcess_ValidateDataStructure );
EXPECT_NE(nullptr, scene2);
}
TEST_F( utSTLImporterExporter, test_with_two_solids ) { TEST_F( utSTLImporterExporter, test_with_two_solids ) {
Assimp::Importer importer; Assimp::Importer importer;
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/STL/triangle_with_two_solids.stl", aiProcess_ValidateDataStructure ); const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/STL/triangle_with_two_solids.stl", aiProcess_ValidateDataStructure );

View File

@ -3,52 +3,28 @@ project(assimp_qt_viewer)
cmake_minimum_required(VERSION 2.6) cmake_minimum_required(VERSION 2.6)
OPTION( ASSIMP_QT4_VIEWER
"Set to ON to enable Qt4 against Qt5 for assimp_qt_viewer"
OFF
)
FIND_PACKAGE(DevIL QUIET)
FIND_PACKAGE(OpenGL QUIET) FIND_PACKAGE(OpenGL QUIET)
IF(ASSIMP_QT4_VIEWER) # Qt5 version
# Qt4 version FIND_PACKAGE(Qt5 COMPONENTS Gui Widgets OpenGL QUIET)
FIND_PACKAGE(Qt4 QUIET)
ELSE(ASSIMP_QT4_VIEWER)
# Qt5 version
FIND_PACKAGE(Qt5 COMPONENTS Gui Widgets OpenGL QUIET)
ENDIF(ASSIMP_QT4_VIEWER)
SET(VIEWER_BUILD:BOOL FALSE) SET(VIEWER_BUILD:BOOL FALSE)
IF((Qt4_FOUND OR Qt5Widgets_FOUND) AND IL_FOUND AND OPENGL_FOUND) IF( Qt5Widgets_FOUND AND OPENGL_FOUND)
SET(VIEWER_BUILD TRUE) SET(VIEWER_BUILD TRUE)
ELSE( Qt5Widgets_FOUND AND OPENGL_FOUND)
ELSE((Qt4_FOUND OR Qt5Widgets_FOUND) AND IL_FOUND AND OPENGL_FOUND)
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "") SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "")
IF(ASSIMP_QT4_VIEWER) IF (NOT Qt5_FOUND)
IF (NOT Qt4_FOUND) SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt5")
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt4") ENDIF (NOT Qt5_FOUND)
ENDIF (NOT Qt4_FOUND)
ELSE(ASSIMP_QT4_VIEWER)
IF (NOT Qt5_FOUND)
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt5")
ENDIF (NOT Qt5_FOUND)
ENDIF(ASSIMP_QT4_VIEWER)
IF (NOT IL_FOUND)
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} DevIL")
ENDIF (NOT IL_FOUND)
IF (NOT OPENGL_FOUND) IF (NOT OPENGL_FOUND)
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} OpengGL") SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} OpengGL")
ENDIF (NOT OPENGL_FOUND) ENDIF (NOT OPENGL_FOUND)
MESSAGE (WARNING "Build of assimp_qt_viewer is disabled. Unsatisfied dendencies: ${ASSIMP_QT_VIEWER_DEPENDENCIES}") MESSAGE (WARNING "Build of assimp_qt_viewer is disabled. Unsatisfied dendencies: ${ASSIMP_QT_VIEWER_DEPENDENCIES}")
ENDIF((Qt4_FOUND OR Qt5Widgets_FOUND) AND IL_FOUND AND OPENGL_FOUND) ENDIF( Qt5Widgets_FOUND AND OPENGL_FOUND)
IF(VIEWER_BUILD) IF(VIEWER_BUILD)
INCLUDE_DIRECTORIES( INCLUDE_DIRECTORIES(
@ -63,28 +39,23 @@ IF(VIEWER_BUILD)
LINK_DIRECTORIES(${Assimp_BINARY_DIR}) LINK_DIRECTORIES(${Assimp_BINARY_DIR})
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pedantic -Wall") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pedantic -Wall")
SET(assimp_qt_viewer_SRCS main.cpp loggerview.cpp glview.cpp mainwindow.cpp) SET(assimp_qt_viewer_SRCS
main.cpp
loggerview.hpp
loggerview.cpp
glview.hpp
glview.cpp
mainwindow.hpp
mainwindow.cpp
)
IF(ASSIMP_QT4_VIEWER) MESSAGE("assimp_qt_viewer use Qt5")
MESSAGE("assimp_qt_viewer use Qt4") INCLUDE_DIRECTORIES(${Qt5Widgets_INCLUDES})
ADD_DEFINITIONS( -DASSIMP_QT4_VIEWER ) qt5_wrap_ui(UISrcs mainwindow.ui)
INCLUDE_DIRECTORIES(${QT_INCLUDES}) qt5_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp)
qt4_wrap_ui(UISrcs mainwindow.ui)
qt4_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp)
ELSE()
MESSAGE("assimp_qt_viewer use Qt5")
INCLUDE_DIRECTORIES(${Qt5Widgets_INCLUDES})
qt5_wrap_ui(UISrcs mainwindow.ui)
qt5_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp)
ENDIF()
add_executable(${PROJECT_NAME} ${assimp_qt_viewer_SRCS} ${UISrcs} ${MOCrcs}) add_executable(${PROJECT_NAME} ${assimp_qt_viewer_SRCS} ${UISrcs} ${MOCrcs})
target_link_libraries(${PROJECT_NAME} Qt5::Gui Qt5::Widgets Qt5::OpenGL ${IL_LIBRARIES} ${OPENGL_LIBRARIES} assimp)
IF(ASSIMP_QT4_VIEWER)
target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${IL_LIBRARIES} ${OPENGL_LIBRARIES} assimp)
ELSE()
target_link_libraries(${PROJECT_NAME} Qt5::Gui Qt5::Widgets Qt5::OpenGL ${IL_LIBRARIES} ${OPENGL_LIBRARIES} assimp)
ENDIF()
IF(WIN32) # Check if we are on Windows IF(WIN32) # Check if we are on Windows
IF(MSVC) # Check if we are using the Visual Studio compiler IF(MSVC) # Check if we are using the Visual Studio compiler

View File

@ -1,8 +1,45 @@
/// \file glview.cpp /*
/// \brief OpenGL visualisation. Implementation file. ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, 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.
---------------------------------------------------------------------------
*/
#include "glview.hpp" #include "glview.hpp"
// Header files, Qt. // Header files, Qt.
@ -16,40 +53,30 @@
#endif #endif
// Header files, DevIL. // Header files, DevIL.
#include <il.h>
// Header files, Assimp. // Header files, Assimp.
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#ifndef __unused #define STB_IMAGE_IMPLEMENTATION
#define __unused __attribute__((unused)) #include "stb_image.h"
#endif // __unused
/**********************************/
/********** SHelper_Mesh **********/
/**********************************/
CGLView::SHelper_Mesh::SHelper_Mesh(const size_t pQuantity_Point, const size_t pQuantity_Line, const size_t pQuantity_Triangle, const SBBox& pBBox) CGLView::SHelper_Mesh::SHelper_Mesh(const size_t pQuantity_Point, const size_t pQuantity_Line, const size_t pQuantity_Triangle, const SBBox& pBBox)
: Quantity_Point(pQuantity_Point), Quantity_Line(pQuantity_Line), Quantity_Triangle(pQuantity_Triangle), BBox(pBBox) : Quantity_Point(pQuantity_Point)
{ , Quantity_Line(pQuantity_Line)
, Quantity_Triangle(pQuantity_Triangle)
, BBox(pBBox) {
Index_Point = pQuantity_Point ? new GLuint[pQuantity_Point * 1] : nullptr; Index_Point = pQuantity_Point ? new GLuint[pQuantity_Point * 1] : nullptr;
Index_Line = pQuantity_Line ? new GLuint[pQuantity_Line * 2] : nullptr; Index_Line = pQuantity_Line ? new GLuint[pQuantity_Line * 2] : nullptr;
Index_Triangle = pQuantity_Triangle ? new GLuint[pQuantity_Triangle * 3] : nullptr; Index_Triangle = pQuantity_Triangle ? new GLuint[pQuantity_Triangle * 3] : nullptr;
} }
CGLView::SHelper_Mesh::~SHelper_Mesh() CGLView::SHelper_Mesh::~SHelper_Mesh() {
{ delete [] Index_Point;
if(Index_Point != nullptr) delete [] Index_Point; delete [] Index_Line;
if(Index_Line != nullptr) delete [] Index_Line; delete [] Index_Triangle;
if(Index_Triangle != nullptr) delete [] Index_Triangle;
} }
/**********************************/ void CGLView::SHelper_Camera::SetDefault() {
/********** SHelper_Mesh **********/
/**********************************/
void CGLView::SHelper_Camera::SetDefault()
{
Position.Set(0, 0, 0); Position.Set(0, 0, 0);
Target.Set(0, 0, -1); Target.Set(0, 0, -1);
Rotation_AroundCamera = aiMatrix4x4(); Rotation_AroundCamera = aiMatrix4x4();
@ -57,39 +84,21 @@ void CGLView::SHelper_Camera::SetDefault()
Translation_ToScene.Set(0, 0, 2); Translation_ToScene.Set(0, 0, 2);
} }
/**********************************/ static void set_float4(float f[4], float a, float b, float c, float d) {
/************ CGLView *************/ f[0] = a;
/**********************************/ f[1] = b;
f[2] = c;
f[3] = d;
}
#if !ASSIMP_QT4_VIEWER static void color4_to_float4(const aiColor4D *c, float f[4]) {
# define ConditionalContextControl_Begin \ f[0] = c->r;
bool ContextEnabledHere; \ f[1] = c->g;
\ f[2] = c->b;
if(mGLContext_Current) \ f[3] = c->a;
{ \ }
ContextEnabledHere = false; \
} \
else \
{ \
makeCurrent(); \
mGLContext_Current = true; \
ContextEnabledHere = true; \
} \
\
do {} while(false)
# define ConditionalContextControl_End \ void CGLView::Material_Apply(const aiMaterial* pMaterial) {
if(ContextEnabledHere) \
{ \
doneCurrent(); \
mGLContext_Current = false; \
} \
\
do {} while(false)
#endif // ASSIMP_QT4_VIEWER
void CGLView::Material_Apply(const aiMaterial* pMaterial)
{
GLfloat tcol[4]; GLfloat tcol[4];
aiColor4D taicol; aiColor4D taicol;
unsigned int max; unsigned int max;
@ -97,15 +106,12 @@ void CGLView::Material_Apply(const aiMaterial* pMaterial)
int texture_index = 0; int texture_index = 0;
aiString texture_path; aiString texture_path;
auto set_float4 = [](float f[4], float a, float b, float c, float d) { f[0] = a, f[1] = b, f[2] = c, f[3] = d; };
auto color4_to_float4 = [](const aiColor4D *c, float f[4]) { f[0] = c->r, f[1] = c->g, f[2] = c->b, f[3] = c->a; };
///TODO: cache materials ///TODO: cache materials
// Disable color material because glMaterial is used. // Disable color material because glMaterial is used.
glDisable(GL_COLOR_MATERIAL);///TODO: cache glDisable(GL_COLOR_MATERIAL);///TODO: cache
// Set texture. If assigned.
if(AI_SUCCESS == pMaterial->GetTexture(aiTextureType_DIFFUSE, texture_index, &texture_path)) // Set texture. If assigned.
{ if(AI_SUCCESS == pMaterial->GetTexture(aiTextureType_DIFFUSE, texture_index, &texture_path)) {
//bind texture //bind texture
unsigned int texture_ID = mTexture_IDMap.value(texture_path.data, 0); unsigned int texture_ID = mTexture_IDMap.value(texture_path.data, 0);
@ -116,20 +122,27 @@ void CGLView::Material_Apply(const aiMaterial* pMaterial)
// //
// Diffuse // Diffuse
set_float4(tcol, 0.8f, 0.8f, 0.8f, 1.0f); set_float4(tcol, 0.8f, 0.8f, 0.8f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(pMaterial, AI_MATKEY_COLOR_DIFFUSE, &taicol)) color4_to_float4(&taicol, tcol); if ( AI_SUCCESS == aiGetMaterialColor( pMaterial, AI_MATKEY_COLOR_DIFFUSE, &taicol )) {
color4_to_float4( &taicol, tcol );
}
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, tcol); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, tcol);
// Specular
// Specular
set_float4(tcol, 0.0f, 0.0f, 0.0f, 1.0f); set_float4(tcol, 0.0f, 0.0f, 0.0f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(pMaterial, AI_MATKEY_COLOR_SPECULAR, &taicol)) color4_to_float4(&taicol, tcol); if ( AI_SUCCESS == aiGetMaterialColor( pMaterial, AI_MATKEY_COLOR_SPECULAR, &taicol )) {
color4_to_float4( &taicol, tcol );
}
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, tcol); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, tcol);
// Ambient // Ambient
set_float4(tcol, 0.2f, 0.2f, 0.2f, 1.0f); set_float4(tcol, 0.2f, 0.2f, 0.2f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(pMaterial, AI_MATKEY_COLOR_AMBIENT, &taicol)) color4_to_float4(&taicol, tcol); if ( AI_SUCCESS == aiGetMaterialColor( pMaterial, AI_MATKEY_COLOR_AMBIENT, &taicol )) {
color4_to_float4( &taicol, tcol );
}
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, tcol); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, tcol);
// Emission
// Emission
set_float4(tcol, 0.0f, 0.0f, 0.0f, 1.0f); set_float4(tcol, 0.0f, 0.0f, 0.0f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(pMaterial, AI_MATKEY_COLOR_EMISSIVE, &taicol)) color4_to_float4(&taicol, tcol); if(AI_SUCCESS == aiGetMaterialColor(pMaterial, AI_MATKEY_COLOR_EMISSIVE, &taicol)) color4_to_float4(&taicol, tcol);
@ -142,12 +155,9 @@ void CGLView::Material_Apply(const aiMaterial* pMaterial)
// Shininess strength // Shininess strength
max = 1; max = 1;
ret2 = aiGetMaterialFloatArray(pMaterial, AI_MATKEY_SHININESS_STRENGTH, &strength, &max); ret2 = aiGetMaterialFloatArray(pMaterial, AI_MATKEY_SHININESS_STRENGTH, &strength, &max);
if((ret1 == AI_SUCCESS) && (ret2 == AI_SUCCESS)) if((ret1 == AI_SUCCESS) && (ret2 == AI_SUCCESS)) {
{
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength);///TODO: cache glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength);///TODO: cache
} } else {
else
{
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);///TODO: cache glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);///TODO: cache
set_float4(tcol, 0.0f, 0.0f, 0.0f, 0.0f); set_float4(tcol, 0.0f, 0.0f, 0.0f, 0.0f);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, tcol); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, tcol);
@ -199,38 +209,26 @@ void CGLView::Matrix_NodeToRoot(const aiNode* pNode, aiMatrix4x4& pOutMatrix)
} }
} }
void CGLView::ImportTextures(const QString& pScenePath) void CGLView::ImportTextures(const QString& scenePath) {
{
auto LoadTexture = [&](const QString& pFileName) -> bool ///TODO: IME texture mode, operation. auto LoadTexture = [&](const QString& pFileName) -> bool ///TODO: IME texture mode, operation.
{ {
ILboolean success;
GLuint id_ogl_texture;// OpenGL texture ID. GLuint id_ogl_texture;// OpenGL texture ID.
if(!pFileName.startsWith(AI_EMBEDDED_TEXNAME_PREFIX)) if(!pFileName.startsWith(AI_EMBEDDED_TEXNAME_PREFIX))
{ {
ILuint id_image;// DevIL image ID. QString basepath = scenePath.left(scenePath.lastIndexOf('/') + 1);// path with '/' at the end.
QString basepath = pScenePath.left(pScenePath.lastIndexOf('/') + 1);// path with '/' at the end.
QString fileloc = (basepath + pFileName); QString fileloc = (basepath + pFileName);
fileloc.replace('\\', "/"); fileloc.replace('\\', "/");
ilGenImages(1, &id_image);// Generate DevIL image ID. int x, y, n;
ilBindImage(id_image); unsigned char *data = stbi_load(fileloc.toLocal8Bit(), &x, &y, &n, STBI_rgb_alpha );
success = ilLoadImage(fileloc.toLocal8Bit()); if ( nullptr == data ) {
if(!success)
{
LogError(QString("Couldn't load Image: %1").arg(fileloc)); LogError(QString("Couldn't load Image: %1").arg(fileloc));
return false; return false;
} }
// Convert every colour component into unsigned byte. If your image contains alpha channel you can replace IL_RGB with IL_RGBA. // Convert every colour component into unsigned byte. If your image contains alpha channel you can replace IL_RGB with IL_RGBA.
success = ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
if(!success)
{
LogError("Couldn't convert image.");
return false;
}
glGenTextures(1, &id_ogl_texture);// Texture ID generation. glGenTextures(1, &id_ogl_texture);// Texture ID generation.
mTexture_IDMap[pFileName] = id_ogl_texture;// save texture ID for filename in map mTexture_IDMap[pFileName] = id_ogl_texture;// save texture ID for filename in map
@ -238,11 +236,9 @@ void CGLView::ImportTextures(const QString& pScenePath)
// Redefine standard texture values // Redefine standard texture values
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// We will use linear interpolation for magnification filter. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// We will use linear interpolation for magnification filter.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);// We will use linear interpolation for minifying filter. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);// We will use linear interpolation for minifying filter.
glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), 0, glTexImage2D(GL_TEXTURE_2D, 0, n, x, y, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, data );// Texture specification.
ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData());// Texture specification.
//Cleanup // Cleanup
ilDeleteImages(1, &id_image);// Because we have already copied image data into texture data we can release memory used by image.
} }
else else
{ {
@ -321,27 +317,18 @@ void CGLView::ImportTextures(const QString& pScenePath)
return; return;
} }
// Before calling ilInit() version should be checked.
if(ilGetInteger(IL_VERSION_NUM) < IL_VERSION)
{
LogError("Wrong DevIL version.");
return;
}
ilInit();// Initialization of DevIL.
// //
// Load textures. // Load textures.
// //
// Get textures file names and number of textures. // Get textures file names and number of textures.
for(size_t idx_material = 0; idx_material < mScene->mNumMaterials; idx_material++) for(size_t idx_material = 0; idx_material < mScene->mNumMaterials; idx_material++) {
{
int idx_texture = 0; int idx_texture = 0;
aiString path; aiString path;
do do {
{ if (mScene->mMaterials[ idx_material ]->GetTexture( aiTextureType_DIFFUSE, idx_texture, &path ) != AI_SUCCESS) {
if(mScene->mMaterials[idx_material]->GetTexture(aiTextureType_DIFFUSE, idx_texture, &path) != AI_SUCCESS) break; break;
}
LoadTexture(QString(path.C_Str())); LoadTexture(QString(path.C_Str()));
idx_texture++; idx_texture++;
@ -349,11 +336,8 @@ void CGLView::ImportTextures(const QString& pScenePath)
}// for(size_t idx_material = 0; idx_material < mScene->mNumMaterials; idx_material++) }// for(size_t idx_material = 0; idx_material < mScene->mNumMaterials; idx_material++)
// Textures list is empty, exit. // Textures list is empty, exit.
if(mTexture_IDMap.size() == 0) if(mTexture_IDMap.empty()) {
{
LogInfo("No textures for import."); LogInfo("No textures for import.");
return;
} }
} }
@ -451,32 +435,21 @@ void CGLView::BBox_GetFromVertices(const aiVector3D* pVertices, const size_t pVe
} }
} }
/********************************************************************/ void CGLView::LogInfo(const QString& pMessage) {
/************************ Logging functions *************************/
/********************************************************************/
void CGLView::LogInfo(const QString& pMessage)
{
Assimp::DefaultLogger::get()->info(pMessage.toStdString()); Assimp::DefaultLogger::get()->info(pMessage.toStdString());
} }
void CGLView::LogError(const QString& pMessage) void CGLView::LogError(const QString& pMessage) {
{
Assimp::DefaultLogger::get()->error(pMessage.toStdString()); Assimp::DefaultLogger::get()->error(pMessage.toStdString());
} }
/********************************************************************/ void CGLView::Draw_Node(const aiNode* pNode) {
/************************** Draw functions **************************/
/********************************************************************/
void CGLView::Draw_Node(const aiNode* pNode)
{
aiMatrix4x4 mat_node = pNode->mTransformation; aiMatrix4x4 mat_node = pNode->mTransformation;
// Apply node transformation matrix. // Apply node transformation matrix.
mat_node.Transpose(); mat_node.Transpose();
glPushMatrix(); glPushMatrix();
#if ASSIMP_DOUBLE_PRECISION #ifdef ASSIMP_DOUBLE_PRECISION
glMultMatrixd((GLdouble*)mat_node[0]); glMultMatrixd((GLdouble*)mat_node[0]);
#else #else
glMultMatrixf((GLfloat*)&mat_node); glMultMatrixf((GLfloat*)&mat_node);
@ -518,7 +491,7 @@ void CGLView::Draw_Mesh(const size_t pMesh_Index)
{ {
glEnable(GL_COLOR_MATERIAL);///TODO: cache glEnable(GL_COLOR_MATERIAL);///TODO: cache
glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_COLOR_ARRAY);
#if ASSIMP_DOUBLE_PRECISION #ifdef ASSIMP_DOUBLE_PRECISION
glColorPointer(4, GL_DOUBLE, 0, mesh_cur.mColors[0]); glColorPointer(4, GL_DOUBLE, 0, mesh_cur.mColors[0]);
#else #else
glColorPointer(4, GL_FLOAT, 0, mesh_cur.mColors[0]); glColorPointer(4, GL_FLOAT, 0, mesh_cur.mColors[0]);
@ -531,7 +504,7 @@ void CGLView::Draw_Mesh(const size_t pMesh_Index)
if(mesh_cur.HasTextureCoords(0)) if(mesh_cur.HasTextureCoords(0))
{ {
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY);
#if ASSIMP_DOUBLE_PRECISION #ifdef ASSIMP_DOUBLE_PRECISION
glTexCoordPointer(2, GL_DOUBLE, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]); glTexCoordPointer(2, GL_DOUBLE, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]);
#else #else
glTexCoordPointer(2, GL_FLOAT, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]); glTexCoordPointer(2, GL_FLOAT, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]);
@ -544,7 +517,7 @@ void CGLView::Draw_Mesh(const size_t pMesh_Index)
if(mesh_cur.HasNormals()) if(mesh_cur.HasNormals())
{ {
glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_NORMAL_ARRAY);
#if ASSIMP_DOUBLE_PRECISION #ifdef ASSIMP_DOUBLE_PRECISION
glNormalPointer(GL_DOUBLE, 0, mesh_cur.mNormals); glNormalPointer(GL_DOUBLE, 0, mesh_cur.mNormals);
#else #else
glNormalPointer(GL_FLOAT, 0, mesh_cur.mNormals); glNormalPointer(GL_FLOAT, 0, mesh_cur.mNormals);
@ -581,16 +554,12 @@ void CGLView::Draw_BBox(const SBBox& pBBox)
glBindTexture(GL_TEXTURE_1D, 0); glBindTexture(GL_TEXTURE_1D, 0);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
glBindTexture(GL_TEXTURE_3D, 0); glBindTexture(GL_TEXTURE_3D, 0);
#if ASSIMP_QT4_VIEWER
qglColor(QColor(Qt::white));
#else
const QColor c_w(Qt::white); const QColor c_w(Qt::white);
glColor3f(c_w.redF(), c_w.greenF(), c_w.blueF()); glColor3f(c_w.redF(), c_w.greenF(), c_w.blueF());
#endif // ASSIMP_QT4_VIEWER
glBegin(GL_LINE_STRIP); glBegin(GL_LINE_STRIP);
# if ASSIMP_DOUBLE_PRECISION # ifdef ASSIMP_DOUBLE_PRECISION
glVertex3dv(&vertex[0][0]), glVertex3dv(&vertex[1][0]), glVertex3dv(&vertex[2][0]), glVertex3dv(&vertex[3][0]), glVertex3dv(&vertex[0][0]);// "Minimum" side. glVertex3dv(&vertex[0][0]), glVertex3dv(&vertex[1][0]), glVertex3dv(&vertex[2][0]), glVertex3dv(&vertex[3][0]), glVertex3dv(&vertex[0][0]);// "Minimum" side.
glVertex3dv(&vertex[4][0]), glVertex3dv(&vertex[5][0]), glVertex3dv(&vertex[6][0]), glVertex3dv(&vertex[7][0]), glVertex3dv(&vertex[4][0]);// Edge and "maximum" side. glVertex3dv(&vertex[4][0]), glVertex3dv(&vertex[5][0]), glVertex3dv(&vertex[6][0]), glVertex3dv(&vertex[7][0]), glVertex3dv(&vertex[4][0]);// Edge and "maximum" side.
# else # else
@ -600,7 +569,7 @@ void CGLView::Draw_BBox(const SBBox& pBBox)
glEnd(); glEnd();
glBegin(GL_LINES); glBegin(GL_LINES);
# if ASSIMP_DOUBLE_PRECISION # ifdef ASSIMP_DOUBLE_PRECISION
glVertex3dv(&vertex[1][0]), glVertex3dv(&vertex[5][0]); glVertex3dv(&vertex[1][0]), glVertex3dv(&vertex[5][0]);
glVertex3dv(&vertex[2][0]), glVertex3dv(&vertex[6][0]); glVertex3dv(&vertex[2][0]), glVertex3dv(&vertex[6][0]);
glVertex3dv(&vertex[3][0]), glVertex3dv(&vertex[7][0]); glVertex3dv(&vertex[3][0]), glVertex3dv(&vertex[7][0]);
@ -615,48 +584,28 @@ void CGLView::Draw_BBox(const SBBox& pBBox)
} }
void CGLView::Enable_Textures(const bool pEnable) void CGLView::Enable_Textures(const bool pEnable) {
{ if(pEnable) {
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
if(pEnable)
{
glEnable(GL_TEXTURE_1D); glEnable(GL_TEXTURE_1D);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_3D); glEnable(GL_TEXTURE_3D);
} } else {
else
{
glDisable(GL_TEXTURE_1D); glDisable(GL_TEXTURE_1D);
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_3D); glDisable(GL_TEXTURE_3D);
} }
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
} }
/********************************************************************/ void CGLView::initializeGL() {
/*********************** Override functions ************************/
/********************************************************************/
void CGLView::initializeGL()
{
#if ASSIMP_QT4_VIEWER
qglClearColor(Qt::gray);
#else
mGLContext_Current = true; mGLContext_Current = true;
initializeOpenGLFunctions(); initializeOpenGLFunctions();
glClearColor(0.5f, 0.5f, 0.5f, 1.0f); glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
#endif // ASSIMP_QT4_VIEWER
glShadeModel(GL_SMOOTH); glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE); glEnable(GL_NORMALIZE);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glEnable( GL_MULTISAMPLE );
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
@ -668,25 +617,14 @@ void CGLView::initializeGL()
glCullFace(GL_BACK); glCullFace(GL_BACK);
glFrontFace(GL_CCW); glFrontFace(GL_CCW);
#if !ASSIMP_QT4_VIEWER
mGLContext_Current = false;
#endif // ASSIMP_QT4_VIEWER
} }
void CGLView::resizeGL(int pWidth, int pHeight) void CGLView::resizeGL(int width, int height) {
{ mCamera_Viewport_AspectRatio = (GLdouble)width / height;
#if !ASSIMP_QT4_VIEWER glViewport(0, 0, width, height);
mGLContext_Current = true;
#endif // ASSIMP_QT4_VIEWER
mCamera_Viewport_AspectRatio = (GLdouble)pWidth / pHeight;
glViewport(0, 0, pWidth, pHeight);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
gluPerspective(mCamera_FOVY, mCamera_Viewport_AspectRatio, 1.0, 100000.0);///TODO: znear/zfar depend on scene size. gluPerspective(mCamera_FOVY, mCamera_Viewport_AspectRatio, 1.0, 100000.0);///TODO: znear/zfar depend on scene size.
#if !ASSIMP_QT4_VIEWER
mGLContext_Current = false;
#endif // ASSIMP_QT4_VIEWER
} }
void CGLView::drawCoordSystem() { void CGLView::drawCoordSystem() {
@ -699,19 +637,8 @@ void CGLView::drawCoordSystem() {
glBindTexture(GL_TEXTURE_3D, 0); glBindTexture(GL_TEXTURE_3D, 0);
glEnable(GL_COLOR_MATERIAL); glEnable(GL_COLOR_MATERIAL);
glBegin(GL_LINES); glBegin(GL_LINES);
#if ASSIMP_QT4_VIEWER
// X, -X // X, -X
qglColor(QColor(Qt::red)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(100000.0, 0.0, 0.0);
qglColor(QColor(Qt::cyan)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(-100000.0, 0.0, 0.0);
// Y, -Y
qglColor(QColor(Qt::green)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 100000.0, 0.0);
qglColor(QColor(Qt::magenta)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, -100000.0, 0.0);
// Z, -Z
qglColor(QColor(Qt::blue)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, 100000.0);
qglColor(QColor(Qt::yellow)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, -100000.0);
qglColor(QColor(Qt::white));
#else
// X, -X
glColor3f(1.0f, 0.0f, 0.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(100000.0, 0.0, 0.0); glColor3f(1.0f, 0.0f, 0.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(100000.0, 0.0, 0.0);
glColor3f(0.5f, 0.5f, 1.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(-100000.0, 0.0, 0.0); glColor3f(0.5f, 0.5f, 1.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(-100000.0, 0.0, 0.0);
// Y, -Y // Y, -Y
@ -721,19 +648,15 @@ void CGLView::drawCoordSystem() {
glColor3f(0.0f, 0.0f, 1.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, 100000.0); glColor3f(0.0f, 0.0f, 1.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, 100000.0);
glColor3f(1.0f, 1.0f, 0.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, -100000.0); glColor3f(1.0f, 1.0f, 0.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, -100000.0);
glColor3f(1.0f, 1.0f, 1.0f); glColor3f(1.0f, 1.0f, 1.0f);
#endif // ASSIMP_QT4_VIEWER
glEnd();
// Restore previous state of lighting.
if(mLightingEnabled) glEnable(GL_LIGHTING);
glEnd();
// Restore previous state of lighting.
if (mLightingEnabled) {
glEnable( GL_LIGHTING );
}
} }
void CGLView::paintGL() void CGLView::paintGL() {
{
#if !ASSIMP_QT4_VIEWER
mGLContext_Current = true;
#endif // ASSIMP_QT4_VIEWER
QTime time_paintbegin; QTime time_paintbegin;
time_paintbegin = QTime::currentTime(); time_paintbegin = QTime::currentTime();
@ -741,6 +664,7 @@ void CGLView::paintGL()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
// Apply current camera transformations. // Apply current camera transformations.
#if ASSIMP_DOUBLE_PRECISION #if ASSIMP_DOUBLE_PRECISION
glMultMatrixd((GLdouble*)&mHelper_Camera.Rotation_AroundCamera); glMultMatrixd((GLdouble*)&mHelper_Camera.Rotation_AroundCamera);
@ -753,58 +677,38 @@ void CGLView::paintGL()
#endif // ASSIMP_DOUBLE_PRECISION #endif // ASSIMP_DOUBLE_PRECISION
// Coordinate system // Coordinate system
if (mScene_AxesEnabled == true) if ( mScene_AxesEnabled ) {
{
drawCoordSystem(); drawCoordSystem();
} }
glDisable(GL_COLOR_MATERIAL); glDisable(GL_COLOR_MATERIAL);
// Scene
if(mScene != nullptr) // Scene
{ if(mScene != nullptr) {
Draw_Node(mScene->mRootNode); Draw_Node(mScene->mRootNode);
// Scene BBox // Scene BBox
if(mScene_DrawBBox) Draw_BBox(mScene_BBox); if (mScene_DrawBBox) {
Draw_BBox( mScene_BBox );
}
} }
emit Paint_Finished((size_t)time_paintbegin.msecsTo(QTime::currentTime()), mHelper_Camera.Translation_ToScene.Length()); emit Paint_Finished((size_t) time_paintbegin.msecsTo(QTime::currentTime()), mHelper_Camera.Translation_ToScene.Length());
#if !ASSIMP_QT4_VIEWER
mGLContext_Current = false;
#endif // ASSIMP_QT4_VIEWER
} }
/********************************************************************/
/********************** Constructor/Destructor **********************/
/********************************************************************/
CGLView::CGLView(QWidget *pParent) CGLView::CGLView( QWidget *pParent )
#if ASSIMP_QT4_VIEWER : QOpenGLWidget( pParent )
: QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer), pParent) , mGLContext_Current( false ) {
#else // set initial view
: QOpenGLWidget(pParent), mGLContext_Current(false) mHelper_CameraDefault.SetDefault();
#endif // ASSIMP_QT4_VIEWER Camera_Set( 0 );
{
// set initial view
mHelper_CameraDefault.SetDefault();
Camera_Set(0);
} }
CGLView::~CGLView() CGLView::~CGLView() {
{
FreeScene(); FreeScene();
} }
/********************************************************************/ void CGLView::FreeScene() {
/********************* Scene control functions **********************/
/********************************************************************/
void CGLView::FreeScene()
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
// Set scene to null and after that \ref paintGL will not try to render it. // Set scene to null and after that \ref paintGL will not try to render it.
mScene = nullptr; mScene = nullptr;
// Clean helper objects. // Clean helper objects.
@ -834,21 +738,14 @@ void CGLView::FreeScene()
mTexture_IDMap.clear(); mTexture_IDMap.clear();
delete [] id_tex; delete [] id_tex;
} }
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
} }
void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath) void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath) {
{ FreeScene();// Clear old data
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
FreeScene();// Clear old data
// Why checking here, not at begin of function. Because old scene may not exist at know. So, need cleanup. // Why checking here, not at begin of function. Because old scene may not exist at know. So, need cleanup.
if(pScene == nullptr) return; if (pScene == nullptr) {
return;
}
mScene = pScene;// Copy pointer of new scene. mScene = pScene;// Copy pointer of new scene.
@ -874,7 +771,7 @@ void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath)
BBox_GetFromVertices(mesh_cur.mVertices, mesh_cur.mNumVertices, mesh_bbox); BBox_GetFromVertices(mesh_cur.mVertices, mesh_cur.mNumVertices, mesh_bbox);
// //
// Create vertices indices arrays splited by primitive type. // Create vertices indices arrays splitted by primitive type.
// //
size_t indcnt_p = 0;// points quantity size_t indcnt_p = 0;// points quantity
size_t indcnt_l = 0;// lines quantity size_t indcnt_l = 0;// lines quantity
@ -1039,7 +936,10 @@ void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath)
}// switch(light_cur.mType) }// switch(light_cur.mType)
// Add light source // Add light source
if(name.isEmpty()) name += QString("%1").arg(idx_light);// Use index if name is empty. // Use index if name is empty.
if (name.isEmpty()) {
name += QString( "%1" ).arg( idx_light );
}
Lighting_EditSource(idx_light, lp); Lighting_EditSource(idx_light, lp);
emit SceneObject_LightSource(name);// Light source will be enabled in signal handler. emit SceneObject_LightSource(name);// Light source will be enabled in signal handler.
@ -1072,66 +972,48 @@ void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath)
emit SceneObject_Camera(mScene->mCameras[idx_cam]->mName.C_Str()); emit SceneObject_Camera(mScene->mCameras[idx_cam]->mName.C_Str());
} }
}// if(!mScene->HasCameras()) else }// if(!mScene->HasCameras()) else
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
} }
/********************************************************************/ void CGLView::Lighting_Enable() {
/******************** Lighting control functions ********************/
/********************************************************************/
void CGLView::Lighting_Enable()
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
mLightingEnabled = true; mLightingEnabled = true;
glEnable(GL_LIGHTING); glEnable(GL_LIGHTING);
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
} }
void CGLView::Lighting_Disable() void CGLView::Lighting_Disable() {
{ glDisable( GL_LIGHTING );
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
glDisable(GL_LIGHTING);
mLightingEnabled = false; mLightingEnabled = false;
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
} }
void CGLView::Lighting_EditSource(const size_t pLightNumber, const SLightParameters& pLightParameters) void CGLView::Lighting_EditSource(const size_t pLightNumber, const SLightParameters& pLightParameters)
{ {
#if !ASSIMP_QT4_VIEWER const size_t light_num = GL_LIGHT0 + pLightNumber;
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
const size_t light_num = GL_LIGHT0 + pLightNumber; GLfloat farr[4];
GLfloat farr[4];
if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value; if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value;
// Ambient color // Ambient color
farr[0] = pLightParameters.Ambient.r, farr[1] = pLightParameters.Ambient.g; farr[2] = pLightParameters.Ambient.b; farr[3] = pLightParameters.Ambient.a; farr[0] = pLightParameters.Ambient.r;
farr[1] = pLightParameters.Ambient.g;
farr[2] = pLightParameters.Ambient.b;
farr[3] = pLightParameters.Ambient.a;
glLightfv(light_num, GL_AMBIENT, farr); glLightfv(light_num, GL_AMBIENT, farr);
// Diffuse color
farr[0] = pLightParameters.Diffuse.r, farr[1] = pLightParameters.Diffuse.g; farr[2] = pLightParameters.Diffuse.b; farr[3] = pLightParameters.Diffuse.a; // Diffuse color
farr[0] = pLightParameters.Diffuse.r;
farr[1] = pLightParameters.Diffuse.g;
farr[2] = pLightParameters.Diffuse.b;
farr[3] = pLightParameters.Diffuse.a;
glLightfv(light_num, GL_DIFFUSE, farr); glLightfv(light_num, GL_DIFFUSE, farr);
// Specular color
farr[0] = pLightParameters.Specular.r, farr[1] = pLightParameters.Specular.g; farr[2] = pLightParameters.Specular.b; farr[3] = pLightParameters.Specular.a; // Specular color
farr[0] = pLightParameters.Specular.r;
farr[1] = pLightParameters.Specular.g;
farr[2] = pLightParameters.Specular.b;
farr[3] = pLightParameters.Specular.a;
glLightfv(light_num, GL_SPECULAR, farr); glLightfv(light_num, GL_SPECULAR, farr);
// Other parameters
// Other parameters
switch(pLightParameters.Type) switch(pLightParameters.Type)
{ {
case aiLightSource_DIRECTIONAL: case aiLightSource_DIRECTIONAL:
@ -1176,46 +1058,21 @@ GLfloat farr[4];
glLightf(light_num, GL_SPOT_CUTOFF, 180.0); glLightf(light_num, GL_SPOT_CUTOFF, 180.0);
break; break;
}// switch(pLightParameters.Type) }// switch(pLightParameters.Type)
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
} }
void CGLView::Lighting_EnableSource(const size_t pLightNumber) void CGLView::Lighting_EnableSource(const size_t pLightNumber) {
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value; if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value;
glEnable(GL_LIGHT0 + pLightNumber); glEnable(GL_LIGHT0 + pLightNumber);
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
} }
void CGLView::Lighting_DisableSource(const size_t pLightNumber) void CGLView::Lighting_DisableSource(const size_t pLightNumber)
{ {
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value; if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value;
glDisable(GL_LIGHT0 + pLightNumber); glDisable(GL_LIGHT0 + pLightNumber);
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
} }
/********************************************************************/
/******************** Cameras control functions *********************/
/********************************************************************/
void CGLView::Camera_Set(const size_t pCameraNumber) void CGLView::Camera_Set(const size_t pCameraNumber)
{ {
SHelper_Camera& hcam = mHelper_Camera;// reference with short name for conveniance. SHelper_Camera& hcam = mHelper_Camera;// reference with short name for conveniance.
@ -1263,7 +1120,7 @@ void CGLView::Camera_Set(const size_t pCameraNumber)
void CGLView::Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial) { void CGLView::Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial) {
auto deg2rad = [](const GLfloat pDegree) -> GLfloat { auto deg2rad = [](const GLfloat pDegree) -> GLfloat {
return pDegree * AI_MATH_PI / 180.0; return pDegree * AI_MATH_PI / 180.0f;
}; };
aiMatrix4x4 mat_rot; aiMatrix4x4 mat_rot;

View File

@ -1,7 +1,45 @@
/// \file glview.hpp /*
/// \brief OpenGL visualisation. ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, 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.
---------------------------------------------------------------------------
*/
#pragma once #pragma once

View File

@ -1,19 +1,64 @@
/// \file loggerview.cpp /*
/// \brief Stream for Assimp logging subsystem. ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, 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.
---------------------------------------------------------------------------
*/
#include "loggerview.hpp" #include "loggerview.hpp"
// Header files, Qt. // Header files, Qt.
#include <QTime> #include <QTime>
#include <QTextBrowser>
CLoggerView::CLoggerView(QTextBrowser* pOutputWidget) CLoggerView::CLoggerView(QTextBrowser* pOutputWidget)
: mOutputWidget(pOutputWidget) : mOutputWidget(pOutputWidget) {
{ // empty
} }
void CLoggerView::write(const char *pMessage) CLoggerView::~CLoggerView() {
{ mOutputWidget = nullptr;
}
void CLoggerView::write(const char *pMessage) {
if (nullptr == mOutputWidget) {
return;
}
mOutputWidget->insertPlainText(QString("[%1] %2").arg(QTime::currentTime().toString()).arg(pMessage)); mOutputWidget->insertPlainText(QString("[%1] %2").arg(QTime::currentTime().toString()).arg(pMessage));
} }

View File

@ -1,33 +1,67 @@
/// \file loggerview.hpp /*
/// \brief Stream for Assimp logging subsystem. ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, 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.
---------------------------------------------------------------------------
*/
#pragma once #pragma once
// Header files, Qt.
#include <QTextBrowser>
// Header files, Assimp. // Header files, Assimp.
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
/// \class CLoggerView class QTextBrowser;
/// GUI-stream for Assimp logging subsytem. Get data for logging and write it to output widget.
class CLoggerView final : public Assimp::LogStream
{
private:
QTextBrowser* mOutputWidget;///< Widget for displaying messages.
/// @class CLoggerView
/// @brief GUI-stream for Assimp logging sub-sytem. Get data for logging and write it to output widget.
class CLoggerView final : public ::Assimp::LogStream {
public: public:
/// @brief The class constructor.
/// @param [in] pOutputWidget - pointer to output widget.
explicit CLoggerView( QTextBrowser* pOutputWidget );
/// \fn explicit CLoggerView(QTextBrowser* pOutputWidget) /// @brief The class destructor.
/// Constructor. virtual ~CLoggerView();
/// \param [in] pOutputWidget - pointer to output widget.
explicit CLoggerView(QTextBrowser* pOutputWidget);
/// \fn virtual void write(const char *pMessage)
/// Write message to output widget. Used by Assimp. /// Write message to output widget. Used by Assimp.
/// \param [in] pMessage - message for displaying. /// \param [in] pMessage - message for displaying.
virtual void write(const char *pMessage); virtual void write(const char *pMessage);
private:
QTextBrowser * mOutputWidget; ///< Widget for displaying messages.
}; };

View File

@ -1,7 +1,46 @@
/// \file main.cpp /*
/// \brief Start-up file which contain function "main". ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, 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.
---------------------------------------------------------------------------
*/
// Thanks to acorn89 for support. // Thanks to acorn89 for support.
// Header files, project. // Header files, project.
@ -11,9 +50,9 @@
#include <QApplication> #include <QApplication>
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
QApplication a(argc, argv); QApplication app(argc, argv);
MainWindow w; MainWindow win;
w.show(); win.show();
return a.exec(); return app.exec();
} }

View File

@ -1,7 +1,45 @@
/// \file mainwindow.hpp /*
/// \brief Main window and algorhytms. ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, 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.
---------------------------------------------------------------------------
*/
#include "mainwindow.hpp" #include "mainwindow.hpp"
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
@ -14,22 +52,13 @@
#define __unused __attribute__((unused)) #define __unused __attribute__((unused))
#endif // __unused #endif // __unused
/**********************************/
/************ Functions ***********/
/**********************************/
/********************************************************************/
/********************* Import/Export functions **********************/
/********************************************************************/
void MainWindow::ImportFile(const QString &pFileName)
{
using namespace Assimp; using namespace Assimp;
QTime time_begin = QTime::currentTime();
if(mScene != nullptr) void MainWindow::ImportFile(const QString &pFileName) {
{ QTime time_begin = QTime::currentTime();
if ( mScene != nullptr ) {
mImporter.FreeScene(); mImporter.FreeScene();
mGLView->FreeScene(); mGLView->FreeScene();
} }
@ -37,8 +66,7 @@ QTime time_begin = QTime::currentTime();
// Try to import scene. // Try to import scene.
mScene = mImporter.ReadFile(pFileName.toStdString(), aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_ValidateDataStructure | \ mScene = mImporter.ReadFile(pFileName.toStdString(), aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_ValidateDataStructure | \
aiProcess_GenUVCoords | aiProcess_TransformUVCoords | aiProcess_FlipUVs); aiProcess_GenUVCoords | aiProcess_TransformUVCoords | aiProcess_FlipUVs);
if(mScene != nullptr) if ( mScene != nullptr ) {
{
ui->lblLoadTime->setText(QString::number(time_begin.secsTo(QTime::currentTime()))); ui->lblLoadTime->setText(QString::number(time_begin.secsTo(QTime::currentTime())));
LogInfo("Import done: " + pFileName); LogInfo("Import done: " + pFileName);
// Prepare widgets for new scene. // Prepare widgets for new scene.
@ -60,8 +88,7 @@ QTime time_begin = QTime::currentTime();
size_t qty_face = 0; size_t qty_face = 0;
size_t qty_vert = 0; size_t qty_vert = 0;
for(size_t idx_mesh = 0; idx_mesh < mScene->mNumMeshes; idx_mesh++) for(size_t idx_mesh = 0; idx_mesh < mScene->mNumMeshes; idx_mesh++) {
{
qty_face += mScene->mMeshes[idx_mesh]->mNumFaces; qty_face += mScene->mMeshes[idx_mesh]->mNumFaces;
qty_vert += mScene->mMeshes[idx_mesh]->mNumVertices; qty_vert += mScene->mMeshes[idx_mesh]->mNumVertices;
} }
@ -241,7 +268,6 @@ MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow), : QMainWindow(parent), ui(new Ui::MainWindow),
mScene(nullptr) mScene(nullptr)
{ {
using namespace Assimp;
// other variables // other variables
mMouse_Transformation.Position_Pressed_Valid = false; mMouse_Transformation.Position_Pressed_Valid = false;

View File

@ -1,7 +1,45 @@
/// \file mainwindow.hpp /*
/// \brief Main window and algorhytms. ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, 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.
---------------------------------------------------------------------------
*/
#pragma once #pragma once
@ -20,125 +58,64 @@
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <assimp/scene.h> #include <assimp/scene.h>
namespace Ui { class MainWindow; } namespace Ui {
class MainWindow;
}
/// \class MainWindow /// \class MainWindow
/// Main window and algorhytms. /// Main window and algorithms.
class MainWindow : public QMainWindow class MainWindow : public QMainWindow {
{ Q_OBJECT
Q_OBJECT
/**********************************/ struct SMouse_Transformation;
/************ Variables ***********/
/**********************************/
private: public:
/// @brief The class constructor.
/// \param [in] pParent - pointer to parent widget.
explicit MainWindow( QWidget* pParent = 0 );
Ui::MainWindow *ui; /// @brief The class destructor.
~MainWindow();
CGLView* mGLView;///< Pointer to OpenGL render.
CLoggerView* mLoggerView;///< Pointer to logging object. /// Import scene from file.
Assimp::Importer mImporter;///< Assimp importer.
const aiScene* mScene;///< Pointer to loaded scene (\ref aiScene).
/// \struct SMouse_Transformation
/// Holds data about transformation of the scene/camera when mouse us used.
struct SMouse_Transformation
{
bool Position_Pressed_Valid;///< Mouse button pressed on GLView.
QPoint Position_Pressed_LMB;///< Position where was pressed left mouse button.
QPoint Position_Pressed_RMB;///< Position where was pressed right mouse button.
aiMatrix4x4 Rotation_AroundCamera;///< Rotation matrix which set rotation angles of the scene around camera.
aiMatrix4x4 Rotation_Scene;///< Rotation matrix which set rotation angles of the scene around own center.
} mMouse_Transformation;
/**********************************/
/************ Functions ***********/
/**********************************/
/********************************************************************/
/********************* Import/Export functions **********************/
/********************************************************************/
/// \fn void ImportFile(const QString& pFileName)
/// Import scene from file.
/// \param [in] pFileName - path and name of the file. /// \param [in] pFileName - path and name of the file.
void ImportFile(const QString& pFileName); void ImportFile(const QString& pFileName);
/// \fn void ResetSceneInfos()
/// Reset informations about the scene /// Reset informations about the scene
void ResetSceneInfos(); void ResetSceneInfos();
/********************************************************************/
/************************ Logging functions *************************/
/********************************************************************/
/// \fn void LogInfo(const QString& pMessage)
/// Add message with severity "Warning" to log. /// Add message with severity "Warning" to log.
void LogInfo(const QString& pMessage); void LogInfo(const QString& pMessage);
/// \fn void LogError(const QString& pMessage)
/// Add message with severity "Error" to log. /// Add message with severity "Error" to log.
void LogError(const QString& pMessage); void LogError(const QString& pMessage);
/********************************************************************/
/*********************** Override functions ************************/
/********************************************************************/
protected: protected:
/// \fn void mousePressEvent(QMouseEvent* pEvent) override
/// Override function which handles mouse event "button pressed". /// Override function which handles mouse event "button pressed".
/// \param [in] pEvent - pointer to event data. /// \param [in] pEvent - pointer to event data.
void mousePressEvent(QMouseEvent* pEvent) override; void mousePressEvent(QMouseEvent* pEvent) override;
/// \fn void mouseReleaseEvent(QMouseEvent *pEvent) override
/// Override function which handles mouse event "button released". /// Override function which handles mouse event "button released".
/// \param [in] pEvent - pointer to event data. /// \param [in] pEvent - pointer to event data.
void mouseReleaseEvent(QMouseEvent *pEvent) override; void mouseReleaseEvent(QMouseEvent *pEvent) override;
/// \fn void mouseMoveEvent(QMouseEvent* pEvent) override
/// Override function which handles mouse event "move". /// Override function which handles mouse event "move".
/// \param [in] pEvent - pointer to event data. /// \param [in] pEvent - pointer to event data.
void mouseMoveEvent(QMouseEvent* pEvent) override; void mouseMoveEvent(QMouseEvent* pEvent) override;
/// \fn void keyPressEvent(QKeyEvent* pEvent) override
/// Override function which handles key event "key pressed". /// Override function which handles key event "key pressed".
/// \param [in] pEvent - pointer to event data. /// \param [in] pEvent - pointer to event data.
void keyPressEvent(QKeyEvent* pEvent) override; void keyPressEvent(QKeyEvent* pEvent) override;
public:
/********************************************************************/
/********************** Constructor/Destructor **********************/
/********************************************************************/
/// \fn explicit MainWindow(QWidget* pParent = 0)
/// \param [in] pParent - pointer to parent widget.
explicit MainWindow(QWidget* pParent = 0);
/// \fn ~MainWindow()
/// Destructor.
~MainWindow();
/********************************************************************/
/****************************** Slots *******************************/
/********************************************************************/
private slots: private slots:
/// \fn void Paint_Finished(const int pPaintTime)
/// Show paint/render time and distance between camera and center of the scene. /// Show paint/render time and distance between camera and center of the scene.
/// \param [in] pPaintTime_ms - paint time in milliseconds. /// \param [in] pPaintTime_ms - paint time in milliseconds.
void Paint_Finished(const size_t pPaintTime_ms, const GLfloat pDistance); void Paint_Finished(const size_t pPaintTime_ms, const GLfloat pDistance);
/// \fn void SceneObject_Camera(const QString& pName)
/// Add camera name to list. /// Add camera name to list.
/// \param [in] pName - name of the camera. /// \param [in] pName - name of the camera.
void SceneObject_Camera(const QString& pName); void SceneObject_Camera(const QString& pName);
/// \fn void SceneObject_LightSource(const QString& pName)
/// Add lighting source name to list. /// Add lighting source name to list.
/// \param [in] pName - name of the light source, /// \param [in] pName - name of the light source,
void SceneObject_LightSource(const QString& pName); void SceneObject_LightSource(const QString& pName);
@ -151,4 +128,21 @@ private slots:
void on_cbxBBox_clicked(bool checked); void on_cbxBBox_clicked(bool checked);
void on_cbxTextures_clicked(bool checked); void on_cbxTextures_clicked(bool checked);
void on_cbxDrawAxes_clicked(bool checked); void on_cbxDrawAxes_clicked(bool checked);
private:
Ui::MainWindow *ui;
CGLView *mGLView;///< Pointer to OpenGL render.
CLoggerView *mLoggerView;///< Pointer to logging object.
Assimp::Importer mImporter;///< Assimp importer.
const aiScene* mScene;///< Pointer to loaded scene (\ref aiScene).
/// \struct SMouse_Transformation
/// Holds data about transformation of the scene/camera when mouse us used.
struct SMouse_Transformation {
bool Position_Pressed_Valid;///< Mouse button pressed on GLView.
QPoint Position_Pressed_LMB;///< Position where was pressed left mouse button.
QPoint Position_Pressed_RMB;///< Position where was pressed right mouse button.
aiMatrix4x4 Rotation_AroundCamera;///< Rotation matrix which set rotation angles of the scene around camera.
aiMatrix4x4 Rotation_Scene;///< Rotation matrix which set rotation angles of the scene around own center.
} mMouse_Transformation;
}; };

File diff suppressed because it is too large Load Diff