[Bf-blender-cvs] [8148a24fb3c] usd-importer-T81257: USD Importer: material assignment improvements.
makowalski
noreply at git.blender.org
Sun Dec 27 22:18:13 CET 2020
Commit: 8148a24fb3cd517d4f173b2ab0b07c06e78402ff
Author: makowalski
Date: Tue Dec 15 00:28:09 2020 -0500
Branches: usd-importer-T81257
https://developer.blender.org/rB8148a24fb3cd517d4f173b2ab0b07c06e78402ff
USD Importer: material assignment improvements.
Simplified code in USDMeshReader::assign_materials() and
added logic to optionally allow assigning mesh material indices,
object material slots, or both.
===================================================================
M source/blender/io/usd/import/usd_reader_mesh.cc
M source/blender/io/usd/import/usd_reader_mesh.h
M source/blender/io/usd/import/usd_reader_mesh_base.cc
M source/blender/io/usd/import/usd_reader_mesh_base.h
===================================================================
diff --git a/source/blender/io/usd/import/usd_reader_mesh.cc b/source/blender/io/usd/import/usd_reader_mesh.cc
index cbfae578581..5a35efd8077 100644
--- a/source/blender/io/usd/import/usd_reader_mesh.cc
+++ b/source/blender/io/usd/import/usd_reader_mesh.cc
@@ -325,7 +325,7 @@ void process_normals(Mesh *mesh, const MeshSampleData &mesh_data)
}
}
-void build_mtl_map(const Main *bmain, std::map<std::string, Material *> &mat_map)
+void build_mat_map(const Main *bmain, std::map<std::string, Material *> &mat_map)
{
Material *material = static_cast<Material *>(bmain->materials.first);
@@ -415,18 +415,16 @@ Mesh *USDMeshReader::create_mesh(Main *bmain, double time)
return mesh;
}
-void USDMeshReader::assign_materials(Main *bmain, Mesh *mesh, double time)
+void USDMeshReader::assign_materials(Main *bmain,
+ Mesh *mesh,
+ double time,
+ bool set_object_materials)
{
- if (!bmain || !mesh || !object_ || !mesh_) {
+ if (!mesh && !(set_object_materials && bmain && this->object_ && this->prim())) {
return;
}
- /* Maps USD material names to material instances. */
- std::map<std::string, pxr::UsdShadeMaterial> usd_mtl_map;
-
- /* Each pair in the following vector represents a subset
- * and the name of the material to which it's bound. */
- std::vector<std::pair<pxr::UsdGeomSubset, std::string>> subset_mtls;
+ std::map<pxr::SdfPath, int> mat_map;
/* Find the geom subsets that have bound materials.
* We don't call pxr::UsdShadeMaterialBindingAPI::GetMaterialBindSubsets()
@@ -437,167 +435,121 @@ void USDMeshReader::assign_materials(Main *bmain, Mesh *mesh, double time)
const std::vector<pxr::UsdGeomSubset> face_subsets = pxr::UsdGeomSubset::GetAllGeomSubsets(
this->mesh_);
- for (const pxr::UsdGeomSubset &sub : face_subsets) {
- pxr::UsdShadeMaterialBindingAPI sub_bind_api(sub);
- PXR_NS::UsdRelationship rel;
- pxr::UsdShadeMaterial sub_bound_mtl = sub_bind_api.ComputeBoundMaterial(
- PXR_NS::UsdShadeTokens->allPurpose, &rel);
-
- /* Check if we have a bound material that was not inherited from another prim. */
- if (sub_bound_mtl && rel.GetPrim() == sub.GetPrim()) {
- pxr::UsdPrim mtl_prim = sub_bound_mtl.GetPrim();
- if (mtl_prim) {
- std::string mtl_name = sub_bound_mtl.GetPrim().GetName().GetString();
- subset_mtls.push_back(std::make_pair(sub, mtl_name));
- usd_mtl_map.insert(std::make_pair(mtl_name, sub_bound_mtl));
- }
- }
- }
-
- USDMaterialImporter mtl_importer(this->context_, bmain);
+ if (!face_subsets.empty()) {
- /* TODO(makowalski): Move more of the material creation logic inot USDMaterialImporter. */
+ int current_mat = 0;
- if (subset_mtls.empty()) {
- /* No material subsets. See if there is a material bound to the mesh. */
+ for (const pxr::UsdGeomSubset &sub : face_subsets) {
+ pxr::UsdShadeMaterialBindingAPI sub_bind_api(sub);
- pxr::UsdShadeMaterialBindingAPI binding_api(this->mesh_.GetPrim());
- pxr::UsdShadeMaterial bound_mtl = binding_api.ComputeBoundMaterial();
+ /* TODO(makowalski): Verify that the following will work for instance proxies. */
- if (!bound_mtl || !bound_mtl.GetPrim()) {
- return;
- }
+ pxr::SdfPath mat_path = sub_bind_api.GetDirectBinding().GetMaterialPath();
- /* We have a material bound to the mesh prim. */
+ if (mat_path.IsEmpty()) {
+ continue;
+ }
- /* Add a material slot to the object .*/
+ if (mat_map.find(mat_path) == mat_map.end()) {
+ mat_map[mat_path] = 1 + current_mat++;
+ }
- if (!BKE_object_material_slot_add(bmain, object_)) {
- std::cerr << "WARNING: Couldn't add material slot for mesh prim " << this->prim_path_
- << std::endl;
- return;
+ if (mesh) {
+ const int mat_idx = mat_map[mat_path] - 1;
+
+ /* Query the subset membership. */
+ pxr::UsdAttribute indicesAttribute = sub.GetIndicesAttr();
+ pxr::VtIntArray indices;
+ indicesAttribute.Get(&indices, time);
+
+ /* Assign the poly material indices. */
+ for (int face_idx : indices) {
+ if (face_idx > mesh->totpoly) {
+ std::cerr << "WARNING: Out of bounds material subset index." << std::endl;
+ continue;
+ }
+ mesh->mpoly[face_idx].mat_nr = mat_idx;
+ }
+ }
}
+ }
- /* Check if a material with the same name already exists. */
-
- std::string mtl_name = bound_mtl.GetPrim().GetName().GetString();
+ if (!(set_object_materials && bmain && this->object_)) {
+ return;
+ }
- Material *mtl = static_cast<Material *>(bmain->materials.first);
- Material *blen_mtl = nullptr;
+ if (mat_map.empty()) {
- for (; mtl; mtl = static_cast<Material *>(mtl->id.next)) {
- if (strcmp(mtl_name.c_str(), mtl->id.name + 2) == 0) {
- /* Found an existing material with the same name. */
- blen_mtl = mtl;
- break;
- }
- }
+ pxr::UsdShadeMaterialBindingAPI binding_api(this->prim());
- if (!blen_mtl) {
- /* No existing material, so add it now. */
- blen_mtl = mtl_importer.add_material(bound_mtl);
- }
-
- if (!blen_mtl) {
- std::cerr << "WARNING: Couldn't add material " << mtl_name << " for mesh prim "
- << this->prim_path_ << std::endl;
- }
+ // Note that calling binding_api.GetDirectBinding() doesn't appear
+ // to work for instance proxies.
+ pxr::UsdShadeMaterial bound_mtl = binding_api.ComputeBoundMaterial();
- /* Set the material IDs on the polys. */
- for (int p = 0; p < mesh->totpoly; ++p) {
- mesh->mpoly[p].mat_nr = 0;
+ if (bound_mtl) {
+ mat_map.insert(std::make_pair(bound_mtl.GetPath(), 1));
}
-
- BKE_object_material_assign(bmain, object_, blen_mtl, 1, BKE_MAT_ASSIGN_OBDATA);
}
- else {
- /* Maps USD material names to material slot index. */
- std::map<std::string, int> mtl_index_map;
+ if (mat_map.empty()) {
+ return;
+ }
- /* Add material slots. */
- std::map<std::string, pxr::UsdShadeMaterial>::const_iterator usd_mtl_iter =
- usd_mtl_map.begin();
+ /* Add material slots. */
+ std::map<pxr::SdfPath, int>::const_iterator mat_iter = mat_map.begin();
- for (; usd_mtl_iter != usd_mtl_map.end(); ++usd_mtl_iter) {
- if (!BKE_object_material_slot_add(bmain, object_)) {
- std::cerr << "WARNING: Couldn't add material slot for mesh prim " << this->prim_path_
- << std::endl;
- return;
- }
+ for (; mat_iter != mat_map.end(); ++mat_iter) {
+ if (!BKE_object_material_slot_add(bmain, object_)) {
+ std::cerr << "WARNING: Couldn't add material slot for mesh prim " << this->prim_path_
+ << std::endl;
+ return;
}
+ }
- /* Create the Blender materials. */
-
- /* Query the current materials. */
- std::map<std::string, Material *> blen_mtl_map;
- build_mtl_map(bmain, blen_mtl_map);
+ USDMaterialImporter mat_importer(this->context_, bmain);
- /* Iterate over the USD materials and add corresponding
- * Blender materials of the same name, if they don't
- * already exist. */
- usd_mtl_iter = usd_mtl_map.begin();
- int idx = 0;
+ /* TODO(makowalski): Move more of the material creation logic into USDMaterialImporter. */
- for (; usd_mtl_iter != usd_mtl_map.end(); ++usd_mtl_iter, ++idx) {
- Material *blen_mtl = nullptr;
+ /* Create the Blender materials. */
- std::string mtl_name = usd_mtl_iter->first.c_str();
+ /* Query the current Blender materials. */
+ std::map<std::string, Material *> blen_mat_map;
+ build_mat_map(bmain, blen_mat_map);
- std::map<std::string, Material *>::const_iterator blen_mtl_iter = blen_mtl_map.find(
- mtl_name);
+ /* Iterate over the USD materials and add corresponding
+ * Blender materials of the same name, if they don't
+ * already exist. */
+ mat_iter = mat_map.begin();
- if (blen_mtl_iter != blen_mtl_map.end()) {
- blen_mtl = blen_mtl_iter->second;
- }
- else {
- blen_mtl = mtl_importer.add_material(usd_mtl_iter->second);
-
- if (blen_mtl) {
- blen_mtl_map.insert(std::make_pair(mtl_name, blen_mtl));
- }
- }
+ for (; mat_iter != mat_map.end(); ++mat_iter) {
+ Material *blen_mtl = nullptr;
- if (!blen_mtl) {
- std::cerr << "WARNING: Couldn't add material " << mtl_name << " for mesh prim "
- << this->prim_path_ << std::endl;
- return;
- }
+ std::string mat_name = mat_iter->first.GetName();
- BKE_object_material_assign(bmain, object_, blen_mtl, idx + 1, BKE_MAT_ASSIGN_OBDATA);
+ std::map<std::string, Material *>::const_iterator blen_mat_iter = blen_mat_map.find(mat_name);
- /* Record this material's index. */
- mtl_index_map.insert(std::make_pair(usd_mtl_iter->first, idx));
+ if (blen_mat_iter != blen_mat_map.end()) {
+ blen_mtl = blen_mat_iter->second;
}
+ else {
- /* Assign the material indices. */
-
- for (const std::pair<pxr::UsdGeomSubset, std::string> &sub_mtl : subset_mtls) {
+ pxr::UsdPrim mat_prim = this->prim().GetStage()->GetPrimAtPath(mat_iter->first);
- /* Find the index of the current material. */
- std::map<std::string, int>::const_iterator mtl_index_iter = mtl_index_map.find(
- sub_mtl.second);
+ pxr::UsdShadeMaterial usd_mat(mat_prim);
+ blen_mtl = mat_importer.add_material(usd_mat);
- if (mtl_index_iter == mtl_index_map.end()) {
- std::cerr << "WARNING: Couldn't find material index." << std::endl;
- return;
+ if (blen_mtl) {
+ blen_mat_map.insert(std::make_pair(mat_name, blen_mtl));
}
+ }
- int mtl_idx = mtl_index_iter->second;
-
- /* Query the subset membership. */
- pxr::VtIntArray indices;
- sub_mtl.first.GetIndicesAttr().Get(&indices, time);
-
- /* Assign the poly material indices. */
- for (int face_idx : indices) {
- if (mtl_idx > mesh->totpoly) {
- std::cerr << "WARNING
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list