コード例 #1
0
ファイル: BlenderLoader.cpp プロジェクト: fluffyfreak/assimp
// ------------------------------------------------------------------------------------------------
void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, const Mesh* mesh,
    ConversionData& conv_data, TempArray<std::vector,aiMesh>&  temp
    )
{
    // TODO: Resolve various problems with BMesh triangulation before re-enabling.
    //       See issues #400, #373, #318  #315 and #132.
#if defined(TODO_FIX_BMESH_CONVERSION)
    BlenderBMeshConverter BMeshConverter( mesh );
    if ( BMeshConverter.ContainsBMesh( ) )
    {
        mesh = BMeshConverter.TriangulateBMesh( );
    }
#endif

    typedef std::pair<const int,size_t> MyPair;
    if ((!mesh->totface && !mesh->totloop) || !mesh->totvert) {
        return;
    }

    // some sanity checks
    if (static_cast<size_t> ( mesh->totface ) > mesh->mface.size() ){
        ThrowException("Number of faces is larger than the corresponding array");
    }

    if (static_cast<size_t> ( mesh->totvert ) > mesh->mvert.size()) {
        ThrowException("Number of vertices is larger than the corresponding array");
    }

    if (static_cast<size_t> ( mesh->totloop ) > mesh->mloop.size()) {
        ThrowException("Number of vertices is larger than the corresponding array");
    }

    // collect per-submesh numbers
    std::map<int,size_t> per_mat;
    std::map<int,size_t> per_mat_verts;
    for (int i = 0; i < mesh->totface; ++i) {

        const MFace& mf = mesh->mface[i];
        per_mat[ mf.mat_nr ]++;
        per_mat_verts[ mf.mat_nr ] += mf.v4?4:3;
    }

    for (int i = 0; i < mesh->totpoly; ++i) {
        const MPoly& mp = mesh->mpoly[i];
        per_mat[ mp.mat_nr ]++;
        per_mat_verts[ mp.mat_nr ] += mp.totloop;
    }

    // ... and allocate the corresponding meshes
    const size_t old = temp->size();
    temp->reserve(temp->size() + per_mat.size());

    std::map<size_t,size_t> mat_num_to_mesh_idx;
    for(MyPair& it : per_mat) {

        mat_num_to_mesh_idx[it.first] = temp->size();
        temp->push_back(new aiMesh());

        aiMesh* out = temp->back();
        out->mVertices = new aiVector3D[per_mat_verts[it.first]];
        out->mNormals  = new aiVector3D[per_mat_verts[it.first]];

        //out->mNumFaces = 0
        //out->mNumVertices = 0
        out->mFaces = new aiFace[it.second]();

        // all sub-meshes created from this mesh are named equally. this allows
        // curious users to recover the original adjacency.
        out->mName = aiString(mesh->id.name+2);
            // skip over the name prefix 'ME'

        // resolve the material reference and add this material to the set of
        // output materials. The (temporary) material index is the index
        // of the material entry within the list of resolved materials.
        if (mesh->mat) {

            if (static_cast<size_t> ( it.first ) >= mesh->mat.size() ) {
                ThrowException("Material index is out of range");
            }

            std::shared_ptr<Material> mat = mesh->mat[it.first];
            const std::deque< std::shared_ptr<Material> >::iterator has = std::find(
                    conv_data.materials_raw.begin(),
                    conv_data.materials_raw.end(),mat
            );

            if (has != conv_data.materials_raw.end()) {
                out->mMaterialIndex = static_cast<unsigned int>( std::distance(conv_data.materials_raw.begin(),has));
            }
            else {
                out->mMaterialIndex = static_cast<unsigned int>( conv_data.materials_raw.size() );
                conv_data.materials_raw.push_back(mat);
            }
        }
        else out->mMaterialIndex = static_cast<unsigned int>( -1 );
    }

    for (int i = 0; i < mesh->totface; ++i) {

        const MFace& mf = mesh->mface[i];

        aiMesh* const out = temp[ mat_num_to_mesh_idx[ mf.mat_nr ] ];
        aiFace& f = out->mFaces[out->mNumFaces++];

        f.mIndices = new unsigned int[ f.mNumIndices = mf.v4?4:3 ];
        aiVector3D* vo = out->mVertices + out->mNumVertices;
        aiVector3D* vn = out->mNormals + out->mNumVertices;

        // XXX we can't fold this easily, because we are restricted
        // to the member names from the BLEND file (v1,v2,v3,v4)
        // which are assigned by the genblenddna.py script and
        // cannot be changed without breaking the entire
        // import process.

        if (mf.v1 >= mesh->totvert) {
            ThrowException("Vertex index v1 out of range");
        }
        const MVert* v = &mesh->mvert[mf.v1];
        vo->x = v->co[0];
        vo->y = v->co[1];
        vo->z = v->co[2];
        vn->x = v->no[0];
        vn->y = v->no[1];
        vn->z = v->no[2];
        f.mIndices[0] = out->mNumVertices++;
        ++vo;
        ++vn;

        //  if (f.mNumIndices >= 2) {
        if (mf.v2 >= mesh->totvert) {
            ThrowException("Vertex index v2 out of range");
        }
        v = &mesh->mvert[mf.v2];
        vo->x = v->co[0];
        vo->y = v->co[1];
        vo->z = v->co[2];
        vn->x = v->no[0];
        vn->y = v->no[1];
        vn->z = v->no[2];
        f.mIndices[1] = out->mNumVertices++;
        ++vo;
        ++vn;

        if (mf.v3 >= mesh->totvert) {
            ThrowException("Vertex index v3 out of range");
        }
        //  if (f.mNumIndices >= 3) {
        v = &mesh->mvert[mf.v3];
        vo->x = v->co[0];
        vo->y = v->co[1];
        vo->z = v->co[2];
        vn->x = v->no[0];
        vn->y = v->no[1];
        vn->z = v->no[2];
        f.mIndices[2] = out->mNumVertices++;
        ++vo;
        ++vn;

        if (mf.v4 >= mesh->totvert) {
            ThrowException("Vertex index v4 out of range");
        }
        //  if (f.mNumIndices >= 4) {
        if (mf.v4) {
            v = &mesh->mvert[mf.v4];
            vo->x = v->co[0];
            vo->y = v->co[1];
            vo->z = v->co[2];
            vn->x = v->no[0];
            vn->y = v->no[1];
            vn->z = v->no[2];
            f.mIndices[3] = out->mNumVertices++;
            ++vo;
            ++vn;

            out->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
        }
        else out->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;

        //  }
        //  }
        //  }
    }

    for (int i = 0; i < mesh->totpoly; ++i) {

        const MPoly& mf = mesh->mpoly[i];

        aiMesh* const out = temp[ mat_num_to_mesh_idx[ mf.mat_nr ] ];
        aiFace& f = out->mFaces[out->mNumFaces++];

        f.mIndices = new unsigned int[ f.mNumIndices = mf.totloop ];
        aiVector3D* vo = out->mVertices + out->mNumVertices;
        aiVector3D* vn = out->mNormals + out->mNumVertices;

        // XXX we can't fold this easily, because we are restricted
        // to the member names from the BLEND file (v1,v2,v3,v4)
        // which are assigned by the genblenddna.py script and
        // cannot be changed without breaking the entire
        // import process.
        for (int j = 0;j < mf.totloop; ++j)
        {
            const MLoop& loop = mesh->mloop[mf.loopstart + j];

            if (loop.v >= mesh->totvert) {
                ThrowException("Vertex index out of range");
            }

            const MVert& v = mesh->mvert[loop.v];

            vo->x = v.co[0];
            vo->y = v.co[1];
            vo->z = v.co[2];
            vn->x = v.no[0];
            vn->y = v.no[1];
            vn->z = v.no[2];
            f.mIndices[j] = out->mNumVertices++;

            ++vo;
            ++vn;

        }
        if (mf.totloop == 3)
        {
            out->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
        }
        else
        {
            out->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
        }
    }

    // TODO should we create the TextureUVMapping map in Convert<Material> to prevent redundant processing?

    // create texture <-> uvname mapping for all materials
    // key is texture number, value is data *
    typedef std::map<uint32_t, const MLoopUV *> TextureUVMapping;
    // key is material number, value is the TextureUVMapping for the material
    typedef std::map<uint32_t, TextureUVMapping> MaterialTextureUVMappings;
    MaterialTextureUVMappings matTexUvMappings;
    const uint32_t maxMat = static_cast<const uint32_t>(mesh->mat.size());
    for (uint32_t m = 0; m < maxMat; ++m) {
        // get material by index
        const std::shared_ptr<Material> pMat = mesh->mat[m];
        TextureUVMapping texuv;
        const uint32_t maxTex = sizeof(pMat->mtex) / sizeof(pMat->mtex[0]);
        for (uint32_t t = 0; t < maxTex; ++t) {
            if (pMat->mtex[t] && pMat->mtex[t]->uvname[0]) {
                // get the CustomData layer for given uvname and correct type
                const ElemBase *pLoop = getCustomDataLayerData(mesh->ldata, CD_MLOOPUV, pMat->mtex[t]->uvname);
                if (pLoop) {
                    texuv.insert(std::make_pair(t, dynamic_cast<const MLoopUV *>(pLoop)));
                }
            }
        }
        if (texuv.size()) {
            matTexUvMappings.insert(std::make_pair(m, texuv));
        }
    }

    // collect texture coordinates, they're stored in a separate per-face buffer
    if (mesh->mtface || mesh->mloopuv) {
        if (mesh->totface > static_cast<int> ( mesh->mtface.size())) {
            ThrowException("Number of UV faces is larger than the corresponding UV face array (#1)");
        }
        for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
            ai_assert((*it)->mNumVertices && (*it)->mNumFaces);
            const auto itMatTexUvMapping = matTexUvMappings.find((*it)->mMaterialIndex);
            if (itMatTexUvMapping == matTexUvMappings.end()) {
                // default behaviour like before
                (*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices];
            }
            else {
                // create texture coords for every mapped tex
                for (uint32_t i = 0; i < itMatTexUvMapping->second.size(); ++i) {
                    (*it)->mTextureCoords[i] = new aiVector3D[(*it)->mNumVertices];
                }
            }
            (*it)->mNumFaces = (*it)->mNumVertices = 0;
        }

        for (int i = 0; i < mesh->totface; ++i) {
            const MTFace* v = &mesh->mtface[i];

            aiMesh* const out = temp[ mat_num_to_mesh_idx[ mesh->mface[i].mat_nr ] ];
            const aiFace& f = out->mFaces[out->mNumFaces++];

            aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
            for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo,++out->mNumVertices) {
                vo->x = v->uv[i][0];
                vo->y = v->uv[i][1];
            }
        }

        for (int i = 0; i < mesh->totpoly; ++i) {
            const MPoly& v = mesh->mpoly[i];
            aiMesh* const out = temp[ mat_num_to_mesh_idx[ v.mat_nr ] ];
            const aiFace& f = out->mFaces[out->mNumFaces++];

            const auto itMatTexUvMapping = matTexUvMappings.find(v.mat_nr);
            if (itMatTexUvMapping == matTexUvMappings.end()) {
                // old behavior
                aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
                for (unsigned int j = 0; j < f.mNumIndices; ++j, ++vo, ++out->mNumVertices) {
                    const MLoopUV& uv = mesh->mloopuv[v.loopstart + j];
                    vo->x = uv.uv[0];
                    vo->y = uv.uv[1];
                }
            }
            else {
                // create textureCoords for every mapped tex
                for (uint32_t m = 0; m < itMatTexUvMapping->second.size(); ++m) {
                    const MLoopUV *tm = itMatTexUvMapping->second[m];
                    aiVector3D* vo = &out->mTextureCoords[m][out->mNumVertices];
                    uint32_t j = 0;
                    for (; j < f.mNumIndices; ++j, ++vo) {
                        const MLoopUV& uv = tm[v.loopstart + j];
                        vo->x = uv.uv[0];
                        vo->y = uv.uv[1];
                    }
                    // only update written mNumVertices in last loop
                    // TODO why must the numVertices be incremented here?
                    if (m == itMatTexUvMapping->second.size() - 1) {
                        out->mNumVertices += j;
                    }
                }
            }
        }
    }

    // collect texture coordinates, old-style (marked as deprecated in current blender sources)
    if (mesh->tface) {
        if (mesh->totface > static_cast<int> ( mesh->tface.size())) {
            ThrowException("Number of faces is larger than the corresponding UV face array (#2)");
        }
        for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
            ai_assert((*it)->mNumVertices && (*it)->mNumFaces);

            (*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices];
            (*it)->mNumFaces = (*it)->mNumVertices = 0;
        }

        for (int i = 0; i < mesh->totface; ++i) {
            const TFace* v = &mesh->tface[i];

            aiMesh* const out = temp[ mat_num_to_mesh_idx[ mesh->mface[i].mat_nr ] ];
            const aiFace& f = out->mFaces[out->mNumFaces++];

            aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
            for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo,++out->mNumVertices) {
                vo->x = v->uv[i][0];
                vo->y = v->uv[i][1];
            }
        }
    }

    // collect vertex colors, stored separately as well
    if (mesh->mcol || mesh->mloopcol) {
        if (mesh->totface > static_cast<int> ( (mesh->mcol.size()/4)) ) {
            ThrowException("Number of faces is larger than the corresponding color face array");
        }
        for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
            ai_assert((*it)->mNumVertices && (*it)->mNumFaces);

            (*it)->mColors[0] = new aiColor4D[(*it)->mNumVertices];
            (*it)->mNumFaces = (*it)->mNumVertices = 0;
        }

        for (int i = 0; i < mesh->totface; ++i) {

            aiMesh* const out = temp[ mat_num_to_mesh_idx[ mesh->mface[i].mat_nr ] ];
            const aiFace& f = out->mFaces[out->mNumFaces++];

            aiColor4D* vo = &out->mColors[0][out->mNumVertices];
            for (unsigned int n = 0; n < f.mNumIndices; ++n, ++vo,++out->mNumVertices) {
                const MCol* col = &mesh->mcol[(i<<2)+n];

                vo->r = col->r;
                vo->g = col->g;
                vo->b = col->b;
                vo->a = col->a;
            }
            for (unsigned int n = f.mNumIndices; n < 4; ++n);
        }

        for (int i = 0; i < mesh->totpoly; ++i) {
            const MPoly& v = mesh->mpoly[i];
            aiMesh* const out = temp[ mat_num_to_mesh_idx[ v.mat_nr ] ];
            const aiFace& f = out->mFaces[out->mNumFaces++];

            aiColor4D* vo = &out->mColors[0][out->mNumVertices];
			const ai_real scaleZeroToOne = 1.f/255.f;
            for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) {
                const MLoopCol& col = mesh->mloopcol[v.loopstart + j];
                vo->r = ai_real(col.r) * scaleZeroToOne;
                vo->g = ai_real(col.g) * scaleZeroToOne;
                vo->b = ai_real(col.b) * scaleZeroToOne;
                vo->a = ai_real(col.a) * scaleZeroToOne;
            }

        }

    }

    return;
}
コード例 #2
0
ファイル: BlenderLoader.cpp プロジェクト: Spirrwell/AMEngine
// ------------------------------------------------------------------------------------------------
void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, const Mesh* mesh,
                                  ConversionData& conv_data, TempArray<std::vector,aiMesh>&  temp
                                 )
{
    // TODO: Resolve various problems with BMesh triangluation before re-enabling.
    //       See issues #400, #373, #318  #315 and #132.
#if defined(TODO_FIX_BMESH_CONVERSION)
    BlenderBMeshConverter BMeshConverter( mesh );
    if ( BMeshConverter.ContainsBMesh( ) )
    {
        mesh = BMeshConverter.TriangulateBMesh( );
    }
#endif

    typedef std::pair<const int,size_t> MyPair;
    if ((!mesh->totface && !mesh->totloop) || !mesh->totvert) {
        return;
    }

    // some sanity checks
    if (static_cast<size_t> ( mesh->totface ) > mesh->mface.size() ) {
        ThrowException("Number of faces is larger than the corresponding array");
    }

    if (static_cast<size_t> ( mesh->totvert ) > mesh->mvert.size()) {
        ThrowException("Number of vertices is larger than the corresponding array");
    }

    if (static_cast<size_t> ( mesh->totloop ) > mesh->mloop.size()) {
        ThrowException("Number of vertices is larger than the corresponding array");
    }

    // collect per-submesh numbers
    std::map<int,size_t> per_mat;
    std::map<int,size_t> per_mat_verts;
    for (int i = 0; i < mesh->totface; ++i) {

        const MFace& mf = mesh->mface[i];
        per_mat[ mf.mat_nr ]++;
        per_mat_verts[ mf.mat_nr ] += mf.v4?4:3;
    }

    for (int i = 0; i < mesh->totpoly; ++i) {
        const MPoly& mp = mesh->mpoly[i];
        per_mat[ mp.mat_nr ]++;
        per_mat_verts[ mp.mat_nr ] += mp.totloop;
    }

    // ... and allocate the corresponding meshes
    const size_t old = temp->size();
    temp->reserve(temp->size() + per_mat.size());

    std::map<size_t,size_t> mat_num_to_mesh_idx;
    for(MyPair& it : per_mat) {

        mat_num_to_mesh_idx[it.first] = temp->size();
        temp->push_back(new aiMesh());

        aiMesh* out = temp->back();
        out->mVertices = new aiVector3D[per_mat_verts[it.first]];
        out->mNormals  = new aiVector3D[per_mat_verts[it.first]];

        //out->mNumFaces = 0
        //out->mNumVertices = 0
        out->mFaces = new aiFace[it.second]();

        // all submeshes created from this mesh are named equally. this allows
        // curious users to recover the original adjacency.
        out->mName = aiString(mesh->id.name+2);
        // skip over the name prefix 'ME'

        // resolve the material reference and add this material to the set of
        // output materials. The (temporary) material index is the index
        // of the material entry within the list of resolved materials.
        if (mesh->mat) {

            if (static_cast<size_t> ( it.first ) >= mesh->mat.size() ) {
                ThrowException("Material index is out of range");
            }

            std::shared_ptr<Material> mat = mesh->mat[it.first];
            const std::deque< std::shared_ptr<Material> >::iterator has = std::find(
                        conv_data.materials_raw.begin(),
                        conv_data.materials_raw.end(),mat
                    );

            if (has != conv_data.materials_raw.end()) {
                out->mMaterialIndex = static_cast<unsigned int>( std::distance(conv_data.materials_raw.begin(),has));
            }
            else {
                out->mMaterialIndex = static_cast<unsigned int>( conv_data.materials_raw.size() );
                conv_data.materials_raw.push_back(mat);
            }
        }
        else out->mMaterialIndex = static_cast<unsigned int>( -1 );
    }

    for (int i = 0; i < mesh->totface; ++i) {

        const MFace& mf = mesh->mface[i];

        aiMesh* const out = temp[ mat_num_to_mesh_idx[ mf.mat_nr ] ];
        aiFace& f = out->mFaces[out->mNumFaces++];

        f.mIndices = new unsigned int[ f.mNumIndices = mf.v4?4:3 ];
        aiVector3D* vo = out->mVertices + out->mNumVertices;
        aiVector3D* vn = out->mNormals + out->mNumVertices;

        // XXX we can't fold this easily, because we are restricted
        // to the member names from the BLEND file (v1,v2,v3,v4)
        // which are assigned by the genblenddna.py script and
        // cannot be changed without breaking the entire
        // import process.

        if (mf.v1 >= mesh->totvert) {
            ThrowException("Vertex index v1 out of range");
        }
        const MVert* v = &mesh->mvert[mf.v1];
        vo->x = v->co[0];
        vo->y = v->co[1];
        vo->z = v->co[2];
        vn->x = v->no[0];
        vn->y = v->no[1];
        vn->z = v->no[2];
        f.mIndices[0] = out->mNumVertices++;
        ++vo;
        ++vn;

        //  if (f.mNumIndices >= 2) {
        if (mf.v2 >= mesh->totvert) {
            ThrowException("Vertex index v2 out of range");
        }
        v = &mesh->mvert[mf.v2];
        vo->x = v->co[0];
        vo->y = v->co[1];
        vo->z = v->co[2];
        vn->x = v->no[0];
        vn->y = v->no[1];
        vn->z = v->no[2];
        f.mIndices[1] = out->mNumVertices++;
        ++vo;
        ++vn;

        if (mf.v3 >= mesh->totvert) {
            ThrowException("Vertex index v3 out of range");
        }
        //  if (f.mNumIndices >= 3) {
        v = &mesh->mvert[mf.v3];
        vo->x = v->co[0];
        vo->y = v->co[1];
        vo->z = v->co[2];
        vn->x = v->no[0];
        vn->y = v->no[1];
        vn->z = v->no[2];
        f.mIndices[2] = out->mNumVertices++;
        ++vo;
        ++vn;

        if (mf.v4 >= mesh->totvert) {
            ThrowException("Vertex index v4 out of range");
        }
        //  if (f.mNumIndices >= 4) {
        if (mf.v4) {
            v = &mesh->mvert[mf.v4];
            vo->x = v->co[0];
            vo->y = v->co[1];
            vo->z = v->co[2];
            vn->x = v->no[0];
            vn->y = v->no[1];
            vn->z = v->no[2];
            f.mIndices[3] = out->mNumVertices++;
            ++vo;
            ++vn;

            out->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
        }
        else out->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;

        //  }
        //  }
        //  }
    }

    for (int i = 0; i < mesh->totpoly; ++i) {

        const MPoly& mf = mesh->mpoly[i];

        aiMesh* const out = temp[ mat_num_to_mesh_idx[ mf.mat_nr ] ];
        aiFace& f = out->mFaces[out->mNumFaces++];

        f.mIndices = new unsigned int[ f.mNumIndices = mf.totloop ];
        aiVector3D* vo = out->mVertices + out->mNumVertices;
        aiVector3D* vn = out->mNormals + out->mNumVertices;

        // XXX we can't fold this easily, because we are restricted
        // to the member names from the BLEND file (v1,v2,v3,v4)
        // which are assigned by the genblenddna.py script and
        // cannot be changed without breaking the entire
        // import process.
        for (int j = 0; j < mf.totloop; ++j)
        {
            const MLoop& loop = mesh->mloop[mf.loopstart + j];

            if (loop.v >= mesh->totvert) {
                ThrowException("Vertex index out of range");
            }

            const MVert& v = mesh->mvert[loop.v];

            vo->x = v.co[0];
            vo->y = v.co[1];
            vo->z = v.co[2];
            vn->x = v.no[0];
            vn->y = v.no[1];
            vn->z = v.no[2];
            f.mIndices[j] = out->mNumVertices++;

            ++vo;
            ++vn;

        }
        if (mf.totloop == 3)
        {
            out->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
        }
        else
        {
            out->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
        }
    }

    // collect texture coordinates, they're stored in a separate per-face buffer
    if (mesh->mtface || mesh->mloopuv) {
        if (mesh->totface > static_cast<int> ( mesh->mtface.size())) {
            ThrowException("Number of UV faces is larger than the corresponding UV face array (#1)");
        }
        for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
            ai_assert((*it)->mNumVertices && (*it)->mNumFaces);

            (*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices];
            (*it)->mNumFaces = (*it)->mNumVertices = 0;
        }

        for (int i = 0; i < mesh->totface; ++i) {
            const MTFace* v = &mesh->mtface[i];

            aiMesh* const out = temp[ mat_num_to_mesh_idx[ mesh->mface[i].mat_nr ] ];
            const aiFace& f = out->mFaces[out->mNumFaces++];

            aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
            for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo,++out->mNumVertices) {
                vo->x = v->uv[i][0];
                vo->y = v->uv[i][1];
            }
        }

        for (int i = 0; i < mesh->totpoly; ++i) {
            const MPoly& v = mesh->mpoly[i];
            aiMesh* const out = temp[ mat_num_to_mesh_idx[ v.mat_nr ] ];
            const aiFace& f = out->mFaces[out->mNumFaces++];

            aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
            for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) {
                const MLoopUV& uv = mesh->mloopuv[v.loopstart + j];
                vo->x = uv.uv[0];
                vo->y = uv.uv[1];
            }

        }
    }

    // collect texture coordinates, old-style (marked as deprecated in current blender sources)
    if (mesh->tface) {
        if (mesh->totface > static_cast<int> ( mesh->tface.size())) {
            ThrowException("Number of faces is larger than the corresponding UV face array (#2)");
        }
        for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
            ai_assert((*it)->mNumVertices && (*it)->mNumFaces);

            (*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices];
            (*it)->mNumFaces = (*it)->mNumVertices = 0;
        }

        for (int i = 0; i < mesh->totface; ++i) {
            const TFace* v = &mesh->tface[i];

            aiMesh* const out = temp[ mat_num_to_mesh_idx[ mesh->mface[i].mat_nr ] ];
            const aiFace& f = out->mFaces[out->mNumFaces++];

            aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
            for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo,++out->mNumVertices) {
                vo->x = v->uv[i][0];
                vo->y = v->uv[i][1];
            }
        }
    }

    // collect vertex colors, stored separately as well
    if (mesh->mcol || mesh->mloopcol) {
        if (mesh->totface > static_cast<int> ( (mesh->mcol.size()/4)) ) {
            ThrowException("Number of faces is larger than the corresponding color face array");
        }
        for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
            ai_assert((*it)->mNumVertices && (*it)->mNumFaces);

            (*it)->mColors[0] = new aiColor4D[(*it)->mNumVertices];
            (*it)->mNumFaces = (*it)->mNumVertices = 0;
        }

        for (int i = 0; i < mesh->totface; ++i) {

            aiMesh* const out = temp[ mat_num_to_mesh_idx[ mesh->mface[i].mat_nr ] ];
            const aiFace& f = out->mFaces[out->mNumFaces++];

            aiColor4D* vo = &out->mColors[0][out->mNumVertices];
            for (unsigned int n = 0; n < f.mNumIndices; ++n, ++vo,++out->mNumVertices) {
                const MCol* col = &mesh->mcol[(i<<2)+n];

                vo->r = col->r;
                vo->g = col->g;
                vo->b = col->b;
                vo->a = col->a;
            }
            for (unsigned int n = f.mNumIndices; n < 4; ++n);
        }

        for (int i = 0; i < mesh->totpoly; ++i) {
            const MPoly& v = mesh->mpoly[i];
            aiMesh* const out = temp[ mat_num_to_mesh_idx[ v.mat_nr ] ];
            const aiFace& f = out->mFaces[out->mNumFaces++];

            aiColor4D* vo = &out->mColors[0][out->mNumVertices];
            for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) {
                const MLoopCol& col = mesh->mloopcol[v.loopstart + j];
                vo->r = col.r;
                vo->g = col.g;
                vo->b = col.b;
                vo->a = col.a;
            }

        }

    }

    return;
}