Cleanup: USD: Simplify our usd-path to material map processing

Since the `usd_path_to_mat_name` map seems to always be used in tandem
with `mat_name_to_mat` to get the material, change it from a map of
[string, string] to [string, Material] and store the Material directly.
This removes the need to do a secondary lookup through `mat_name_to_mat`
and less memory will be used at runtime due to the smaller Value size.

Pull Request: https://projects.blender.org/blender/blender/pulls/132647
This commit is contained in:
Jesse Yurkovich
2025-01-07 19:59:42 +01:00
committed by Jesse Yurkovich
parent 30b48f32fb
commit 4d5be451a7
6 changed files with 26 additions and 45 deletions

View File

@@ -619,7 +619,7 @@ void call_import_hooks(USDStageReader *archive, ReportList *reports)
/* Resize based on the typical scenario where there will be both Object and Data entries
* in the map in addition to each material. */
prim_map.reserve((readers.size() * 2) + settings.usd_path_to_mat_name.size());
prim_map.reserve((readers.size() * 2) + settings.usd_path_to_mat.size());
for (const USDPrimReader *reader : readers) {
if (!reader) {
@@ -636,12 +636,9 @@ void call_import_hooks(USDStageReader *archive, ReportList *reports)
}
}
settings.usd_path_to_mat_name.foreach_item(
[&](const std::string &path, const std::string &name) {
if (Material *mat = settings.mat_name_to_mat.lookup_default(name, nullptr)) {
prim_map.lookup_or_add_default(path).append(RNA_id_pointer_create(&mat->id));
}
});
settings.usd_path_to_mat.foreach_item([&prim_map](const std::string &path, Material *mat) {
prim_map.lookup_or_add_default(path).append(RNA_id_pointer_create(&mat->id));
});
OnImportInvoker on_import(archive->stage(), prim_map, reports);
on_import.call();

View File

@@ -1495,22 +1495,14 @@ void build_material_map(const Main *bmain, blender::Map<std::string, Material *>
}
}
Material *find_existing_material(
const pxr::SdfPath &usd_mat_path,
const USDImportParams &params,
const blender::Map<std::string, Material *> &mat_map,
const blender::Map<std::string, std::string> &usd_path_to_mat_name)
Material *find_existing_material(const pxr::SdfPath &usd_mat_path,
const USDImportParams &params,
const blender::Map<std::string, Material *> &mat_map,
const blender::Map<std::string, Material *> &usd_path_to_mat)
{
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. */
const std::string *mat_name = usd_path_to_mat_name.lookup_ptr(usd_mat_path.GetAsString());
if (mat_name == nullptr) {
return nullptr;
}
Material *mat = mat_map.lookup_default(*mat_name, nullptr);
BLI_assert_msg(mat != nullptr, "Previously created material cannot be found any more");
return mat;
return usd_path_to_mat.lookup_default(usd_mat_path.GetAsString(), nullptr);
}
return mat_map.lookup_default(usd_mat_path.GetName(), nullptr);

View File

@@ -196,16 +196,15 @@ void build_material_map(const Main *bmain, blender::Map<std::string, Material *>
* \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.
* \param usd_path_to_mat: Map a USD material path to the imported Blender material.
*
* The usd_path_to_mat_name is needed to determine the name of the Blender
* The usd_path_to_mat 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 blender::Map<std::string, Material *> &mat_map,
const blender::Map<std::string, std::string> &usd_path_to_mat_name);
Material *find_existing_material(const pxr::SdfPath &usd_mat_path,
const USDImportParams &params,
const blender::Map<std::string, Material *> &mat_map,
const blender::Map<std::string, Material *> &usd_path_to_mat);
} // namespace blender::io::usd

View File

@@ -110,7 +110,7 @@ static void assign_materials(Main *bmain,
for (const auto item : mat_index_map.items()) {
Material *assigned_mat = find_existing_material(
item.key, params, settings.mat_name_to_mat, settings.usd_path_to_mat_name);
item.key, params, settings.mat_name_to_mat, settings.usd_path_to_mat);
if (!assigned_mat) {
/* Blender material doesn't exist, so create it now. */
@@ -142,9 +142,8 @@ static void assign_materials(Main *bmain,
settings.mat_name_to_mat.lookup_or_add_default(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
* with the given path. */
settings.usd_path_to_mat_name.lookup_or_add_default(item.key.GetAsString()) = mat_name;
/* Record the Blender material we created for the USD material with the given path. */
settings.usd_path_to_mat.lookup_or_add_default(item.key.GetAsString()) = assigned_mat;
}
if (have_import_hook) {

View File

@@ -42,9 +42,9 @@ struct ImportSettings {
* the other import settings are to remain const.
*/
/* Map a USD material prim path to a Blender material name.
/* Map a USD material prim path to a Blender material.
* This map is updated by readers during stage traversal. */
mutable blender::Map<std::string, std::string> usd_path_to_mat_name{};
mutable blender::Map<std::string, Material *> usd_path_to_mat{};
/* Map a material name to Blender material.
* This map is updated by readers during stage traversal. */
mutable blender::Map<std::string, Material *> mat_name_to_mat{};

View File

@@ -607,7 +607,7 @@ void USDStageReader::import_all_materials(Main *bmain)
}
if (blender::io::usd::find_existing_material(
prim.GetPath(), params_, settings_.mat_name_to_mat, settings_.usd_path_to_mat_name))
prim.GetPath(), params_, settings_.mat_name_to_mat, settings_.usd_path_to_mat))
{
/* The material already exists. */
continue;
@@ -625,11 +625,10 @@ void USDStageReader::import_all_materials(Main *bmain)
settings_.mat_name_to_mat.lookup_or_add_default(mtl_name) = new_mtl;
if (params_.mtl_name_collision_mode == USD_MTL_NAME_COLLISION_MAKE_UNIQUE) {
/* Record the unique name of the Blender material we created for the USD material
* with the given path, so we don't import the material again when assigning
* materials to objects elsewhere in the code. */
settings_.usd_path_to_mat_name.lookup_or_add_default(
prim.GetPath().GetAsString()) = mtl_name;
/* Record the Blender material we created for the USD material with the given path.
* This is to prevent importing the material again when assigning materials to objects
* elsewhere in the code. */
settings_.usd_path_to_mat.lookup_or_add_default(prim.GetPath().GetAsString()) = new_mtl;
}
if (have_import_hook) {
@@ -644,12 +643,7 @@ void USDStageReader::fake_users_for_unused_materials()
{
/* Iterate over the imported materials and set a fake user for any unused
* materials. */
for (const auto path_mat_pair : settings_.usd_path_to_mat_name.items()) {
Material *mat = settings_.mat_name_to_mat.lookup_default(path_mat_pair.value, nullptr);
if (mat == nullptr) {
continue;
}
for (Material *mat : settings_.usd_path_to_mat.values()) {
if (mat->id.us == 0) {
id_fake_user_set(&mat->id);
}