/*
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 Implementation of the SplitLargeMeshes postprocessing step
*/



// internal headers of the post-processing framework
#include "SplitLargeMeshes.h"
#include "ProcessHelper.h"

using namespace Assimp;


// ------------------------------------------------------------------------------------------------
SplitLargeMeshesProcess_Triangle::SplitLargeMeshesProcess_Triangle()
{
    LIMIT = AI_SLM_DEFAULT_MAX_TRIANGLES;
}

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

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

// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void SplitLargeMeshesProcess_Triangle::Execute( aiScene* pScene)
{
    if (0xffffffff == this->LIMIT)return;

    DefaultLogger::get()->debug("SplitLargeMeshesProcess_Triangle begin");
    std::vector<std::pair<aiMesh*, unsigned int> > avList;

    for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
        this->SplitMesh(a, pScene->mMeshes[a],avList);

    if (avList.size() != pScene->mNumMeshes)
    {
        // it seems something has been split. rebuild the mesh list
        delete[] pScene->mMeshes;
        pScene->mNumMeshes = (unsigned int)avList.size();
        pScene->mMeshes = new aiMesh*[avList.size()];

        for (unsigned int i = 0; i < avList.size();++i)
            pScene->mMeshes[i] = avList[i].first;

        // now we need to update all nodes
        this->UpdateNode(pScene->mRootNode,avList);
        DefaultLogger::get()->info("SplitLargeMeshesProcess_Triangle finished. Meshes have been split");
    }
    else DefaultLogger::get()->debug("SplitLargeMeshesProcess_Triangle finished. There was nothing to do");
    return;
}

// ------------------------------------------------------------------------------------------------
// Setup properties
void SplitLargeMeshesProcess_Triangle::SetupProperties( const Importer* pImp)
{
    // get the current value of the split property
    this->LIMIT = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT,AI_SLM_DEFAULT_MAX_TRIANGLES);
}

// ------------------------------------------------------------------------------------------------
// Update a node after some meshes have been split
void SplitLargeMeshesProcess_Triangle::UpdateNode(aiNode* pcNode,
    const std::vector<std::pair<aiMesh*, unsigned int> >& avList)
{
    // for every index in out list build a new entry
    std::vector<unsigned int> aiEntries;
    aiEntries.reserve(pcNode->mNumMeshes + 1);
    for (unsigned int i = 0; i < pcNode->mNumMeshes;++i)
    {
        for (unsigned int a = 0; a < avList.size();++a)
        {
            if (avList[a].second == pcNode->mMeshes[i])
            {
                aiEntries.push_back(a);
            }
        }
    }

    // now build the new list
    delete[] pcNode->mMeshes;
    pcNode->mNumMeshes = (unsigned int)aiEntries.size();
    pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];

    for (unsigned int b = 0; b < pcNode->mNumMeshes;++b)
        pcNode->mMeshes[b] = aiEntries[b];

    // recusively update all other nodes
    for (unsigned int i = 0; i < pcNode->mNumChildren;++i)
    {
        UpdateNode ( pcNode->mChildren[i], avList );
    }
    return;
}

// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void SplitLargeMeshesProcess_Triangle::SplitMesh(
    unsigned int a,
    aiMesh* pMesh,
    std::vector<std::pair<aiMesh*, unsigned int> >& avList)
{
    if (pMesh->mNumFaces > SplitLargeMeshesProcess_Triangle::LIMIT)
    {
        DefaultLogger::get()->info("Mesh exceeds the triangle limit. It will be split ...");

        // we need to split this mesh into sub meshes
        // determine the size of a submesh
        const unsigned int iSubMeshes = (pMesh->mNumFaces / LIMIT) + 1;

        const unsigned int iOutFaceNum = pMesh->mNumFaces / iSubMeshes;
        const unsigned int iOutVertexNum = iOutFaceNum * 3;

        // now generate all submeshes
        for (unsigned int i = 0; i < iSubMeshes;++i)
        {
            aiMesh* pcMesh          = new aiMesh;
            pcMesh->mNumFaces       = iOutFaceNum;
            pcMesh->mMaterialIndex  = pMesh->mMaterialIndex;

            // the name carries the adjacency information between the meshes
            pcMesh->mName = pMesh->mName;

            if (i == iSubMeshes-1)
            {
                pcMesh->mNumFaces = iOutFaceNum + (
                    pMesh->mNumFaces - iOutFaceNum * iSubMeshes);
            }
            // copy the list of faces
            pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];

            const unsigned int iBase = iOutFaceNum * i;

            // get the total number of indices
            unsigned int iCnt = 0;
            for (unsigned int p = iBase; p < pcMesh->mNumFaces + iBase;++p)
            {
                iCnt += pMesh->mFaces[p].mNumIndices;
            }
            pcMesh->mNumVertices = iCnt;

            // allocate storage
            if (pMesh->mVertices != NULL)
                pcMesh->mVertices = new aiVector3D[iCnt];

            if (pMesh->HasNormals())
                pcMesh->mNormals = new aiVector3D[iCnt];

            if (pMesh->HasTangentsAndBitangents())
            {
                pcMesh->mTangents = new aiVector3D[iCnt];
                pcMesh->mBitangents = new aiVector3D[iCnt];
            }

            // texture coordinates
            for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
            {
                pcMesh->mNumUVComponents[c] = pMesh->mNumUVComponents[c];
                if (pMesh->HasTextureCoords( c))
                {
                    pcMesh->mTextureCoords[c] = new aiVector3D[iCnt];
                }
            }

            // vertex colors
            for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_COLOR_SETS;++c)
            {
                if (pMesh->HasVertexColors( c))
                {
                    pcMesh->mColors[c] = new aiColor4D[iCnt];
                }
            }

            if (pMesh->HasBones())
            {
                // assume the number of bones won't change in most cases
                pcMesh->mBones = new aiBone*[pMesh->mNumBones];

                // iterate through all bones of the mesh and find those which
                // need to be copied to the split mesh
                std::vector<aiVertexWeight> avTempWeights;
                for (unsigned int p = 0; p < pcMesh->mNumBones;++p)
                {
                    aiBone* const bone = pcMesh->mBones[p];
                    avTempWeights.clear();
                    avTempWeights.reserve(bone->mNumWeights / iSubMeshes);

                    for (unsigned int q = 0; q < bone->mNumWeights;++q)
                    {
                        aiVertexWeight& weight = bone->mWeights[q];
                        if(weight.mVertexId >= iBase && weight.mVertexId < iBase + iOutVertexNum)
                        {
                            avTempWeights.push_back(weight);
                            weight = avTempWeights.back();
                            weight.mVertexId -= iBase;
                        }
                    }

                    if (!avTempWeights.empty())
                    {
                        // we'll need this bone. Copy it ...
                        aiBone* pc = new aiBone();
                        pcMesh->mBones[pcMesh->mNumBones++] = pc;
                        pc->mName = aiString(bone->mName);
                        pc->mNumWeights = (unsigned int)avTempWeights.size();
                        pc->mOffsetMatrix = bone->mOffsetMatrix;

                        // no need to reallocate the array for the last submesh.
                        // Here we can reuse the (large) source array, although
                        // we'll waste some memory
                        if (iSubMeshes-1 == i)
                        {
                            pc->mWeights = bone->mWeights;
                            bone->mWeights = NULL;
                        }
                        else pc->mWeights = new aiVertexWeight[pc->mNumWeights];

                        // copy the weights
                        ::memcpy(pc->mWeights,&avTempWeights[0],sizeof(aiVertexWeight)*pc->mNumWeights);
                    }
                }
            }

            // (we will also need to copy the array of indices)
            unsigned int iCurrent = 0;
            for (unsigned int p = 0; p < pcMesh->mNumFaces;++p)
            {
                pcMesh->mFaces[p].mNumIndices = 3;
                // allocate a new array
                const unsigned int iTemp = p + iBase;
                const unsigned int iNumIndices = pMesh->mFaces[iTemp].mNumIndices;

                // setup face type and number of indices
                pcMesh->mFaces[p].mNumIndices = iNumIndices;
                unsigned int* pi = pMesh->mFaces[iTemp].mIndices;
                unsigned int* piOut = pcMesh->mFaces[p].mIndices = new unsigned int[iNumIndices];

                // need to update the output primitive types
                switch (iNumIndices)
                {
                case 1:
                    pcMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
                    break;
                case 2:
                    pcMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
                    break;
                case 3:
                    pcMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
                    break;
                default:
                    pcMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
                }

                // and copy the contents of the old array, offset by current base
                for (unsigned int v = 0; v < iNumIndices;++v)
                {
                    unsigned int iIndex = pi[v];
                    unsigned int iIndexOut = iCurrent++;
                    piOut[v] = iIndexOut;

                    // copy positions
                    if (pMesh->mVertices != NULL)
                        pcMesh->mVertices[iIndexOut] = pMesh->mVertices[iIndex];

                    // copy normals
                    if (pMesh->HasNormals())
                        pcMesh->mNormals[iIndexOut] = pMesh->mNormals[iIndex];

                    // copy tangents/bitangents
                    if (pMesh->HasTangentsAndBitangents())
                    {
                        pcMesh->mTangents[iIndexOut] = pMesh->mTangents[iIndex];
                        pcMesh->mBitangents[iIndexOut] = pMesh->mBitangents[iIndex];
                    }

                    // texture coordinates
                    for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
                    {
                        if (pMesh->HasTextureCoords( c))
                            pcMesh->mTextureCoords[c][iIndexOut] = pMesh->mTextureCoords[c][iIndex];
                    }
                    // vertex colors
                    for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_COLOR_SETS;++c)
                    {
                        if (pMesh->HasVertexColors( c))
                            pcMesh->mColors[c][iIndexOut] = pMesh->mColors[c][iIndex];
                    }
                }
            }

            // add the newly created mesh to the list
            avList.push_back(std::pair<aiMesh*, unsigned int>(pcMesh,a));
        }

        // now delete the old mesh data
        delete pMesh;
    }
    else avList.push_back(std::pair<aiMesh*, unsigned int>(pMesh,a));
    return;
}

// ------------------------------------------------------------------------------------------------
SplitLargeMeshesProcess_Vertex::SplitLargeMeshesProcess_Vertex()
{
    LIMIT = AI_SLM_DEFAULT_MAX_VERTICES;
}

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

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

// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void SplitLargeMeshesProcess_Vertex::Execute( aiScene* pScene)
{
    std::vector<std::pair<aiMesh*, unsigned int> > avList;

    if (0xffffffff == this->LIMIT)return;

    DefaultLogger::get()->debug("SplitLargeMeshesProcess_Vertex begin");
    for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
        this->SplitMesh(a, pScene->mMeshes[a],avList);

    if (avList.size() != pScene->mNumMeshes)
    {
        // it seems something has been split. rebuild the mesh list
        delete[] pScene->mMeshes;
        pScene->mNumMeshes = (unsigned int)avList.size();
        pScene->mMeshes = new aiMesh*[avList.size()];

        for (unsigned int i = 0; i < avList.size();++i)
            pScene->mMeshes[i] = avList[i].first;

        // now we need to update all nodes
        SplitLargeMeshesProcess_Triangle::UpdateNode(pScene->mRootNode,avList);
        DefaultLogger::get()->info("SplitLargeMeshesProcess_Vertex finished. Meshes have been split");
    }
    else DefaultLogger::get()->debug("SplitLargeMeshesProcess_Vertex finished. There was nothing to do");
    return;
}

// ------------------------------------------------------------------------------------------------
// Setup properties
void SplitLargeMeshesProcess_Vertex::SetupProperties( const Importer* pImp)
{
    this->LIMIT = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT,AI_SLM_DEFAULT_MAX_VERTICES);
}

// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void SplitLargeMeshesProcess_Vertex::SplitMesh(
    unsigned int a,
    aiMesh* pMesh,
    std::vector<std::pair<aiMesh*, unsigned int> >& avList)
{
    if (pMesh->mNumVertices > SplitLargeMeshesProcess_Vertex::LIMIT)
    {
        typedef std::vector< std::pair<unsigned int,float> > VertexWeightTable;

        // build a per-vertex weight list if necessary
        VertexWeightTable* avPerVertexWeights = ComputeVertexBoneWeightTable(pMesh);

        // we need to split this mesh into sub meshes
        // determine the estimated size of a submesh
        // (this could be too large. Max waste is a single digit percentage)
        const unsigned int iSubMeshes = (pMesh->mNumVertices / SplitLargeMeshesProcess_Vertex::LIMIT) + 1;
        //const unsigned int iOutVertexNum2 = pMesh->mNumVertices /iSubMeshes;

        // create a std::vector<unsigned int> to indicate which vertices
        // have already been copied
        std::vector<unsigned int> avWasCopied;
        avWasCopied.resize(pMesh->mNumVertices,0xFFFFFFFF);

        // try to find a good estimate for the number of output faces
        // per mesh. Add 12.5% as buffer
        unsigned int iEstimatedSize = pMesh->mNumFaces / iSubMeshes;
        iEstimatedSize += iEstimatedSize >> 3;

        // now generate all submeshes
        unsigned int iBase = 0;
        while (true)
        {
            const unsigned int iOutVertexNum = SplitLargeMeshesProcess_Vertex::LIMIT;

            aiMesh* pcMesh          = new aiMesh;
            pcMesh->mNumVertices    = 0;
            pcMesh->mMaterialIndex  = pMesh->mMaterialIndex;

            // the name carries the adjacency information between the meshes
            pcMesh->mName = pMesh->mName;

            typedef std::vector<aiVertexWeight> BoneWeightList;
            if (pMesh->HasBones())
            {
                pcMesh->mBones = new aiBone*[pMesh->mNumBones];
                ::memset(pcMesh->mBones,0,sizeof(void*)*pMesh->mNumBones);
            }

            // clear the temporary helper array
            if (iBase)
            {
                // we can't use memset here we unsigned int needn' be 32 bits
                for (auto &elem : avWasCopied)
                {
                    elem = 0xffffffff;
                }
            }

            // output vectors
            std::vector<aiFace> vFaces;

            // reserve enough storage for most cases
            if (pMesh->HasPositions())
            {
                pcMesh->mVertices = new aiVector3D[iOutVertexNum];
            }
            if (pMesh->HasNormals())
            {
                pcMesh->mNormals = new aiVector3D[iOutVertexNum];
            }
            if (pMesh->HasTangentsAndBitangents())
            {
                pcMesh->mTangents = new aiVector3D[iOutVertexNum];
                pcMesh->mBitangents = new aiVector3D[iOutVertexNum];
            }
            for (unsigned int c = 0; pMesh->HasVertexColors(c);++c)
            {
                pcMesh->mColors[c] = new aiColor4D[iOutVertexNum];
            }
            for (unsigned int c = 0; pMesh->HasTextureCoords(c);++c)
            {
                pcMesh->mNumUVComponents[c] = pMesh->mNumUVComponents[c];
                pcMesh->mTextureCoords[c] = new aiVector3D[iOutVertexNum];
            }
            vFaces.reserve(iEstimatedSize);

            // (we will also need to copy the array of indices)
            while (iBase < pMesh->mNumFaces)
            {
                // allocate a new array
                const unsigned int iNumIndices = pMesh->mFaces[iBase].mNumIndices;

                // doesn't catch degenerates but is quite fast
                unsigned int iNeed = 0;
                for (unsigned int v = 0; v < iNumIndices;++v)
                {
                    unsigned int iIndex = pMesh->mFaces[iBase].mIndices[v];

                    // check whether we do already have this vertex
                    if (0xFFFFFFFF == avWasCopied[iIndex])
                    {
                        iNeed++;
                    }
                }
                if (pcMesh->mNumVertices + iNeed > iOutVertexNum)
                {
                    // don't use this face
                    break;
                }

                vFaces.push_back(aiFace());
                aiFace& rFace = vFaces.back();

                // setup face type and number of indices
                rFace.mNumIndices = iNumIndices;
                rFace.mIndices = new unsigned int[iNumIndices];

                // need to update the output primitive types
                switch (rFace.mNumIndices)
                {
                case 1:
                    pcMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
                    break;
                case 2:
                    pcMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
                    break;
                case 3:
                    pcMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
                    break;
                default:
                    pcMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
                }

                // and copy the contents of the old array, offset by current base
                for (unsigned int v = 0; v < iNumIndices;++v)
                {
                    unsigned int iIndex = pMesh->mFaces[iBase].mIndices[v];

                    // check whether we do already have this vertex
                    if (0xFFFFFFFF != avWasCopied[iIndex])
                    {
                        rFace.mIndices[v] = avWasCopied[iIndex];
                        continue;
                    }

                    // copy positions
                    pcMesh->mVertices[pcMesh->mNumVertices] = (pMesh->mVertices[iIndex]);

                    // copy normals
                    if (pMesh->HasNormals())
                    {
                        pcMesh->mNormals[pcMesh->mNumVertices] = (pMesh->mNormals[iIndex]);
                    }

                    // copy tangents/bitangents
                    if (pMesh->HasTangentsAndBitangents())
                    {
                        pcMesh->mTangents[pcMesh->mNumVertices] = (pMesh->mTangents[iIndex]);
                        pcMesh->mBitangents[pcMesh->mNumVertices] = (pMesh->mBitangents[iIndex]);
                    }

                    // texture coordinates
                    for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
                    {
                        if (pMesh->HasTextureCoords( c))
                        {
                            pcMesh->mTextureCoords[c][pcMesh->mNumVertices] = pMesh->mTextureCoords[c][iIndex];
                        }
                    }
                    // vertex colors
                    for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_COLOR_SETS;++c)
                    {
                        if (pMesh->HasVertexColors( c))
                        {
                            pcMesh->mColors[c][pcMesh->mNumVertices] = pMesh->mColors[c][iIndex];
                        }
                    }
                    // check whether we have bone weights assigned to this vertex
                    rFace.mIndices[v] = pcMesh->mNumVertices;
                    if (avPerVertexWeights)
                    {
                        VertexWeightTable& table = avPerVertexWeights[ pcMesh->mNumVertices ];
                        if( !table.empty() )
                        {
                            for (VertexWeightTable::const_iterator
                                iter =  table.begin();
                                iter != table.end();++iter)
                            {
                                // allocate the bone weight array if necessary
                                BoneWeightList* pcWeightList = (BoneWeightList*)pcMesh->mBones[(*iter).first];
                                if (!pcWeightList)
                                {
                                    pcMesh->mBones[(*iter).first] = (aiBone*)(pcWeightList = new BoneWeightList());
                                }
                                pcWeightList->push_back(aiVertexWeight(pcMesh->mNumVertices,(*iter).second));
                            }
                        }
                    }

                    avWasCopied[iIndex] = pcMesh->mNumVertices;
                    pcMesh->mNumVertices++;
                }
                iBase++;
                if(pcMesh->mNumVertices == iOutVertexNum)
                {
                    // break here. The face is only added if it was complete
                    break;
                }
            }

            // check which bones we'll need to create for this submesh
            if (pMesh->HasBones())
            {
                aiBone** ppCurrent = pcMesh->mBones;
                for (unsigned int k = 0; k < pMesh->mNumBones;++k)
                {
                    // check whether the bone is existing
                    BoneWeightList* pcWeightList;
                    if ((pcWeightList = (BoneWeightList*)pcMesh->mBones[k]))
                    {
                        aiBone* pcOldBone = pMesh->mBones[k];
                        aiBone* pcOut;
                        *ppCurrent++ = pcOut = new aiBone();
                        pcOut->mName = aiString(pcOldBone->mName);
                        pcOut->mOffsetMatrix = pcOldBone->mOffsetMatrix;
                        pcOut->mNumWeights = (unsigned int)pcWeightList->size();
                        pcOut->mWeights = new aiVertexWeight[pcOut->mNumWeights];

                        // copy the vertex weights
                        ::memcpy(pcOut->mWeights,&pcWeightList->operator[](0),
                            pcOut->mNumWeights * sizeof(aiVertexWeight));

                        // delete the temporary bone weight list
                        delete pcWeightList;
                        pcMesh->mNumBones++;
                    }
                }
            }

            // copy the face list to the mesh
            pcMesh->mFaces = new aiFace[vFaces.size()];
            pcMesh->mNumFaces = (unsigned int)vFaces.size();

            for (unsigned int p = 0; p < pcMesh->mNumFaces;++p)
                pcMesh->mFaces[p] = vFaces[p];

            // add the newly created mesh to the list
            avList.push_back(std::pair<aiMesh*, unsigned int>(pcMesh,a));

            if (iBase == pMesh->mNumFaces)
            {
                // have all faces ... finish the outer loop, too
                break;
            }
        }

        // delete the per-vertex weight list again
        delete[] avPerVertexWeights;

        // now delete the old mesh data
        delete pMesh;
        return;
    }
    avList.push_back(std::pair<aiMesh*, unsigned int>(pMesh,a));
    return;
}
