[Bf-blender-cvs] [ffe45ad87a5] master: USD import unused materials.

Michael Kowalski noreply at git.blender.org
Wed Jan 25 16:46:44 CET 2023


Commit: ffe45ad87a564fd2cb7d53f222785ecb608a6e30
Author: Michael Kowalski
Date:   Wed Jan 25 10:46:07 2023 -0500
Branches: master
https://developer.blender.org/rBffe45ad87a564fd2cb7d53f222785ecb608a6e30

USD import unused materials.

Added a new Import All Materials USD import option.  When this
option is enabled, USD materials not used by any geometry will
be included in the import.  Imported materials with no users
will have a fake user assigned.

Maniphest Tasks: T97195

Differential Revision: https://developer.blender.org/D16172

===================================================================

M	source/blender/editors/io/io_usd.c
M	source/blender/io/usd/intern/usd_capi_import.cc
M	source/blender/io/usd/intern/usd_reader_material.cc
M	source/blender/io/usd/intern/usd_reader_material.h
M	source/blender/io/usd/intern/usd_reader_mesh.cc
M	source/blender/io/usd/intern/usd_reader_stage.cc
M	source/blender/io/usd/intern/usd_reader_stage.h
M	source/blender/io/usd/usd.h

===================================================================

diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c
index acd60bbd40a..99d4e84cfd4 100644
--- a/source/blender/editors/io/io_usd.c
+++ b/source/blender/editors/io/io_usd.c
@@ -381,6 +381,8 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
   const bool import_proxy = RNA_boolean_get(op->ptr, "import_proxy");
   const bool import_render = RNA_boolean_get(op->ptr, "import_render");
 
+  const bool import_all_materials = RNA_boolean_get(op->ptr, "import_all_materials");
+
   const bool import_usd_preview = RNA_boolean_get(op->ptr, "import_usd_preview");
   const bool set_material_blend = RNA_boolean_get(op->ptr, "set_material_blend");
 
@@ -427,7 +429,8 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
                                    .import_usd_preview = import_usd_preview,
                                    .set_material_blend = set_material_blend,
                                    .light_intensity_scale = light_intensity_scale,
-                                   .mtl_name_collision_mode = mtl_name_collision_mode};
+                                   .mtl_name_collision_mode = mtl_name_collision_mode,
+                                   .import_all_materials = import_all_materials};
 
   STRNCPY(params.prim_path_mask, prim_path_mask);
 
@@ -480,6 +483,7 @@ static void wm_usd_import_draw(bContext *UNUSED(C), wmOperator *op)
 
   box = uiLayoutBox(layout);
   col = uiLayoutColumnWithHeading(box, true, IFACE_("Materials"));
+  uiItemR(col, ptr, "import_all_materials", 0, NULL, ICON_NONE);
   uiItemR(col, ptr, "import_usd_preview", 0, NULL, ICON_NONE);
   uiLayoutSetEnabled(col, RNA_boolean_get(ptr, "import_materials"));
   uiLayout *row = uiLayoutRow(col, true);
@@ -579,6 +583,14 @@ void WM_OT_usd_import(struct wmOperatorType *ot)
 
   RNA_def_boolean(ot->srna, "import_render", true, "Render", "Import final render geometry");
 
+  RNA_def_boolean(ot->srna,
+                  "import_all_materials",
+                  false,
+                  "Import All Materials",
+                  "Also import materials that are not used by any geometry.  "
+                  "Note that when this option is false, materials referenced "
+                  "by geometry will still be imported");
+
   RNA_def_boolean(ot->srna,
                   "import_usd_preview",
                   true,
diff --git a/source/blender/io/usd/intern/usd_capi_import.cc b/source/blender/io/usd/intern/usd_capi_import.cc
index 600d1f0a9eb..66319a7f04e 100644
--- a/source/blender/io/usd/intern/usd_capi_import.cc
+++ b/source/blender/io/usd/intern/usd_capi_import.cc
@@ -227,6 +227,10 @@ static void import_startjob(void *customdata, bool *stop, bool *do_update, float
 
   archive->collect_readers(data->bmain);
 
+  if (data->params.import_materials && data->params.import_all_materials) {
+    archive->import_all_materials(data->bmain);
+  }
+
   *data->do_update = true;
   *data->progress = 0.2f;
 
@@ -352,6 +356,10 @@ static void import_endjob(void *customdata)
 
     DEG_id_tag_update(&data->scene->id, ID_RECALC_BASE_FLAGS);
     DEG_relations_tag_update(data->bmain);
+
+    if (data->params.import_materials && data->params.import_all_materials) {
+      data->archive->fake_users_for_unused_materials();
+    }
   }
 
   WM_set_locked_interface(data->wm, false);
diff --git a/source/blender/io/usd/intern/usd_reader_material.cc b/source/blender/io/usd/intern/usd_reader_material.cc
index d1af4553083..351f9bc3438 100644
--- a/source/blender/io/usd/intern/usd_reader_material.cc
+++ b/source/blender/io/usd/intern/usd_reader_material.cc
@@ -757,4 +757,45 @@ void USDMaterialReader::convert_usd_primvar_reader_float2(
   link_nodes(ntree, uv_map, "UV", dest_node, dest_socket_name);
 }
 
+void build_material_map(const Main *bmain, std::map<std::string, Material *> *r_mat_map)
+{
+  BLI_assert_msg(r_mat_map, "...");
+
+  LISTBASE_FOREACH (Material *, material, &bmain->materials) {
+    std::string usd_name = pxr::TfMakeValidIdentifier(material->id.name + 2);
+    (*r_mat_map)[usd_name] = material;
+  }
+}
+
+Material *find_existing_material(const pxr::SdfPath &usd_mat_path,
+                                 const USDImportParams &params,
+                                 const std::map<std::string, Material *> &mat_map,
+                                 const std::map<std::string, std::string> &usd_path_to_mat_name)
+{
+  if (params.mtl_name_collision_mode == USD_MTL_NAME_COLLISION_MAKE_UNIQUE) {
+    /* Check if we've already created the Blender material with a modified name. */
+    std::map<std::string, std::string>::const_iterator path_to_name_iter =
+        usd_path_to_mat_name.find(usd_mat_path.GetAsString());
+
+    if (path_to_name_iter == usd_path_to_mat_name.end()) {
+      return nullptr;
+    }
+
+    std::string mat_name = path_to_name_iter->second;
+    std::map<std::string, Material *>::const_iterator mat_iter = mat_map.find(mat_name);
+    BLI_assert_msg(mat_iter != mat_map.end(),
+                   "Previously created material cannot be found any more");
+    return mat_iter->second;
+  }
+
+  std::string mat_name = usd_mat_path.GetName();
+  std::map<std::string, Material *>::const_iterator mat_iter = mat_map.find(mat_name);
+
+  if (mat_iter == mat_map.end()) {
+    return nullptr;
+  }
+
+  return mat_iter->second;
+}
+
 }  // namespace blender::io::usd
diff --git a/source/blender/io/usd/intern/usd_reader_material.h b/source/blender/io/usd/intern/usd_reader_material.h
index 24d80e99c38..6fd6d2f1213 100644
--- a/source/blender/io/usd/intern/usd_reader_material.h
+++ b/source/blender/io/usd/intern/usd_reader_material.h
@@ -6,6 +6,8 @@
 
 #include <pxr/usd/usdShade/material.h>
 
+#include <map>
+
 struct Main;
 struct Material;
 struct bNode;
@@ -129,4 +131,32 @@ class USDMaterialReader {
                                          NodePlacementContext *r_ctx) const;
 };
 
+/* Utility functions. */
+
+/**
+ * Returns a map containing all the Blender materials which allows a fast
+ * lookup of the material by name.  Note that the material name key
+ * might be modified to be a valid USD identifier, to match material
+ * names in the imported USD.
+ */
+void build_material_map(const Main *bmain, std::map<std::string, Material *> *r_mat_map);
+
+/**
+ * Returns an existing Blender material that corresponds to the USD material with the given path.
+ * Returns null if no such material exists.
+ *
+ * \param mat_map Map a material name to a Blender material.  Note that the name key
+ *  might be the Blender material name modified to be a valid USD identifier,
+ *  to match the material names in the imported USD.
+ * \param usd_path_to_mat_name Map a USD material path to the imported Blender material name.
+ *
+ * The usd_path_to_mat_name is needed to determine the name of the Blender
+ * material imported from a USD path in the case when a unique name was generated
+ * for the material due to a name collision.
+ */
+Material *find_existing_material(const pxr::SdfPath &usd_mat_path,
+                                 const USDImportParams &params,
+                                 const std::map<std::string, Material *> &mat_map,
+                                 const std::map<std::string, std::string> &usd_path_to_mat_name);
+
 }  // namespace blender::io::usd
diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc
index f961fa64a05..fd4b80b9137 100644
--- a/source/blender/io/usd/intern/usd_reader_mesh.cc
+++ b/source/blender/io/usd/intern/usd_reader_mesh.cc
@@ -49,20 +49,6 @@ static const pxr::TfToken normalsPrimvar("normals", pxr::TfToken::Immortal);
 }  // namespace usdtokens
 
 namespace utils {
-/* Very similar to #blender::io::alembic::utils. */
-static void build_mat_map(const Main *bmain, std::map<std::string, Material *> *r_mat_map)
-{
-  if (r_mat_map == nullptr) {
-    return;
-  }
-
-  Material *material = static_cast<Material *>(bmain->materials.first);
-
-  for (; material; material = static_cast<Material *>(material->id.next)) {
-    /* We have to do this because the stored material name is coming directly from USD. */
-    (*r_mat_map)[pxr::TfMakeValidIdentifier(material->id.name + 2)] = material;
-  }
-}
 
 static pxr::UsdShadeMaterial compute_bound_material(const pxr::UsdPrim &prim)
 {
@@ -84,42 +70,6 @@ static pxr::UsdShadeMaterial compute_bound_material(const pxr::UsdPrim &prim)
   return mtl;
 }
 
-/* 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 &params,
-    const std::map<std::string, Material *> &mat_map,
-    const std::map<std::string, std::string> &usd_path_to_mat_name)
-{
-  if (params.mtl_name_collision_mode == USD_MTL_NAME_COLLISION_MAKE_UNIQUE) {
-    /* Check if we've already created the Blender material with a modified name. */
-    std::map<std::string, std::string>::const_iterator path_to_name_iter =
-        usd_path_to_mat_name.find(usd_mat_path.GetAsString());
-
-    if (path_to_name_iter != usd_path_to_mat_name.end()) {
-      std::string mat_name = path_to_name_iter->second;
-      std::map<std::string, Material *>::const_iterator mat_iter = mat_map.find(mat_name);
-      if (mat_iter != mat_map.end()) {
-        return mat_iter->second;
-      }
-      /* We can't find the Blender material which was previously created for this USD
-       * material, which should never happen. */
-      BLI_assert_unreachable();
-    }
-  }
-  else {
-    std::string mat_name = usd_mat_path.GetName();
-    std::map<std::string, Material *>::const_iterator mat_iter = mat_map.find(mat_name);
-
-    if (mat_iter != mat_map.end()) {
-      return mat_iter->second;
-    }
-  }
-
-  return nullptr;
-}
-
 static void assign_materials(Main *bmain,
                              Object *ob,
                              const std::map<pxr::SdfPath, int> &mat_index_map,
@@ -142,7 +92,7 @@ static void assign_materials(Main *bmain,
        it != mat_index_map.end();
        ++it) {
 
-    Material *assigned_mat = find_existing_material(
+    Material *assign

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list