From 80dffb63e86733b43530b7a52bb49a1ae6987d2f Mon Sep 17 00:00:00 2001 From: Charlie Gettys Date: Sat, 9 Mar 2019 12:01:45 -0500 Subject: [PATCH 01/16] Add aiNode::mName to ValidateDataStructure error reporting to ease debugging --- code/ValidateDataStructure.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/code/ValidateDataStructure.cpp b/code/ValidateDataStructure.cpp index 405670bdd..5a80f73c9 100644 --- a/code/ValidateDataStructure.cpp +++ b/code/ValidateDataStructure.cpp @@ -905,19 +905,22 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation, // ------------------------------------------------------------------------------------------------ void ValidateDSProcess::Validate( const aiNode* pNode) { - if (!pNode)ReportError("A node of the scenegraph is NULL"); - if (pNode != mScene->mRootNode && !pNode->mParent) - this->ReportError("A node has no valid parent (aiNode::mParent is NULL)"); - + if (!pNode) { + ReportError("A node of the scenegraph is NULL"); + } + // Validate node name string first so that it's safe to use in below expressions this->Validate(&pNode->mName); + if (pNode != mScene->mRootNode && !pNode->mParent){ + this->ReportError("Non-root node %s lacks a valid parent (aiNode::mParent is NULL) ",pNode->mName); + } // validate all meshes if (pNode->mNumMeshes) { if (!pNode->mMeshes) { - ReportError("aiNode::mMeshes is NULL (aiNode::mNumMeshes is %i)", - pNode->mNumMeshes); + ReportError("aiNode::mMeshes is NULL for node %s (aiNode::mNumMeshes is %i)", + pNode->mNumMeshes, pNode->mName); } std::vector abHadMesh; abHadMesh.resize(mScene->mNumMeshes,false); @@ -925,13 +928,13 @@ void ValidateDSProcess::Validate( const aiNode* pNode) { if (pNode->mMeshes[i] >= mScene->mNumMeshes) { - ReportError("aiNode::mMeshes[%i] is out of range (maximum is %i)", - pNode->mMeshes[i],mScene->mNumMeshes-1); + ReportError("aiNode::mMeshes[%i] is out of range for node %s (maximum is %i)", + pNode->mMeshes[i], pNode->mName, mScene->mNumMeshes-1); } if (abHadMesh[pNode->mMeshes[i]]) { - ReportError("aiNode::mMeshes[%i] is already referenced by this node (value: %i)", - i,pNode->mMeshes[i]); + ReportError("aiNode::mMeshes[%i] is already referenced by this node %s (value: %i)", + i, pNode->mName, pNode->mMeshes[i]); } abHadMesh[pNode->mMeshes[i]] = true; } @@ -939,8 +942,8 @@ void ValidateDSProcess::Validate( const aiNode* pNode) if (pNode->mNumChildren) { if (!pNode->mChildren) { - ReportError("aiNode::mChildren is NULL (aiNode::mNumChildren is %i)", - pNode->mNumChildren); + ReportError("aiNode::mChildren is NULL for node %s (aiNode::mNumChildren is %i)", + pNode->mName, pNode->mNumChildren); } for (unsigned int i = 0; i < pNode->mNumChildren;++i) { Validate(pNode->mChildren[i]); From 2e262dbbc601e4fec6798aeced0140c7aeece4fb Mon Sep 17 00:00:00 2001 From: Charlie Gettys Date: Sat, 9 Mar 2019 12:36:21 -0500 Subject: [PATCH 02/16] Make syntax used to call ReportError & ReportWarning a bit more consistent --- code/ValidateDataStructure.cpp | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/code/ValidateDataStructure.cpp b/code/ValidateDataStructure.cpp index 5a80f73c9..0a6b0b2ac 100644 --- a/code/ValidateDataStructure.cpp +++ b/code/ValidateDataStructure.cpp @@ -170,7 +170,7 @@ inline void ValidateDSProcess::DoValidationEx(T** parray, unsigned int size, { if (parray[i]->mName == parray[a]->mName) { - this->ReportError("aiScene::%s[%i] has the same name as " + ReportError("aiScene::%s[%i] has the same name as " "aiScene::%s[%i]",firstName, i,secondName, a); } } @@ -422,7 +422,9 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh) if (!abRefList[i])b = true; } abRefList.clear(); - if (b)ReportWarning("There are unreferenced vertices"); + if (b) { + ReportWarning("There are unreferenced vertices"); + } // texture channel 2 may not be set if channel 1 is zero ... { @@ -557,7 +559,9 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation) Validate(pAnimation, pAnimation->mChannels[i]); } } - else ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there."); + else { + ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there."); + } // Animation duration is allowed to be zero in cases where the anim contains only a single key frame. // if (!pAnimation->mDuration)this->ReportError("aiAnimation::mDuration is zero"); @@ -773,8 +777,10 @@ void ValidateDSProcess::Validate( const aiTexture* pTexture) } if (pTexture->mHeight) { - if (!pTexture->mWidth)ReportError("aiTexture::mWidth is zero " - "(aiTexture::mHeight is %i, uncompressed texture)",pTexture->mHeight); + if (!pTexture->mWidth){ + ReportError("aiTexture::mWidth is zero (aiTexture::mHeight is %i, uncompressed texture)", + pTexture->mHeight); + } } else { @@ -813,7 +819,7 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation, { if (!pNodeAnim->mPositionKeys) { - this->ReportError("aiNodeAnim::mPositionKeys is NULL (aiNodeAnim::mNumPositionKeys is %i)", + ReportError("aiNodeAnim::mPositionKeys is NULL (aiNodeAnim::mNumPositionKeys is %i)", pNodeAnim->mNumPositionKeys); } double dLast = -10e10; @@ -844,7 +850,7 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation, { if (!pNodeAnim->mRotationKeys) { - this->ReportError("aiNodeAnim::mRotationKeys is NULL (aiNodeAnim::mNumRotationKeys is %i)", + ReportError("aiNodeAnim::mRotationKeys is NULL (aiNodeAnim::mNumRotationKeys is %i)", pNodeAnim->mNumRotationKeys); } double dLast = -10e10; @@ -911,7 +917,7 @@ void ValidateDSProcess::Validate( const aiNode* pNode) // Validate node name string first so that it's safe to use in below expressions this->Validate(&pNode->mName); if (pNode != mScene->mRootNode && !pNode->mParent){ - this->ReportError("Non-root node %s lacks a valid parent (aiNode::mParent is NULL) ",pNode->mName); + ReportError("Non-root node %s lacks a valid parent (aiNode::mParent is NULL) ",pNode->mName); } // validate all meshes @@ -956,7 +962,7 @@ void ValidateDSProcess::Validate( const aiString* pString) { if (pString->length > MAXLEN) { - this->ReportError("aiString::length is too large (%i, maximum is %lu)", + ReportError("aiString::length is too large (%i, maximum is %lu)", pString->length,MAXLEN); } const char* sz = pString->data; @@ -964,12 +970,14 @@ void ValidateDSProcess::Validate( const aiString* pString) { if ('\0' == *sz) { - if (pString->length != (unsigned int)(sz-pString->data)) + if (pString->length != (unsigned int)(sz-pString->data)) { ReportError("aiString::data is invalid: the terminal zero is at a wrong offset"); + } break; } - else if (sz >= &pString->data[MAXLEN]) + else if (sz >= &pString->data[MAXLEN]) { ReportError("aiString::data is invalid. There is no terminal character"); + } ++sz; } } From 925ac6b3723ba520c32657e3d31c5e0e82362ad4 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sun, 10 Mar 2019 11:17:52 +0100 Subject: [PATCH 03/16] Typo Fix a typo in a comment. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6417053ac..a6e511b66 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -157,7 +157,7 @@ SET (PROJECT_VERSION "${ASSIMP_VERSION}") SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" ) -# Enable C++1 globally +# Enable C++11 support globally set_property( GLOBAL PROPERTY CXX_STANDARD 11 ) IF(NOT IGNORE_GIT_HASH) From 7bb130377395a5f270618538d36690defba30d2f Mon Sep 17 00:00:00 2001 From: Charlie Gettys Date: Sun, 10 Mar 2019 13:12:56 -0400 Subject: [PATCH 04/16] ValidateDataStructure.cpp: * Fixed warnings introduced by last commit (hopefully) * Fixed case fallthrough (due to exception flow, it didn't make a practical difference, but hopefully will remove a warning) * Minor formatting consistency improvements --- code/ValidateDataStructure.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/code/ValidateDataStructure.cpp b/code/ValidateDataStructure.cpp index 0a6b0b2ac..e73d1cca4 100644 --- a/code/ValidateDataStructure.cpp +++ b/code/ValidateDataStructure.cpp @@ -330,6 +330,7 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh) { case 0: ReportError("aiMesh::mFaces[%i].mNumIndices is 0",i); + break; case 1: if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POINT)) { @@ -811,9 +812,9 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation, { Validate(&pNodeAnim->mNodeName); - if (!pNodeAnim->mNumPositionKeys && !pNodeAnim->mScalingKeys && !pNodeAnim->mNumRotationKeys) + if (!pNodeAnim->mNumPositionKeys && !pNodeAnim->mScalingKeys && !pNodeAnim->mNumRotationKeys) { ReportError("Empty node animation channel"); - + } // otherwise check whether one of the keys exceeds the total duration of the animation if (pNodeAnim->mNumPositionKeys) { @@ -916,8 +917,9 @@ void ValidateDSProcess::Validate( const aiNode* pNode) } // Validate node name string first so that it's safe to use in below expressions this->Validate(&pNode->mName); + const char* nodeName = (&pNode->mName)->C_Str(); if (pNode != mScene->mRootNode && !pNode->mParent){ - ReportError("Non-root node %s lacks a valid parent (aiNode::mParent is NULL) ",pNode->mName); + ReportError("Non-root node %s lacks a valid parent (aiNode::mParent is NULL) ", nodeName); } // validate all meshes @@ -926,7 +928,7 @@ void ValidateDSProcess::Validate( const aiNode* pNode) if (!pNode->mMeshes) { ReportError("aiNode::mMeshes is NULL for node %s (aiNode::mNumMeshes is %i)", - pNode->mNumMeshes, pNode->mName); + pNode->mNumMeshes, nodeName); } std::vector abHadMesh; abHadMesh.resize(mScene->mNumMeshes,false); @@ -935,12 +937,12 @@ void ValidateDSProcess::Validate( const aiNode* pNode) if (pNode->mMeshes[i] >= mScene->mNumMeshes) { ReportError("aiNode::mMeshes[%i] is out of range for node %s (maximum is %i)", - pNode->mMeshes[i], pNode->mName, mScene->mNumMeshes-1); + pNode->mMeshes[i], nodeName, mScene->mNumMeshes-1); } if (abHadMesh[pNode->mMeshes[i]]) { ReportError("aiNode::mMeshes[%i] is already referenced by this node %s (value: %i)", - i, pNode->mName, pNode->mMeshes[i]); + i, nodeName, pNode->mMeshes[i]); } abHadMesh[pNode->mMeshes[i]] = true; } @@ -949,7 +951,7 @@ void ValidateDSProcess::Validate( const aiNode* pNode) { if (!pNode->mChildren) { ReportError("aiNode::mChildren is NULL for node %s (aiNode::mNumChildren is %i)", - pNode->mName, pNode->mNumChildren); + nodeName, pNode->mNumChildren); } for (unsigned int i = 0; i < pNode->mNumChildren;++i) { Validate(pNode->mChildren[i]); From 28c110af2e7a594eea64a390f1af370455963f98 Mon Sep 17 00:00:00 2001 From: Charlie Gettys Date: Sun, 10 Mar 2019 13:15:15 -0400 Subject: [PATCH 05/16] Initial pass --- test/unit/utValidateDataStructure.cpp | 199 ++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 test/unit/utValidateDataStructure.cpp diff --git a/test/unit/utValidateDataStructure.cpp b/test/unit/utValidateDataStructure.cpp new file mode 100644 index 000000000..61fc93dd7 --- /dev/null +++ b/test/unit/utValidateDataStructure.cpp @@ -0,0 +1,199 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2019, 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 +#include +#include + +using namespace std; +using namespace Assimp; + + +class ValidateDataStructureTest : public ::testing::Test +{ +public: + + virtual void SetUp(); + virtual void TearDown(); + +protected: + + + ValidateDSProcess* vds; + aiScene* scene; +}; + +// ------------------------------------------------------------------------------------------------ +void ValidateDataStructureTest::SetUp() +{ + // setup a dummy scene with a single node + scene = new aiScene(); + scene->mRootNode = new aiNode(); + scene->mRootNode->mName.Set(""); + + // add some translation + scene->mRootNode->mTransformation.a4 = 1.f; + scene->mRootNode->mTransformation.b4 = 2.f; + scene->mRootNode->mTransformation.c4 = 3.f; + + // and allocate a ScenePreprocessor to operate on the scene + vds = new ValidateDSProcess(); +} + +// ------------------------------------------------------------------------------------------------ +void ValidateDataStructureTest::TearDown() +{ + delete vds; + delete scene; +} + + + +// ------------------------------------------------------------------------------------------------ +//Template +//TEST_F(ScenePreprocessorTest, test) +//{ +//} +// TODO Conditions not yet checked: +//132: ReportError("aiScene::%s is NULL (aiScene::%s is %i)", +//139: ReportError("aiScene::%s[%i] is NULL (aiScene::%s is %i)", +//156: ReportError("aiScene::%s is NULL (aiScene::%s is %i)", +//163: ReportError("aiScene::%s[%i] is NULL (aiScene::%s is %i)", +//173: ReportError("aiScene::%s[%i] has the same name as " +//192: ReportError("aiScene::%s[%i] has no corresponding node in the scene graph (%s)", +//196: ReportError("aiScene::%s[%i]: there are more than one nodes with %s as name", +//217: ReportError("aiScene::mNumMeshes is 0. At least one mesh must be there"); +//220: ReportError("aiScene::mMeshes is non-null although there are no meshes"); +//229: ReportError("aiScene::mAnimations is non-null although there are no animations"); +//238: ReportError("aiScene::mCameras is non-null although there are no cameras"); +//247: ReportError("aiScene::mLights is non-null although there are no lights"); +//256: ReportError("aiScene::mTextures is non-null although there are no textures"); +//266: ReportError("aiScene::mNumMaterials is 0. At least one material must be there"); +//270: ReportError("aiScene::mMaterials is non-null although there are no materials"); +//281: ReportWarning("aiLight::mType is aiLightSource_UNDEFINED"); +//286: ReportWarning("aiLight::mAttenuationXXX - all are zero"); +//290: ReportError("aiLight::mAngleInnerCone is larger than aiLight::mAngleOuterCone"); +//295: ReportWarning("aiLight::mColorXXX - all are black and won't have any influence"); +//303: ReportError("aiCamera::mClipPlaneFar must be >= aiCamera::mClipPlaneNear"); +//308: ReportWarning("%f is not a valid value for aiCamera::mHorizontalFOV",pCamera->mHorizontalFOV); +//317: ReportError("aiMesh::mMaterialIndex is invalid (value: %i maximum: %i)", +//332: ReportError("aiMesh::mFaces[%i].mNumIndices is 0",i); +//336: ReportError("aiMesh::mFaces[%i] is a POINT but aiMesh::mPrimitiveTypes " +//337: "does not report the POINT flag",i); +//343: ReportError("aiMesh::mFaces[%i] is a LINE but aiMesh::mPrimitiveTypes " +//344: "does not report the LINE flag",i); +//350: ReportError("aiMesh::mFaces[%i] is a TRIANGLE but aiMesh::mPrimitiveTypes " +//351: "does not report the TRIANGLE flag",i); +//357: this->ReportError("aiMesh::mFaces[%i] is a POLYGON but aiMesh::mPrimitiveTypes " +//358: "does not report the POLYGON flag",i); +//365: ReportError("aiMesh::mFaces[%i].mIndices is NULL",i); +//370: ReportError("The mesh %s contains no vertices", pMesh->mName.C_Str()); +//374: ReportError("Mesh has too many vertices: %u, but the limit is %u",pMesh->mNumVertices,AI_MAX_VERTICES); +//377: ReportError("Mesh has too many faces: %u, but the limit is %u",pMesh->mNumFaces,AI_MAX_FACES); +//382: ReportError("If there are tangents, bitangent vectors must be present as well"); +//387: ReportError("Mesh %s contains no faces", pMesh->mName.C_Str()); +//398: ReportError("Face %u has too many faces: %u, but the limit is %u",i,face.mNumIndices,AI_MAX_FACE_INDICES); +//404: ReportError("aiMesh::mFaces[%i]::mIndices[%i] is out of range",i,a); +//412: ReportError("aiMesh::mVertices[%i] is referenced twice - second " +//426: ReportWarning("There are unreferenced vertices"); +//439: ReportError("Texture coordinate channel %i exists " +//453: ReportError("Vertex color channel %i is exists " +//464: ReportError("aiMesh::mBones is NULL (aiMesh::mNumBones is %i)", +//480: ReportError("Bone %u has too many weights: %u, but the limit is %u",i,bone->mNumWeights,AI_MAX_BONE_WEIGHTS); +//485: ReportError("aiMesh::mBones[%i] is NULL (aiMesh::mNumBones is %i)", +//498: ReportError("aiMesh::mBones[%i], name = \"%s\" has the same name as " +//507: ReportWarning("aiMesh::mVertices[%i]: bone weight sum != 1.0 (sum is %f)",i,afSum[i]); +//513: ReportError("aiMesh::mBones is non-null although there are no bones"); +//524: ReportError("aiBone::mNumWeights is zero"); +//531: ReportError("aiBone::mWeights[%i].mVertexId is out of range",i); +//534: ReportWarning("aiBone::mWeights[%i].mWeight has an invalid value",i); +//549: ReportError("aiAnimation::mChannels is NULL (aiAnimation::mNumChannels is %i)", +//556: ReportError("aiAnimation::mChannels[%i] is NULL (aiAnimation::mNumChannels is %i)", +//563: ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there."); +//567: // if (!pAnimation->mDuration)this->ReportError("aiAnimation::mDuration is zero"); +//592: ReportError("Material property %s is expected to be a string",prop->mKey.data); +//596: ReportError("%s #%i is set, but there are only %i %s textures", +//611: ReportError("Found texture property with index %i, although there " +//619: ReportError("Material property %s%i is expected to be an integer (size is %i)", +//627: ReportError("Material property %s%i is expected to be 5 floats large (size is %i)", +//635: ReportError("Material property %s%i is expected to be an integer (size is %i)", +//656: ReportWarning("Invalid UV index: %i (key %s). Mesh %i has only %i UV channels", +//676: ReportWarning("UV-mapped texture, but there are no UV coords"); +//690: ReportError("aiMaterial::mProperties[%i] is NULL (aiMaterial::mNumProperties is %i)", +//694: ReportError("aiMaterial::mProperties[%i].mDataLength or " +//702: ReportError("aiMaterial::mProperties[%i].mDataLength is " +//707: ReportError("Missing null-terminator in string material property"); +//713: ReportError("aiMaterial::mProperties[%i].mDataLength is " +//720: ReportError("aiMaterial::mProperties[%i].mDataLength is " +//739: ReportWarning("A specular shading model is specified but there is no " +//743: ReportWarning("A specular shading model is specified but the value of the " +//752: ReportWarning("Invalid opacity value (must be 0 < opacity < 1.0)"); +//776: ReportError("aiTexture::pcData is NULL"); +//781: ReportError("aiTexture::mWidth is zero (aiTexture::mHeight is %i, uncompressed texture)", +//788: ReportError("aiTexture::mWidth is zero (compressed texture)"); +//791: ReportWarning("aiTexture::achFormatHint must be zero-terminated"); +//794: ReportWarning("aiTexture::achFormatHint should contain a file extension " +//804: ReportError("aiTexture::achFormatHint contains non-lowercase letters"); +//815: ReportError("Empty node animation channel"); +//822: ReportError("aiNodeAnim::mPositionKeys is NULL (aiNodeAnim::mNumPositionKeys is %i)", +//833: ReportError("aiNodeAnim::mPositionKeys[%i].mTime (%.5f) is larger " +//840: ReportWarning("aiNodeAnim::mPositionKeys[%i].mTime (%.5f) is smaller " +//853: ReportError("aiNodeAnim::mRotationKeys is NULL (aiNodeAnim::mNumRotationKeys is %i)", +//861: ReportError("aiNodeAnim::mRotationKeys[%i].mTime (%.5f) is larger " +//868: ReportWarning("aiNodeAnim::mRotationKeys[%i].mTime (%.5f) is smaller " +//880: ReportError("aiNodeAnim::mScalingKeys is NULL (aiNodeAnim::mNumScalingKeys is %i)", +//888: ReportError("aiNodeAnim::mScalingKeys[%i].mTime (%.5f) is larger " +//895: ReportWarning("aiNodeAnim::mScalingKeys[%i].mTime (%.5f) is smaller " +//907: ReportError("A node animation channel must have at least one subtrack"); +//915: ReportError("A node of the scenegraph is NULL"); +//920: ReportError("Non-root node %s lacks a valid parent (aiNode::mParent is NULL) ",pNode->mName); +//928: ReportError("aiNode::mMeshes is NULL for node %s (aiNode::mNumMeshes is %i)", +//937: ReportError("aiNode::mMeshes[%i] is out of range for node %s (maximum is %i)", +//942: ReportError("aiNode::mMeshes[%i] is already referenced by this node %s (value: %i)", +//951: ReportError("aiNode::mChildren is NULL for node %s (aiNode::mNumChildren is %i)", +//965: ReportError("aiString::length is too large (%i, maximum is %lu)", +//974: ReportError("aiString::data is invalid: the terminal zero is at a wrong offset"); +//979: ReportError("aiString::data is invalid. There is no terminal character"); +} + From 27dc922d096cbe0a1d25c79b541704660db8accb Mon Sep 17 00:00:00 2001 From: Charlie Gettys Date: Tue, 12 Mar 2019 01:06:54 -0400 Subject: [PATCH 06/16] Hopefully fix all warnings? --- code/ValidateDataStructure.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/ValidateDataStructure.cpp b/code/ValidateDataStructure.cpp index e73d1cca4..0cbc89b1f 100644 --- a/code/ValidateDataStructure.cpp +++ b/code/ValidateDataStructure.cpp @@ -160,7 +160,7 @@ inline void ValidateDSProcess::DoValidationEx(T** parray, unsigned int size, { if (!parray[i]) { - ReportError("aiScene::%s[%i] is NULL (aiScene::%s is %i)", + ReportError("aiScene::%s[%y] is NULL (aiScene::%s is %u)", firstName,i,secondName,size); } Validate(parray[i]); @@ -170,8 +170,8 @@ inline void ValidateDSProcess::DoValidationEx(T** parray, unsigned int size, { if (parray[i]->mName == parray[a]->mName) { - ReportError("aiScene::%s[%i] has the same name as " - "aiScene::%s[%i]",firstName, i,secondName, a); + ReportError("aiScene::%s[%u] has the same name as " + "aiScene::%s[%u]",firstName, i,secondName, a); } } } @@ -964,7 +964,7 @@ void ValidateDSProcess::Validate( const aiString* pString) { if (pString->length > MAXLEN) { - ReportError("aiString::length is too large (%i, maximum is %lu)", + ReportError("aiString::length is too large (%lu, maximum is %lu)", pString->length,MAXLEN); } const char* sz = pString->data; From 4728c1bb68af0a57e3e2118a3bd5ab243f17a253 Mon Sep 17 00:00:00 2001 From: Charlie Gettys Date: Tue, 12 Mar 2019 02:49:33 -0400 Subject: [PATCH 07/16] remove 1 more of the warnings --- code/ValidateDataStructure.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ValidateDataStructure.cpp b/code/ValidateDataStructure.cpp index 0cbc89b1f..4571d5884 100644 --- a/code/ValidateDataStructure.cpp +++ b/code/ValidateDataStructure.cpp @@ -928,7 +928,7 @@ void ValidateDSProcess::Validate( const aiNode* pNode) if (!pNode->mMeshes) { ReportError("aiNode::mMeshes is NULL for node %s (aiNode::mNumMeshes is %i)", - pNode->mNumMeshes, nodeName); + nodeName, pNode->mNumMeshes); } std::vector abHadMesh; abHadMesh.resize(mScene->mNumMeshes,false); From 5fd9789fc3006d819266f0f61b791c984731d1a8 Mon Sep 17 00:00:00 2001 From: Charlie Gettys Date: Tue, 12 Mar 2019 02:51:37 -0400 Subject: [PATCH 08/16] remove last warning? --- code/ValidateDataStructure.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ValidateDataStructure.cpp b/code/ValidateDataStructure.cpp index 4571d5884..0e84297a4 100644 --- a/code/ValidateDataStructure.cpp +++ b/code/ValidateDataStructure.cpp @@ -160,7 +160,7 @@ inline void ValidateDSProcess::DoValidationEx(T** parray, unsigned int size, { if (!parray[i]) { - ReportError("aiScene::%s[%y] is NULL (aiScene::%s is %u)", + ReportError("aiScene::%s[%u] is NULL (aiScene::%s is %u)", firstName,i,secondName,size); } Validate(parray[i]); From f0ed1702b99df30ae593208e3a0e2db668d2f9e1 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 12 Mar 2019 20:49:14 +0100 Subject: [PATCH 09/16] Reenable vs2015 and vs1017 --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index a1890b9cb..2b5f212f9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,8 +15,8 @@ matrix: image: - Visual Studio 2013 -# - Visual Studio 2015 -# - Visual Studio 2017 + - Visual Studio 2015 + - Visual Studio 2017 platform: - Win32 From ac80b116a9a29940d083ee03ff6a02ff76734338 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 12 Mar 2019 21:42:32 +0100 Subject: [PATCH 10/16] Update appveyor.yml Fix build image. --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 2b5f212f9..6924380e5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,8 +15,8 @@ matrix: image: - Visual Studio 2013 - - Visual Studio 2015 - - Visual Studio 2017 + - Previous Visual Studio 2015 + - Previous Visual Studio 2017 platform: - Win32 From 63afcf82670ac12c78687cd00a6d373b3014a8f4 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 12 Mar 2019 21:56:28 +0100 Subject: [PATCH 11/16] Update appveyor.yml Fix cmake generation. --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 6924380e5..78ef4da75 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -28,8 +28,8 @@ install: - set PATH=C:\Ruby24-x64\bin;%PATH% - set CMAKE_DEFINES -DASSIMP_WERROR=ON - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2013" set CMAKE_GENERATOR_NAME=Visual Studio 12 2013 - - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" set CMAKE_GENERATOR_NAME=Visual Studio 14 2015 - - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" set CMAKE_GENERATOR_NAME=Visual Studio 15 2017 + - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Previous Visual Studio 2015" set CMAKE_GENERATOR_NAME=Visual Studio 14 2015 + - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Previous Visual Studio 2017" set CMAKE_GENERATOR_NAME=Visual Studio 15 2017 - if "%platform%"=="x64" set CMAKE_GENERATOR_NAME=%CMAKE_GENERATOR_NAME% Win64 - cmake %CMAKE_DEFINES% -G "%CMAKE_GENERATOR_NAME%" - set PATH=%PATH%;"C:\\Program Files (x86)\\Inno Setup 5" From 0a731a0bffe6581d73e8de7a53aaac068e641418 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 13 Mar 2019 19:32:13 +0100 Subject: [PATCH 12/16] closes https://github.com/assimp/assimp/issues/934: introduce material keys for shader types. --- include/assimp/material.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/assimp/material.h b/include/assimp/material.h index 81b5fb05f..0fb2f9759 100644 --- a/include/assimp/material.h +++ b/include/assimp/material.h @@ -198,8 +198,6 @@ enum aiTextureType */ aiTextureType_NONE = 0x0, - - /** The texture is combined with the result of the diffuse * lighting equation. */ @@ -278,7 +276,7 @@ enum aiTextureType * * A texture reference that does not match any of the definitions * above is considered to be 'unknown'. It is still imported, - * but is excluded from any further postprocessing. + * but is excluded from any further post-processing. */ aiTextureType_UNKNOWN = 0xC, @@ -375,7 +373,7 @@ enum aiShadingMode */ enum aiTextureFlags { - /** The texture's color values have to be inverted (componentwise 1-n) + /** The texture's color values have to be inverted (component-wise 1-n) */ aiTextureFlags_Invert = 0x1, From 145c3d15890daebb45d6d627f9a5172e15fad386 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 13 Mar 2019 19:35:36 +0100 Subject: [PATCH 13/16] add missing changes. --- code/LWOMaterial.cpp | 5 +---- include/assimp/material.h | 9 +++++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/code/LWOMaterial.cpp b/code/LWOMaterial.cpp index 55d0e23f1..b54c21c26 100644 --- a/code/LWOMaterial.cpp +++ b/code/LWOMaterial.cpp @@ -320,13 +320,10 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat) // opacity ... either additive or default-blended, please if (0.0 != surf.mAdditiveTransparency) { - const int add = aiBlendMode_Additive; pcMat->AddProperty(&surf.mAdditiveTransparency,1,AI_MATKEY_OPACITY); pcMat->AddProperty(&add,1,AI_MATKEY_BLEND_FUNC); - } - - else if (10e10f != surf.mTransparency) { + } else if (10e10f != surf.mTransparency) { const int def = aiBlendMode_Default; const float f = 1.0f-surf.mTransparency; pcMat->AddProperty(&f,1,AI_MATKEY_OPACITY); diff --git a/include/assimp/material.h b/include/assimp/material.h index 0fb2f9759..b882bbc72 100644 --- a/include/assimp/material.h +++ b/include/assimp/material.h @@ -912,6 +912,13 @@ extern "C" { #define AI_MATKEY_COLOR_TRANSPARENT "$clr.transparent",0,0 #define AI_MATKEY_COLOR_REFLECTIVE "$clr.reflective",0,0 #define AI_MATKEY_GLOBAL_BACKGROUND_IMAGE "?bg.global",0,0 +#define AI_MATKEY_GLOBAL_SHADERLANG "?sh.lang",0,0 +#define AI_MATKEY_SHADER_VERTEX "?sh.vs",0,0 +#define AI_MATKEY_SHADER_FRAGMENT "?sh.fs",0,0 +#define AI_MATKEY_SHADER_GEO "?sh.gs",0,0 +#define AI_MATKEY_SHADER_TESSELATION "?sh.ts",0,0 +#define AI_MATKEY_SHADER_PRIMITIVE "?sh.ps",0,0 +#define AI_MATKEY_SHADER_COMPUTE "?sh.cs",0,0 // --------------------------------------------------------------------------- // Pure key names for all texture-related properties @@ -1455,8 +1462,6 @@ inline aiReturn aiGetMaterialInteger(const C_STRUCT aiMaterial* pMat, #endif //!__cplusplus - - // --------------------------------------------------------------------------- /** @brief Retrieve a color value from the material property table * From 93e8a1054f19d1f1f8294b26dd6beaf49a6f5815 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 13 Mar 2019 22:07:03 +0100 Subject: [PATCH 14/16] Add short documentation. --- doc/dox.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/doc/dox.h b/doc/dox.h index d63c8a806..910e77eae 100644 --- a/doc/dox.h +++ b/doc/dox.h @@ -1173,6 +1173,18 @@ float4 PimpMyPixel (float4 prev) @endcode +@section shdacc How to access shader-code from a texture (AI_MATKEY_GLOBAL_SHADERLANG and AI_MATKEY_SHADER_VERTEX, ...) + +You can get assigned shader sources by using the following material keys: + +
  • AI_MATKEY_GLOBAL_SHADERLANG
  • To get the used shader language. +
  • AI_MATKEY_SHADER_VERTEX
  • Assigned vertex shader code stored as a string. +
  • AI_MATKEY_SHADER_FRAGMENT
  • Assigned fragment shader code stored as a string. +
  • AI_MATKEY_SHADER_GEO
  • Assigned geometry shader code stored as a string. +
  • AI_MATKEY_SHADER_TESSELATION
  • Assigned tesselation shader code stored as a string. +
  • AI_MATKEY_SHADER_PRIMITIVE
  • Assigned primitive shader code stored as a string. +
  • AI_MATKEY_SHADER_COMPUTE
  • Assigned compute shader code stored as a string. + */ From 170549559edb5cbf9a7d0ccea4bfe98bace1e057 Mon Sep 17 00:00:00 2001 From: Aidmx Date: Thu, 14 Mar 2019 21:50:50 +0800 Subject: [PATCH 15/16] fix: change ScaleProcess priority --- code/PostStepRegistry.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/PostStepRegistry.cpp b/code/PostStepRegistry.cpp index 469a8ef39..15b4a2884 100644 --- a/code/PostStepRegistry.cpp +++ b/code/PostStepRegistry.cpp @@ -173,6 +173,9 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out) #ifndef ASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS out.push_back( new TextureTransformStep()); #endif +#if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS) + out.push_back( new ScaleProcess()); +#endif #if (!defined ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS) out.push_back( new PretransformVertices()); #endif @@ -208,9 +211,6 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out) #endif #if (!defined ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS) out.push_back( new GenFaceNormalsProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS) - out.push_back( new ScaleProcess()); #endif // ......................................................................... // DON'T change the order of these five .. From 9a533d826ad6f880ded45c801d2a022f6d9e4f68 Mon Sep 17 00:00:00 2001 From: Tomas Maly Date: Fri, 15 Mar 2019 22:43:12 +0100 Subject: [PATCH 16/16] fix loading 3D uvs from obj --- code/ObjFileData.h | 3 +++ code/ObjFileImporter.cpp | 2 +- code/ObjFileParser.cpp | 6 ++++-- code/ObjFileParser.h | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/code/ObjFileData.h b/code/ObjFileData.h index 5ff9db68c..a2d9f2cc7 100644 --- a/code/ObjFileData.h +++ b/code/ObjFileData.h @@ -281,6 +281,8 @@ struct Model { std::string m_strActiveGroup; //! Vector with generated texture coordinates std::vector m_TextureCoord; + //! Maximum dimension of texture coordinates + unsigned int m_TextureCoordDim; //! Current mesh instance Mesh *m_pCurrentMesh; //! Vector with stored meshes @@ -296,6 +298,7 @@ struct Model { m_pDefaultMaterial(NULL), m_pGroupFaceIDs(NULL), m_strActiveGroup(""), + m_TextureCoordDim(0), m_pCurrentMesh(NULL) { // empty diff --git a/code/ObjFileImporter.cpp b/code/ObjFileImporter.cpp index 814180c81..549956474 100644 --- a/code/ObjFileImporter.cpp +++ b/code/ObjFileImporter.cpp @@ -442,7 +442,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, // Allocate buffer for texture coordinates if ( !pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0] ) { - pMesh->mNumUVComponents[ 0 ] = 2; + pMesh->mNumUVComponents[ 0 ] = pModel->m_TextureCoordDim; pMesh->mTextureCoords[ 0 ] = new aiVector3D[ pMesh->mNumVertices ]; } diff --git a/code/ObjFileParser.cpp b/code/ObjFileParser.cpp index d303cb8b9..a8509b583 100644 --- a/code/ObjFileParser.cpp +++ b/code/ObjFileParser.cpp @@ -151,7 +151,8 @@ void ObjFileParser::parseFile( IOStreamBuffer &streamBuffer ) { } else if (*m_DataIt == 't') { // read in texture coordinate ( 2D or 3D ) ++m_DataIt; - getVector( m_pModel->m_TextureCoord ); + size_t dim = getVector(m_pModel->m_TextureCoord); + m_pModel->m_TextureCoordDim = std::max(m_pModel->m_TextureCoordDim, (unsigned int)dim); } else if (*m_DataIt == 'n') { // Read in normal vector definition ++m_DataIt; @@ -296,7 +297,7 @@ size_t ObjFileParser::getNumComponentsInDataDefinition() { return numComponents; } -void ObjFileParser::getVector( std::vector &point3d_array ) { +size_t ObjFileParser::getVector( std::vector &point3d_array ) { size_t numComponents = getNumComponentsInDataDefinition(); ai_real x, y, z; if( 2 == numComponents ) { @@ -320,6 +321,7 @@ void ObjFileParser::getVector( std::vector &point3d_array ) { } point3d_array.push_back( aiVector3D( x, y, z ) ); m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + return numComponents; } void ObjFileParser::getVector3( std::vector &point3d_array ) { diff --git a/code/ObjFileParser.h b/code/ObjFileParser.h index e00382f4c..a8961452d 100644 --- a/code/ObjFileParser.h +++ b/code/ObjFileParser.h @@ -96,7 +96,7 @@ protected: /// Get the number of components in a line. size_t getNumComponentsInDataDefinition(); /// Stores the vector - void getVector( std::vector &point3d_array ); + size_t getVector( std::vector &point3d_array ); /// Stores the following 3d vector. void getVector3( std::vector &point3d_array ); /// Stores the following homogeneous vector as a 3D vector