﻿/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------

Copyright (c) 2006-2017, assimp team


All rights reserved.

Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:

* Redistributions of source code must retain the above
  copyright notice, this list of conditions and the
  following disclaimer.

* Redistributions in binary form must reproduce the above
  copyright notice, this list of conditions and the
  following disclaimer in the documentation and/or other
  materials provided with the distribution.

* Neither the name of the assimp team, nor the names of its
  contributors may be used to endorse or promote products
  derived from this software without specific prior
  written permission of the assimp team.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/

/** @file  ValidateDataStructure.cpp
 *  @brief Implementation of the post processing step to validate
 *    the data structure returned by Assimp.
 */



// internal headers
#include "ValidateDataStructure.h"
#include "BaseImporter.h"
#include "fast_atof.h"
#include "ProcessHelper.h"
#include <memory>

// CRT headers
#include <stdarg.h>

using namespace Assimp;

// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
ValidateDSProcess::ValidateDSProcess() :
    mScene()
{}

// ------------------------------------------------------------------------------------------------
// Destructor, private as well
ValidateDSProcess::~ValidateDSProcess()
{}

// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool ValidateDSProcess::IsActive( unsigned int pFlags) const
{
    return (pFlags & aiProcess_ValidateDataStructure) != 0;
}
// ------------------------------------------------------------------------------------------------
AI_WONT_RETURN void ValidateDSProcess::ReportError(const char* msg,...)
{
    ai_assert(NULL != msg);

    va_list args;
    va_start(args,msg);

    char szBuffer[3000];
    const int iLen = vsprintf(szBuffer,msg,args);
    ai_assert(iLen > 0);

    va_end(args);

    throw DeadlyImportError("Validation failed: " + std::string(szBuffer,iLen));
}
// ------------------------------------------------------------------------------------------------
void ValidateDSProcess::ReportWarning(const char* msg,...)
{
    ai_assert(NULL != msg);

    va_list args;
    va_start(args,msg);

    char szBuffer[3000];
    const int iLen = vsprintf(szBuffer,msg,args);
    ai_assert(iLen > 0);

    va_end(args);
    DefaultLogger::get()->warn("Validation warning: " + std::string(szBuffer,iLen));
}

// ------------------------------------------------------------------------------------------------
inline int HasNameMatch(const aiString& in, aiNode* node)
{
    int result = (node->mName == in ? 1 : 0 );
    for (unsigned int i = 0; i < node->mNumChildren;++i)    {
        result += HasNameMatch(in,node->mChildren[i]);
    }
    return result;
}

// ------------------------------------------------------------------------------------------------
template <typename T>
inline void ValidateDSProcess::DoValidation(T** parray, unsigned int size,
    const char* firstName, const char* secondName)
{
    // validate all entries
    if (size)
    {
        if (!parray)
        {
            ReportError("aiScene::%s is NULL (aiScene::%s is %i)",
                firstName, secondName, size);
        }
        for (unsigned int i = 0; i < size;++i)
        {
            if (!parray[i])
            {
                ReportError("aiScene::%s[%i] is NULL (aiScene::%s is %i)",
                    firstName,i,secondName,size);
            }
            Validate(parray[i]);
        }
    }
}

// ------------------------------------------------------------------------------------------------
template <typename T>
inline void ValidateDSProcess::DoValidationEx(T** parray, unsigned int size,
    const char* firstName, const char* secondName)
{
    // validate all entries
    if (size)
    {
        if (!parray)    {
            ReportError("aiScene::%s is NULL (aiScene::%s is %i)",
                firstName, secondName, size);
        }
        for (unsigned int i = 0; i < size;++i)
        {
            if (!parray[i])
            {
                ReportError("aiScene::%s[%i] is NULL (aiScene::%s is %i)",
                    firstName,i,secondName,size);
            }
            Validate(parray[i]);

            // check whether there are duplicate names
            for (unsigned int a = i+1; a < size;++a)
            {
                if (parray[i]->mName == parray[a]->mName)
                {
                    this->ReportError("aiScene::%s[%i] has the same name as "
                        "aiScene::%s[%i]",firstName, i,secondName, a);
                }
            }
        }
    }
}

// ------------------------------------------------------------------------------------------------
template <typename T>
inline void ValidateDSProcess::DoValidationWithNameCheck(T** array,
    unsigned int size, const char* firstName,
    const char* secondName)
{
    // validate all entries
    DoValidationEx(array,size,firstName,secondName);

    for (unsigned int i = 0; i < size;++i)
    {
        int res = HasNameMatch(array[i]->mName,mScene->mRootNode);
        if (!res)   {
            ReportError("aiScene::%s[%i] has no corresponding node in the scene graph (%s)",
                firstName,i,array[i]->mName.data);
        }
        else if (1 != res)  {
            ReportError("aiScene::%s[%i]: there are more than one nodes with %s as name",
                firstName,i,array[i]->mName.data);
        }
    }
}

// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void ValidateDSProcess::Execute( aiScene* pScene)
{
    this->mScene = pScene;
    DefaultLogger::get()->debug("ValidateDataStructureProcess begin");

    // validate the node graph of the scene
    Validate(pScene->mRootNode);

    // validate all meshes
    if (pScene->mNumMeshes) {
        DoValidation(pScene->mMeshes,pScene->mNumMeshes,"mMeshes","mNumMeshes");
    }
    else if (!(mScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE)) {
        ReportError("aiScene::mNumMeshes is 0. At least one mesh must be there");
    }
    else if (pScene->mMeshes)   {
        ReportError("aiScene::mMeshes is non-null although there are no meshes");
    }

    // validate all animations
    if (pScene->mNumAnimations) {
        DoValidation(pScene->mAnimations,pScene->mNumAnimations,
            "mAnimations","mNumAnimations");
    }
    else if (pScene->mAnimations)   {
        ReportError("aiScene::mAnimations is non-null although there are no animations");
    }

    // validate all cameras
    if (pScene->mNumCameras) {
        DoValidationWithNameCheck(pScene->mCameras,pScene->mNumCameras,
            "mCameras","mNumCameras");
    }
    else if (pScene->mCameras)  {
        ReportError("aiScene::mCameras is non-null although there are no cameras");
    }

    // validate all lights
    if (pScene->mNumLights) {
        DoValidationWithNameCheck(pScene->mLights,pScene->mNumLights,
            "mLights","mNumLights");
    }
    else if (pScene->mLights)   {
        ReportError("aiScene::mLights is non-null although there are no lights");
    }

    // validate all textures
    if (pScene->mNumTextures) {
        DoValidation(pScene->mTextures,pScene->mNumTextures,
            "mTextures","mNumTextures");
    }
    else if (pScene->mTextures) {
        ReportError("aiScene::mTextures is non-null although there are no textures");
    }

    // validate all materials
    if (pScene->mNumMaterials) {
        DoValidation(pScene->mMaterials,pScene->mNumMaterials,"mMaterials","mNumMaterials");
    }
#if 0
    // NOTE: ScenePreprocessor generates a default material if none is there
    else if (!(mScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE)) {
        ReportError("aiScene::mNumMaterials is 0. At least one material must be there");
    }
#endif
    else if (pScene->mMaterials)    {
        ReportError("aiScene::mMaterials is non-null although there are no materials");
    }

//  if (!has)ReportError("The aiScene data structure is empty");
    DefaultLogger::get()->debug("ValidateDataStructureProcess end");
}

// ------------------------------------------------------------------------------------------------
void ValidateDSProcess::Validate( const aiLight* pLight)
{
    if (pLight->mType == aiLightSource_UNDEFINED)
        ReportWarning("aiLight::mType is aiLightSource_UNDEFINED");

    if (!pLight->mAttenuationConstant &&
        !pLight->mAttenuationLinear   &&
        !pLight->mAttenuationQuadratic) {
        ReportWarning("aiLight::mAttenuationXXX - all are zero");
    }

    if (pLight->mAngleInnerCone > pLight->mAngleOuterCone)
        ReportError("aiLight::mAngleInnerCone is larger than aiLight::mAngleOuterCone");

    if (pLight->mColorDiffuse.IsBlack() && pLight->mColorAmbient.IsBlack()
        && pLight->mColorSpecular.IsBlack())
    {
        ReportWarning("aiLight::mColorXXX - all are black and won't have any influence");
    }
}

// ------------------------------------------------------------------------------------------------
void ValidateDSProcess::Validate( const aiCamera* pCamera)
{
    if (pCamera->mClipPlaneFar <= pCamera->mClipPlaneNear)
        ReportError("aiCamera::mClipPlaneFar must be >= aiCamera::mClipPlaneNear");

    // FIX: there are many 3ds files with invalid FOVs. No reason to
    // reject them at all ... a warning is appropriate.
    if (!pCamera->mHorizontalFOV || pCamera->mHorizontalFOV >= (float)AI_MATH_PI)
        ReportWarning("%f is not a valid value for aiCamera::mHorizontalFOV",pCamera->mHorizontalFOV);
}

// ------------------------------------------------------------------------------------------------
void ValidateDSProcess::Validate( const aiMesh* pMesh)
{
    // validate the material index of the mesh
    if (mScene->mNumMaterials && pMesh->mMaterialIndex >= mScene->mNumMaterials)
    {
        ReportError("aiMesh::mMaterialIndex is invalid (value: %i maximum: %i)",
            pMesh->mMaterialIndex,mScene->mNumMaterials-1);
    }

    Validate(&pMesh->mName);

    for (unsigned int i = 0; i < pMesh->mNumFaces; ++i)
    {
        aiFace& face = pMesh->mFaces[i];

        if (pMesh->mPrimitiveTypes)
        {
            switch (face.mNumIndices)
            {
            case 0:
                ReportError("aiMesh::mFaces[%i].mNumIndices is 0",i);
            case 1:
                if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POINT))
                {
                    ReportError("aiMesh::mFaces[%i] is a POINT but aiMesh::mPrimitiveTypes "
                        "does not report the POINT flag",i);
                }
                break;
            case 2:
                if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_LINE))
                {
                    ReportError("aiMesh::mFaces[%i] is a LINE but aiMesh::mPrimitiveTypes "
                        "does not report the LINE flag",i);
                }
                break;
            case 3:
                if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE))
                {
                    ReportError("aiMesh::mFaces[%i] is a TRIANGLE but aiMesh::mPrimitiveTypes "
                        "does not report the TRIANGLE flag",i);
                }
                break;
            default:
                if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON))
                {
                    this->ReportError("aiMesh::mFaces[%i] is a POLYGON but aiMesh::mPrimitiveTypes "
                        "does not report the POLYGON flag",i);
                }
                break;
            };
        }

        if (!face.mIndices)
            ReportError("aiMesh::mFaces[%i].mIndices is NULL",i);
    }

    // positions must always be there ...
    if (!pMesh->mNumVertices || (!pMesh->mVertices && !mScene->mFlags)) {
        ReportError("The mesh contains no vertices");
    }

    if (pMesh->mNumVertices > AI_MAX_VERTICES) {
        ReportError("Mesh has too many vertices: %u, but the limit is %u",pMesh->mNumVertices,AI_MAX_VERTICES);
    }
    if (pMesh->mNumFaces > AI_MAX_FACES) {
        ReportError("Mesh has too many faces: %u, but the limit is %u",pMesh->mNumFaces,AI_MAX_FACES);
    }

    // if tangents are there there must also be bitangent vectors ...
    if ((pMesh->mTangents != NULL) != (pMesh->mBitangents != NULL)) {
        ReportError("If there are tangents, bitangent vectors must be present as well");
    }

    // faces, too
    if (!pMesh->mNumFaces || (!pMesh->mFaces && !mScene->mFlags))   {
        ReportError("Mesh contains no faces");
    }

    // now check whether the face indexing layout is correct:
    // unique vertices, pseudo-indexed.
    std::vector<bool> abRefList;
    abRefList.resize(pMesh->mNumVertices,false);
    for (unsigned int i = 0; i < pMesh->mNumFaces;++i)
    {
        aiFace& face = pMesh->mFaces[i];
        if (face.mNumIndices > AI_MAX_FACE_INDICES) {
            ReportError("Face %u has too many faces: %u, but the limit is %u",i,face.mNumIndices,AI_MAX_FACE_INDICES);
        }

        for (unsigned int a = 0; a < face.mNumIndices;++a)
        {
            if (face.mIndices[a] >= pMesh->mNumVertices)    {
                ReportError("aiMesh::mFaces[%i]::mIndices[%i] is out of range",i,a);
            }
            // the MSB flag is temporarily used by the extra verbose
            // mode to tell us that the JoinVerticesProcess might have
            // been executed already.
			/*if ( !(this->mScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT ) && !(this->mScene->mFlags & AI_SCENE_FLAGS_ALLOW_SHARED) &&
				abRefList[face.mIndices[a]])
            {
                ReportError("aiMesh::mVertices[%i] is referenced twice - second "
                    "time by aiMesh::mFaces[%i]::mIndices[%i]",face.mIndices[a],i,a);
            }*/
            abRefList[face.mIndices[a]] = true;
        }
    }

    // check whether there are vertices that aren't referenced by a face
    bool b = false;
    for (unsigned int i = 0; i < pMesh->mNumVertices;++i)   {
        if (!abRefList[i])b = true;
    }
    abRefList.clear();
    if (b)ReportWarning("There are unreferenced vertices");

    // texture channel 2 may not be set if channel 1 is zero ...
    {
        unsigned int i = 0;
        for (;i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
        {
            if (!pMesh->HasTextureCoords(i))break;
        }
        for (;i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
            if (pMesh->HasTextureCoords(i))
            {
                ReportError("Texture coordinate channel %i exists "
                    "although the previous channel was NULL.",i);
            }
    }
    // the same for the vertex colors
    {
        unsigned int i = 0;
        for (;i < AI_MAX_NUMBER_OF_COLOR_SETS;++i)
        {
            if (!pMesh->HasVertexColors(i))break;
        }
        for (;i < AI_MAX_NUMBER_OF_COLOR_SETS;++i)
            if (pMesh->HasVertexColors(i))
            {
                ReportError("Vertex color channel %i is exists "
                    "although the previous channel was NULL.",i);
            }
    }


    // now validate all bones
    if (pMesh->mNumBones)
    {
        if (!pMesh->mBones)
        {
            ReportError("aiMesh::mBones is NULL (aiMesh::mNumBones is %i)",
                pMesh->mNumBones);
        }
        std::unique_ptr<float[]> afSum(nullptr);
        if (pMesh->mNumVertices)
        {
            afSum.reset(new float[pMesh->mNumVertices]);
            for (unsigned int i = 0; i < pMesh->mNumVertices;++i)
                afSum[i] = 0.0f;
        }

        // check whether there are duplicate bone names
        for (unsigned int i = 0; i < pMesh->mNumBones;++i)
        {
            const aiBone* bone = pMesh->mBones[i];
            if (bone->mNumWeights > AI_MAX_BONE_WEIGHTS) {
                ReportError("Bone %u has too many weights: %u, but the limit is %u",i,bone->mNumWeights,AI_MAX_BONE_WEIGHTS);
            }

            if (!pMesh->mBones[i])
            {
                ReportError("aiMesh::mBones[%i] is NULL (aiMesh::mNumBones is %i)",
                    i,pMesh->mNumBones);
            }
            Validate(pMesh,pMesh->mBones[i],afSum.get());

            for (unsigned int a = i+1; a < pMesh->mNumBones;++a)
            {
                if (pMesh->mBones[i]->mName == pMesh->mBones[a]->mName)
                {
                    ReportError("aiMesh::mBones[%i] has the same name as "
                        "aiMesh::mBones[%i]",i,a);
                }
            }
        }
        // check whether all bone weights for a vertex sum to 1.0 ...
        for (unsigned int i = 0; i < pMesh->mNumVertices;++i)
        {
            if (afSum[i] && (afSum[i] <= 0.94 || afSum[i] >= 1.05)) {
                ReportWarning("aiMesh::mVertices[%i]: bone weight sum != 1.0 (sum is %f)",i,afSum[i]);
            }
        }
    }
    else if (pMesh->mBones)
    {
        ReportError("aiMesh::mBones is non-null although there are no bones");
    }
}

// ------------------------------------------------------------------------------------------------
void ValidateDSProcess::Validate( const aiMesh* pMesh,
    const aiBone* pBone,float* afSum)
{
    this->Validate(&pBone->mName);

    if (!pBone->mNumWeights)    {
        ReportError("aiBone::mNumWeights is zero");
    }

    // check whether all vertices affected by this bone are valid
    for (unsigned int i = 0; i < pBone->mNumWeights;++i)
    {
        if (pBone->mWeights[i].mVertexId >= pMesh->mNumVertices)    {
            ReportError("aiBone::mWeights[%i].mVertexId is out of range",i);
        }
        else if (!pBone->mWeights[i].mWeight || pBone->mWeights[i].mWeight > 1.0f)  {
            ReportWarning("aiBone::mWeights[%i].mWeight has an invalid value",i);
        }
        afSum[pBone->mWeights[i].mVertexId] += pBone->mWeights[i].mWeight;
    }
}

// ------------------------------------------------------------------------------------------------
void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
{
    Validate(&pAnimation->mName);

    // validate all materials
    if (pAnimation->mNumChannels)
    {
        if (!pAnimation->mChannels) {
            ReportError("aiAnimation::mChannels is NULL (aiAnimation::mNumChannels is %i)",
                pAnimation->mNumChannels);
        }
        for (unsigned int i = 0; i < pAnimation->mNumChannels;++i)
        {
            if (!pAnimation->mChannels[i])
            {
                ReportError("aiAnimation::mChannels[%i] is NULL (aiAnimation::mNumChannels is %i)",
                    i, pAnimation->mNumChannels);
            }
            Validate(pAnimation, pAnimation->mChannels[i]);
        }
    }
    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");
}

// ------------------------------------------------------------------------------------------------
void ValidateDSProcess::SearchForInvalidTextures(const aiMaterial* pMaterial,
    aiTextureType type)
{
    const char* szType = TextureTypeToString(type);

    // ****************************************************************************
    // Search all keys of the material ...
    // textures must be specified with ascending indices
    // (e.g. diffuse #2 may not be specified if diffuse #1 is not there ...)
    // ****************************************************************************

    int iNumIndices = 0;
    int iIndex = -1;
    for (unsigned int i = 0; i < pMaterial->mNumProperties;++i)
    {
        aiMaterialProperty* prop = pMaterial->mProperties[i];
        if (!::strcmp(prop->mKey.data,"$tex.file") && prop->mSemantic == type)  {
            iIndex = std::max(iIndex, (int) prop->mIndex);
            ++iNumIndices;

            if (aiPTI_String != prop->mType)
                ReportError("Material property %s is expected to be a string",prop->mKey.data);
        }
    }
    if (iIndex +1 != iNumIndices)   {
        ReportError("%s #%i is set, but there are only %i %s textures",
            szType,iIndex,iNumIndices,szType);
    }
    if (!iNumIndices)return;
    std::vector<aiTextureMapping> mappings(iNumIndices);

    // Now check whether all UV indices are valid ...
    bool bNoSpecified = true;
    for (unsigned int i = 0; i < pMaterial->mNumProperties;++i)
    {
        aiMaterialProperty* prop = pMaterial->mProperties[i];
        if (prop->mSemantic != type)continue;

        if ((int)prop->mIndex >= iNumIndices)
        {
            ReportError("Found texture property with index %i, although there "
                "are only %i textures of type %s",
                prop->mIndex, iNumIndices, szType);
        }

        if (!::strcmp(prop->mKey.data,"$tex.mapping"))  {
            if (aiPTI_Integer != prop->mType || prop->mDataLength < sizeof(aiTextureMapping))
            {
                ReportError("Material property %s%i is expected to be an integer (size is %i)",
                    prop->mKey.data,prop->mIndex,prop->mDataLength);
            }
            mappings[prop->mIndex] = *((aiTextureMapping*)prop->mData);
        }
        else if (!::strcmp(prop->mKey.data,"$tex.uvtrafo")) {
            if (aiPTI_Float != prop->mType || prop->mDataLength < sizeof(aiUVTransform))
            {
                ReportError("Material property %s%i is expected to be 5 floats large (size is %i)",
                    prop->mKey.data,prop->mIndex, prop->mDataLength);
            }
            mappings[prop->mIndex] = *((aiTextureMapping*)prop->mData);
        }
        else if (!::strcmp(prop->mKey.data,"$tex.uvwsrc")) {
            if (aiPTI_Integer != prop->mType || sizeof(int) > prop->mDataLength)
            {
                ReportError("Material property %s%i is expected to be an integer (size is %i)",
                    prop->mKey.data,prop->mIndex,prop->mDataLength);
            }
            bNoSpecified = false;

            // Ignore UV indices for texture channels that are not there ...

            // Get the value
            iIndex = *((unsigned int*)prop->mData);

            // Check whether there is a mesh using this material
            // which has not enough UV channels ...
            for (unsigned int a = 0; a < mScene->mNumMeshes;++a)
            {
                aiMesh* mesh = this->mScene->mMeshes[a];
                if(mesh->mMaterialIndex == (unsigned int)i)
                {
                    int iChannels = 0;
                    while (mesh->HasTextureCoords(iChannels))++iChannels;
                    if (iIndex >= iChannels)
                    {
                        ReportWarning("Invalid UV index: %i (key %s). Mesh %i has only %i UV channels",
                            iIndex,prop->mKey.data,a,iChannels);
                    }
                }
            }
        }
    }
    if (bNoSpecified)
    {
        // Assume that all textures are using the first UV channel
        for (unsigned int a = 0; a < mScene->mNumMeshes;++a)
        {
            aiMesh* mesh = mScene->mMeshes[a];
            if(mesh->mMaterialIndex == (unsigned int)iIndex && mappings[0] == aiTextureMapping_UV)
            {
                if (!mesh->mTextureCoords[0])
                {
                    // This is a special case ... it could be that the
                    // original mesh format intended the use of a special
                    // mapping here.
                    ReportWarning("UV-mapped texture, but there are no UV coords");
                }
            }
        }
    }
}
// ------------------------------------------------------------------------------------------------
void ValidateDSProcess::Validate( const aiMaterial* pMaterial)
{
    // check whether there are material keys that are obviously not legal
    for (unsigned int i = 0; i < pMaterial->mNumProperties;++i)
    {
        const aiMaterialProperty* prop = pMaterial->mProperties[i];
        if (!prop)  {
            ReportError("aiMaterial::mProperties[%i] is NULL (aiMaterial::mNumProperties is %i)",
                i,pMaterial->mNumProperties);
        }
        if (!prop->mDataLength || !prop->mData) {
            ReportError("aiMaterial::mProperties[%i].mDataLength or "
                "aiMaterial::mProperties[%i].mData is 0",i,i);
        }
        // check all predefined types
        if (aiPTI_String == prop->mType)    {
            // FIX: strings are now stored in a less expensive way, but we can't use the
            // validation routine for 'normal' aiStrings
            if (prop->mDataLength < 5 || prop->mDataLength < 4 + (*reinterpret_cast<uint32_t*>(prop->mData)) + 1)   {
                ReportError("aiMaterial::mProperties[%i].mDataLength is "
                    "too small to contain a string (%i, needed: %i)",
                    i,prop->mDataLength,sizeof(aiString));
            }
            if(prop->mData[prop->mDataLength-1]) {
                ReportError("Missing null-terminator in string material property");
            }
        //  Validate((const aiString*)prop->mData);
        }
        else if (aiPTI_Float == prop->mType)    {
            if (prop->mDataLength < sizeof(float))  {
                ReportError("aiMaterial::mProperties[%i].mDataLength is "
                    "too small to contain a float (%i, needed: %i)",
                    i,prop->mDataLength,sizeof(float));
            }
        }
        else if (aiPTI_Integer == prop->mType)  {
            if (prop->mDataLength < sizeof(int))    {
                ReportError("aiMaterial::mProperties[%i].mDataLength is "
                    "too small to contain an integer (%i, needed: %i)",
                    i,prop->mDataLength,sizeof(int));
            }
        }
        // TODO: check whether there is a key with an unknown name ...
    }

    // make some more specific tests
    ai_real fTemp;
    int iShading;
    if (AI_SUCCESS == aiGetMaterialInteger( pMaterial,AI_MATKEY_SHADING_MODEL,&iShading))   {
        switch ((aiShadingMode)iShading)
        {
        case aiShadingMode_Blinn:
        case aiShadingMode_CookTorrance:
        case aiShadingMode_Phong:

            if (AI_SUCCESS != aiGetMaterialFloat(pMaterial,AI_MATKEY_SHININESS,&fTemp)) {
                ReportWarning("A specular shading model is specified but there is no "
                    "AI_MATKEY_SHININESS key");
            }
            if (AI_SUCCESS == aiGetMaterialFloat(pMaterial,AI_MATKEY_SHININESS_STRENGTH,&fTemp) && !fTemp)  {
                ReportWarning("A specular shading model is specified but the value of the "
                    "AI_MATKEY_SHININESS_STRENGTH key is 0.0");
            }
            break;
        default: ;
        };
    }

    if (AI_SUCCESS == aiGetMaterialFloat( pMaterial,AI_MATKEY_OPACITY,&fTemp) && (!fTemp || fTemp > 1.01)) {
        ReportWarning("Invalid opacity value (must be 0 < opacity < 1.0)");
    }

    // Check whether there are invalid texture keys
    // TODO: that's a relict of the past, where texture type and index were baked
    // into the material string ... we could do that in one single pass.
    SearchForInvalidTextures(pMaterial,aiTextureType_DIFFUSE);
    SearchForInvalidTextures(pMaterial,aiTextureType_SPECULAR);
    SearchForInvalidTextures(pMaterial,aiTextureType_AMBIENT);
    SearchForInvalidTextures(pMaterial,aiTextureType_EMISSIVE);
    SearchForInvalidTextures(pMaterial,aiTextureType_OPACITY);
    SearchForInvalidTextures(pMaterial,aiTextureType_SHININESS);
    SearchForInvalidTextures(pMaterial,aiTextureType_HEIGHT);
    SearchForInvalidTextures(pMaterial,aiTextureType_NORMALS);
    SearchForInvalidTextures(pMaterial,aiTextureType_DISPLACEMENT);
    SearchForInvalidTextures(pMaterial,aiTextureType_LIGHTMAP);
    SearchForInvalidTextures(pMaterial,aiTextureType_REFLECTION);
}

// ------------------------------------------------------------------------------------------------
void ValidateDSProcess::Validate( const aiTexture* pTexture)
{
    // the data section may NEVER be NULL
    if (!pTexture->pcData)  {
        ReportError("aiTexture::pcData is NULL");
    }
    if (pTexture->mHeight)
    {
        if (!pTexture->mWidth)ReportError("aiTexture::mWidth is zero "
            "(aiTexture::mHeight is %i, uncompressed texture)",pTexture->mHeight);
    }
    else
    {
        if (!pTexture->mWidth) {
            ReportError("aiTexture::mWidth is zero (compressed texture)");
        }
        if ('\0' != pTexture->achFormatHint[3]) {
            ReportWarning("aiTexture::achFormatHint must be zero-terminated");
        }
        else if ('.'  == pTexture->achFormatHint[0])    {
            ReportWarning("aiTexture::achFormatHint should contain a file extension "
                "without a leading dot (format hint: %s).",pTexture->achFormatHint);
        }
    }

    const char* sz = pTexture->achFormatHint;
    if ((sz[0] >= 'A' && sz[0] <= 'Z') ||
        (sz[1] >= 'A' && sz[1] <= 'Z') ||
        (sz[2] >= 'A' && sz[2] <= 'Z') ||
        (sz[3] >= 'A' && sz[3] <= 'Z')) {
        ReportError("aiTexture::achFormatHint contains non-lowercase letters");
    }
}

// ------------------------------------------------------------------------------------------------
void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
     const aiNodeAnim* pNodeAnim)
{
    Validate(&pNodeAnim->mNodeName);

    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)
    {
        if (!pNodeAnim->mPositionKeys)
        {
            this->ReportError("aiNodeAnim::mPositionKeys is NULL (aiNodeAnim::mNumPositionKeys is %i)",
                pNodeAnim->mNumPositionKeys);
        }
        double dLast = -10e10;
        for (unsigned int i = 0; i < pNodeAnim->mNumPositionKeys;++i)
        {
            // ScenePreprocessor will compute the duration if still the default value
            // (Aramis) Add small epsilon, comparison tended to fail if max_time == duration,
            //  seems to be due the compilers register usage/width.
            if (pAnimation->mDuration > 0. && pNodeAnim->mPositionKeys[i].mTime > pAnimation->mDuration+0.001)
            {
                ReportError("aiNodeAnim::mPositionKeys[%i].mTime (%.5f) is larger "
                    "than aiAnimation::mDuration (which is %.5f)",i,
                    (float)pNodeAnim->mPositionKeys[i].mTime,
                    (float)pAnimation->mDuration);
            }
            if (i && pNodeAnim->mPositionKeys[i].mTime <= dLast)
            {
                ReportWarning("aiNodeAnim::mPositionKeys[%i].mTime (%.5f) is smaller "
                    "than aiAnimation::mPositionKeys[%i] (which is %.5f)",i,
                    (float)pNodeAnim->mPositionKeys[i].mTime,
                    i-1, (float)dLast);
            }
            dLast = pNodeAnim->mPositionKeys[i].mTime;
        }
    }
    // rotation keys
    if (pNodeAnim->mNumRotationKeys)
    {
        if (!pNodeAnim->mRotationKeys)
        {
            this->ReportError("aiNodeAnim::mRotationKeys is NULL (aiNodeAnim::mNumRotationKeys is %i)",
                pNodeAnim->mNumRotationKeys);
        }
        double dLast = -10e10;
        for (unsigned int i = 0; i < pNodeAnim->mNumRotationKeys;++i)
        {
            if (pAnimation->mDuration > 0. && pNodeAnim->mRotationKeys[i].mTime > pAnimation->mDuration+0.001)
            {
                ReportError("aiNodeAnim::mRotationKeys[%i].mTime (%.5f) is larger "
                    "than aiAnimation::mDuration (which is %.5f)",i,
                    (float)pNodeAnim->mRotationKeys[i].mTime,
                    (float)pAnimation->mDuration);
            }
            if (i && pNodeAnim->mRotationKeys[i].mTime <= dLast)
            {
                ReportWarning("aiNodeAnim::mRotationKeys[%i].mTime (%.5f) is smaller "
                    "than aiAnimation::mRotationKeys[%i] (which is %.5f)",i,
                    (float)pNodeAnim->mRotationKeys[i].mTime,
                    i-1, (float)dLast);
            }
            dLast = pNodeAnim->mRotationKeys[i].mTime;
        }
    }
    // scaling keys
    if (pNodeAnim->mNumScalingKeys)
    {
        if (!pNodeAnim->mScalingKeys)   {
            ReportError("aiNodeAnim::mScalingKeys is NULL (aiNodeAnim::mNumScalingKeys is %i)",
                pNodeAnim->mNumScalingKeys);
        }
        double dLast = -10e10;
        for (unsigned int i = 0; i < pNodeAnim->mNumScalingKeys;++i)
        {
            if (pAnimation->mDuration > 0. && pNodeAnim->mScalingKeys[i].mTime > pAnimation->mDuration+0.001)
            {
                ReportError("aiNodeAnim::mScalingKeys[%i].mTime (%.5f) is larger "
                    "than aiAnimation::mDuration (which is %.5f)",i,
                    (float)pNodeAnim->mScalingKeys[i].mTime,
                    (float)pAnimation->mDuration);
            }
            if (i && pNodeAnim->mScalingKeys[i].mTime <= dLast)
            {
                ReportWarning("aiNodeAnim::mScalingKeys[%i].mTime (%.5f) is smaller "
                    "than aiAnimation::mScalingKeys[%i] (which is %.5f)",i,
                    (float)pNodeAnim->mScalingKeys[i].mTime,
                    i-1, (float)dLast);
            }
            dLast = pNodeAnim->mScalingKeys[i].mTime;
        }
    }

    if (!pNodeAnim->mNumScalingKeys && !pNodeAnim->mNumRotationKeys &&
        !pNodeAnim->mNumPositionKeys)
    {
        ReportError("A node animation channel must have at least one subtrack");
    }
}

// ------------------------------------------------------------------------------------------------
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)");

    this->Validate(&pNode->mName);

    // validate all meshes
    if (pNode->mNumMeshes)
    {
        if (!pNode->mMeshes)
        {
            ReportError("aiNode::mMeshes is NULL (aiNode::mNumMeshes is %i)",
                pNode->mNumMeshes);
        }
        std::vector<bool> abHadMesh;
        abHadMesh.resize(mScene->mNumMeshes,false);
        for (unsigned int i = 0; i < pNode->mNumMeshes;++i)
        {
            if (pNode->mMeshes[i] >= mScene->mNumMeshes)
            {
                ReportError("aiNode::mMeshes[%i] is out of range (maximum is %i)",
                    pNode->mMeshes[i],mScene->mNumMeshes-1);
            }
            if (abHadMesh[pNode->mMeshes[i]])
            {
                ReportError("aiNode::mMeshes[%i] is already referenced by this node (value: %i)",
                    i,pNode->mMeshes[i]);
            }
            abHadMesh[pNode->mMeshes[i]] = true;
        }
    }
    if (pNode->mNumChildren)
    {
        if (!pNode->mChildren)  {
            ReportError("aiNode::mChildren is NULL (aiNode::mNumChildren is %i)",
                pNode->mNumChildren);
        }
        for (unsigned int i = 0; i < pNode->mNumChildren;++i)   {
            Validate(pNode->mChildren[i]);
        }
    }
}

// ------------------------------------------------------------------------------------------------
void ValidateDSProcess::Validate( const aiString* pString)
{
    if (pString->length > MAXLEN)
    {
        this->ReportError("aiString::length is too large (%i, maximum is %i)",
            pString->length,MAXLEN);
    }
    const char* sz = pString->data;
    while (true)
    {
        if ('\0' == *sz)
        {
            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])
            ReportError("aiString::data is invalid. There is no terminal character");
        ++sz;
    }
}
