From b0db5363fac313a5bae87850c6550857b9d86beb Mon Sep 17 00:00:00 2001 From: Jesse Yurkovich Date: Fri, 5 Jan 2024 20:35:55 +0100 Subject: [PATCH] Cleanup: Use blender C++ containers for USD Use Vector, Map, and Set as appropriate. The remaining uses of the std:: types come from USD APIs. Pull Request: https://projects.blender.org/blender/blender/pulls/116801 --- .../blender/io/usd/intern/usd_asset_utils.cc | 9 +- .../blender/io/usd/intern/usd_capi_import.cc | 5 +- .../io/usd/intern/usd_reader_material.cc | 45 +++----- .../io/usd/intern/usd_reader_material.h | 14 ++- .../blender/io/usd/intern/usd_reader_mesh.cc | 62 +++++------ .../blender/io/usd/intern/usd_reader_mesh.h | 7 +- .../blender/io/usd/intern/usd_reader_prim.h | 7 +- .../blender/io/usd/intern/usd_reader_stage.cc | 90 +++++++-------- .../blender/io/usd/intern/usd_reader_stage.h | 13 ++- .../blender/io/usd/intern/usd_skel_convert.cc | 103 +++++++++--------- .../blender/io/usd/intern/usd_skel_convert.h | 1 - .../io/usd/intern/usd_writer_material.cc | 55 +++++----- 12 files changed, 190 insertions(+), 221 deletions(-) diff --git a/source/blender/io/usd/intern/usd_asset_utils.cc b/source/blender/io/usd/intern/usd_asset_utils.cc index 96d6da5417b..7f5c5b77502 100644 --- a/source/blender/io/usd/intern/usd_asset_utils.cc +++ b/source/blender/io/usd/intern/usd_asset_utils.cc @@ -16,9 +16,6 @@ #include "BLI_path_util.h" #include "BLI_string.h" -#include "WM_api.hh" -#include "WM_types.hh" - static const char UDIM_PATTERN[] = ""; static const char UDIM_PATTERN2[] = "%3CUDIM%3E"; @@ -39,16 +36,14 @@ namespace blender::io::usd { */ static std::pair split_udim_pattern(const std::string &path) { - static const std::vector patterns = {UDIM_PATTERN, UDIM_PATTERN2}; - - for (const std::string &pattern : patterns) { + for (const std::string &pattern : {UDIM_PATTERN, UDIM_PATTERN2}) { const std::string::size_type pos = path.find(pattern); if (pos != std::string::npos) { return {path.substr(0, pos), path.substr(pos + pattern.size())}; } } - return {std::string(), std::string()}; + return {}; } /* Return the asset file base name, with special handling of diff --git a/source/blender/io/usd/intern/usd_capi_import.cc b/source/blender/io/usd/intern/usd_capi_import.cc index 3d44ee3c07d..0072c203c73 100644 --- a/source/blender/io/usd/intern/usd_capi_import.cc +++ b/source/blender/io/usd/intern/usd_capi_import.cc @@ -255,9 +255,8 @@ static void import_startjob(void *customdata, wmJobWorkerStatus *worker_status) std::string prim_path_mask(data->params.prim_path_mask); pxr::UsdStagePopulationMask pop_mask; if (!prim_path_mask.empty()) { - const std::vector mask_tokens = pxr::TfStringTokenize(prim_path_mask, ",;"); - for (const std::string &tok : mask_tokens) { - pxr::SdfPath prim_path(tok); + for (const std::string &mask_token : pxr::TfStringTokenize(prim_path_mask, ",;")) { + pxr::SdfPath prim_path(mask_token); if (!prim_path.IsEmpty()) { pop_mask.Add(prim_path); } diff --git a/source/blender/io/usd/intern/usd_reader_material.cc b/source/blender/io/usd/intern/usd_reader_material.cc index 42412f2c7d6..f4deb0669a0 100644 --- a/source/blender/io/usd/intern/usd_reader_material.cc +++ b/source/blender/io/usd/intern/usd_reader_material.cc @@ -16,6 +16,7 @@ #include "BKE_report.h" #include "BLI_fileops.h" +#include "BLI_map.hh" #include "BLI_math_vector.h" #include "BLI_path_util.h" #include "BLI_string.h" @@ -31,7 +32,6 @@ #include #include -#include namespace usdtokens { @@ -112,10 +112,7 @@ using blender::io::usd::ShaderToNodeMap; static bNode *get_cached_node(const ShaderToNodeMap &node_cache, const pxr::UsdShadeShader &usd_shader) { - if (bNode *const *node_ptr = node_cache.lookup_ptr(usd_shader.GetPath().GetAsString())) { - return *node_ptr; - } - return nullptr; + return node_cache.lookup_default(usd_shader.GetPath().GetAsString(), nullptr); } /* Cache the Blender node translated from the given USD shader @@ -431,7 +428,7 @@ void compute_node_loc(const int column, float *r_locx, float *r_locy, NodePlacem (*r_locx) = r_ctx->origx - column * r_ctx->horizontal_step; if (column >= r_ctx->column_offsets.size()) { - r_ctx->column_offsets.push_back(0.0f); + r_ctx->column_offsets.append(0.0f); } (*r_locy) = r_ctx->origy - r_ctx->column_offsets[column]; @@ -1088,45 +1085,35 @@ void USDMaterialReader::convert_usd_primvar_reader_float2(const pxr::UsdShadeSha link_nodes(ntree, uv_map, "UV", dest_node, dest_socket_name); } -void build_material_map(const Main *bmain, std::map *r_mat_map) +void build_material_map(const Main *bmain, blender::Map *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; + r_mat_map->lookup_or_add_default(usd_name) = material; } } -Material *find_existing_material(const pxr::SdfPath &usd_mat_path, - const USDImportParams ¶ms, - const std::map &mat_map, - const std::map &usd_path_to_mat_name) +Material *find_existing_material( + const pxr::SdfPath &usd_mat_path, + const USDImportParams ¶ms, + const blender::Map &mat_map, + const blender::Map &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::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()) { + const std::string *mat_name = usd_path_to_mat_name.lookup_ptr(usd_mat_path.GetAsString()); + if (mat_name == nullptr) { return nullptr; } - std::string mat_name = path_to_name_iter->second; - std::map::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; + Material *mat = mat_map.lookup_default(*mat_name, nullptr); + BLI_assert_msg(mat != nullptr, "Previously created material cannot be found any more"); + return mat; } - std::string mat_name = usd_mat_path.GetName(); - std::map::const_iterator mat_iter = mat_map.find(mat_name); - - if (mat_iter == mat_map.end()) { - return nullptr; - } - - return mat_iter->second; + return mat_map.lookup_default(usd_mat_path.GetName(), nullptr); } } // 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 49bf2263af2..cfb539a53e8 100644 --- a/source/blender/io/usd/intern/usd_reader_material.h +++ b/source/blender/io/usd/intern/usd_reader_material.h @@ -8,6 +8,7 @@ #include "WM_types.hh" #include "BLI_map.hh" +#include "BLI_vector.hh" #include @@ -29,7 +30,7 @@ using ShaderToNodeMap = blender::Map; struct NodePlacementContext { float origx; float origy; - std::vector column_offsets; + blender::Vector column_offsets; const float horizontal_step; const float vertical_step; @@ -170,7 +171,7 @@ class USDMaterialReader { * 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 *r_mat_map); +void build_material_map(const Main *bmain, blender::Map *r_mat_map); /** * Returns an existing Blender material that corresponds to the USD material with the given path. @@ -185,9 +186,10 @@ void build_material_map(const Main *bmain, std::map *r_ * 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 ¶ms, - const std::map &mat_map, - const std::map &usd_path_to_mat_name); +Material *find_existing_material( + const pxr::SdfPath &usd_mat_path, + const USDImportParams ¶ms, + const blender::Map &mat_map, + const blender::Map &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 4a401161ebe..ecf8887ae3d 100644 --- a/source/blender/io/usd/intern/usd_reader_mesh.cc +++ b/source/blender/io/usd/intern/usd_reader_mesh.cc @@ -6,6 +6,7 @@ * NVIDIA Corporation. All rights reserved. */ #include "usd_reader_mesh.h" +#include "usd_hash_types.h" #include "usd_reader_material.h" #include "usd_skel_convert.h" @@ -17,14 +18,12 @@ #include "BKE_object.hh" #include "BKE_report.h" +#include "BLI_map.hh" #include "BLI_math_color.hh" -#include "BLI_math_geom.h" #include "BLI_math_vector_types.hh" #include "BLI_span.hh" #include "BLI_string.h" -#include "usd_hash_types.h" - #include "DNA_customdata_types.h" #include "DNA_material_types.h" #include "DNA_modifier_types.h" @@ -80,11 +79,11 @@ static pxr::UsdShadeMaterial compute_bound_material(const pxr::UsdPrim &prim) static void assign_materials(Main *bmain, Object *ob, - const std::map &mat_index_map, + const blender::Map &mat_index_map, const USDImportParams ¶ms, pxr::UsdStageRefPtr stage, - std::map &mat_name_to_mat, - std::map &usd_path_to_mat_name) + blender::Map &mat_name_to_mat, + blender::Map &usd_path_to_mat_name) { if (!(stage && bmain && ob)) { return; @@ -96,22 +95,18 @@ static void assign_materials(Main *bmain, blender::io::usd::USDMaterialReader mat_reader(params, bmain); - for (std::map::const_iterator it = mat_index_map.begin(); - it != mat_index_map.end(); - ++it) - { - + for (const auto item : mat_index_map.items()) { Material *assigned_mat = blender::io::usd::find_existing_material( - it->first, params, mat_name_to_mat, usd_path_to_mat_name); + item.key, params, mat_name_to_mat, usd_path_to_mat_name); if (!assigned_mat) { /* Blender material doesn't exist, so create it now. */ /* Look up the USD material. */ - pxr::UsdPrim prim = stage->GetPrimAtPath(it->first); + pxr::UsdPrim prim = stage->GetPrimAtPath(item.key); pxr::UsdShadeMaterial usd_mat(prim); if (!usd_mat) { - std::cout << "WARNING: Couldn't construct USD material from prim " << it->first + std::cout << "WARNING: Couldn't construct USD material from prim " << item.key << std::endl; continue; } @@ -120,27 +115,27 @@ static void assign_materials(Main *bmain, assigned_mat = mat_reader.add_material(usd_mat); if (!assigned_mat) { - std::cout << "WARNING: Couldn't create Blender material from USD material " << it->first + std::cout << "WARNING: Couldn't create Blender material from USD material " << item.key << std::endl; continue; } const std::string mat_name = pxr::TfMakeValidIdentifier(assigned_mat->id.name + 2); - mat_name_to_mat[mat_name] = assigned_mat; + 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. */ - usd_path_to_mat_name[it->first.GetAsString()] = mat_name; + usd_path_to_mat_name.lookup_or_add_default(item.key.GetAsString()) = mat_name; } } if (assigned_mat) { - BKE_object_material_assign_single_obdata(bmain, ob, assigned_mat, it->second); + BKE_object_material_assign_single_obdata(bmain, ob, assigned_mat, item.value); } else { /* This shouldn't happen. */ - std::cout << "WARNING: Couldn't assign material " << it->first << std::endl; + std::cout << "WARNING: Couldn't assign material " << item.key << std::endl; } } if (ob->totcol > 0) { @@ -919,9 +914,8 @@ void USDMeshReader::read_custom_data(const ImportSettings *settings, /* To avoid unnecessarily reloading static primvars during animation, * early out if not first load and this primvar isn't animated. */ - if (!new_mesh && primvar_varying_map_.find(name) != primvar_varying_map_.end() && - !primvar_varying_map_.at(name)) - { + const bool is_time_varying = primvar_varying_map_.lookup_default(name, false); + if (!new_mesh && !is_time_varying) { continue; } @@ -975,9 +969,9 @@ void USDMeshReader::read_custom_data(const ImportSettings *settings, } /* Record whether the primvar attribute might be time varying. */ - if (primvar_varying_map_.find(name) == primvar_varying_map_.end()) { + if (!primvar_varying_map_.contains(name)) { bool might_be_time_varying = pv.ValueMightBeTimeVarying(); - primvar_varying_map_.insert(std::make_pair(name, might_be_time_varying)); + primvar_varying_map_.add(name, might_be_time_varying); if (might_be_time_varying) { is_time_varying_ = true; } @@ -1001,7 +995,7 @@ void USDMeshReader::read_custom_data(const ImportSettings *settings, void USDMeshReader::assign_facesets_to_material_indices(double motionSampleTime, MutableSpan material_indices, - std::map *r_mat_map) + blender::Map *r_mat_map) { if (r_mat_map == nullptr) { return; @@ -1031,30 +1025,26 @@ void USDMeshReader::assign_facesets_to_material_indices(double motionSampleTime, continue; } - if (r_mat_map->find(subset_mtl_path) == r_mat_map->end()) { - (*r_mat_map)[subset_mtl_path] = 1 + current_mat++; - } - - const int mat_idx = (*r_mat_map)[subset_mtl_path] - 1; + const int mat_idx = r_mat_map->lookup_or_add(subset_mtl_path, 1 + current_mat++); pxr::UsdAttribute indicesAttribute = subset.GetIndicesAttr(); pxr::VtIntArray indices; indicesAttribute.Get(&indices, motionSampleTime); for (const int i : indices) { - material_indices[i] = mat_idx; + material_indices[i] = mat_idx - 1; } } } - if (r_mat_map->empty()) { + if (r_mat_map->is_empty()) { pxr::UsdShadeMaterial mtl = utils::compute_bound_material(prim_); if (mtl) { pxr::SdfPath mtl_path = mtl.GetPath(); if (!mtl_path.IsEmpty()) { - r_mat_map->insert(std::make_pair(mtl.GetPath(), 1)); + r_mat_map->add(mtl.GetPath(), 1); } } } @@ -1066,7 +1056,7 @@ void USDMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, const double mot return; } - std::map mat_map; + blender::Map mat_map; bke::MutableAttributeAccessor attributes = mesh->attributes_for_write(); bke::SpanAttributeWriter material_indices = attributes.lookup_or_add_for_write_span( @@ -1074,7 +1064,7 @@ void USDMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, const double mot this->assign_facesets_to_material_indices(motionSampleTime, material_indices.span, &mat_map); material_indices.finish(); /* Build material name map if it's not built yet. */ - if (this->settings_->mat_name_to_mat.empty()) { + if (this->settings_->mat_name_to_mat.is_empty()) { build_material_map(bmain, &this->settings_->mat_name_to_mat); } utils::assign_materials(bmain, @@ -1122,7 +1112,7 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh, * the material slots that were created when the object was loaded from * USD are still valid now. */ if (active_mesh->faces_num != 0 && import_params_.import_materials) { - std::map mat_map; + blender::Map mat_map; bke::MutableAttributeAccessor attributes = active_mesh->attributes_for_write(); bke::SpanAttributeWriter material_indices = attributes.lookup_or_add_for_write_span("material_index", bke::AttrDomain::Face); diff --git a/source/blender/io/usd/intern/usd_reader_mesh.h b/source/blender/io/usd/intern/usd_reader_mesh.h index 0cd5d3002ae..e296214f9bb 100644 --- a/source/blender/io/usd/intern/usd_reader_mesh.h +++ b/source/blender/io/usd/intern/usd_reader_mesh.h @@ -5,6 +5,7 @@ * Modifications Copyright 2021 Tangent Animation and. NVIDIA Corporation. All rights reserved. */ #pragma once +#include "BLI_map.hh" #include "BLI_span.hh" #include "usd.h" @@ -18,8 +19,8 @@ class USDMeshReader : public USDGeomReader { private: pxr::UsdGeomMesh mesh_prim_; - std::unordered_map uv_token_map_; - std::map primvar_varying_map_; + blender::Map uv_token_map_; + blender::Map primvar_varying_map_; /* TODO(makowalski): Is it the best strategy to cache the * mesh geometry in the following members? It appears these @@ -73,7 +74,7 @@ class USDMeshReader : public USDGeomReader { void readFaceSetsSample(Main *bmain, Mesh *mesh, double motionSampleTime); void assign_facesets_to_material_indices(double motionSampleTime, MutableSpan material_indices, - std::map *r_mat_map); + blender::Map *r_mat_map); void read_mpolys(Mesh *mesh); void read_vertex_creases(Mesh *mesh, double motionSampleTime); diff --git a/source/blender/io/usd/intern/usd_reader_prim.h b/source/blender/io/usd/intern/usd_reader_prim.h index dfa51ef2da8..55d9fda1af2 100644 --- a/source/blender/io/usd/intern/usd_reader_prim.h +++ b/source/blender/io/usd/intern/usd_reader_prim.h @@ -9,12 +9,13 @@ #include "usd.h" +#include "BLI_map.hh" + #include "WM_types.hh" #include #include -#include #include struct CacheFile; @@ -50,11 +51,11 @@ struct ImportSettings { * This field is mutable because it is used to keep track * 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; + mutable blender::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; + mutable blender::Map mat_name_to_mat; /* We use the stage metersPerUnit to convert camera properties from USD scene units to the * correct millimeter scale that Blender uses for camera parameters. */ diff --git a/source/blender/io/usd/intern/usd_reader_stage.cc b/source/blender/io/usd/intern/usd_reader_stage.cc index fc66c9de871..b55c7309ce3 100644 --- a/source/blender/io/usd/intern/usd_reader_stage.cc +++ b/source/blender/io/usd/intern/usd_reader_stage.cc @@ -38,8 +38,7 @@ # include #endif -#include - +#include "BLI_map.hh" #include "BLI_sort.hh" #include "BLI_string.h" @@ -78,7 +77,7 @@ static Collection *create_collection(Main *bmain, Collection *parent, const char */ static void set_instance_collection( USDInstanceReader *instance_reader, - const std::map &proto_collection_map) + const blender::Map &proto_collection_map) { if (!instance_reader) { return; @@ -86,10 +85,9 @@ static void set_instance_collection( pxr::SdfPath proto_path = instance_reader->proto_path(); - std::map::const_iterator it = proto_collection_map.find(proto_path); - - if (it != proto_collection_map.end()) { - instance_reader->set_instance_collection(it->second); + Collection *collection = proto_collection_map.lookup_default(proto_path, nullptr); + if (collection != nullptr) { + instance_reader->set_instance_collection(collection); } else { CLOG_WARN( @@ -304,7 +302,7 @@ static bool merge_with_parent(USDPrimReader *reader) USDPrimReader *USDStageReader::collect_readers(Main *bmain, const pxr::UsdPrim &prim, - std::vector &r_readers) + blender::Vector &r_readers) { if (prim.IsA()) { pxr::UsdGeomImageable imageable(prim); @@ -326,11 +324,11 @@ USDPrimReader *USDStageReader::collect_readers(Main *bmain, pxr::UsdPrimSiblingRange children = prim.GetFilteredChildren(filter_predicate); - std::vector child_readers; + blender::Vector child_readers; for (const auto &childPrim : children) { if (USDPrimReader *child_reader = collect_readers(bmain, childPrim, r_readers)) { - child_readers.push_back(child_reader); + child_readers.append(child_reader); } } @@ -349,7 +347,7 @@ USDPrimReader *USDStageReader::collect_readers(Main *bmain, /* Check if we can merge an Xform with its child prim. */ if (child_readers.size() == 1) { - USDPrimReader *child_reader = child_readers.front(); + USDPrimReader *child_reader = child_readers.first(); if (merge_with_parent(child_reader)) { return child_reader; @@ -359,7 +357,7 @@ USDPrimReader *USDStageReader::collect_readers(Main *bmain, if (prim.IsA()) { /* Record material path for later processing, if needed, * e.g., when importing all materials. */ - material_paths_.push_back(prim.GetPath().GetAsString()); + material_paths_.append(prim.GetPath().GetAsString()); /* We don't create readers for materials, so return early. */ return nullptr; @@ -371,7 +369,7 @@ USDPrimReader *USDStageReader::collect_readers(Main *bmain, return nullptr; } - r_readers.push_back(reader); + r_readers.append(reader); reader->incref(); /* Set each child reader's parent. */ @@ -402,12 +400,12 @@ void USDStageReader::collect_readers(Main *bmain) std::vector protos = stage_->GetPrototypes(); for (const pxr::UsdPrim &proto_prim : protos) { - std::vector proto_readers; + blender::Vector proto_readers; collect_readers(bmain, proto_prim, proto_readers); - proto_readers_.insert(std::make_pair(proto_prim.GetPath(), proto_readers)); + proto_readers_.add(proto_prim.GetPath(), proto_readers); for (USDPrimReader *reader : proto_readers) { - readers_.push_back(reader); + readers_.append(reader); reader->incref(); } } @@ -419,10 +417,10 @@ void USDStageReader::process_armature_modifiers() const /* Iterate over the skeleton readers to create the * armature object map, which maps a USD skeleton prim * path to the corresponding armature object. */ - std::map usd_path_to_armature; + blender::Map usd_path_to_armature; for (const USDPrimReader *reader : readers_) { if (dynamic_cast(reader) && reader->object()) { - usd_path_to_armature.insert(std::make_pair(reader->prim_path(), reader->object())); + usd_path_to_armature.add(reader->prim_path(), reader->object()); } } @@ -445,15 +443,15 @@ void USDStageReader::process_armature_modifiers() const /* Assign the armature based on the bound USD skeleton path of the skinned mesh. */ std::string skel_path = mesh_reader->get_skeleton_path(); - std::map::const_iterator it = usd_path_to_armature.find(skel_path); - if (it == usd_path_to_armature.end()) { + Object *object = usd_path_to_armature.lookup_default(skel_path, nullptr); + if (object == nullptr) { BKE_reportf(reports(), RPT_WARNING, "%s: Couldn't find armature object corresponding to USD skeleton %s", __func__, skel_path.c_str()); } - amd->object = it->second; + amd->object = object; } } @@ -462,7 +460,7 @@ void USDStageReader::import_all_materials(Main *bmain) BLI_assert(valid()); /* Build the material name map if it's not built yet. */ - if (settings_.mat_name_to_mat.empty()) { + if (settings_.mat_name_to_mat.is_empty()) { build_material_map(bmain, &settings_.mat_name_to_mat); } @@ -488,13 +486,14 @@ void USDStageReader::import_all_materials(Main *bmain) BLI_assert_msg(new_mtl, "Failed to create material"); const std::string mtl_name = pxr::TfMakeValidIdentifier(new_mtl->id.name + 2); - settings_.mat_name_to_mat[mtl_name] = new_mtl; + 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[prim.GetPath().GetAsString()] = mtl_name; + settings_.usd_path_to_mat_name.lookup_or_add_default( + prim.GetPath().GetAsString()) = mtl_name; } } } @@ -503,18 +502,12 @@ void USDStageReader::fake_users_for_unused_materials() { /* Iterate over the imported materials and set a fake user for any unused * materials. */ - for (const std::pair &path_mat_pair : - settings_.usd_path_to_mat_name) - { - - std::map::iterator mat_it = settings_.mat_name_to_mat.find( - path_mat_pair.second); - - if (mat_it == settings_.mat_name_to_mat.end()) { + 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; } - Material *mat = mat_it->second; if (mat->id.us == 0) { id_fake_user_set(&mat->id); } @@ -540,9 +533,9 @@ void USDStageReader::clear_readers() void USDStageReader::clear_proto_readers() { - for (auto &pair : proto_readers_) { + for (const auto item : proto_readers_.items()) { - for (USDPrimReader *reader : pair.second) { + for (USDPrimReader *reader : item.value) { if (!reader) { continue; @@ -571,7 +564,7 @@ void USDStageReader::sort_readers() void USDStageReader::create_proto_collections(Main *bmain, Collection *parent_collection) { - if (proto_readers_.empty()) { + if (proto_readers_.is_empty()) { return; } @@ -585,12 +578,12 @@ void USDStageReader::create_proto_collections(Main *bmain, Collection *parent_co } } - std::map proto_collection_map; + blender::Map proto_collection_map; - for (const auto &pair : proto_readers_) { + for (const pxr::SdfPath &path : proto_readers_.keys()) { Collection *proto_collection = create_collection(bmain, all_protos_collection, "proto"); - proto_collection_map.insert(std::make_pair(pair.first, proto_collection)); + proto_collection_map.add(path, proto_collection); } /* Set the instance collections on the readers, including the prototype @@ -603,30 +596,23 @@ void USDStageReader::create_proto_collections(Main *bmain, Collection *parent_co } /* Add the prototype objects to the collections. */ - for (const auto &pair : proto_readers_) { - - std::map::const_iterator it = proto_collection_map.find( - pair.first); - - if (it == proto_collection_map.end()) { - std::cerr << "WARNING: Couldn't find collection when adding objects for prototype " - << pair.first << std::endl; + for (const auto &item : proto_readers_.items()) { + Collection *collection = proto_collection_map.lookup_default(item.key, nullptr); + if (collection == nullptr) { CLOG_WARN(&LOG, "Couldn't find collection when adding objects for prototype %s", - pair.first.GetAsString().c_str()); + item.key.GetAsString().c_str()); continue; } - for (USDPrimReader *reader : pair.second) { + for (USDPrimReader *reader : item.value) { Object *ob = reader->object(); if (!ob) { continue; } - Collection *coll = it->second; - - BKE_collection_object_add(bmain, coll, ob); + BKE_collection_object_add(bmain, collection, ob); } } } diff --git a/source/blender/io/usd/intern/usd_reader_stage.h b/source/blender/io/usd/intern/usd_reader_stage.h index acbeb7f1811..c28f44fe537 100644 --- a/source/blender/io/usd/intern/usd_reader_stage.h +++ b/source/blender/io/usd/intern/usd_reader_stage.h @@ -8,12 +8,13 @@ struct Main; #include "WM_types.hh" #include "usd.h" +#include "usd_hash_types.h" #include "usd_reader_prim.h" #include #include -#include +#include struct ImportSettings; @@ -23,7 +24,7 @@ namespace blender::io::usd { * Map a USD prototype prim path to the list of readers that convert * the prototype data. */ -using ProtoReaderMap = std::map>; +using ProtoReaderMap = blender::Map>; class USDStageReader { @@ -32,11 +33,11 @@ class USDStageReader { USDImportParams params_; ImportSettings settings_; - std::vector readers_; + blender::Vector readers_; /* USD material prim paths encountered during stage * traversal, for importing unused materials. */ - std::vector material_paths_; + blender::Vector material_paths_; /* Readers for scenegraph instance prototypes. */ ProtoReaderMap proto_readers_; @@ -98,7 +99,7 @@ class USDStageReader { void clear_proto_readers(); - const std::vector &readers() const + const blender::Vector &readers() const { return readers_; }; @@ -113,7 +114,7 @@ class USDStageReader { private: USDPrimReader *collect_readers(Main *bmain, const pxr::UsdPrim &prim, - std::vector &r_readers); + blender::Vector &r_readers); /** * Returns true if the given prim should be included in the diff --git a/source/blender/io/usd/intern/usd_skel_convert.cc b/source/blender/io/usd/intern/usd_skel_convert.cc index 29e3c933b9e..feb973fb397 100644 --- a/source/blender/io/usd/intern/usd_skel_convert.cc +++ b/source/blender/io/usd/intern/usd_skel_convert.cc @@ -39,9 +39,12 @@ #include "BKE_object_deform.h" #include "BKE_report.h" +#include "BLI_map.hh" #include "BLI_math_vector.h" +#include "BLI_set.hh" #include "BLI_span.hh" #include "BLI_string.h" +#include "BLI_vector.hh" #include "ED_armature.hh" #include "ED_keyframing.hh" @@ -120,7 +123,7 @@ void add_bezt(FCurve *fcu, void import_skeleton_curves(Main *bmain, Object *arm_obj, const pxr::UsdSkelSkeletonQuery &skel_query, - const std::map &joint_to_bone_map, + const blender::Map &joint_to_bone_map, ReportList *reports) { @@ -128,7 +131,7 @@ void import_skeleton_curves(Main *bmain, return; } - if (joint_to_bone_map.empty()) { + if (joint_to_bone_map.is_empty()) { return; } @@ -156,50 +159,50 @@ void import_skeleton_curves(Main *bmain, /* Get the joint paths. */ pxr::VtTokenArray joint_order = skel_query.GetJointOrder(); - std::vector loc_curves; - std::vector rot_curves; - std::vector scale_curves; + blender::Vector loc_curves; + blender::Vector rot_curves; + blender::Vector scale_curves; /* Iterate over the joints and create the corresponding curves for the bones. */ for (const pxr::TfToken &joint : joint_order) { - std::map::const_iterator it = joint_to_bone_map.find(joint); + const std::string *name = joint_to_bone_map.lookup_ptr(joint); - if (it == joint_to_bone_map.end()) { + if (name == nullptr) { /* This joint doesn't correspond to any bone we created. * Add null placeholders for the channel curves. */ - loc_curves.push_back(nullptr); - loc_curves.push_back(nullptr); - loc_curves.push_back(nullptr); - rot_curves.push_back(nullptr); - rot_curves.push_back(nullptr); - rot_curves.push_back(nullptr); - rot_curves.push_back(nullptr); - scale_curves.push_back(nullptr); - scale_curves.push_back(nullptr); - scale_curves.push_back(nullptr); + loc_curves.append(nullptr); + loc_curves.append(nullptr); + loc_curves.append(nullptr); + rot_curves.append(nullptr); + rot_curves.append(nullptr); + rot_curves.append(nullptr); + rot_curves.append(nullptr); + scale_curves.append(nullptr); + scale_curves.append(nullptr); + scale_curves.append(nullptr); continue; } - bActionGroup *grp = action_groups_add_new(act, it->second.c_str()); + bActionGroup *grp = action_groups_add_new(act, name->c_str()); /* Add translation curves. */ - std::string rna_path = "pose.bones[\"" + it->second + "\"].location"; - loc_curves.push_back(create_chan_fcurve(act, grp, 0, rna_path, num_samples)); - loc_curves.push_back(create_chan_fcurve(act, grp, 1, rna_path, num_samples)); - loc_curves.push_back(create_chan_fcurve(act, grp, 2, rna_path, num_samples)); + std::string rna_path = "pose.bones[\"" + *name + "\"].location"; + loc_curves.append(create_chan_fcurve(act, grp, 0, rna_path, num_samples)); + loc_curves.append(create_chan_fcurve(act, grp, 1, rna_path, num_samples)); + loc_curves.append(create_chan_fcurve(act, grp, 2, rna_path, num_samples)); /* Add rotation curves. */ - rna_path = "pose.bones[\"" + it->second + "\"].rotation_quaternion"; - rot_curves.push_back(create_chan_fcurve(act, grp, 0, rna_path, num_samples)); - rot_curves.push_back(create_chan_fcurve(act, grp, 1, rna_path, num_samples)); - rot_curves.push_back(create_chan_fcurve(act, grp, 2, rna_path, num_samples)); - rot_curves.push_back(create_chan_fcurve(act, grp, 3, rna_path, num_samples)); + rna_path = "pose.bones[\"" + *name + "\"].rotation_quaternion"; + rot_curves.append(create_chan_fcurve(act, grp, 0, rna_path, num_samples)); + rot_curves.append(create_chan_fcurve(act, grp, 1, rna_path, num_samples)); + rot_curves.append(create_chan_fcurve(act, grp, 2, rna_path, num_samples)); + rot_curves.append(create_chan_fcurve(act, grp, 3, rna_path, num_samples)); /* Add scale curves. */ - rna_path = "pose.bones[\"" + it->second + "\"].scale"; - scale_curves.push_back(create_chan_fcurve(act, grp, 0, rna_path, num_samples)); - scale_curves.push_back(create_chan_fcurve(act, grp, 1, rna_path, num_samples)); - scale_curves.push_back(create_chan_fcurve(act, grp, 2, rna_path, num_samples)); + rna_path = "pose.bones[\"" + *name + "\"].scale"; + scale_curves.append(create_chan_fcurve(act, grp, 0, rna_path, num_samples)); + scale_curves.append(create_chan_fcurve(act, grp, 1, rna_path, num_samples)); + scale_curves.append(create_chan_fcurve(act, grp, 2, rna_path, num_samples)); } /* Sanity checks: make sure we have a curve entry for each joint. */ @@ -469,7 +472,7 @@ void import_blendshapes(Main *bmain, /* Keep track of the shape-keys we're adding, * for validation when creating curves later. */ - std::set shapekey_names; + blender::Set shapekey_names; for (int i = 0; i < targets.size(); ++i) { /* Get USD path to blend shape. */ @@ -505,7 +508,7 @@ void import_blendshapes(Main *bmain, continue; } - shapekey_names.insert(blendshapes[i]); + shapekey_names.add(blendshapes[i]); /* Add the key block. */ kb = BKE_keyblock_add(key, blendshapes[i].GetString().c_str()); @@ -629,13 +632,13 @@ void import_blendshapes(Main *bmain, /* Create the animation and curves. */ bAction *act = blender::animrig::id_action_ensure(bmain, (ID *)&key->id); - std::vector curves; + blender::Vector curves; for (auto blendshape_name : blendshapes) { - if (shapekey_names.find(blendshape_name) == shapekey_names.end()) { + if (!shapekey_names.contains(blendshape_name)) { /* We didn't create a shape-key for this blend-shape, so we don't * create a curve and insert a null placeholder in the curve array. */ - curves.push_back(nullptr); + curves.append(nullptr); continue; } @@ -643,7 +646,7 @@ void import_blendshapes(Main *bmain, std::string rna_path = "key_blocks[\"" + blendshape_name.GetString() + "\"].value"; FCurve *fcu = create_fcurve(0, rna_path); fcu->totvert = num_samples; - curves.push_back(fcu); + curves.append(fcu); BLI_addtail(&act->curves, fcu); } @@ -715,12 +718,12 @@ void import_skeleton(Main *bmain, ED_armature_to_edit(arm); /* The bones we create, stored in the skeleton's joint order. */ - std::vector edit_bones; + blender::Vector edit_bones; /* Keep track of the bones we create for each joint. * We'll need this when creating animation curves * later. */ - std::map joint_to_bone_map; + blender::Map joint_to_bone_map; /* Create the bones. */ for (const pxr::TfToken &joint : joint_order) { @@ -732,11 +735,11 @@ void import_skeleton(Main *bmain, "%s: Couldn't add bone for joint %s", __func__, joint.GetString().c_str()); - edit_bones.push_back(nullptr); + edit_bones.append(nullptr); continue; } - joint_to_bone_map.insert(std::make_pair(joint, bone->name)); - edit_bones.push_back(bone); + joint_to_bone_map.add(joint, bone->name); + edit_bones.append(bone); } /* Sanity check: we should have created a bone for each joint. */ @@ -829,7 +832,7 @@ void import_skeleton(Main *bmain, /* This will record the child bone indices per parent bone, * to simplify accessing children when computing lengths. */ - std::vector> child_bones(num_joints); + blender::Vector> child_bones(num_joints); for (size_t i = 0; i < num_joints; ++i) { const int parent_idx = skel_topology.GetParent(i); @@ -842,7 +845,7 @@ void import_skeleton(Main *bmain, continue; } - child_bones[parent_idx].push_back(i); + child_bones[parent_idx].append(i); if (edit_bones[i] && edit_bones[parent_idx]) { edit_bones[i]->parent = edit_bones[parent_idx]; } @@ -855,7 +858,7 @@ void import_skeleton(Main *bmain, * by the distance between this bone's head * and the average head location of its children. */ - if (child_bones[i].empty()) { + if (child_bones[i].is_empty()) { continue; } @@ -893,7 +896,7 @@ void import_skeleton(Main *bmain, avg_len_scale /= num_joints; for (size_t i = 0; i < num_joints; ++i) { - if (!child_bones[i].empty()) { + if (!child_bones[i].is_empty()) { /* Not a terminal bone. */ continue; } @@ -1042,7 +1045,7 @@ void import_mesh_skel_bindings(Main *bmain, } /* Determine which joint indices are used for skinning this prim. */ - std::vector used_indices; + blender::Vector used_indices; for (int index : joint_indices) { if (std::find(used_indices.begin(), used_indices.end(), index) == used_indices.end()) { /* We haven't accounted for this index yet. */ @@ -1050,11 +1053,11 @@ void import_mesh_skel_bindings(Main *bmain, std::cerr << "Out of bound joint index " << index << std::endl; continue; } - used_indices.push_back(index); + used_indices.append(index); } } - if (used_indices.empty()) { + if (used_indices.is_empty()) { return; } @@ -1074,7 +1077,7 @@ void import_mesh_skel_bindings(Main *bmain, } /* Create a deform group per joint. */ - std::vector joint_def_grps(joints.size(), nullptr); + blender::Vector joint_def_grps(joints.size(), nullptr); for (int idx : used_indices) { std::string joint_name = pxr::SdfPath(joints[idx]).GetName(); diff --git a/source/blender/io/usd/intern/usd_skel_convert.h b/source/blender/io/usd/intern/usd_skel_convert.h index 31ad3ca8574..910be403fa8 100644 --- a/source/blender/io/usd/intern/usd_skel_convert.h +++ b/source/blender/io/usd/intern/usd_skel_convert.h @@ -8,7 +8,6 @@ #include "DNA_windowmanager_types.h" -#include #include #include #include diff --git a/source/blender/io/usd/intern/usd_writer_material.cc b/source/blender/io/usd/intern/usd_writer_material.cc index f8dd2d3b95c..42e337c4615 100644 --- a/source/blender/io/usd/intern/usd_writer_material.cc +++ b/source/blender/io/usd/intern/usd_writer_material.cc @@ -20,6 +20,7 @@ #include "BLI_fileops.h" #include "BLI_linklist.h" #include "BLI_listbase.h" +#include "BLI_map.hh" #include "BLI_memory_utils.hh" #include "BLI_path_util.h" #include "BLI_string.h" @@ -103,7 +104,7 @@ struct InputSpec { }; /* Map Blender socket names to USD Preview Surface InputSpec structs. */ -using InputSpecMap = std::map; +using InputSpecMap = blender::Map; /* Static function forward declarations. */ static pxr::UsdShadeShader create_usd_preview_shader(const USDExporterContext &usd_export_context, @@ -124,7 +125,7 @@ static bNode *find_bsdf_node(Material *material); static void get_absolute_path(Image *ima, char *r_path); static std::string get_tex_image_asset_filepath(const USDExporterContext &usd_export_context, bNode *node); -static InputSpecMap &preview_surface_input_map(); +static const InputSpecMap &preview_surface_input_map(); static bNodeLink *traverse_channel(bNodeSocket *input, short target_type); void set_normal_texture_range(pxr::UsdShadeShader &usd_shader, const InputSpec &input_spec); @@ -174,16 +175,15 @@ static void create_usd_preview_surface_material(const USDExporterContext &usd_ex LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) { /* Check if this socket is mapped to a USD preview shader input. */ - const InputSpecMap::const_iterator it = input_map.find(sock->name); - - if (it == input_map.end()) { + const InputSpec *spec = input_map.lookup_ptr(sock->name); + if (spec == nullptr) { continue; } /* Allow scaling inputs. */ float scale = 1.0; - const InputSpec &input_spec = it->second; + const InputSpec &input_spec = *spec; bNodeLink *input_link = traverse_channel(sock, SH_NODE_TEX_IMAGE); if (input_spec.input_name == usdtokens::emissive_color) { @@ -336,22 +336,27 @@ static void create_usd_viewport_material(const USDExporterContext &usd_export_co } /* Return USD Preview Surface input map singleton. */ -static InputSpecMap &preview_surface_input_map() +static const InputSpecMap &preview_surface_input_map() { - static InputSpecMap input_map = { - {"Base Color", {usdtokens::diffuse_color, pxr::SdfValueTypeNames->Color3f, true}}, - {"Emission Color", {usdtokens::emissive_color, pxr::SdfValueTypeNames->Color3f, true}}, - {"Color", {usdtokens::diffuse_color, pxr::SdfValueTypeNames->Color3f, true}}, - {"Roughness", {usdtokens::roughness, pxr::SdfValueTypeNames->Float, true}}, - {"Metallic", {usdtokens::metallic, pxr::SdfValueTypeNames->Float, true}}, - {"Specular IOR Level", {usdtokens::specular, pxr::SdfValueTypeNames->Float, true}}, - {"Alpha", {usdtokens::opacity, pxr::SdfValueTypeNames->Float, true}}, - {"IOR", {usdtokens::ior, pxr::SdfValueTypeNames->Float, true}}, - /* Note that for the Normal input set_default_value is false. */ - {"Normal", {usdtokens::normal, pxr::SdfValueTypeNames->Float3, false}}, - {"Coat Weight", {usdtokens::clearcoat, pxr::SdfValueTypeNames->Float, true}}, - {"Coat Roughness", {usdtokens::clearcoatRoughness, pxr::SdfValueTypeNames->Float, true}}, - }; + static const InputSpecMap input_map = []() { + InputSpecMap map; + map.add_new("Base Color", {usdtokens::diffuse_color, pxr::SdfValueTypeNames->Color3f, true}); + map.add_new("Emission Color", + {usdtokens::emissive_color, pxr::SdfValueTypeNames->Color3f, true}); + map.add_new("Color", {usdtokens::diffuse_color, pxr::SdfValueTypeNames->Color3f, true}); + map.add_new("Roughness", {usdtokens::roughness, pxr::SdfValueTypeNames->Float, true}); + map.add_new("Metallic", {usdtokens::metallic, pxr::SdfValueTypeNames->Float, true}); + map.add_new("Specular IOR Level", {usdtokens::specular, pxr::SdfValueTypeNames->Float, true}); + map.add_new("Alpha", {usdtokens::opacity, pxr::SdfValueTypeNames->Float, true}); + map.add_new("IOR", {usdtokens::ior, pxr::SdfValueTypeNames->Float, true}); + + /* Note that for the Normal input set_default_value is false. */ + map.add_new("Normal", {usdtokens::normal, pxr::SdfValueTypeNames->Float3, false}); + map.add_new("Coat Weight", {usdtokens::clearcoat, pxr::SdfValueTypeNames->Float, true}); + map.add_new("Coat Roughness", + {usdtokens::clearcoatRoughness, pxr::SdfValueTypeNames->Float, true}); + return map; + }(); return input_map; } @@ -990,13 +995,13 @@ static void export_texture(const USDExporterContext &usd_export_context, bNode * const pxr::TfToken token_for_input(const char *input_name) { const InputSpecMap &input_map = preview_surface_input_map(); - const InputSpecMap::const_iterator it = input_map.find(input_name); + const InputSpec *spec = input_map.lookup_ptr(input_name); - if (it == input_map.end()) { - return pxr::TfToken(); + if (spec == nullptr) { + return {}; } - return it->second.input_name; + return spec->input_name; } pxr::UsdShadeMaterial create_usd_material(const USDExporterContext &usd_export_context,