From 5b5811c97b59fd187a7aafd874535c749054d5db Mon Sep 17 00:00:00 2001 From: Aras Pranckevicius Date: Fri, 17 Jun 2022 22:28:22 +0300 Subject: USD: speed up large USD imports by not rebuilding material name map for each object Previous code was rebuilding "name to material" map for each object being imported. Which means O(N*M) complexity (N=object count, M=material count). There was already a TODO comment suggesting that a single map that's maintained for the whole import would be enough. This commit does exactly that. While importing Moana USD scene (260k objects, 18k materials) this saves about 6 minutes of import time. Reviewed By: Bastien Montagne Differential Revision: https://developer.blender.org/D15222 --- source/blender/io/usd/intern/usd_reader_mesh.cc | 14 ++++++++------ source/blender/io/usd/intern/usd_reader_prim.h | 5 +++++ 2 files changed, 13 insertions(+), 6 deletions(-) (limited to 'source/blender/io/usd/intern') diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc index 368d0e1bab9..36e1a40953c 100644 --- a/source/blender/io/usd/intern/usd_reader_mesh.cc +++ b/source/blender/io/usd/intern/usd_reader_mesh.cc @@ -111,6 +111,7 @@ static void assign_materials(Main *bmain, const std::map &mat_index_map, const USDImportParams ¶ms, pxr::UsdStageRefPtr stage, + std::map &mat_name_to_mat, std::map &usd_path_to_mat_name) { if (!(stage && bmain && ob)) { @@ -132,16 +133,12 @@ static void assign_materials(Main *bmain, return; } - /* TODO(kevin): use global map? */ - std::map 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) { 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 +162,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 @@ -805,11 +802,16 @@ void USDMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, const double mot std::map mat_map; assign_facesets_to_mpoly(motionSampleTime, mesh->mpoly, mesh->totpoly, &mat_map); + /* 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); } diff --git a/source/blender/io/usd/intern/usd_reader_prim.h b/source/blender/io/usd/intern/usd_reader_prim.h index f2df00accf6..c44c4a14ad7 100644 --- a/source/blender/io/usd/intern/usd_reader_prim.h +++ b/source/blender/io/usd/intern/usd_reader_prim.h @@ -11,6 +11,7 @@ #include struct Main; +struct Material; struct Object; namespace blender::io::usd { @@ -42,6 +43,10 @@ struct ImportSettings { * of what the importer is doing. This is necessary even * when all the other import settings are to remain const. */ mutable std::map usd_path_to_mat_name; + /* Map a material name to Blender material. + * This map is updated by readers during stage traversal, + * and is mutable similar to the map above. */ + mutable std::map mat_name_to_mat; ImportSettings() : do_convert_mat(false), -- cgit v1.2.3