diff options
author | Peter Kim <pk15950@gmail.com> | 2022-09-08 07:00:12 +0300 |
---|---|---|
committer | Peter Kim <pk15950@gmail.com> | 2022-09-08 07:00:12 +0300 |
commit | 00dcfdf916c69672210b006e62d966f1bc2fbeb7 (patch) | |
tree | 0cbb1b91fe26c750197126085b74224a795a103c /source/blender/io/usd/intern/usd_reader_mesh.cc | |
parent | a39532670f6b668da7be5810fb1f844b82feeba3 (diff) | |
parent | d5934974219135102f364f57c45a8b1465e2b8d9 (diff) |
Merge branch 'master' into xr-devxr-dev
Diffstat (limited to 'source/blender/io/usd/intern/usd_reader_mesh.cc')
-rw-r--r-- | source/blender/io/usd/intern/usd_reader_mesh.cc | 165 |
1 files changed, 90 insertions, 75 deletions
diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc index 368d0e1bab9..0b96cd8ce90 100644 --- a/source/blender/io/usd/intern/usd_reader_mesh.cc +++ b/source/blender/io/usd/intern/usd_reader_mesh.cc @@ -6,6 +6,7 @@ #include "usd_reader_mesh.h" #include "usd_reader_material.h" +#include "BKE_attribute.hh" #include "BKE_customdata.h" #include "BKE_main.h" #include "BKE_material.h" @@ -64,12 +65,26 @@ static void build_mat_map(const Main *bmain, std::map<std::string, Material *> * static pxr::UsdShadeMaterial compute_bound_material(const pxr::UsdPrim &prim) { - return pxr::UsdShadeMaterialBindingAPI(prim).ComputeBoundMaterial(); + pxr::UsdShadeMaterialBindingAPI api = pxr::UsdShadeMaterialBindingAPI(prim); + + /* Compute generically bound ('allPurpose') materials. */ + pxr::UsdShadeMaterial mtl = api.ComputeBoundMaterial(); + + /* If no generic material could be resolved, also check for 'preview' and + * 'full' purpose materials as fallbacks. */ + if (!mtl) { + mtl = api.ComputeBoundMaterial(pxr::UsdShadeTokens->preview); + } + + if (!mtl) { + mtl = api.ComputeBoundMaterial(pxr::UsdShadeTokens->full); + } + + return mtl; } -/* Returns an existing Blender material that corresponds to the USD - * material with with the given path. Returns null if no such material - * exists. */ +/* Returns an existing Blender material that corresponds to the USD material with the given path. + * Returns null if no such material exists. */ static Material *find_existing_material( const pxr::SdfPath &usd_mat_path, const USDImportParams ¶ms, @@ -87,11 +102,9 @@ static Material *find_existing_material( if (mat_iter != mat_map.end()) { return mat_iter->second; } - else { - /* We can't find the Blender material which was previously created for this USD - * material, which should never happen. */ - BLI_assert_unreachable(); - } + /* We can't find the Blender material which was previously created for this USD + * material, which should never happen. */ + BLI_assert_unreachable(); } } else { @@ -111,37 +124,25 @@ static void assign_materials(Main *bmain, const std::map<pxr::SdfPath, int> &mat_index_map, const USDImportParams ¶ms, pxr::UsdStageRefPtr stage, + std::map<std::string, Material *> &mat_name_to_mat, std::map<std::string, std::string> &usd_path_to_mat_name) { if (!(stage && bmain && ob)) { return; } - bool can_assign = true; - std::map<pxr::SdfPath, int>::const_iterator it = mat_index_map.begin(); - - int matcount = 0; - for (; it != mat_index_map.end(); ++it, matcount++) { - if (!BKE_object_material_slot_add(bmain, ob)) { - can_assign = false; - break; - } - } - - if (!can_assign) { + if (mat_index_map.size() > MAXMAT) { return; } - /* TODO(kevin): use global map? */ - std::map<std::string, Material *> mat_map; - build_mat_map(bmain, &mat_map); - blender::io::usd::USDMaterialReader mat_reader(params, bmain); - for (it = mat_index_map.begin(); it != mat_index_map.end(); ++it) { + for (std::map<pxr::SdfPath, int>::const_iterator it = mat_index_map.begin(); + it != mat_index_map.end(); + ++it) { Material *assigned_mat = find_existing_material( - it->first, params, mat_map, usd_path_to_mat_name); + it->first, params, mat_name_to_mat, usd_path_to_mat_name); if (!assigned_mat) { /* Blender material doesn't exist, so create it now. */ @@ -165,7 +166,7 @@ static void assign_materials(Main *bmain, } const std::string mat_name = pxr::TfMakeValidIdentifier(assigned_mat->id.name + 2); - mat_map[mat_name] = assigned_mat; + mat_name_to_mat[mat_name] = assigned_mat; if (params.mtl_name_collision_mode == USD_MTL_NAME_COLLISION_MAKE_UNIQUE) { /* Record the name of the Blender material we created for the USD material @@ -175,13 +176,16 @@ static void assign_materials(Main *bmain, } if (assigned_mat) { - BKE_object_material_assign(bmain, ob, assigned_mat, it->second, BKE_MAT_ASSIGN_OBDATA); + BKE_object_material_assign_single_obdata(bmain, ob, assigned_mat, it->second); } else { /* This shouldn't happen. */ std::cout << "WARNING: Couldn't assign material " << it->first << std::endl; } } + if (ob->totcol > 0) { + ob->actcol = 1; + } } } // namespace utils @@ -207,7 +211,8 @@ static void *add_customdata_cb(Mesh *mesh, const char *name, const int data_type /* Create a new layer. */ numloops = mesh->totloop; - cd_ptr = CustomData_add_layer_named(loopdata, cd_data_type, CD_DEFAULT, nullptr, numloops, name); + cd_ptr = CustomData_add_layer_named( + loopdata, cd_data_type, CD_SET_DEFAULT, nullptr, numloops, name); return cd_ptr; } @@ -307,18 +312,17 @@ bool USDMeshReader::topology_changed(const Mesh *existing_mesh, const double mot void USDMeshReader::read_mpolys(Mesh *mesh) { - MPoly *mpolys = mesh->mpoly; - MLoop *mloops = mesh->mloop; + MutableSpan<MPoly> polys = mesh->polys_for_write(); + MutableSpan<MLoop> loops = mesh->loops_for_write(); int loop_index = 0; for (int i = 0; i < face_counts_.size(); i++) { const int face_size = face_counts_[i]; - MPoly &poly = mpolys[i]; + MPoly &poly = polys[i]; poly.loopstart = loop_index; poly.totloop = face_size; - poly.mat_nr = 0; /* Polygons are always assumed to be smooth-shaded. If the mesh should be flat-shaded, * this is encoded in custom loop normals. */ @@ -327,12 +331,12 @@ void USDMeshReader::read_mpolys(Mesh *mesh) if (is_left_handed_) { int loop_end_index = loop_index + (face_size - 1); for (int f = 0; f < face_size; ++f, ++loop_index) { - mloops[loop_index].v = face_indices_[loop_end_index - f]; + loops[loop_index].v = face_indices_[loop_end_index - f]; } } else { for (int f = 0; f < face_size; ++f, ++loop_index) { - mloops[loop_index].v = face_indices_[loop_index]; + loops[loop_index].v = face_indices_[loop_index]; } } } @@ -396,6 +400,7 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo } } + const Span<MLoop> loops = mesh->loops(); for (int i = 0; i < face_counts_.size(); i++) { const int face_size = face_counts_[i]; @@ -431,7 +436,7 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo /* For Vertex interpolation, use the vertex index. */ int usd_uv_index = sample.interpolation == pxr::UsdGeomTokens->vertex ? - mesh->mloop[loop_index].v : + loops[loop_index].v : loop_index; if (usd_uv_index >= sample.uvs.size()) { @@ -511,24 +516,23 @@ void USDMeshReader::read_colors(Mesh *mesh, const double motionSampleTime) MLoopCol *colors = static_cast<MLoopCol *>(cd_ptr); - mesh->mloopcol = colors; - - MPoly *poly = mesh->mpoly; - - for (int i = 0, e = mesh->totpoly; i < e; ++i, ++poly) { - for (int j = 0; j < poly->totloop; ++j) { - int loop_index = poly->loopstart + j; + const Span<MPoly> polys = mesh->polys(); + const Span<MLoop> loops = mesh->loops(); + for (const int i : polys.index_range()) { + const MPoly &poly = polys[i]; + for (int j = 0; j < poly.totloop; ++j) { + int loop_index = poly.loopstart + j; /* Default for constant varying interpolation. */ int usd_index = 0; if (interp == pxr::UsdGeomTokens->vertex) { - usd_index = mesh->mloop[loop_index].v; + usd_index = loops[loop_index].v; } else if (interp == pxr::UsdGeomTokens->faceVarying) { - usd_index = poly->loopstart; + usd_index = poly.loopstart; if (is_left_handed_) { - usd_index += poly->totloop - 1 - j; + usd_index += poly.totloop - 1 - j; } else { usd_index += j; @@ -576,7 +580,7 @@ void USDMeshReader::read_vertex_creases(Mesh *mesh, const double motionSampleTim } float *creases = static_cast<float *>( - CustomData_add_layer(&mesh->vdata, CD_CREASE, CD_DEFAULT, nullptr, mesh->totvert)); + CustomData_add_layer(&mesh->vdata, CD_CREASE, CD_SET_DEFAULT, nullptr, mesh->totvert)); for (size_t i = 0; i < corner_indices.size(); i++) { creases[corner_indices[i]] = corner_sharpnesses[i]; @@ -626,15 +630,15 @@ void USDMeshReader::process_normals_face_varying(Mesh *mesh) float(*lnors)[3] = static_cast<float(*)[3]>( MEM_malloc_arrayN(loop_count, sizeof(float[3]), "USD::FaceNormals")); - MPoly *mpoly = mesh->mpoly; + const Span<MPoly> polys = mesh->polys(); + for (const int i : polys.index_range()) { + const MPoly &poly = polys[i]; + for (int j = 0; j < poly.totloop; j++) { + int blender_index = poly.loopstart + j; - for (int i = 0, e = mesh->totpoly; i < e; ++i, ++mpoly) { - for (int j = 0; j < mpoly->totloop; j++) { - int blender_index = mpoly->loopstart + j; - - int usd_index = mpoly->loopstart; + int usd_index = poly.loopstart; if (is_left_handed_) { - usd_index += mpoly->totloop - 1 - j; + usd_index += poly.totloop - 1 - j; } else { usd_index += j; @@ -667,12 +671,11 @@ void USDMeshReader::process_normals_uniform(Mesh *mesh) float(*lnors)[3] = static_cast<float(*)[3]>( MEM_malloc_arrayN(mesh->totloop, sizeof(float[3]), "USD::FaceNormals")); - MPoly *mpoly = mesh->mpoly; - - for (int i = 0, e = mesh->totpoly; i < e; ++i, ++mpoly) { - - for (int j = 0; j < mpoly->totloop; j++) { - int loop_index = mpoly->loopstart + j; + const Span<MPoly> polys = mesh->polys(); + for (const int i : polys.index_range()) { + const MPoly &poly = polys[i]; + for (int j = 0; j < poly.totloop; j++) { + int loop_index = poly.loopstart + j; lnors[loop_index][0] = normals_[i][0]; lnors[loop_index][1] = normals_[i][1]; lnors[loop_index][2] = normals_[i][2]; @@ -695,8 +698,9 @@ void USDMeshReader::read_mesh_sample(ImportSettings *settings, * in code that expect this data to be there. */ if (new_mesh || (settings->read_flag & MOD_MESHSEQ_READ_VERT) != 0) { + MutableSpan<MVert> verts = mesh->verts_for_write(); for (int i = 0; i < positions_.size(); i++) { - MVert &mvert = mesh->mvert[i]; + MVert &mvert = verts[i]; mvert.co[0] = positions_[i][0]; mvert.co[1] = positions_[i][1]; mvert.co[2] = positions_[i][2]; @@ -734,10 +738,9 @@ void USDMeshReader::read_mesh_sample(ImportSettings *settings, } } -void USDMeshReader::assign_facesets_to_mpoly(double motionSampleTime, - MPoly *mpoly, - const int /* totpoly */, - std::map<pxr::SdfPath, int> *r_mat_map) +void USDMeshReader::assign_facesets_to_material_indices(double motionSampleTime, + MutableSpan<int> material_indices, + std::map<pxr::SdfPath, int> *r_mat_map) { if (r_mat_map == nullptr) { return; @@ -777,9 +780,8 @@ void USDMeshReader::assign_facesets_to_mpoly(double motionSampleTime, pxr::VtIntArray indices; indicesAttribute.Get(&indices, motionSampleTime); - for (int i = 0; i < indices.size(); i++) { - MPoly &poly = mpoly[indices[i]]; - poly.mat_nr = mat_idx; + for (const int i : indices) { + material_indices[i] = mat_idx; } } } @@ -804,12 +806,22 @@ void USDMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, const double mot } std::map<pxr::SdfPath, int> mat_map; - assign_facesets_to_mpoly(motionSampleTime, mesh->mpoly, mesh->totpoly, &mat_map); + + bke::MutableAttributeAccessor attributes = mesh->attributes_for_write(); + bke::SpanAttributeWriter<int> material_indices = + attributes.lookup_or_add_for_write_only_span<int>("material_index", ATTR_DOMAIN_FACE); + this->assign_facesets_to_material_indices(motionSampleTime, material_indices.span, &mat_map); + material_indices.finish(); + /* Build material name map if it's not built yet. */ + if (this->settings_->mat_name_to_mat.empty()) { + utils::build_mat_map(bmain, &this->settings_->mat_name_to_mat); + } utils::assign_materials(bmain, object_, mat_map, this->import_params_, this->prim_.GetStage(), + this->settings_->mat_name_to_mat, this->settings_->usd_path_to_mat_name); } @@ -891,8 +903,7 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh, existing_mesh, positions_.size(), 0, 0, face_indices_.size(), face_counts_.size()); for (pxr::TfToken token : uv_tokens) { - void *cd_ptr = add_customdata_cb(active_mesh, token.GetText(), CD_MLOOPUV); - active_mesh->mloopuv = static_cast<MLoopUV *>(cd_ptr); + add_customdata_cb(active_mesh, token.GetText(), CD_MLOOPUV); } } @@ -902,10 +913,14 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh, /* 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 * USD are still valid now. */ - size_t num_polys = active_mesh->totpoly; - if (num_polys > 0 && import_params_.import_materials) { + MutableSpan<MPoly> polys = active_mesh->polys_for_write(); + if (!polys.is_empty() && import_params_.import_materials) { std::map<pxr::SdfPath, int> mat_map; - assign_facesets_to_mpoly(motionSampleTime, active_mesh->mpoly, num_polys, &mat_map); + bke::MutableAttributeAccessor attributes = active_mesh->attributes_for_write(); + bke::SpanAttributeWriter<int> material_indices = + attributes.lookup_or_add_for_write_only_span<int>("material_index", ATTR_DOMAIN_FACE); + assign_facesets_to_material_indices(motionSampleTime, material_indices.span, &mat_map); + material_indices.finish(); } } |