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

View File

@ -30,6 +30,8 @@ One-off donations via PayPal:
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 ####
__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
#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"
};
const aiImporterDesc* AssbinImporter::GetInfo() const
{
// -----------------------------------------------------------------------------------
const aiImporterDesc* AssbinImporter::GetInfo() const {
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);
if (!in)
if (nullptr == in) {
return false;
}
char s[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;
}
// -----------------------------------------------------------------------------------
template <typename T>
T Read(IOStream * stream)
{
T Read(IOStream * stream) {
T t;
stream->Read( &t, sizeof(T), 1 );
return t;
}
// -----------------------------------------------------------------------------------
template <>
aiVector3D Read<aiVector3D>(IOStream * stream)
{
aiVector3D Read<aiVector3D>(IOStream * stream) {
aiVector3D v;
v.x = Read<float>(stream);
v.y = Read<float>(stream);
@ -116,9 +117,9 @@ aiVector3D Read<aiVector3D>(IOStream * stream)
return v;
}
// -----------------------------------------------------------------------------------
template <>
aiColor4D Read<aiColor4D>(IOStream * stream)
{
aiColor4D Read<aiColor4D>(IOStream * stream) {
aiColor4D c;
c.r = Read<float>(stream);
c.g = Read<float>(stream);
@ -127,9 +128,9 @@ aiColor4D Read<aiColor4D>(IOStream * stream)
return c;
}
// -----------------------------------------------------------------------------------
template <>
aiQuaternion Read<aiQuaternion>(IOStream * stream)
{
aiQuaternion Read<aiQuaternion>(IOStream * stream) {
aiQuaternion v;
v.w = Read<float>(stream);
v.x = Read<float>(stream);
@ -138,9 +139,9 @@ aiQuaternion Read<aiQuaternion>(IOStream * stream)
return v;
}
// -----------------------------------------------------------------------------------
template <>
aiString Read<aiString>(IOStream * stream)
{
aiString Read<aiString>(IOStream * stream) {
aiString s;
stream->Read(&s.length,4,1);
stream->Read(s.data,s.length,1);
@ -148,18 +149,18 @@ aiString Read<aiString>(IOStream * stream)
return s;
}
// -----------------------------------------------------------------------------------
template <>
aiVertexWeight Read<aiVertexWeight>(IOStream * stream)
{
aiVertexWeight Read<aiVertexWeight>(IOStream * stream) {
aiVertexWeight w;
w.mVertexId = Read<unsigned int>(stream);
w.mWeight = Read<float>(stream);
return w;
}
// -----------------------------------------------------------------------------------
template <>
aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream)
{
aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream) {
aiMatrix4x4 m;
for (unsigned int i = 0; i < 4;++i) {
for (unsigned int i2 = 0; i2 < 4;++i2) {
@ -169,36 +170,43 @@ aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream)
return m;
}
// -----------------------------------------------------------------------------------
template <>
aiVectorKey Read<aiVectorKey>(IOStream * stream)
{
aiVectorKey Read<aiVectorKey>(IOStream * stream) {
aiVectorKey v;
v.mTime = Read<double>(stream);
v.mValue = Read<aiVector3D>(stream);
return v;
}
// -----------------------------------------------------------------------------------
template <>
aiQuatKey Read<aiQuatKey>(IOStream * stream)
{
aiQuatKey Read<aiQuatKey>(IOStream * stream) {
aiQuatKey v;
v.mTime = Read<double>(stream);
v.mValue = Read<aiQuaternion>(stream);
return v;
}
// -----------------------------------------------------------------------------------
template <typename T>
void ReadArray(IOStream * stream, T * out, unsigned int size)
{
for (unsigned int i=0; i<size; i++) out[i] = Read<T>(stream);
void ReadArray( IOStream *stream, T * out, unsigned int size) {
ai_assert( nullptr != 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.
stream->Seek( sizeof(T) * n, aiOrigin_CUR );
}
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* parent ) {
uint32_t chunkID = Read<uint32_t>(stream);
(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);
(void)(chunkID);
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.
// maybe I'll add a better, hash-like solution later
if (shortened)
{
if (shortened) {
ReadBounds(stream,b->mWeights,b->mNumWeights);
} // else write as usual
else
{
} else {
// else write as usual
b->mWeights = new aiVertexWeight[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);
(void)(chunkID);
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
unsigned int c = Read<unsigned int>(stream);
if (c & ASSBIN_MESH_HAS_POSITIONS)
{
if (c & ASSBIN_MESH_HAS_POSITIONS) {
if (shortened) {
ReadBounds(stream,mesh->mVertices,mesh->mNumVertices);
} // else write as usual
else
{
} else {
// else write as usual
mesh->mVertices = new aiVector3D[mesh->mNumVertices];
ReadArray<aiVector3D>(stream,mesh->mVertices,mesh->mNumVertices);
}
}
if (c & ASSBIN_MESH_HAS_NORMALS)
{
if (c & ASSBIN_MESH_HAS_NORMALS) {
if (shortened) {
ReadBounds(stream,mesh->mNormals,mesh->mNumVertices);
} // else write as usual
else
{
} else {
// else write as usual
mesh->mNormals = new aiVector3D[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) {
ReadBounds(stream,mesh->mTangents,mesh->mNumVertices);
ReadBounds(stream,mesh->mBitangents,mesh->mNumVertices);
} // else write as usual
else
{
} else {
// else write as usual
mesh->mTangents = new aiVector3D[mesh->mNumVertices];
ReadArray<aiVector3D>(stream,mesh->mTangents,mesh->mNumVertices);
mesh->mBitangents = new aiVector3D[mesh->mNumVertices];
ReadArray<aiVector3D>(stream,mesh->mBitangents,mesh->mNumVertices);
}
}
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n)
{
if (!(c & ASSBIN_MESH_HAS_COLOR(n)))
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) {
if (!(c & ASSBIN_MESH_HAS_COLOR(n))) {
break;
}
if (shortened)
{
if (shortened) {
ReadBounds(stream,mesh->mColors[n],mesh->mNumVertices);
} // else write as usual
else
{
} else {
// else write as usual
mesh->mColors[n] = new aiColor4D[mesh->mNumVertices];
ReadArray<aiColor4D>(stream,mesh->mColors[n],mesh->mNumVertices);
}
}
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n)
{
if (!(c & ASSBIN_MESH_HAS_TEXCOORD(n)))
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
if (!(c & ASSBIN_MESH_HAS_TEXCOORD(n))) {
break;
}
// write number of UV components
mesh->mNumUVComponents[n] = Read<unsigned int>(stream);
if (shortened) {
ReadBounds(stream,mesh->mTextureCoords[n],mesh->mNumVertices);
} // else write as usual
else
{
} else {
// else write as usual
mesh->mTextureCoords[n] = new aiVector3D[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.
if (shortened) {
Read<unsigned int>(stream);
}
else // else write as usual
{
} else {
// else write as usual
// if there are less than 2^16 vertices, we can simply use 16 bit integers ...
mesh->mFaces = new aiFace[mesh->mNumFaces];
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];
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);
}
else
{
} else {
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);
(void)(chunkID);
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);
(void)(chunkID);
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);
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AINODEANIM);
@ -493,9 +488,8 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
if (shortened) {
ReadBounds(stream,nd->mRotationKeys,nd->mNumRotationKeys);
} // else write as usual
else
{
} else {
// else write as usual
nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys];
ReadArray<aiQuatKey>(stream,nd->mRotationKeys,nd->mNumRotationKeys);
}
@ -504,19 +498,16 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
if (shortened) {
ReadBounds(stream,nd->mScalingKeys,nd->mNumScalingKeys);
} // else write as usual
else
{
} else {
// else write as usual
nd->mScalingKeys = new aiVectorKey[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);
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AIANIMATION);
@ -527,8 +518,7 @@ void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
anim->mTicksPerSecond = Read<double> (stream);
anim->mNumChannels = Read<unsigned int>(stream);
if (anim->mNumChannels)
{
if (anim->mNumChannels) {
anim->mChannels = new aiNodeAnim*[ anim->mNumChannels ];
for (unsigned int a = 0; a < anim->mNumChannels;++a) {
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);
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AITEXTURE);
@ -552,18 +542,15 @@ void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex)
if (!tex->mHeight) {
tex->pcData = new aiTexel[ tex->mWidth ];
stream->Read(tex->pcData,1,tex->mWidth);
}
else {
} else {
tex->pcData = new aiTexel[ tex->mWidth*tex->mHeight ];
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);
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AILIGHT);
@ -586,12 +573,10 @@ void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l )
l->mAngleInnerCone = 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);
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AICAMERA);
@ -607,8 +592,8 @@ void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam )
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);
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AISCENE);
@ -623,12 +608,11 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
scene->mNumCameras = Read<unsigned int>(stream);
// Read node graph
scene->mRootNode = new aiNode[1];
//scene->mRootNode = new aiNode[1];
ReadBinaryNode( stream, &scene->mRootNode, (aiNode*)NULL );
// Read all meshes
if (scene->mNumMeshes)
{
if (scene->mNumMeshes) {
scene->mMeshes = new aiMesh*[scene->mNumMeshes];
for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
scene->mMeshes[i] = new aiMesh();
@ -637,8 +621,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
}
// Read materials
if (scene->mNumMaterials)
{
if (scene->mNumMaterials) {
scene->mMaterials = new aiMaterial*[scene->mNumMaterials];
for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
scene->mMaterials[i] = new aiMaterial();
@ -647,8 +630,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
}
// Read all animations
if (scene->mNumAnimations)
{
if (scene->mNumAnimations) {
scene->mAnimations = new aiAnimation*[scene->mNumAnimations];
for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
scene->mAnimations[i] = new aiAnimation();
@ -657,8 +639,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
}
// Read all textures
if (scene->mNumTextures)
{
if (scene->mNumTextures) {
scene->mTextures = new aiTexture*[scene->mNumTextures];
for (unsigned int i = 0; i < scene->mNumTextures;++i) {
scene->mTextures[i] = new aiTexture();
@ -667,8 +648,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
}
// Read lights
if (scene->mNumLights)
{
if (scene->mNumLights) {
scene->mLights = new aiLight*[scene->mNumLights];
for (unsigned int i = 0; i < scene->mNumLights;++i) {
scene->mLights[i] = new aiLight();
@ -677,8 +657,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
}
// Read cameras
if (scene->mNumCameras)
{
if (scene->mNumCameras) {
scene->mCameras = new aiCamera*[scene->mNumCameras];
for (unsigned int i = 0; i < scene->mNumCameras;++i) {
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");
if (!stream)
if (nullptr == stream) {
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 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( 64, aiOrigin_CUR ); // padding
if (compressed)
{
if (compressed) {
uLongf uncompressedSize = Read<uint32_t>(stream);
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[] compressedData;
}
else
{
} else {
ReadBinaryScene(stream,pScene);
}

View File

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

View File

@ -272,8 +272,6 @@ void aiReleaseImport( const aiScene* pScene)
ASSIMP_BEGIN_EXCEPTION_REGION();
aiReleaseDefaultMaterial();
// find the importer associated with this data
const ScenePrivateData* priv = ScenePriv(pScene);
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/scene.h>
#include <assimp/importerdesc.h>
#include <map>
using namespace Assimp;
using namespace Assimp::Formatter;
@ -461,6 +462,13 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
aiNodeAnim* nodeAnim = new aiNodeAnim;
anim->mChannels[a] = nodeAnim;
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
if( node.mChannels.size() == 6)
@ -472,16 +480,32 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
{
poskey->mTime = double( fr);
// Now compute all translations in the right order
for( unsigned int channel = 0; channel < 3; ++channel)
// Now compute all translations
for(BVHLoader::ChannelType channel = Channel_PositionX; channel <= Channel_PositionZ; channel = (BVHLoader::ChannelType)(channel +1))
{
switch( node.mChannels[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;
case Channel_PositionZ: poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
}
//Find channel in node
std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
if (mapIter == channelMap.end())
throw DeadlyImportError("Missing position channel in 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;
}
@ -497,12 +521,6 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
// 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
nodeAnim->mNumRotationKeys = mAnimNumFrames;
@ -512,20 +530,33 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
{
aiMatrix4x4 temp;
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)
{
// translate ZXY euler angels into a quaternion
const float angle = node.mChannelValues[fr * node.mChannels.size() + rotOffset + channel] * float( AI_MATH_PI) / 180.0f;
if (mapIter == channelMap.end())
throw DeadlyImportError("Missing rotation channel in node " + nodeName);
else {
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
switch (node.mChannels[rotOffset+channel])
{
case Channel_RotationX: aiMatrix4x4::RotationX( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
case Channel_RotationY: aiMatrix4x4::RotationY( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
case Channel_RotationZ: aiMatrix4x4::RotationZ( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
}
// Compute rotation transformations in the right order
switch (channel)
{
case Channel_RotationX:
aiMatrix4x4::RotationX(angle, temp); rotMatrix *= aiMatrix3x3(temp);
break;
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);

View File

@ -297,8 +297,9 @@ private:
return false;
}
//format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
const size_t len( strlen( color ) );
if ( 9 != len ) {
if ( 9 != len && 7 != len) {
return false;
}
@ -313,26 +314,28 @@ private:
++buf;
comp[ 1 ] = *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;
++buf;
comp[ 1 ] = *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;
++buf;
comp[ 1 ] = *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;
++buf;
comp[ 1 ] = *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;
}

View File

@ -185,12 +185,8 @@ void FBXConverter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4&
}
if ( !name_carrier ) {
NodeNameCache::const_iterator it = mNodeNames.find(original_name);
if ( it != mNodeNames.end() ) {
original_name = original_name + std::string( "001" );
}
mNodeNames.insert( original_name );
std::string old_original_name = original_name;
GetUniqueName(old_original_name, original_name);
nodes_chain.push_back( new aiNode( original_name ) );
} else {
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
// now it seems unavoidable.
if (MappingInformationType == "ByVertice" && isDirect) {
if (!HasElement(source, indexDataElementName)) {
if (!HasElement(source, dataElementName)) {
return;
}
std::vector<T> tempData;

View File

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

View File

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

View File

@ -387,26 +387,6 @@ aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
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;

View File

@ -210,22 +210,80 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
ai_assert(false);
}
// Create nodes for the whole scene
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);
}
if (pModel->m_Objects.size() > 0) {
// 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 ];
unsigned int meshCount = 0;
unsigned int childCount = 0;
for(size_t index = 0; index < pModel->m_Objects.size(); ++index) {
if(pModel->m_Objects[index]) {
++childCount;
meshCount += (unsigned int)pModel->m_Objects[index]->m_Meshes.size();
}
}
}
// Create all materials
createMaterials( pModel, pScene );
// Allocate space for the child nodes on the root node
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;
// If we have a parent node, store it
if( pParent != NULL ) {
appendChildToParentNode( pParent, pNode );
}
ai_assert( NULL != pParent );
appendChildToParentNode( pParent, pNode );
for ( size_t i=0; i< pObject->m_Meshes.size(); ++i ) {
unsigned int meshId = pObject->m_Meshes[ i ];
@ -401,8 +458,8 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
pMesh->mNumVertices = numIndices;
if (pMesh->mNumVertices == 0) {
throw DeadlyImportError( "OBJ: no vertices" );
} else if (pMesh->mNumVertices > AI_MAX_ALLOC(aiVector3D)) {
throw DeadlyImportError( "OBJ: Too many vertices, would run out of memory" );
} else if (pMesh->mNumVertices > AI_MAX_VERTICES) {
throw DeadlyImportError( "OBJ: Too many vertices" );
}
pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ];
@ -452,7 +509,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
// Copy all vertex colors
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);
}
@ -729,25 +786,8 @@ void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild)
// Assign parent to child
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
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;
}

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
// other geometric types (e.g., PLY).
aiMaterial* pcMat = aiCreateAndRegisterDefaultMaterial();
/*aiMaterial* pcMat = new aiMaterial();
aiMaterial* pcMat = new aiMaterial();
aiString s;
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));
if (bMatClr) {

View File

@ -393,7 +393,7 @@ void SplitByBoneCountProcess::UpdateNode( aiNode* pNode) const
newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end());
}
delete pNode->mMeshes;
delete [] pNode->mMeshes;
pNode->mNumMeshes = static_cast<unsigned int>(newMeshList.size());
pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
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) {
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]);
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 */
class ASSIMP_API DefaultIOSystem : public IOSystem
{
class ASSIMP_API DefaultIOSystem : public IOSystem {
public:
// -------------------------------------------------------------------
/** 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
* of a file easily. Works with StreamReader.
*/
#pragma once
#ifndef INCLUDED_LINE_SPLITTER_H
#define INCLUDED_LINE_SPLITTER_H
#include <stdexcept>
#include "StreamReader.h"
#include "ParsingUtils.h"
@ -81,164 +81,205 @@ public:
/** construct from existing stream reader
note: trim is *always* assumed true if skyp_empty_lines==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++();
LineSplitter(StreamReaderLE& stream, bool skip_empty_lines = true, bool trim = true);
idx = 0;
}
~LineSplitter() {
// empty
}
public:
~LineSplitter();
// -----------------------------------------
/** pseudo-iterator increment */
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++();
// -----------------------------------------
LineSplitter& operator++(int) {
return ++(*this);
}
LineSplitter& operator++(int);
// -----------------------------------------
/** get a pointer to the beginning of a particular token */
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;
}
const char* operator[] (size_t idx) const;
// -----------------------------------------
/** extract the start positions of N tokens from the current line*/
template <size_t N>
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);
}
}
void get_tokens(const char* (&tokens)[N]) const;
// -----------------------------------------
/** member access */
const std::string* operator -> () const {
return &cur;
}
const std::string* operator -> () const;
std::string operator* () const {
return cur;
}
std::string operator* () const;
// -----------------------------------------
/** boolean context */
operator bool() const {
return stream.GetRemainingSize()>0;
}
operator bool() const;
// -----------------------------------------
/** line indices are zero-based, empty lines are included */
operator line_idx() const {
return idx;
}
operator line_idx() const;
line_idx get_index() const {
return idx;
}
line_idx get_index() const;
// -----------------------------------------
/** access the underlying stream object */
StreamReaderLE& get_stream() {
return stream;
}
StreamReaderLE& get_stream();
// -----------------------------------------
/** !strcmp((*this)->substr(0,strlen(check)),check) */
bool match_start(const char* check) {
const size_t len = strlen(check);
return len <= cur.length() && std::equal(check,check+len,cur.begin());
}
bool match_start(const char* check);
// -----------------------------------------
/** swallow the next call to ++, return the previous value. */
void swallow_next_increment() {
swallow = true;
}
void swallow_next_increment();
LineSplitter( const LineSplitter & ) = delete;
LineSplitter(LineSplitter &&) = delete;
LineSplitter &operator = ( const LineSplitter & ) = delete;
private:
LineSplitter( const LineSplitter & );
LineSplitter &operator = ( const LineSplitter & );
private:
line_idx idx;
std::string cur;
StreamReaderLE& stream;
bool swallow, skip_empty_lines, trim;
line_idx mIdx;
std::string mCur;
StreamReaderLE& mStream;
bool mSwallow, mSkip_empty_lines, mTrim;
};
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

View File

@ -67,16 +67,13 @@ namespace Assimp {
* XXX switch from unsigned int for size types to size_t? or ptrdiff_t?*/
// --------------------------------------------------------------------------------------------
template <bool SwapEndianess = false, bool RuntimeSwitch = false>
class StreamReader
{
class StreamReader {
public:
// FIXME: use these data types throughout the whole library,
// 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.
*
@ -111,8 +108,6 @@ public:
delete[] buffer;
}
public:
// deprecated, use overloaded operator>> instead
// ---------------------------------------------------------------------
@ -176,7 +171,6 @@ public:
return Get<uint64_t>();
}
public:
// ---------------------------------------------------------------------
/** Get the remaining stream size (to the end of the stream) */
unsigned int GetRemainingSize() const {

View File

@ -1565,26 +1565,6 @@ C_ENUM aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
unsigned int* flags /*= NULL*/);
#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
}

View File

@ -66,6 +66,13 @@ def make_tuple(ai_obj, type = None):
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
def _init_face(aiFace):
aiFace.indices = [aiFace.mIndices[i] for i in range(aiFace.mNumIndices)]
@ -118,14 +125,9 @@ def _init(self, target = None, parent = None):
continue
if m == 'mName':
obj = self.mName
try:
uni = unicode(obj.data, errors='ignore')
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
target.name = str(_convert_assimp_string(self.mName))
target.__class__.__repr__ = lambda x: str(x.__class__) + "(" + getattr(x, 'name','') + ")"
target.__class__.__str__ = lambda x: getattr(x, 'name', '')
continue
name = m[1:].lower()
@ -220,6 +222,9 @@ def _init(self, target = None, parent = None):
if isinstance(self, structs.Texture):
_finalize_texture(self, target)
if isinstance(self, structs.Metadata):
_finalize_metadata(self, target)
return self
@ -412,6 +417,43 @@ def _finalize_mesh(mesh, target):
faces = [f.indices for f in target.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):
def __getitem__(self, key):
@ -443,11 +485,8 @@ def _get_properties(properties, length):
for p in [properties[i] for i in range(length)]:
#the name
p = p.contents
try:
uni = unicode(p.mKey.data, errors='ignore')
except:
uni = str(p.mKey.data, errors='ignore')
key = (str(uni).split('.')[1], p.mSemantic)
key = str(_convert_assimp_string(p.mKey))
key = (key.split('.')[1], p.mSemantic)
#the data
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
value = [x for x in arr]
elif p.mType == 3: #string can't be an array
try:
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
value = _convert_assimp_string(cast(p.mData, POINTER(structs.MaterialPropertyString)).contents)
elif p.mType == 4:
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):
"""
See 'aiVector2D.h' for details.
See 'vector2.h' for details.
"""
@ -15,7 +15,7 @@ class Vector2D(Structure):
class Matrix3x3(Structure):
"""
See 'aiMatrix3x3.h' for details.
See 'matrix3x3.h' for details.
"""
@ -27,7 +27,7 @@ class Matrix3x3(Structure):
class Texel(Structure):
"""
See 'aiTexture.h' for details.
See 'texture.h' for details.
"""
_fields_ = [
@ -36,7 +36,7 @@ class Texel(Structure):
class Color4D(Structure):
"""
See 'aiColor4D.h' for details.
See 'color4.h' for details.
"""
@ -47,7 +47,7 @@ class Color4D(Structure):
class Plane(Structure):
"""
See 'aiTypes.h' for details.
See 'types.h' for details.
"""
_fields_ = [
@ -57,7 +57,7 @@ class Plane(Structure):
class Color3D(Structure):
"""
See 'aiTypes.h' for details.
See 'types.h' for details.
"""
_fields_ = [
@ -67,7 +67,7 @@ class Color3D(Structure):
class String(Structure):
"""
See 'aiTypes.h' for details.
See 'types.h' for details.
"""
MAXLEN = 1024
@ -84,7 +84,7 @@ class String(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
material property (see MaterialSystem.cpp aiMaterial::AddProperty() for details).
@ -104,7 +104,7 @@ class MaterialPropertyString(Structure):
class MemoryInfo(Structure):
"""
See 'aiTypes.h' for details.
See 'types.h' for details.
"""
_fields_ = [
@ -135,7 +135,7 @@ class MemoryInfo(Structure):
class Quaternion(Structure):
"""
See 'aiQuaternion.h' for details.
See 'quaternion.h' for details.
"""
@ -146,7 +146,7 @@ class Quaternion(Structure):
class Face(Structure):
"""
See 'aiMesh.h' for details.
See 'mesh.h' for details.
"""
_fields_ = [
@ -161,7 +161,7 @@ class Face(Structure):
class VertexWeight(Structure):
"""
See 'aiMesh.h' for details.
See 'mesh.h' for details.
"""
_fields_ = [
@ -175,7 +175,7 @@ class VertexWeight(Structure):
class Matrix4x4(Structure):
"""
See 'aiMatrix4x4.h' for details.
See 'matrix4x4.h' for details.
"""
@ -188,7 +188,7 @@ class Matrix4x4(Structure):
class Vector3D(Structure):
"""
See 'aiVector3D.h' for details.
See 'vector3.h' for details.
"""
@ -198,7 +198,7 @@ class Vector3D(Structure):
class MeshKey(Structure):
"""
See 'aiAnim.h' for details.
See 'anim.h' for details.
"""
_fields_ = [
@ -214,9 +214,44 @@ class MeshKey(Structure):
("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):
"""
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
("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):
"""
See 'aiLight.h' for details.
See 'light.h' for details.
"""
@ -283,6 +322,13 @@ class Light(Structure):
# may be normalized, but it needn't.
("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.
# The intensity of the light source at a given distance 'd' from
# the light's position is
@ -354,11 +400,14 @@ class Light(Structure):
# interpolation between the inner and the outer cone of the
# spot light.
("mAngleOuterCone", c_float),
# Size of area light source.
("mSize", Vector2D),
]
class Texture(Structure):
"""
See 'aiTexture.h' for details.
See 'texture.h' for details.
"""
@ -375,16 +424,25 @@ class Texture(Structure):
("mHeight", c_uint),
# A hint from the loader to make it easier for applications
# to determine the type of embedded compressed textures.
# If mHeight != 0 this member is undefined. Otherwise it
# is set set to '\\0\\0\\0\\0' if the loader has no additional
# to determine the type of embedded textures.
#
# 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
# file extension of the format without a trailing dot. If there
# are multiple file extensions for a format, the shortest
# extension is chosen (JPEG maps to 'jpg', not to 'jpeg').
# E.g. 'dds\\0', 'pcx\\0', 'jpg\\0'. All characters are lower-case.
# The fourth character will always be '\\0'.
("achFormatHint", c_char*4),
("achFormatHint", c_char*9),
# Data of the texture.
# Points to an array of mWidth
@ -395,11 +453,15 @@ class Texture(Structure):
# buffer of size mWidth containing the compressed texture
# data. Good luck, have fun!
("pcData", POINTER(Texel)),
# Texture original filename
# Used to get the texture reference
("mFilename", String),
]
class Ray(Structure):
"""
See 'aiTypes.h' for details.
See 'types.h' for details.
"""
_fields_ = [
@ -409,7 +471,7 @@ class Ray(Structure):
class UVTransform(Structure):
"""
See 'aiMaterial.h' for details.
See 'material.h' for details.
"""
_fields_ = [
@ -430,7 +492,7 @@ class UVTransform(Structure):
class MaterialProperty(Structure):
"""
See 'aiMaterial.h' for details.
See 'material.h' for details.
"""
_fields_ = [
@ -466,7 +528,7 @@ class MaterialProperty(Structure):
class Material(Structure):
"""
See 'aiMaterial.h' for details.
See 'material.h' for details.
"""
_fields_ = [
@ -482,7 +544,7 @@ class Material(Structure):
class Bone(Structure):
"""
See 'aiMesh.h' for details.
See 'mesh.h' for details.
"""
_fields_ = [
@ -501,20 +563,66 @@ class Bone(Structure):
("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_BONE_WEIGHTS = 0x7fffffff
AI_MAX_VERTICES = 0x7fffffff
AI_MAX_FACES = 0x7fffffff
AI_MAX_NUMBER_OF_COLOR_SETS = 0x8
AI_MAX_NUMBER_OF_TEXTURECOORDS = 0x8
AI_MAX_NUMBER_OF_TEXTURECOORDS = 0x8
AI_MAX_NUMBER_OF_COLOR_SETS = 0x8
_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.
# This specifies which types of primitives are present in the mesh.
# 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.
("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),
# NOT CURRENTLY IN USE. Attachment meshes for this mesh, for vertex-based animation.
# Attachment meshes carry replacement data for some of the
# mesh'es vertex components (usually positions, normals).
# Attachment meshes for this mesh, for vertex-based animation.
# Attachment meshes carry replacement data for some of the
# 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):
"""
See 'aiCamera.h' for details.
See 'camera.h' for details.
"""
@ -707,7 +821,7 @@ class Camera(Structure):
class VectorKey(Structure):
"""
See 'aiAnim.h' for details.
See 'anim.h' for details.
"""
_fields_ = [
@ -720,7 +834,7 @@ class VectorKey(Structure):
class QuatKey(Structure):
"""
See 'aiAnim.h' for details.
See 'anim.h' for details.
"""
_fields_ = [
@ -731,9 +845,27 @@ class QuatKey(Structure):
("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):
"""
See 'aiAnim.h' for details.
See 'anim.h' for details.
"""
_fields_ = [
@ -782,9 +914,48 @@ class NodeAnim(Structure):
("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):
"""
See 'aiAnim.h' for details.
See 'anim.h' for details.
"""
_fields_ = [
@ -813,6 +984,16 @@ class Animation(Structure):
# The mesh animation channels. Each channel affects a single mesh.
# 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):
@ -820,11 +1001,12 @@ class Scene(Structure):
See 'aiScene.h' for details.
"""
AI_SCENE_FLAGS_INCOMPLETE = 0x1
AI_SCENE_FLAGS_VALIDATED = 0x2
AI_SCENE_FLAGS_VALIDATION_WARNING = 0x4
AI_SCENE_FLAGS_NON_VERBOSE_FORMAT = 0x8
AI_SCENE_FLAGS_TERRAIN = 0x10
AI_SCENE_FLAGS_INCOMPLETE = 0x1
AI_SCENE_FLAGS_VALIDATED = 0x2
AI_SCENE_FLAGS_VALIDATION_WARNING = 0x4
AI_SCENE_FLAGS_NON_VERBOSE_FORMAT = 0x8
AI_SCENE_FLAGS_TERRAIN = 0x10
AI_SCENE_FLAGS_ALLOW_SHARED = 0x20
_fields_ = [
# 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
# the scene.
("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,

File diff suppressed because it is too large Load Diff

View File

@ -40,8 +40,9 @@
cmake_minimum_required( VERSION 2.6 )
INCLUDE_DIRECTORIES(
../contrib/gtest/include
../contrib/gtest/
${Assimp_SOURCE_DIR}/contrib/gtest/include
${Assimp_SOURCE_DIR}/contrib/gtest/
${Assimp_SOURCE_DIR}/test/unit
${Assimp_SOURCE_DIR}/include
${Assimp_SOURCE_DIR}/code
)
@ -74,6 +75,7 @@ SET( COMMON
unit/utProfiler.cpp
unit/utSharedPPData.cpp
unit/utStringUtils.cpp
unit/Common/utLineSplitter.cpp
)
SET( IMPORTERS
@ -113,6 +115,8 @@ SET( IMPORTERS
unit/utColladaImportExport.cpp
unit/utCSMImportExport.cpp
unit/utB3DImportExport.cpp
unit/utMDCImportExport.cpp
unit/utAssbinImportExport.cpp
)
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);
}
// ------------------------------------------------------------------------------------------------
TEST_F(MaterialSystemTest, testDefaultMaterialAccess) {
aiMaterial *mat = aiCreateAndRegisterDefaultMaterial();
EXPECT_NE(nullptr, mat);
aiReleaseDefaultMaterial();
delete mat;
}
// ------------------------------------------------------------------------------------------------
TEST_F(MaterialSystemTest, testMaterialNameAccess) {
aiMaterial *mat = aiCreateAndRegisterDefaultMaterial();
aiMaterial *mat = new aiMaterial();
EXPECT_NE(nullptr, mat);
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));
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() );
}
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 ) {
Assimp::Importer importer;
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)
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)
IF(ASSIMP_QT4_VIEWER)
# Qt4 version
FIND_PACKAGE(Qt4 QUIET)
ELSE(ASSIMP_QT4_VIEWER)
# Qt5 version
FIND_PACKAGE(Qt5 COMPONENTS Gui Widgets OpenGL QUIET)
ENDIF(ASSIMP_QT4_VIEWER)
# Qt5 version
FIND_PACKAGE(Qt5 COMPONENTS Gui Widgets OpenGL QUIET)
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)
ELSE((Qt4_FOUND OR Qt5Widgets_FOUND) AND IL_FOUND AND OPENGL_FOUND)
ELSE( Qt5Widgets_FOUND AND OPENGL_FOUND)
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "")
IF(ASSIMP_QT4_VIEWER)
IF (NOT Qt4_FOUND)
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt4")
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 Qt5_FOUND)
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt5")
ENDIF (NOT Qt5_FOUND)
IF (NOT OPENGL_FOUND)
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} OpengGL")
ENDIF (NOT OPENGL_FOUND)
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)
INCLUDE_DIRECTORIES(
@ -63,28 +39,23 @@ IF(VIEWER_BUILD)
LINK_DIRECTORIES(${Assimp_BINARY_DIR})
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 Qt4")
ADD_DEFINITIONS( -DASSIMP_QT4_VIEWER )
INCLUDE_DIRECTORIES(${QT_INCLUDES})
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()
MESSAGE("assimp_qt_viewer use Qt5")
INCLUDE_DIRECTORIES(${Qt5Widgets_INCLUDES})
qt5_wrap_ui(UISrcs mainwindow.ui)
qt5_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp)
add_executable(${PROJECT_NAME} ${assimp_qt_viewer_SRCS} ${UISrcs} ${MOCrcs})
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()
target_link_libraries(${PROJECT_NAME} Qt5::Gui Qt5::Widgets Qt5::OpenGL ${IL_LIBRARIES} ${OPENGL_LIBRARIES} assimp)
IF(WIN32) # Check if we are on Windows
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
/// \date 2016
/*
---------------------------------------------------------------------------
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 "glview.hpp"
// Header files, Qt.
@ -16,40 +53,30 @@
#endif
// Header files, DevIL.
#include <il.h>
// Header files, Assimp.
#include <assimp/DefaultLogger.hpp>
#ifndef __unused
#define __unused __attribute__((unused))
#endif // __unused
/**********************************/
/********** SHelper_Mesh **********/
/**********************************/
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
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_Line = pQuantity_Line ? new GLuint[pQuantity_Line * 2] : nullptr;
Index_Triangle = pQuantity_Triangle ? new GLuint[pQuantity_Triangle * 3] : nullptr;
}
CGLView::SHelper_Mesh::~SHelper_Mesh()
{
if(Index_Point != nullptr) delete [] Index_Point;
if(Index_Line != nullptr) delete [] Index_Line;
if(Index_Triangle != nullptr) delete [] Index_Triangle;
CGLView::SHelper_Mesh::~SHelper_Mesh() {
delete [] Index_Point;
delete [] Index_Line;
delete [] Index_Triangle;
}
/**********************************/
/********** SHelper_Mesh **********/
/**********************************/
void CGLView::SHelper_Camera::SetDefault()
{
void CGLView::SHelper_Camera::SetDefault() {
Position.Set(0, 0, 0);
Target.Set(0, 0, -1);
Rotation_AroundCamera = aiMatrix4x4();
@ -57,39 +84,21 @@ void CGLView::SHelper_Camera::SetDefault()
Translation_ToScene.Set(0, 0, 2);
}
/**********************************/
/************ CGLView *************/
/**********************************/
static void 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;
}
#if !ASSIMP_QT4_VIEWER
# define ConditionalContextControl_Begin \
bool ContextEnabledHere; \
\
if(mGLContext_Current) \
{ \
ContextEnabledHere = false; \
} \
else \
{ \
makeCurrent(); \
mGLContext_Current = true; \
ContextEnabledHere = true; \
} \
\
do {} while(false)
static void 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;
}
# define ConditionalContextControl_End \
if(ContextEnabledHere) \
{ \
doneCurrent(); \
mGLContext_Current = false; \
} \
\
do {} while(false)
#endif // ASSIMP_QT4_VIEWER
void CGLView::Material_Apply(const aiMaterial* pMaterial)
{
void CGLView::Material_Apply(const aiMaterial* pMaterial) {
GLfloat tcol[4];
aiColor4D taicol;
unsigned int max;
@ -97,15 +106,12 @@ void CGLView::Material_Apply(const aiMaterial* pMaterial)
int texture_index = 0;
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
// Disable color material because glMaterial is used.
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
unsigned int texture_ID = mTexture_IDMap.value(texture_path.data, 0);
@ -116,20 +122,27 @@ void CGLView::Material_Apply(const aiMaterial* pMaterial)
//
// Diffuse
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);
// Specular
// Specular
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);
// Ambient
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);
// Emission
// Emission
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);
@ -142,12 +155,9 @@ void CGLView::Material_Apply(const aiMaterial* pMaterial)
// Shininess strength
max = 1;
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
}
else
{
} else {
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);///TODO: cache
set_float4(tcol, 0.0f, 0.0f, 0.0f, 0.0f);
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.
{
ILboolean success;
GLuint id_ogl_texture;// OpenGL texture ID.
if(!pFileName.startsWith(AI_EMBEDDED_TEXNAME_PREFIX))
{
ILuint id_image;// DevIL image ID.
QString basepath = pScenePath.left(pScenePath.lastIndexOf('/') + 1);// path with '/' at the end.
QString basepath = scenePath.left(scenePath.lastIndexOf('/') + 1);// path with '/' at the end.
QString fileloc = (basepath + pFileName);
fileloc.replace('\\', "/");
ilGenImages(1, &id_image);// Generate DevIL image ID.
ilBindImage(id_image);
success = ilLoadImage(fileloc.toLocal8Bit());
if(!success)
{
int x, y, n;
unsigned char *data = stbi_load(fileloc.toLocal8Bit(), &x, &y, &n, STBI_rgb_alpha );
if ( nullptr == data ) {
LogError(QString("Couldn't load Image: %1").arg(fileloc));
return false;
}
// 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.
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
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.
glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), 0,
ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData());// Texture specification.
glTexImage2D(GL_TEXTURE_2D, 0, n, x, y, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, data );// Texture specification.
//Cleanup
ilDeleteImages(1, &id_image);// Because we have already copied image data into texture data we can release memory used by image.
// Cleanup
}
else
{
@ -321,27 +317,18 @@ void CGLView::ImportTextures(const QString& pScenePath)
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.
//
// 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;
aiString path;
do
{
if(mScene->mMaterials[idx_material]->GetTexture(aiTextureType_DIFFUSE, idx_texture, &path) != AI_SUCCESS) break;
do {
if (mScene->mMaterials[ idx_material ]->GetTexture( aiTextureType_DIFFUSE, idx_texture, &path ) != AI_SUCCESS) {
break;
}
LoadTexture(QString(path.C_Str()));
idx_texture++;
@ -349,11 +336,8 @@ void CGLView::ImportTextures(const QString& pScenePath)
}// for(size_t idx_material = 0; idx_material < mScene->mNumMaterials; idx_material++)
// Textures list is empty, exit.
if(mTexture_IDMap.size() == 0)
{
if(mTexture_IDMap.empty()) {
LogInfo("No textures for import.");
return;
}
}
@ -451,32 +435,21 @@ void CGLView::BBox_GetFromVertices(const aiVector3D* pVertices, const size_t pVe
}
}
/********************************************************************/
/************************ Logging functions *************************/
/********************************************************************/
void CGLView::LogInfo(const QString& pMessage)
{
void CGLView::LogInfo(const QString& pMessage) {
Assimp::DefaultLogger::get()->info(pMessage.toStdString());
}
void CGLView::LogError(const QString& pMessage)
{
void CGLView::LogError(const QString& pMessage) {
Assimp::DefaultLogger::get()->error(pMessage.toStdString());
}
/********************************************************************/
/************************** Draw functions **************************/
/********************************************************************/
void CGLView::Draw_Node(const aiNode* pNode)
{
void CGLView::Draw_Node(const aiNode* pNode) {
aiMatrix4x4 mat_node = pNode->mTransformation;
// Apply node transformation matrix.
mat_node.Transpose();
glPushMatrix();
#if ASSIMP_DOUBLE_PRECISION
#ifdef ASSIMP_DOUBLE_PRECISION
glMultMatrixd((GLdouble*)mat_node[0]);
#else
glMultMatrixf((GLfloat*)&mat_node);
@ -518,7 +491,7 @@ void CGLView::Draw_Mesh(const size_t pMesh_Index)
{
glEnable(GL_COLOR_MATERIAL);///TODO: cache
glEnableClientState(GL_COLOR_ARRAY);
#if ASSIMP_DOUBLE_PRECISION
#ifdef ASSIMP_DOUBLE_PRECISION
glColorPointer(4, GL_DOUBLE, 0, mesh_cur.mColors[0]);
#else
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))
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
#if ASSIMP_DOUBLE_PRECISION
#ifdef ASSIMP_DOUBLE_PRECISION
glTexCoordPointer(2, GL_DOUBLE, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]);
#else
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())
{
glEnableClientState(GL_NORMAL_ARRAY);
#if ASSIMP_DOUBLE_PRECISION
#ifdef ASSIMP_DOUBLE_PRECISION
glNormalPointer(GL_DOUBLE, 0, mesh_cur.mNormals);
#else
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_2D, 0);
glBindTexture(GL_TEXTURE_3D, 0);
#if ASSIMP_QT4_VIEWER
qglColor(QColor(Qt::white));
#else
const QColor c_w(Qt::white);
glColor3f(c_w.redF(), c_w.greenF(), c_w.blueF());
#endif // ASSIMP_QT4_VIEWER
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[4][0]), glVertex3dv(&vertex[5][0]), glVertex3dv(&vertex[6][0]), glVertex3dv(&vertex[7][0]), glVertex3dv(&vertex[4][0]);// Edge and "maximum" side.
# else
@ -600,7 +569,7 @@ void CGLView::Draw_BBox(const SBBox& pBBox)
glEnd();
glBegin(GL_LINES);
# if ASSIMP_DOUBLE_PRECISION
# ifdef ASSIMP_DOUBLE_PRECISION
glVertex3dv(&vertex[1][0]), glVertex3dv(&vertex[5][0]);
glVertex3dv(&vertex[2][0]), glVertex3dv(&vertex[6][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)
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
if(pEnable)
{
void CGLView::Enable_Textures(const bool pEnable) {
if(pEnable) {
glEnable(GL_TEXTURE_1D);
glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_3D);
}
else
{
} else {
glDisable(GL_TEXTURE_1D);
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_3D);
}
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
}
/********************************************************************/
/*********************** Override functions ************************/
/********************************************************************/
void CGLView::initializeGL()
{
#if ASSIMP_QT4_VIEWER
qglClearColor(Qt::gray);
#else
void CGLView::initializeGL() {
mGLContext_Current = true;
initializeOpenGLFunctions();
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
#endif // ASSIMP_QT4_VIEWER
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glEnable(GL_TEXTURE_2D);
glEnable( GL_MULTISAMPLE );
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
@ -668,25 +617,14 @@ void CGLView::initializeGL()
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
#if !ASSIMP_QT4_VIEWER
mGLContext_Current = false;
#endif // ASSIMP_QT4_VIEWER
}
void CGLView::resizeGL(int pWidth, int pHeight)
{
#if !ASSIMP_QT4_VIEWER
mGLContext_Current = true;
#endif // ASSIMP_QT4_VIEWER
mCamera_Viewport_AspectRatio = (GLdouble)pWidth / pHeight;
glViewport(0, 0, pWidth, pHeight);
void CGLView::resizeGL(int width, int height) {
mCamera_Viewport_AspectRatio = (GLdouble)width / height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
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() {
@ -699,19 +637,8 @@ void CGLView::drawCoordSystem() {
glBindTexture(GL_TEXTURE_3D, 0);
glEnable(GL_COLOR_MATERIAL);
glBegin(GL_LINES);
#if ASSIMP_QT4_VIEWER
// 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
// X, -X
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);
// 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(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);
#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()
{
#if !ASSIMP_QT4_VIEWER
mGLContext_Current = true;
#endif // ASSIMP_QT4_VIEWER
void CGLView::paintGL() {
QTime time_paintbegin;
time_paintbegin = QTime::currentTime();
@ -741,6 +664,7 @@ void CGLView::paintGL()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Apply current camera transformations.
#if ASSIMP_DOUBLE_PRECISION
glMultMatrixd((GLdouble*)&mHelper_Camera.Rotation_AroundCamera);
@ -753,58 +677,38 @@ void CGLView::paintGL()
#endif // ASSIMP_DOUBLE_PRECISION
// Coordinate system
if (mScene_AxesEnabled == true)
{
if ( mScene_AxesEnabled ) {
drawCoordSystem();
}
glDisable(GL_COLOR_MATERIAL);
// Scene
if(mScene != nullptr)
{
// Scene
if(mScene != nullptr) {
Draw_Node(mScene->mRootNode);
// 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());
#if !ASSIMP_QT4_VIEWER
mGLContext_Current = false;
#endif // ASSIMP_QT4_VIEWER
emit Paint_Finished((size_t) time_paintbegin.msecsTo(QTime::currentTime()), mHelper_Camera.Translation_ToScene.Length());
}
/********************************************************************/
/********************** Constructor/Destructor **********************/
/********************************************************************/
CGLView::CGLView(QWidget *pParent)
#if ASSIMP_QT4_VIEWER
: QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer), pParent)
#else
: QOpenGLWidget(pParent), mGLContext_Current(false)
#endif // ASSIMP_QT4_VIEWER
{
// set initial view
mHelper_CameraDefault.SetDefault();
Camera_Set(0);
CGLView::CGLView( QWidget *pParent )
: QOpenGLWidget( pParent )
, mGLContext_Current( false ) {
// set initial view
mHelper_CameraDefault.SetDefault();
Camera_Set( 0 );
}
CGLView::~CGLView()
{
CGLView::~CGLView() {
FreeScene();
}
/********************************************************************/
/********************* Scene control functions **********************/
/********************************************************************/
void CGLView::FreeScene()
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
void CGLView::FreeScene() {
// Set scene to null and after that \ref paintGL will not try to render it.
mScene = nullptr;
// Clean helper objects.
@ -834,21 +738,14 @@ void CGLView::FreeScene()
mTexture_IDMap.clear();
delete [] id_tex;
}
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
}
void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath)
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
FreeScene();// Clear old data
void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath) {
FreeScene();// Clear old data
// 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.
@ -874,7 +771,7 @@ void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath)
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_l = 0;// lines quantity
@ -1039,7 +936,10 @@ void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath)
}// switch(light_cur.mType)
// 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);
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());
}
}// if(!mScene->HasCameras()) else
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
}
/********************************************************************/
/******************** Lighting control functions ********************/
/********************************************************************/
void CGLView::Lighting_Enable()
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
void CGLView::Lighting_Enable() {
mLightingEnabled = true;
glEnable(GL_LIGHTING);
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
}
void CGLView::Lighting_Disable()
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
glDisable(GL_LIGHTING);
void CGLView::Lighting_Disable() {
glDisable( GL_LIGHTING );
mLightingEnabled = false;
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
}
void CGLView::Lighting_EditSource(const size_t pLightNumber, const SLightParameters& pLightParameters)
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
const size_t light_num = GL_LIGHT0 + pLightNumber;
const size_t light_num = GL_LIGHT0 + pLightNumber;
GLfloat farr[4];
GLfloat farr[4];
if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value;
// 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);
// 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);
// 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);
// Other parameters
// Other parameters
switch(pLightParameters.Type)
{
case aiLightSource_DIRECTIONAL:
@ -1176,46 +1058,21 @@ GLfloat farr[4];
glLightf(light_num, GL_SPOT_CUTOFF, 180.0);
break;
}// switch(pLightParameters.Type)
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
}
void CGLView::Lighting_EnableSource(const size_t pLightNumber)
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
void CGLView::Lighting_EnableSource(const size_t pLightNumber) {
if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value;
glEnable(GL_LIGHT0 + pLightNumber);
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
}
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;
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)
{
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) {
auto deg2rad = [](const GLfloat pDegree) -> GLfloat {
return pDegree * AI_MATH_PI / 180.0;
return pDegree * AI_MATH_PI / 180.0f;
};
aiMatrix4x4 mat_rot;

View File

@ -1,7 +1,45 @@
/// \file glview.hpp
/// \brief OpenGL visualisation.
/// \author smal.root@gmail.com
/// \date 2016
/*
---------------------------------------------------------------------------
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.
---------------------------------------------------------------------------
*/
#pragma once

View File

@ -1,19 +1,64 @@
/// \file loggerview.cpp
/// \brief Stream for Assimp logging subsystem.
/// \author smal.root@gmail.com
/// \date 2016
/*
---------------------------------------------------------------------------
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 "loggerview.hpp"
// Header files, Qt.
#include <QTime>
#include <QTextBrowser>
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));
}

View File

@ -1,33 +1,67 @@
/// \file loggerview.hpp
/// \brief Stream for Assimp logging subsystem.
/// \author smal.root@gmail.com
/// \date 2016
/*
---------------------------------------------------------------------------
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.
---------------------------------------------------------------------------
*/
#pragma once
// Header files, Qt.
#include <QTextBrowser>
// Header files, Assimp.
#include <assimp/DefaultLogger.hpp>
/// \class CLoggerView
/// 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 QTextBrowser;
/// @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:
/// @brief The class constructor.
/// @param [in] pOutputWidget - pointer to output widget.
explicit CLoggerView( QTextBrowser* pOutputWidget );
/// \fn explicit CLoggerView(QTextBrowser* pOutputWidget)
/// Constructor.
/// \param [in] pOutputWidget - pointer to output widget.
explicit CLoggerView(QTextBrowser* pOutputWidget);
/// @brief The class destructor.
virtual ~CLoggerView();
/// \fn virtual void write(const char *pMessage)
/// Write message to output widget. Used by Assimp.
/// \param [in] pMessage - message for displaying.
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
/// \date 2016
/*
---------------------------------------------------------------------------
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.
---------------------------------------------------------------------------
*/
// Thanks to acorn89 for support.
// Header files, project.
@ -11,9 +50,9 @@
#include <QApplication>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow w;
w.show();
QApplication app(argc, argv);
MainWindow win;
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
/// \date 2016
/*
---------------------------------------------------------------------------
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 "mainwindow.hpp"
#include "ui_mainwindow.h"
@ -14,22 +52,13 @@
#define __unused __attribute__((unused))
#endif // __unused
/**********************************/
/************ Functions ***********/
/**********************************/
/********************************************************************/
/********************* Import/Export functions **********************/
/********************************************************************/
void MainWindow::ImportFile(const QString &pFileName)
{
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();
mGLView->FreeScene();
}
@ -37,8 +66,7 @@ QTime time_begin = QTime::currentTime();
// Try to import scene.
mScene = mImporter.ReadFile(pFileName.toStdString(), aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_ValidateDataStructure | \
aiProcess_GenUVCoords | aiProcess_TransformUVCoords | aiProcess_FlipUVs);
if(mScene != nullptr)
{
if ( mScene != nullptr ) {
ui->lblLoadTime->setText(QString::number(time_begin.secsTo(QTime::currentTime())));
LogInfo("Import done: " + pFileName);
// Prepare widgets for new scene.
@ -60,8 +88,7 @@ QTime time_begin = QTime::currentTime();
size_t qty_face = 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_vert += mScene->mMeshes[idx_mesh]->mNumVertices;
}
@ -241,7 +268,6 @@ MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow),
mScene(nullptr)
{
using namespace Assimp;
// other variables
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
/// \date 2016
/*
---------------------------------------------------------------------------
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.
---------------------------------------------------------------------------
*/
#pragma once
@ -20,125 +58,64 @@
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
namespace Ui { class MainWindow; }
namespace Ui {
class MainWindow;
}
/// \class MainWindow
/// Main window and algorhytms.
class MainWindow : public QMainWindow
{
Q_OBJECT
/// Main window and algorithms.
class MainWindow : public QMainWindow {
Q_OBJECT
/**********************************/
/************ Variables ***********/
/**********************************/
struct SMouse_Transformation;
private:
public:
/// @brief The class constructor.
/// \param [in] pParent - pointer to parent widget.
explicit MainWindow( QWidget* pParent = 0 );
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;
/**********************************/
/************ Functions ***********/
/**********************************/
/********************************************************************/
/********************* Import/Export functions **********************/
/********************************************************************/
/// \fn void ImportFile(const QString& pFileName)
/// Import scene from file.
/// @brief The class destructor.
~MainWindow();
/// Import scene from file.
/// \param [in] pFileName - path and name of the file.
void ImportFile(const QString& pFileName);
/// \fn void ResetSceneInfos()
/// Reset informations about the scene
void ResetSceneInfos();
/********************************************************************/
/************************ Logging functions *************************/
/********************************************************************/
/// \fn void LogInfo(const QString& pMessage)
/// Add message with severity "Warning" to log.
void LogInfo(const QString& pMessage);
/// \fn void LogError(const QString& pMessage)
/// Add message with severity "Error" to log.
void LogError(const QString& pMessage);
/********************************************************************/
/*********************** Override functions ************************/
/********************************************************************/
protected:
/// \fn void mousePressEvent(QMouseEvent* pEvent) override
/// Override function which handles mouse event "button pressed".
/// \param [in] pEvent - pointer to event data.
void mousePressEvent(QMouseEvent* pEvent) override;
/// \fn void mouseReleaseEvent(QMouseEvent *pEvent) override
/// Override function which handles mouse event "button released".
/// \param [in] pEvent - pointer to event data.
void mouseReleaseEvent(QMouseEvent *pEvent) override;
/// \fn void mouseMoveEvent(QMouseEvent* pEvent) override
/// Override function which handles mouse event "move".
/// \param [in] pEvent - pointer to event data.
void mouseMoveEvent(QMouseEvent* pEvent) override;
/// \fn void keyPressEvent(QKeyEvent* pEvent) override
/// Override function which handles key event "key pressed".
/// \param [in] pEvent - pointer to event data.
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:
/// \fn void Paint_Finished(const int pPaintTime)
/// Show paint/render time and distance between camera and center of the scene.
/// \param [in] pPaintTime_ms - paint time in milliseconds.
void Paint_Finished(const size_t pPaintTime_ms, const GLfloat pDistance);
/// \fn void SceneObject_Camera(const QString& pName)
/// Add camera name to list.
/// \param [in] pName - name of the camera.
void SceneObject_Camera(const QString& pName);
/// \fn void SceneObject_LightSource(const QString& pName)
/// Add lighting source name to list.
/// \param [in] pName - name of the light source,
void SceneObject_LightSource(const QString& pName);
@ -151,4 +128,21 @@ private slots:
void on_cbxBBox_clicked(bool checked);
void on_cbxTextures_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