From 45d7513f84bd3f3ee52207d4373e2ff980c954aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Wed, 9 Aug 2017 13:05:22 +0200 Subject: Fix T52240: Alembic Not Transferring Materials Per Frame When a mesh changes its number of vertices during the animation, Blender rebuilds the DerivedMesh, after which the materials weren't applied any more (causing the default to the first material slot). --- source/blender/alembic/intern/abc_mesh.cc | 42 ++++++++++++++++++++++--------- source/blender/alembic/intern/abc_mesh.h | 5 ++++ 2 files changed, 35 insertions(+), 12 deletions(-) (limited to 'source/blender/alembic') diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc index 7949a371283..456d16b3e0d 100644 --- a/source/blender/alembic/intern/abc_mesh.cc +++ b/source/blender/alembic/intern/abc_mesh.cc @@ -983,8 +983,6 @@ static void read_mesh_sample(ImportSettings *settings, if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) { read_custom_data(schema.getArbGeomParams(), config, selector); } - - /* TODO: face sets */ } CDStreamConfig get_config(DerivedMesh *dm) @@ -1123,6 +1121,16 @@ DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, CDDM_calc_normals(new_dm); CDDM_calc_edges(new_dm); + /* Here we assume that the number of materials doesn't change, i.e. that + * the material slots that were created when the object was loaded from + * Alembic are still valid now. */ + size_t num_polys = new_dm->getNumPolys(new_dm); + if (num_polys > 0) { + MPoly *dmpolies = new_dm->getPolyArray(new_dm); + std::map mat_map; + assign_facesets_to_mpoly(sample_sel, 0, dmpolies, num_polys, mat_map); + } + return new_dm; } @@ -1133,8 +1141,11 @@ DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, return dm; } -void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start, - const ISampleSelector &sample_sel) +void AbcMeshReader::assign_facesets_to_mpoly( + const ISampleSelector &sample_sel, + size_t poly_start, + MPoly *mpoly, int totpoly, + std::map & r_mat_map) { std::vector face_sets; m_schema.getFaceSetNames(face_sets); @@ -1143,21 +1154,21 @@ void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_star return; } - std::map mat_map; int current_mat = 0; for (int i = 0; i < face_sets.size(); ++i) { const std::string &grp_name = face_sets[i]; - if (mat_map.find(grp_name) == mat_map.end()) { - mat_map[grp_name] = 1 + current_mat++; + if (r_mat_map.find(grp_name) == r_mat_map.end()) { + r_mat_map[grp_name] = 1 + current_mat++; } - const int assigned_mat = mat_map[grp_name]; + const int assigned_mat = r_mat_map[grp_name]; const IFaceSet faceset = m_schema.getFaceSet(grp_name); if (!faceset.valid()) { + std::cerr << " Face set " << grp_name << " invalid for " << m_object_name << "\n"; continue; } @@ -1169,16 +1180,25 @@ void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_star for (size_t l = 0; l < num_group_faces; l++) { size_t pos = (*group_faces)[l] + poly_start; - if (pos >= mesh->totpoly) { + if (pos >= totpoly) { std::cerr << "Faceset overflow on " << faceset.getName() << '\n'; break; } - MPoly &poly = mesh->mpoly[pos]; + MPoly &poly = mpoly[pos]; poly.mat_nr = assigned_mat - 1; } } +} + +void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start, + const ISampleSelector &sample_sel) +{ + std::map mat_map; + assign_facesets_to_mpoly(sample_sel, + poly_start, mesh->mpoly, mesh->totpoly, + mat_map); utils::assign_materials(bmain, m_object, mat_map); } @@ -1234,8 +1254,6 @@ static void read_subd_sample(ImportSettings *settings, if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) { read_custom_data(schema.getArbGeomParams(), config, selector); } - - /* TODO: face sets */ } /* ************************************************************************** */ diff --git a/source/blender/alembic/intern/abc_mesh.h b/source/blender/alembic/intern/abc_mesh.h index 6bf1dde3d1d..5c1eb01d8e0 100644 --- a/source/blender/alembic/intern/abc_mesh.h +++ b/source/blender/alembic/intern/abc_mesh.h @@ -112,6 +112,11 @@ public: private: void readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start, const Alembic::AbcGeom::ISampleSelector &sample_sel); + + void assign_facesets_to_mpoly(const Alembic::Abc::ISampleSelector &sample_sel, + size_t poly_start, + MPoly *mpoly, int totpoly, + std::map & r_mat_map); }; /* ************************************************************************** */ -- cgit v1.2.3