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