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
This commit is contained in:
parent
0a8129e0cf
commit
b0db5363fa
@ -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[] = "<UDIM>";
|
||||
static const char UDIM_PATTERN2[] = "%3CUDIM%3E";
|
||||
|
||||
@ -39,16 +36,14 @@ namespace blender::io::usd {
|
||||
*/
|
||||
static std::pair<std::string, std::string> split_udim_pattern(const std::string &path)
|
||||
{
|
||||
static const std::vector<std::string> 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
|
||||
|
@ -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<std::string> 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);
|
||||
}
|
||||
|
@ -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 <pxr/usd/usdShade/shader.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
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<std::string, Material *> *r_mat_map)
|
||||
void build_material_map(const Main *bmain, blender::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;
|
||||
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<std::string, Material *> &mat_map,
|
||||
const std::map<std::string, std::string> &usd_path_to_mat_name)
|
||||
Material *find_existing_material(
|
||||
const pxr::SdfPath &usd_mat_path,
|
||||
const USDImportParams ¶ms,
|
||||
const blender::Map<std::string, Material *> &mat_map,
|
||||
const blender::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()) {
|
||||
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<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;
|
||||
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<std::string, Material *>::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
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "WM_types.hh"
|
||||
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include <pxr/usd/usdShade/material.h>
|
||||
|
||||
@ -29,7 +30,7 @@ using ShaderToNodeMap = blender::Map<std::string, bNode *>;
|
||||
struct NodePlacementContext {
|
||||
float origx;
|
||||
float origy;
|
||||
std::vector<float> column_offsets;
|
||||
blender::Vector<float, 0> 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<std::string, Material *> *r_mat_map);
|
||||
void build_material_map(const Main *bmain, blender::Map<std::string, Material *> *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<std::string, Material *> *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<std::string, Material *> &mat_map,
|
||||
const std::map<std::string, std::string> &usd_path_to_mat_name);
|
||||
Material *find_existing_material(
|
||||
const pxr::SdfPath &usd_mat_path,
|
||||
const USDImportParams ¶ms,
|
||||
const blender::Map<std::string, Material *> &mat_map,
|
||||
const blender::Map<std::string, std::string> &usd_path_to_mat_name);
|
||||
|
||||
} // namespace blender::io::usd
|
||||
|
@ -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<pxr::SdfPath, int> &mat_index_map,
|
||||
const blender::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)
|
||||
blender::Map<std::string, Material *> &mat_name_to_mat,
|
||||
blender::Map<std::string, std::string> &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<pxr::SdfPath, int>::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<int> material_indices,
|
||||
std::map<pxr::SdfPath, int> *r_mat_map)
|
||||
blender::Map<pxr::SdfPath, int> *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<pxr::SdfPath, int> mat_map;
|
||||
blender::Map<pxr::SdfPath, int> mat_map;
|
||||
|
||||
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
|
||||
bke::SpanAttributeWriter<int> material_indices = attributes.lookup_or_add_for_write_span<int>(
|
||||
@ -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<pxr::SdfPath, int> mat_map;
|
||||
blender::Map<pxr::SdfPath, int> mat_map;
|
||||
bke::MutableAttributeAccessor attributes = active_mesh->attributes_for_write();
|
||||
bke::SpanAttributeWriter<int> material_indices =
|
||||
attributes.lookup_or_add_for_write_span<int>("material_index", bke::AttrDomain::Face);
|
||||
|
@ -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<std::string, pxr::TfToken> uv_token_map_;
|
||||
std::map<const pxr::TfToken, bool> primvar_varying_map_;
|
||||
blender::Map<std::string, pxr::TfToken> uv_token_map_;
|
||||
blender::Map<const pxr::TfToken, bool> 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<int> material_indices,
|
||||
std::map<pxr::SdfPath, int> *r_mat_map);
|
||||
blender::Map<pxr::SdfPath, int> *r_mat_map);
|
||||
|
||||
void read_mpolys(Mesh *mesh);
|
||||
void read_vertex_creases(Mesh *mesh, double motionSampleTime);
|
||||
|
@ -9,12 +9,13 @@
|
||||
|
||||
#include "usd.h"
|
||||
|
||||
#include "BLI_map.hh"
|
||||
|
||||
#include "WM_types.hh"
|
||||
|
||||
#include <pxr/usd/sdf/path.h>
|
||||
#include <pxr/usd/usd/prim.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
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<std::string, std::string> usd_path_to_mat_name;
|
||||
mutable blender::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;
|
||||
mutable blender::Map<std::string, Material *> 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. */
|
||||
|
@ -38,8 +38,7 @@
|
||||
# include <pxr/usd/usdLux/light.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#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<pxr::SdfPath, Collection *> &proto_collection_map)
|
||||
const blender::Map<pxr::SdfPath, Collection *> &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<pxr::SdfPath, Collection *>::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<USDPrimReader *> &r_readers)
|
||||
blender::Vector<USDPrimReader *> &r_readers)
|
||||
{
|
||||
if (prim.IsA<pxr::UsdGeomImageable>()) {
|
||||
pxr::UsdGeomImageable imageable(prim);
|
||||
@ -326,11 +324,11 @@ USDPrimReader *USDStageReader::collect_readers(Main *bmain,
|
||||
|
||||
pxr::UsdPrimSiblingRange children = prim.GetFilteredChildren(filter_predicate);
|
||||
|
||||
std::vector<USDPrimReader *> child_readers;
|
||||
blender::Vector<USDPrimReader *> 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<pxr::UsdShadeMaterial>()) {
|
||||
/* 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<pxr::UsdPrim> protos = stage_->GetPrototypes();
|
||||
|
||||
for (const pxr::UsdPrim &proto_prim : protos) {
|
||||
std::vector<USDPrimReader *> proto_readers;
|
||||
blender::Vector<USDPrimReader *> 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<std::string, Object *> usd_path_to_armature;
|
||||
blender::Map<std::string, Object *> usd_path_to_armature;
|
||||
for (const USDPrimReader *reader : readers_) {
|
||||
if (dynamic_cast<const USDSkeletonReader *>(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<std::string, Object *>::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<const std::string, std::string> &path_mat_pair :
|
||||
settings_.usd_path_to_mat_name)
|
||||
{
|
||||
|
||||
std::map<std::string, Material *>::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<pxr::SdfPath, Collection *> proto_collection_map;
|
||||
blender::Map<pxr::SdfPath, Collection *> 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<pxr::SdfPath, Collection *>::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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,12 +8,13 @@ struct Main;
|
||||
#include "WM_types.hh"
|
||||
|
||||
#include "usd.h"
|
||||
#include "usd_hash_types.h"
|
||||
#include "usd_reader_prim.h"
|
||||
|
||||
#include <pxr/usd/usd/stage.h>
|
||||
#include <pxr/usd/usdGeom/imageable.h>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
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<pxr::SdfPath, std::vector<USDPrimReader *>>;
|
||||
using ProtoReaderMap = blender::Map<pxr::SdfPath, blender::Vector<USDPrimReader *>>;
|
||||
|
||||
class USDStageReader {
|
||||
|
||||
@ -32,11 +33,11 @@ class USDStageReader {
|
||||
USDImportParams params_;
|
||||
ImportSettings settings_;
|
||||
|
||||
std::vector<USDPrimReader *> readers_;
|
||||
blender::Vector<USDPrimReader *> readers_;
|
||||
|
||||
/* USD material prim paths encountered during stage
|
||||
* traversal, for importing unused materials. */
|
||||
std::vector<std::string> material_paths_;
|
||||
blender::Vector<std::string> material_paths_;
|
||||
|
||||
/* Readers for scenegraph instance prototypes. */
|
||||
ProtoReaderMap proto_readers_;
|
||||
@ -98,7 +99,7 @@ class USDStageReader {
|
||||
|
||||
void clear_proto_readers();
|
||||
|
||||
const std::vector<USDPrimReader *> &readers() const
|
||||
const blender::Vector<USDPrimReader *> &readers() const
|
||||
{
|
||||
return readers_;
|
||||
};
|
||||
@ -113,7 +114,7 @@ class USDStageReader {
|
||||
private:
|
||||
USDPrimReader *collect_readers(Main *bmain,
|
||||
const pxr::UsdPrim &prim,
|
||||
std::vector<USDPrimReader *> &r_readers);
|
||||
blender::Vector<USDPrimReader *> &r_readers);
|
||||
|
||||
/**
|
||||
* Returns true if the given prim should be included in the
|
||||
|
@ -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<pxr::TfToken, std::string> &joint_to_bone_map,
|
||||
const blender::Map<pxr::TfToken, std::string> &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<FCurve *> loc_curves;
|
||||
std::vector<FCurve *> rot_curves;
|
||||
std::vector<FCurve *> scale_curves;
|
||||
blender::Vector<FCurve *> loc_curves;
|
||||
blender::Vector<FCurve *> rot_curves;
|
||||
blender::Vector<FCurve *> scale_curves;
|
||||
|
||||
/* Iterate over the joints and create the corresponding curves for the bones. */
|
||||
for (const pxr::TfToken &joint : joint_order) {
|
||||
std::map<pxr::TfToken, std::string>::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<pxr::TfToken> shapekey_names;
|
||||
blender::Set<pxr::TfToken> 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<FCurve *> curves;
|
||||
blender::Vector<FCurve *> 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<EditBone *> edit_bones;
|
||||
blender::Vector<EditBone *> edit_bones;
|
||||
|
||||
/* Keep track of the bones we create for each joint.
|
||||
* We'll need this when creating animation curves
|
||||
* later. */
|
||||
std::map<pxr::TfToken, std::string> joint_to_bone_map;
|
||||
blender::Map<pxr::TfToken, std::string> 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<std::vector<int>> child_bones(num_joints);
|
||||
blender::Vector<blender::Vector<int>> 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<int> used_indices;
|
||||
blender::Vector<int> 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<bDeformGroup *> joint_def_grps(joints.size(), nullptr);
|
||||
blender::Vector<bDeformGroup *> joint_def_grps(joints.size(), nullptr);
|
||||
|
||||
for (int idx : used_indices) {
|
||||
std::string joint_name = pxr::SdfPath(joints[idx]).GetName();
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
#include <map>
|
||||
#include <pxr/usd/usd/prim.h>
|
||||
#include <pxr/usd/usdGeom/xformCache.h>
|
||||
#include <pxr/usd/usdSkel/bindingAPI.h>
|
||||
|
@ -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<std::string, InputSpec>;
|
||||
using InputSpecMap = blender::Map<std::string, InputSpec>;
|
||||
|
||||
/* 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,
|
||||
|
Loading…
Reference in New Issue
Block a user