/*
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 SplitByBoneCountProcess.cpp
/// Implementation of the SplitByBoneCount postprocessing step

// internal headers of the post-processing framework
#include "SplitByBoneCountProcess.h"
#include <assimp/postprocess.h>
#include <assimp/DefaultLogger.hpp>

#include <limits>
#include "TinyFormatter.h"

using namespace Assimp;
using namespace Assimp::Formatter;

// ------------------------------------------------------------------------------------------------
// Constructor
SplitByBoneCountProcess::SplitByBoneCountProcess()
{
    // set default, might be overridden by importer config
    mMaxBoneCount = AI_SBBC_DEFAULT_MAX_BONES;
}

// ------------------------------------------------------------------------------------------------
// Destructor
SplitByBoneCountProcess::~SplitByBoneCountProcess()
{
    // nothing to do here
}

// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag.
bool SplitByBoneCountProcess::IsActive( unsigned int pFlags) const
{
    return !!(pFlags & aiProcess_SplitByBoneCount);
}

// ------------------------------------------------------------------------------------------------
// Updates internal properties
void SplitByBoneCountProcess::SetupProperties(const Importer* pImp)
{
    mMaxBoneCount = pImp->GetPropertyInteger(AI_CONFIG_PP_SBBC_MAX_BONES,AI_SBBC_DEFAULT_MAX_BONES);
}

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

    // early out
    bool isNecessary = false;
    for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
        if( pScene->mMeshes[a]->mNumBones > mMaxBoneCount )
            isNecessary = true;

    if( !isNecessary )
    {
        DefaultLogger::get()->debug( format() << "SplitByBoneCountProcess early-out: no meshes with more than " << mMaxBoneCount << " bones." );
        return;
    }

    // we need to do something. Let's go.
    mSubMeshIndices.clear();
    mSubMeshIndices.resize( pScene->mNumMeshes);

    // build a new array of meshes for the scene
    std::vector<aiMesh*> meshes;

    for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
    {
        aiMesh* srcMesh = pScene->mMeshes[a];

        std::vector<aiMesh*> newMeshes;
        SplitMesh( pScene->mMeshes[a], newMeshes);

        // mesh was split
        if( !newMeshes.empty() )
        {
            // store new meshes and indices of the new meshes
            for( unsigned int b = 0; b < newMeshes.size(); ++b)
            {
                mSubMeshIndices[a].push_back( static_cast<unsigned int>(meshes.size()));
                meshes.push_back( newMeshes[b]);
            }

            // and destroy the source mesh. It should be completely contained inside the new submeshes
            delete srcMesh;
        }
        else
        {
            // Mesh is kept unchanged - store it's new place in the mesh array
            mSubMeshIndices[a].push_back( static_cast<unsigned int>(meshes.size()));
            meshes.push_back( srcMesh);
        }
    }

    // rebuild the scene's mesh array
    pScene->mNumMeshes = static_cast<unsigned int>(meshes.size());
    delete [] pScene->mMeshes;
    pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
    std::copy( meshes.begin(), meshes.end(), pScene->mMeshes);

    // recurse through all nodes and translate the node's mesh indices to fit the new mesh array
    UpdateNode( pScene->mRootNode);

    DefaultLogger::get()->debug( format() << "SplitByBoneCountProcess end: split " << mSubMeshIndices.size() << " meshes into " << meshes.size() << " submeshes." );
}

// ------------------------------------------------------------------------------------------------
// Splits the given mesh by bone count.
void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh*>& poNewMeshes) const
{
    // skip if not necessary
    if( pMesh->mNumBones <= mMaxBoneCount )
        return;

    // necessary optimisation: build a list of all affecting bones for each vertex
    // TODO: (thom) maybe add a custom allocator here to avoid allocating tens of thousands of small arrays
    typedef std::pair<unsigned int, float> BoneWeight;
    std::vector< std::vector<BoneWeight> > vertexBones( pMesh->mNumVertices);
    for( unsigned int a = 0; a < pMesh->mNumBones; ++a)
    {
        const aiBone* bone = pMesh->mBones[a];
        for( unsigned int b = 0; b < bone->mNumWeights; ++b)
            vertexBones[ bone->mWeights[b].mVertexId ].push_back( BoneWeight( a, bone->mWeights[b].mWeight));
    }

    unsigned int numFacesHandled = 0;
    std::vector<bool> isFaceHandled( pMesh->mNumFaces, false);
    while( numFacesHandled < pMesh->mNumFaces )
    {
        // which bones are used in the current submesh
        unsigned int numBones = 0;
        std::vector<bool> isBoneUsed( pMesh->mNumBones, false);
        // indices of the faces which are going to go into this submesh
        std::vector<unsigned int> subMeshFaces;
        subMeshFaces.reserve( pMesh->mNumFaces);
        // accumulated vertex count of all the faces in this submesh
        unsigned int numSubMeshVertices = 0;
        // a small local array of new bones for the current face. State of all used bones for that face
        // can only be updated AFTER the face is completely analysed. Thanks to imre for the fix.
        std::vector<unsigned int> newBonesAtCurrentFace;

        // add faces to the new submesh as long as all bones affecting the faces' vertices fit in the limit
        for( unsigned int a = 0; a < pMesh->mNumFaces; ++a)
        {
            // skip if the face is already stored in a submesh
            if( isFaceHandled[a] )
                continue;

            const aiFace& face = pMesh->mFaces[a];
            // check every vertex if its bones would still fit into the current submesh
            for( unsigned int b = 0; b < face.mNumIndices; ++b )
            {
                const std::vector<BoneWeight>& vb = vertexBones[face.mIndices[b]];
                for( unsigned int c = 0; c < vb.size(); ++c)
                {
                    unsigned int boneIndex = vb[c].first;
                    // if the bone is already used in this submesh, it's ok
                    if( isBoneUsed[boneIndex] )
                        continue;

                    // if it's not used, yet, we would need to add it. Store its bone index
                    if( std::find( newBonesAtCurrentFace.begin(), newBonesAtCurrentFace.end(), boneIndex) == newBonesAtCurrentFace.end() )
                        newBonesAtCurrentFace.push_back( boneIndex);
                }
            }

            // leave out the face if the new bones required for this face don't fit the bone count limit anymore
            if( numBones + newBonesAtCurrentFace.size() > mMaxBoneCount )
                continue;

            // mark all new bones as necessary
            while( !newBonesAtCurrentFace.empty() )
            {
                unsigned int newIndex = newBonesAtCurrentFace.back();
                newBonesAtCurrentFace.pop_back(); // this also avoids the deallocation which comes with a clear()
                if( isBoneUsed[newIndex] )
                    continue;

                isBoneUsed[newIndex] = true;
                numBones++;
            }

            // store the face index and the vertex count
            subMeshFaces.push_back( a);
            numSubMeshVertices += face.mNumIndices;

            // remember that this face is handled
            isFaceHandled[a] = true;
            numFacesHandled++;
        }

        // create a new mesh to hold this subset of the source mesh
        aiMesh* newMesh = new aiMesh;
        if( pMesh->mName.length > 0 )
            newMesh->mName.Set( format() << pMesh->mName.data << "_sub" << poNewMeshes.size());
        newMesh->mMaterialIndex = pMesh->mMaterialIndex;
        newMesh->mPrimitiveTypes = pMesh->mPrimitiveTypes;
        poNewMeshes.push_back( newMesh);

        // create all the arrays for this mesh if the old mesh contained them
        newMesh->mNumVertices = numSubMeshVertices;
        newMesh->mNumFaces = static_cast<unsigned int>(subMeshFaces.size());
        newMesh->mVertices = new aiVector3D[newMesh->mNumVertices];
        if( pMesh->HasNormals() )
            newMesh->mNormals = new aiVector3D[newMesh->mNumVertices];
        if( pMesh->HasTangentsAndBitangents() )
        {
            newMesh->mTangents = new aiVector3D[newMesh->mNumVertices];
            newMesh->mBitangents = new aiVector3D[newMesh->mNumVertices];
        }
        for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
        {
            if( pMesh->HasTextureCoords( a) )
                newMesh->mTextureCoords[a] = new aiVector3D[newMesh->mNumVertices];
            newMesh->mNumUVComponents[a] = pMesh->mNumUVComponents[a];
        }
        for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a )
        {
            if( pMesh->HasVertexColors( a) )
                newMesh->mColors[a] = new aiColor4D[newMesh->mNumVertices];
        }

        // and copy over the data, generating faces with linear indices along the way
        newMesh->mFaces = new aiFace[subMeshFaces.size()];
        unsigned int nvi = 0; // next vertex index
        std::vector<unsigned int> previousVertexIndices( numSubMeshVertices, std::numeric_limits<unsigned int>::max()); // per new vertex: its index in the source mesh
        for( unsigned int a = 0; a < subMeshFaces.size(); ++a )
        {
            const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]];
            aiFace& dstFace = newMesh->mFaces[a];
            dstFace.mNumIndices = srcFace.mNumIndices;
            dstFace.mIndices = new unsigned int[dstFace.mNumIndices];

            // accumulate linearly all the vertices of the source face
            for( unsigned int b = 0; b < dstFace.mNumIndices; ++b )
            {
                unsigned int srcIndex = srcFace.mIndices[b];
                dstFace.mIndices[b] = nvi;
                previousVertexIndices[nvi] = srcIndex;

                newMesh->mVertices[nvi] = pMesh->mVertices[srcIndex];
                if( pMesh->HasNormals() )
                    newMesh->mNormals[nvi] = pMesh->mNormals[srcIndex];
                if( pMesh->HasTangentsAndBitangents() )
                {
                    newMesh->mTangents[nvi] = pMesh->mTangents[srcIndex];
                    newMesh->mBitangents[nvi] = pMesh->mBitangents[srcIndex];
                }
                for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c )
                {
                    if( pMesh->HasTextureCoords( c) )
                        newMesh->mTextureCoords[c][nvi] = pMesh->mTextureCoords[c][srcIndex];
                }
                for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c )
                {
                    if( pMesh->HasVertexColors( c) )
                        newMesh->mColors[c][nvi] = pMesh->mColors[c][srcIndex];
                }

                nvi++;
            }
        }

        ai_assert( nvi == numSubMeshVertices );

        // Create the bones for the new submesh: first create the bone array
        newMesh->mNumBones = 0;
        newMesh->mBones = new aiBone*[numBones];

        std::vector<unsigned int> mappedBoneIndex( pMesh->mNumBones, std::numeric_limits<unsigned int>::max());
        for( unsigned int a = 0; a < pMesh->mNumBones; ++a )
        {
            if( !isBoneUsed[a] )
                continue;

            // create the new bone
            const aiBone* srcBone = pMesh->mBones[a];
            aiBone* dstBone = new aiBone;
            mappedBoneIndex[a] = newMesh->mNumBones;
            newMesh->mBones[newMesh->mNumBones++] = dstBone;
            dstBone->mName = srcBone->mName;
            dstBone->mOffsetMatrix = srcBone->mOffsetMatrix;
            dstBone->mNumWeights = 0;
        }

        ai_assert( newMesh->mNumBones == numBones );

        // iterate over all new vertices and count which bones affected its old vertex in the source mesh
        for( unsigned int a = 0; a < numSubMeshVertices; ++a )
        {
            unsigned int oldIndex = previousVertexIndices[a];
            const std::vector<BoneWeight>& bonesOnThisVertex = vertexBones[oldIndex];

            for( unsigned int b = 0; b < bonesOnThisVertex.size(); ++b )
            {
                unsigned int newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ];
                if( newBoneIndex != std::numeric_limits<unsigned int>::max() )
                    newMesh->mBones[newBoneIndex]->mNumWeights++;
            }
        }

        // allocate all bone weight arrays accordingly
        for( unsigned int a = 0; a < newMesh->mNumBones; ++a )
        {
            aiBone* bone = newMesh->mBones[a];
            ai_assert( bone->mNumWeights > 0 );
            bone->mWeights = new aiVertexWeight[bone->mNumWeights];
            bone->mNumWeights = 0; // for counting up in the next step
        }

        // now copy all the bone vertex weights for all the vertices which made it into the new submesh
        for( unsigned int a = 0; a < numSubMeshVertices; ++a)
        {
            // find the source vertex for it in the source mesh
            unsigned int previousIndex = previousVertexIndices[a];
            // these bones were affecting it
            const std::vector<BoneWeight>& bonesOnThisVertex = vertexBones[previousIndex];
            // all of the bones affecting it should be present in the new submesh, or else
            // the face it comprises shouldn't be present
            for( unsigned int b = 0; b < bonesOnThisVertex.size(); ++b)
            {
                unsigned int newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ];
                ai_assert( newBoneIndex != std::numeric_limits<unsigned int>::max() );
                aiVertexWeight* dstWeight = newMesh->mBones[newBoneIndex]->mWeights + newMesh->mBones[newBoneIndex]->mNumWeights;
                newMesh->mBones[newBoneIndex]->mNumWeights++;

                dstWeight->mVertexId = a;
                dstWeight->mWeight = bonesOnThisVertex[b].second;
            }
        }

        // I have the strange feeling that this will break apart at some point in time...
    }
}

// ------------------------------------------------------------------------------------------------
// Recursively updates the node's mesh list to account for the changed mesh list
void SplitByBoneCountProcess::UpdateNode( aiNode* pNode) const
{
    // rebuild the node's mesh index list
    if( pNode->mNumMeshes > 0 )
    {
        std::vector<unsigned int> newMeshList;
        for( unsigned int a = 0; a < pNode->mNumMeshes; ++a)
        {
            unsigned int srcIndex = pNode->mMeshes[a];
            const std::vector<unsigned int>& replaceMeshes = mSubMeshIndices[srcIndex];
            newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end());
        }

        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);
    }

    // do that also recursively for all children
    for( unsigned int a = 0; a < pNode->mNumChildren; ++a )
    {
        UpdateNode( pNode->mChildren[a]);
    }
}
