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
This commit is contained in:
parent
230f72347a
commit
5b5811c97b
@ -111,6 +111,7 @@ 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)) {
|
||||
@ -132,16 +133,12 @@ static void assign_materials(Main *bmain,
|
||||
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) {
|
||||
|
||||
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<pxr::SdfPath, int> 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);
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <string>
|
||||
|
||||
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<std::string, std::string> 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<std::string, Material *> mat_name_to_mat;
|
||||
|
||||
ImportSettings()
|
||||
: do_convert_mat(false),
|
||||
|
Loading…
Reference in New Issue
Block a user