/*
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.

----------------------------------------------------------------------
*/

#include "Subdivision.h"
#include <assimp/SceneCombiner.h>
#include "SpatialSort.h"
#include "ProcessHelper.h"
#include "Vertex.h"
#include <assimp/ai_assert.h>
#include <stdio.h>

using namespace Assimp;
void mydummy() {}

// ------------------------------------------------------------------------------------------------
/** Subdivider stub class to implement the Catmull-Clarke subdivision algorithm. The
 *  implementation is basing on recursive refinement. Directly evaluating the result is also
 *  possible and much quicker, but it depends on lengthy matrix lookup tables. */
// ------------------------------------------------------------------------------------------------
class CatmullClarkSubdivider : public Subdivider
{
public:
    void Subdivide (aiMesh* mesh, aiMesh*& out, unsigned int num, bool discard_input);
    void Subdivide (aiMesh** smesh, size_t nmesh,
        aiMesh** out, unsigned int num, bool discard_input);

    // ---------------------------------------------------------------------------
    /** Intermediate description of an edge between two corners of a polygon*/
    // ---------------------------------------------------------------------------
    struct Edge
    {
        Edge()
            : ref(0)
        {}
        Vertex edge_point, midpoint;
        unsigned int ref;
    };

    typedef std::vector<unsigned int> UIntVector;
    typedef std::map<uint64_t,Edge> EdgeMap;

    // ---------------------------------------------------------------------------
    // Hashing function to derive an index into an #EdgeMap from two given
    // 'unsigned int' vertex coordinates (!!distinct coordinates - same
    // vertex position == same index!!).
    // NOTE - this leads to rare hash collisions if a) sizeof(unsigned int)>4
    // and (id[0]>2^32-1 or id[0]>2^32-1).
    // MAKE_EDGE_HASH() uses temporaries, so INIT_EDGE_HASH() needs to be put
    // at the head of every function which is about to use MAKE_EDGE_HASH().
    // Reason is that the hash is that hash construction needs to hold the
    // invariant id0<id1 to identify an edge - else two hashes would refer
    // to the same edge.
    // ---------------------------------------------------------------------------
#define MAKE_EDGE_HASH(id0,id1) (eh_tmp0__=id0,eh_tmp1__=id1,\
    (eh_tmp0__<eh_tmp1__?std::swap(eh_tmp0__,eh_tmp1__):mydummy()),(uint64_t)eh_tmp0__^((uint64_t)eh_tmp1__<<32u))


#define INIT_EDGE_HASH_TEMPORARIES()\
    unsigned int eh_tmp0__, eh_tmp1__;

private:
    void InternSubdivide (const aiMesh* const * smesh,
        size_t nmesh,aiMesh** out, unsigned int num);
};


// ------------------------------------------------------------------------------------------------
// Construct a subdivider of a specific type
Subdivider* Subdivider::Create (Algorithm algo)
{
    switch (algo)
    {
    case CATMULL_CLARKE:
        return new CatmullClarkSubdivider();
    };

    ai_assert(false);
    return NULL; // shouldn't happen
}

// ------------------------------------------------------------------------------------------------
// Call the Catmull Clark subdivision algorithm for one mesh
void  CatmullClarkSubdivider::Subdivide (
    aiMesh* mesh,
    aiMesh*& out,
    unsigned int num,
    bool discard_input
    )
{
    ai_assert(mesh != out);
    
    Subdivide(&mesh,1,&out,num,discard_input);
}

// ------------------------------------------------------------------------------------------------
// Call the Catmull Clark subdivision algorithm for multiple meshes
void CatmullClarkSubdivider::Subdivide (
    aiMesh** smesh,
    size_t nmesh,
    aiMesh** out,
    unsigned int num,
    bool discard_input
    )
{
    ai_assert( NULL != smesh );
    ai_assert( NULL != out );

    // course, both regions may not overlap
    ai_assert(smesh<out || smesh+nmesh>out+nmesh);
    if (!num) {
        // No subdivision at all. Need to copy all the meshes .. argh.
        if (discard_input) {
            for (size_t s = 0; s < nmesh; ++s) {
                out[s] = smesh[s];
                smesh[s] = NULL;
            }
        }
        else {
            for (size_t s = 0; s < nmesh; ++s) {
                SceneCombiner::Copy(out+s,smesh[s]);
            }
        }
        return;
    }

    std::vector<aiMesh*> inmeshes;
    std::vector<aiMesh*> outmeshes;
    std::vector<unsigned int> maptbl;

    inmeshes.reserve(nmesh);
    outmeshes.reserve(nmesh);
    maptbl.reserve(nmesh);

    // Remove pure line and point meshes from the working set to reduce the
    // number of edge cases the subdivider is forced to deal with. Line and
    // point meshes are simply passed through.
    for (size_t s = 0; s < nmesh; ++s) {
        aiMesh* i = smesh[s];
        // FIX - mPrimitiveTypes might not yet be initialized
        if (i->mPrimitiveTypes && (i->mPrimitiveTypes & (aiPrimitiveType_LINE|aiPrimitiveType_POINT))==i->mPrimitiveTypes) {
            DefaultLogger::get()->debug("Catmull-Clark Subdivider: Skipping pure line/point mesh");

            if (discard_input) {
                out[s] = i;
                smesh[s] = NULL;
            }
            else {
                SceneCombiner::Copy(out+s,i);
            }
            continue;
        }

        outmeshes.push_back(NULL);inmeshes.push_back(i);
        maptbl.push_back(static_cast<unsigned int>(s));
    }

    // Do the actual subdivision on the preallocated storage. InternSubdivide
    // *always* assumes that enough storage is available, it does not bother
    // checking any ranges.
    ai_assert(inmeshes.size()==outmeshes.size()&&inmeshes.size()==maptbl.size());
    if (inmeshes.empty()) {
        DefaultLogger::get()->warn("Catmull-Clark Subdivider: Pure point/line scene, I can't do anything");
        return;
    }
    InternSubdivide(&inmeshes.front(),inmeshes.size(),&outmeshes.front(),num);
    for (unsigned int i = 0; i < maptbl.size(); ++i) {
        ai_assert(outmeshes[i]);
        out[maptbl[i]] = outmeshes[i];
    }

    if (discard_input) {
        for (size_t s = 0; s < nmesh; ++s) {
            delete smesh[s];
        }
    }
}

// ------------------------------------------------------------------------------------------------
// Note - this is an implementation of the standard (recursive) Cm-Cl algorithm without further
// optimizations (except we're using some nice LUTs). A description of the algorithm can be found
// here: http://en.wikipedia.org/wiki/Catmull-Clark_subdivision_surface
//
// The code is mostly O(n), however parts are O(nlogn) which is therefore the algorithm's
// expected total runtime complexity. The implementation is able to work in-place on the same
// mesh arrays. Calling #InternSubdivide() directly is not encouraged. The code can operate
// in-place unless 'smesh' and 'out' are equal (no strange overlaps or reorderings).
// Previous data is replaced/deleted then.
// ------------------------------------------------------------------------------------------------
void CatmullClarkSubdivider::InternSubdivide (
    const aiMesh* const * smesh,
    size_t nmesh,
    aiMesh** out,
    unsigned int num
    )
{
    ai_assert(NULL != smesh && NULL != out);
    INIT_EDGE_HASH_TEMPORARIES();

    // no subdivision requested or end of recursive refinement
    if (!num) {
        return;
    }

    UIntVector maptbl;
    SpatialSort spatial;

    // ---------------------------------------------------------------------
    // 0. Offset table to index all meshes continuously, generate a spatially
    // sorted representation of all vertices in all meshes.
    // ---------------------------------------------------------------------
    typedef std::pair<unsigned int,unsigned int> IntPair;
    std::vector<IntPair> moffsets(nmesh);
    unsigned int totfaces = 0, totvert = 0;
    for (size_t t = 0; t < nmesh; ++t) {
        const aiMesh* mesh = smesh[t];

        spatial.Append(mesh->mVertices,mesh->mNumVertices,sizeof(aiVector3D),false);
        moffsets[t] = IntPair(totfaces,totvert);

        totfaces += mesh->mNumFaces;
        totvert  += mesh->mNumVertices;
    }

    spatial.Finalize();
    const unsigned int num_unique = spatial.GenerateMappingTable(maptbl,ComputePositionEpsilon(smesh,nmesh));


#define FLATTEN_VERTEX_IDX(mesh_idx, vert_idx) (moffsets[mesh_idx].second+vert_idx)
#define   FLATTEN_FACE_IDX(mesh_idx, face_idx) (moffsets[mesh_idx].first+face_idx)

    // ---------------------------------------------------------------------
    // 1. Compute the centroid point for all faces
    // ---------------------------------------------------------------------
    std::vector<Vertex> centroids(totfaces);
    unsigned int nfacesout = 0;
    for (size_t t = 0, n = 0; t < nmesh; ++t) {
        const aiMesh* mesh = smesh[t];
        for (unsigned int i = 0; i < mesh->mNumFaces;++i,++n)
        {
            const aiFace& face = mesh->mFaces[i];
            Vertex& c = centroids[n];

            for (unsigned int a = 0; a < face.mNumIndices;++a) {
                c += Vertex(mesh,face.mIndices[a]);
            }

            c /= static_cast<float>(face.mNumIndices);
            nfacesout += face.mNumIndices;
        }
    }

    {
    // we want edges to go away before the recursive calls so begin a new scope
    EdgeMap edges;

    // ---------------------------------------------------------------------
    // 2. Set each edge point to be the average of all neighbouring
    // face points and original points. Every edge exists twice
    // if there is a neighboring face.
    // ---------------------------------------------------------------------
    for (size_t t = 0; t < nmesh; ++t) {
        const aiMesh* mesh = smesh[t];

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

            for (unsigned int p =0; p< face.mNumIndices; ++p) {
                const unsigned int id[] = {
                    face.mIndices[p],
                    face.mIndices[p==face.mNumIndices-1?0:p+1]
                };
                const unsigned int mp[] = {
                    maptbl[FLATTEN_VERTEX_IDX(t,id[0])],
                    maptbl[FLATTEN_VERTEX_IDX(t,id[1])]
                };

                Edge& e = edges[MAKE_EDGE_HASH(mp[0],mp[1])];
                e.ref++;
                if (e.ref<=2) {
                    if (e.ref==1) { // original points (end points) - add only once
                        e.edge_point = e.midpoint = Vertex(mesh,id[0])+Vertex(mesh,id[1]);
                        e.midpoint *= 0.5f;
                    }
                    e.edge_point += centroids[FLATTEN_FACE_IDX(t,i)];
                }
            }
        }
    }

    // ---------------------------------------------------------------------
    // 3. Normalize edge points
    // ---------------------------------------------------------------------
    {unsigned int bad_cnt = 0;
    for (EdgeMap::iterator it = edges.begin(); it != edges.end(); ++it) {
        if ((*it).second.ref < 2) {
            ai_assert((*it).second.ref);
            ++bad_cnt;
        }
        (*it).second.edge_point *= 1.f/((*it).second.ref+2.f);
    }

    if (bad_cnt) {
        // Report the number of bad edges. bad edges are referenced by less than two
        // faces in the mesh. They occur at outer model boundaries in non-closed
        // shapes.
        char tmp[512];
        ai_snprintf(tmp, 512, "Catmull-Clark Subdivider: got %u bad edges touching only one face (totally %u edges). ",
            bad_cnt,static_cast<unsigned int>(edges.size()));

        DefaultLogger::get()->debug(tmp);
    }}

    // ---------------------------------------------------------------------
    // 4. Compute a vertex-face adjacency table. We can't reuse the code
    // from VertexTriangleAdjacency because we need the table for multiple
    // meshes and out vertex indices need to be mapped to distinct values
    // first.
    // ---------------------------------------------------------------------
    UIntVector faceadjac(nfacesout), cntadjfac(maptbl.size(),0), ofsadjvec(maptbl.size()+1,0); {
    for (size_t t = 0; t < nmesh; ++t) {
        const aiMesh* const minp = smesh[t];
        for (unsigned int i = 0; i < minp->mNumFaces; ++i) {

            const aiFace& f = minp->mFaces[i];
            for (unsigned int n = 0; n < f.mNumIndices; ++n) {
                ++cntadjfac[maptbl[FLATTEN_VERTEX_IDX(t,f.mIndices[n])]];
            }
        }
    }
    unsigned int cur = 0;
    for (size_t i = 0; i < cntadjfac.size(); ++i) {
        ofsadjvec[i+1] = cur;
        cur += cntadjfac[i];
    }
    for (size_t t = 0; t < nmesh; ++t) {
        const aiMesh* const minp = smesh[t];
        for (unsigned int i = 0; i < minp->mNumFaces; ++i) {

            const aiFace& f = minp->mFaces[i];
            for (unsigned int n = 0; n < f.mNumIndices; ++n) {
                faceadjac[ofsadjvec[1+maptbl[FLATTEN_VERTEX_IDX(t,f.mIndices[n])]]++] = FLATTEN_FACE_IDX(t,i);
            }
        }
    }

    // check the other way round for consistency
#ifdef ASSIMP_BUILD_DEBUG

    for (size_t t = 0; t < ofsadjvec.size()-1; ++t) {
        for (unsigned int m = 0; m <  cntadjfac[t]; ++m) {
            const unsigned int fidx = faceadjac[ofsadjvec[t]+m];
            ai_assert(fidx < totfaces);
            for (size_t n = 1; n < nmesh; ++n) {

                if (moffsets[n].first > fidx) {
                    const aiMesh* msh = smesh[--n];
                    const aiFace& f = msh->mFaces[fidx-moffsets[n].first];

                    bool haveit = false;
                    for (unsigned int i = 0; i < f.mNumIndices; ++i) {
                        if (maptbl[FLATTEN_VERTEX_IDX(n,f.mIndices[i])]==(unsigned int)t) {
                            haveit = true;
                            break;
                        }
                    }
                    ai_assert(haveit);
                    if (!haveit) {
                        DefaultLogger::get()->debug("Catmull-Clark Subdivider: Index not used");
                    }
                    break;
                }
            }
        }
    }

#endif
    }

#define GET_ADJACENT_FACES_AND_CNT(vidx,fstartout,numout) \
    fstartout = &faceadjac[ofsadjvec[vidx]], numout = cntadjfac[vidx]

    typedef std::pair<bool,Vertex> TouchedOVertex;
    std::vector<TouchedOVertex > new_points(num_unique,TouchedOVertex(false,Vertex()));
    // ---------------------------------------------------------------------
    // 5. Spawn a quad from each face point to the corresponding edge points
    // the original points being the fourth quad points.
    // ---------------------------------------------------------------------
    for (size_t t = 0; t < nmesh; ++t) {
        const aiMesh* const minp = smesh[t];
        aiMesh* const mout = out[t] = new aiMesh();

        for (unsigned int a  = 0; a < minp->mNumFaces; ++a) {
            mout->mNumFaces += minp->mFaces[a].mNumIndices;
        }

        // We need random access to the old face buffer, so reuse is not possible.
        mout->mFaces = new aiFace[mout->mNumFaces];

        mout->mNumVertices = mout->mNumFaces*4;
        mout->mVertices = new aiVector3D[mout->mNumVertices];

        // quads only, keep material index
        mout->mPrimitiveTypes = aiPrimitiveType_POLYGON;
        mout->mMaterialIndex = minp->mMaterialIndex;

        if (minp->HasNormals()) {
            mout->mNormals = new aiVector3D[mout->mNumVertices];
        }

        if (minp->HasTangentsAndBitangents()) {
            mout->mTangents = new aiVector3D[mout->mNumVertices];
            mout->mBitangents = new aiVector3D[mout->mNumVertices];
        }

        for(unsigned int i = 0; minp->HasTextureCoords(i); ++i) {
            mout->mTextureCoords[i] = new aiVector3D[mout->mNumVertices];
            mout->mNumUVComponents[i] = minp->mNumUVComponents[i];
        }

        for(unsigned int i = 0; minp->HasVertexColors(i); ++i) {
            mout->mColors[i] = new aiColor4D[mout->mNumVertices];
        }

        mout->mNumVertices = mout->mNumFaces<<2u;
        for (unsigned int i = 0, v = 0, n = 0; i < minp->mNumFaces;++i) {

            const aiFace& face = minp->mFaces[i];
            for (unsigned int a = 0; a < face.mNumIndices;++a)  {

                // Get a clean new face.
                aiFace& faceOut = mout->mFaces[n++];
                faceOut.mIndices = new unsigned int [faceOut.mNumIndices = 4];

                // Spawn a new quadrilateral (ccw winding) for this original point between:
                // a) face centroid
                centroids[FLATTEN_FACE_IDX(t,i)].SortBack(mout,faceOut.mIndices[0]=v++);

                // b) adjacent edge on the left, seen from the centroid
                const Edge& e0 = edges[MAKE_EDGE_HASH(maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a])],
                    maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a==face.mNumIndices-1?0:a+1])
                    ])];  // fixme: replace with mod face.mNumIndices?

                // c) adjacent edge on the right, seen from the centroid
                const Edge& e1 = edges[MAKE_EDGE_HASH(maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a])],
                    maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[!a?face.mNumIndices-1:a-1])
                    ])];  // fixme: replace with mod face.mNumIndices?

                e0.edge_point.SortBack(mout,faceOut.mIndices[3]=v++);
                e1.edge_point.SortBack(mout,faceOut.mIndices[1]=v++);

                // d= original point P with distinct index i
                // F := 0
                // R := 0
                // n := 0
                // for each face f containing i
                //    F := F+ centroid of f
                //    R := R+ midpoint of edge of f from i to i+1
                //    n := n+1
                //
                // (F+2R+(n-3)P)/n
                const unsigned int org = maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a])];
                TouchedOVertex& ov = new_points[org];

                if (!ov.first) {
                    ov.first = true;

                    const unsigned int* adj; unsigned int cnt;
                    GET_ADJACENT_FACES_AND_CNT(org,adj,cnt);

                    if (cnt < 3) {
                        ov.second = Vertex(minp,face.mIndices[a]);
                    }
                    else {

                        Vertex F,R;
                        for (unsigned int o = 0; o < cnt; ++o) {
                            ai_assert(adj[o] < totfaces);
                            F += centroids[adj[o]];

                            // adj[0] is a global face index - search the face in the mesh list
                            const aiMesh* mp = NULL;
                            size_t nidx;

                            if (adj[o] < moffsets[0].first) {
                                mp = smesh[nidx=0];
                            }
                            else {
                                for (nidx = 1; nidx<= nmesh; ++nidx) {
                                    if (nidx == nmesh ||moffsets[nidx].first > adj[o]) {
                                        mp = smesh[--nidx];
                                        break;
                                    }
                                }
                            }

                            ai_assert(adj[o]-moffsets[nidx].first < mp->mNumFaces);
                            const aiFace& f = mp->mFaces[adj[o]-moffsets[nidx].first];
                            bool haveit = false;

                            // find our original point in the face
                            for (unsigned int m = 0; m < f.mNumIndices; ++m) {
                                if (maptbl[FLATTEN_VERTEX_IDX(nidx,f.mIndices[m])] == org) {

                                    // add *both* edges. this way, we can be sure that we add
                                    // *all* adjacent edges to R. In a closed shape, every
                                    // edge is added twice - so we simply leave out the
                                    // factor 2.f in the amove formula and get the right
                                    // result.

                                    const Edge& c0 = edges[MAKE_EDGE_HASH(org,maptbl[FLATTEN_VERTEX_IDX(
                                        nidx,f.mIndices[!m?f.mNumIndices-1:m-1])])];
                                    // fixme: replace with mod face.mNumIndices?

                                    const Edge& c1 = edges[MAKE_EDGE_HASH(org,maptbl[FLATTEN_VERTEX_IDX(
                                        nidx,f.mIndices[m==f.mNumIndices-1?0:m+1])])];
                                    // fixme: replace with mod face.mNumIndices?
                                    R += c0.midpoint+c1.midpoint;

                                    haveit = true;
                                    break;
                                }
                            }

                            // this invariant *must* hold if the vertex-to-face adjacency table is valid
                            ai_assert(haveit);
                            if ( !haveit ) {
                                DefaultLogger::get()->warn( "OBJ: no name for material library specified." );
                            }
                        }

                        const float div = static_cast<float>(cnt), divsq = 1.f/(div*div);
                        ov.second = Vertex(minp,face.mIndices[a])*((div-3.f) / div) + R*divsq + F*divsq;
                    }
                }
                ov.second.SortBack(mout,faceOut.mIndices[2]=v++);
            }
        }
    }
    }  // end of scope for edges, freeing its memory

    // ---------------------------------------------------------------------
    // 7. Apply the next subdivision step.
    // ---------------------------------------------------------------------
    if (num != 1) {
        std::vector<aiMesh*> tmp(nmesh);
        InternSubdivide (out,nmesh,&tmp.front(),num-1);
        for (size_t i = 0; i < nmesh; ++i) {
            delete out[i];
            out[i] = tmp[i];
        }
    }
}
