From 61419cc0aeca872a8b246d1727dfe563d9e8d643 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Mon, 19 Sep 2016 21:35:45 +0200 Subject: [PATCH] Unittest: add first approach for modeldiffer. --- include/assimp/anim.h | 2 - include/assimp/scene.h | 47 ++++----- test/unit/ModelDiffer.cpp | 254 ++++++++++++++++++++++++++++++++++++++++++++++ test/unit/ModelDiffer.h | 65 ++++++++++++ 4 files changed, 339 insertions(+), 29 deletions(-) create mode 100644 test/unit/ModelDiffer.cpp create mode 100644 test/unit/ModelDiffer.h diff --git a/include/assimp/anim.h b/include/assimp/anim.h index e2961a6..6380b46 100644 --- a/include/assimp/anim.h +++ b/include/assimp/anim.h @@ -255,7 +255,6 @@ struct aiNodeAnim * scaling and one position key. */ C_STRUCT aiQuatKey* mRotationKeys; - /** The number of scaling keys */ unsigned int mNumScalingKeys; @@ -266,7 +265,6 @@ struct aiNodeAnim * position and one rotation key.*/ C_STRUCT aiVectorKey* mScalingKeys; - /** Defines how the animation behaves before the first * key is encountered. * diff --git a/include/assimp/scene.h b/include/assimp/scene.h index 31bb8b6..398f712 100644 --- a/include/assimp/scene.h +++ b/include/assimp/scene.h @@ -60,9 +60,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. extern "C" { #endif - // ------------------------------------------------------------------------------- -/** A node in the imported hierarchy. +/** + * A node in the imported hierarchy. * * Each node has name, a parent node (except for the root node), * a transformation relative to its parent and possibly several child nodes. @@ -278,7 +278,6 @@ struct aiNode // ------------------------------------------------------------------------------- struct aiScene { - /** Any combination of the AI_SCENE_FLAGS_XXX flags. By default * this value is 0, no flags are set. Most applications will * want to reject all scenes with the AI_SCENE_FLAGS_INCOMPLETE @@ -286,7 +285,6 @@ struct aiScene */ unsigned int mFlags; - /** The root node of the hierarchy. * * There will always be at least the root node if the import @@ -296,8 +294,6 @@ struct aiScene */ C_STRUCT aiNode* mRootNode; - - /** The number of meshes in the scene. */ unsigned int mNumMeshes; @@ -310,8 +306,6 @@ struct aiScene */ C_STRUCT aiMesh** mMeshes; - - /** The number of materials in the scene. */ unsigned int mNumMaterials; @@ -324,8 +318,6 @@ struct aiScene */ C_STRUCT aiMaterial** mMaterials; - - /** The number of animations in the scene. */ unsigned int mNumAnimations; @@ -336,8 +328,6 @@ struct aiScene */ C_STRUCT aiAnimation** mAnimations; - - /** The number of textures embedded into the file */ unsigned int mNumTextures; @@ -349,7 +339,6 @@ struct aiScene */ C_STRUCT aiTexture** mTextures; - /** The number of light sources in the scene. Light sources * are fully optional, in most cases this attribute will be 0 */ @@ -362,7 +351,6 @@ struct aiScene */ C_STRUCT aiLight** mLights; - /** The number of cameras in the scene. Cameras * are fully optional, in most cases this attribute will be 0 */ @@ -387,33 +375,38 @@ struct aiScene //! Check whether the scene contains meshes //! Unless no special scene flags are set this will always be true. - inline bool HasMeshes() const - { return mMeshes != NULL && mNumMeshes > 0; } + inline bool HasMeshes() const { + return mMeshes != NULL && mNumMeshes > 0; + } //! Check whether the scene contains materials //! Unless no special scene flags are set this will always be true. - inline bool HasMaterials() const - { return mMaterials != NULL && mNumMaterials > 0; } + inline bool HasMaterials() const { + return mMaterials != NULL && mNumMaterials > 0; + } //! Check whether the scene contains lights - inline bool HasLights() const - { return mLights != NULL && mNumLights > 0; } + inline bool HasLights() const { + return mLights != NULL && mNumLights > 0; + } //! Check whether the scene contains textures - inline bool HasTextures() const - { return mTextures != NULL && mNumTextures > 0; } + inline bool HasTextures() const { + return mTextures != NULL && mNumTextures > 0; + } //! Check whether the scene contains cameras - inline bool HasCameras() const - { return mCameras != NULL && mNumCameras > 0; } + inline bool HasCameras() const { + return mCameras != NULL && mNumCameras > 0; + } //! Check whether the scene contains animations - inline bool HasAnimations() const - { return mAnimations != NULL && mNumAnimations > 0; } + inline bool HasAnimations() const { + return mAnimations != NULL && mNumAnimations > 0; + } #endif // __cplusplus - /** Internal data, do not touch */ #ifdef __cplusplus void* mPrivate; diff --git a/test/unit/ModelDiffer.cpp b/test/unit/ModelDiffer.cpp new file mode 100644 index 0000000..8234643 --- /dev/null +++ b/test/unit/ModelDiffer.cpp @@ -0,0 +1,254 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2016, 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 "ModelDiffer.h" +#include +#include + +using namespace Assimp; + +ModelDiffer::ModelDiffer() { + // empty +} + +ModelDiffer::~ModelDiffer() { + // empty +} + +bool ModelDiffer::isEqual( aiScene *expected, aiScene *toCompare ) { + if ( expected == toCompare ) { + return true; + } + + if ( nullptr == expected ) { + return false; + } + + if ( nullptr == toCompare ) { + return false; + } + + if ( expected->mNumMeshes != toCompare->mNumMeshes ) { + std::stringstream stream; + stream << "Number of meshes not equal ( expected: " << expected->mNumMeshes << ", found : " << toCompare->mNumMeshes << " )\n"; + addDiff( stream.str() ); + } + + for ( unsigned int i = 0; i < expected->mNumMeshes; i++ ) { + aiMesh *expMesh( expected->mMeshes[ i ] ); + aiMesh *toCompMesh( toCompare->mMeshes[ i ] ); + compareMesh( expMesh, toCompMesh ); + } +} + +void ModelDiffer::showReport() { + if ( m_diffs.empty() ) { + return; + } + + for ( std::vector::iterator it = m_diffs.begin(); it != m_diffs.end(); it++ ) { + std::cout << *it << "\n"; + } + + std::cout << std::endl; +} + +void ModelDiffer::reset() { + m_diffs.resize( 0 ); +} + +void ModelDiffer::addDiff( const std::string &diff ) { + if ( diff.empty() ) { + return; + } + m_diffs.push_back( diff ); +} + +static std::string dumpVector3( const aiVector3D &toDump ) { + std::stringstream stream; + stream << "( " << toDump.x << ", " << toDump.y << ", " << toDump.z << ")"; + return stream.str(); +} + +static std::string dumpColor4D( const aiColor4D &toDump ) { + std::stringstream stream; + stream << "( " << toDump.r << ", " << toDump.g << ", " << toDump.b << ", " << toDump.a << ")"; + return stream.str(); +} + +bool ModelDiffer::compareMesh( aiMesh *expected, aiMesh *toCompare ) { + if ( expected == toCompare ) { + return true; + } + + if ( nullptr == expected || nullptr == toCompare ) { + return false; + } + + if ( expected->mName != toCompare->mName ) { + std::stringstream stream; + stream << "Mesh name not equal ( expected: " << expected->mName.C_Str() << ", found : " << toCompare->mName.C_Str() << " )\n"; + addDiff( stream.str() ); + } + + if ( expected->mNumVertices != toCompare->mNumVertices ) { + std::stringstream stream; + stream << "Number of vertices not equal ( expected: " << expected->mNumVertices << ", found : " << toCompare->mNumVertices << " )\n"; + addDiff( stream.str() ); + return false; + } + + // positions + if ( expected->HasPositions() != toCompare->HasPositions() ) { + addDiff( "Expected are vertices, toCompare does not have any." ); + return false; + } + + bool vertEqual( true ); + for ( unsigned int i = 0; i < expected->mNumVertices; i++ ) { + aiVector3D &expVert( expected->mVertices[ i ] ); + aiVector3D &toCompVert( toCompare->mVertices[ i ] ); + if ( expVert != toCompVert ) { + std::stringstream stream; + stream << "Vertex not equal ( expected: " << dumpVector3( expVert ) << ", found: " << dumpVector3( toCompVert ) << "\n"; + addDiff( stream.str() ); + vertEqual = false; + } + } + if ( !vertEqual ) { + return false; + } + + // normals + if ( expected->HasNormals() != toCompare->HasNormals() ) { + addDiff( "Expected are normals, toCompare does not have any." ); + return false; + } + + bool normalEqual( true ); + for ( unsigned int i = 0; i < expected->mNumVertices; i++ ) { + aiVector3D &expNormal( expected->mNormals[ i ] ); + aiVector3D &toCompNormal( toCompare->mNormals[ i ] ); + if ( expNormal != toCompNormal ) { + std::stringstream stream; + stream << "Normal not equal ( expected: " << dumpVector3( expNormal ) << ", found: " << dumpVector3( toCompNormal ) << "\n"; + addDiff( stream.str() ); + normalEqual = false; + } + } + if ( !normalEqual ) { + return false; + } + + // vertex colors + bool vertColEqual( true ); + for ( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++ ) { + if ( expected->HasVertexColors(a) != toCompare->HasVertexColors(a) ) { + addDiff( "Expected are normals, toCompare does not have any." ); + return false; + } + for ( unsigned int i = 0; i < expected->mNumVertices; i++ ) { + aiColor4D &expColor4D( expected->mColors[ a ][ i ] ); + aiColor4D &toCompColor4D( toCompare->mColors[ a ][ i ] ); + if ( expColor4D != toCompColor4D ) { + std::stringstream stream; + stream << "Color4D not equal ( expected: " << dumpColor4D( expColor4D ) << ", found: " << dumpColor4D( toCompColor4D ) << "\n"; + addDiff( stream.str() ); + vertColEqual = false; + } + } + if ( !vertColEqual ) { + return false; + } + } + + // texture coords + bool texCoordsEqual( true ); + for ( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++ ) { + if ( expected->HasTextureCoords( a ) != toCompare->HasTextureCoords( a ) ) { + addDiff( "Expected are texture coords, toCompare does not have any." ); + return false; + } + for ( unsigned int i = 0; i < expected->mNumVertices; i++ ) { + aiVector3D &expTexCoord( expected->mTextureCoords[ a ][ i ] ); + aiVector3D &toCompTexCoord( toCompare->mTextureCoords[ a ][ i ] ); + if ( expTexCoord != toCompTexCoord ) { + std::stringstream stream; + stream << "Texture coords not equal ( expected: " << dumpVector3( expTexCoord ) << ", found: " << dumpVector3( toCompTexCoord ) << "\n"; + addDiff( stream.str() ); + vertColEqual = false; + } + } + if ( !vertColEqual ) { + return false; + } + } + + // tangents and bi-tangents + if ( expected->HasTangentsAndBitangents() != toCompare->HasTangentsAndBitangents() ) { + addDiff( "Expected are tangents and bi-tangents, toCompare does not have any." ); + return false; + } + bool tangentsEqual( true ); + for ( unsigned int i = 0; i < expected->mNumVertices; i++ ) { + aiVector3D &expTangents( expected->mTangents[ i ] ); + aiVector3D &toCompTangents( toCompare->mTangents[ i ] ); + if ( expTangents != toCompTangents ) { + std::stringstream stream; + stream << "Tangents not equal ( expected: " << dumpVector3( expTangents ) << ", found: " << dumpVector3( toCompTangents ) << "\n"; + addDiff( stream.str() ); + tangentsEqual = false; + } + + aiVector3D &expBiTangents( expected->mBitangents[ i ] ); + aiVector3D &toCompBiTangents( toCompare->mBitangents[ i ] ); + if ( expBiTangents != toCompBiTangents ) { + std::stringstream stream; + stream << "Tangents not equal ( expected: " << dumpVector3( expBiTangents ) << ", found: " << dumpVector3( toCompBiTangents ) << "\n"; + addDiff( stream.str() ); + tangentsEqual = false; + } + } + if ( !tangentsEqual ) { + return false; + } + + return true; +} diff --git a/test/unit/ModelDiffer.h b/test/unit/ModelDiffer.h new file mode 100644 index 0000000..03c4462 --- /dev/null +++ b/test/unit/ModelDiffer.h @@ -0,0 +1,65 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2016, 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 + +#include "UnitTestPCH.h" +#include +#include +#include + +struct aiScene; +struct aiMesh; + +class ModelDiffer { +public: + ModelDiffer(); + ~ModelDiffer(); + bool isEqual( aiScene *expected, aiScene *toCompare ); + void showReport(); + void reset(); + +private: + void addDiff( const std::string &diff ); + bool compareMesh( aiMesh *expected, aiMesh *toCompare ); + +private: + std::vector m_diffs; +}; -- 2.7.4