diff options
author | Michael A. Kowalski <makowalski@nvidia.com> | 2020-12-04 05:01:59 +0300 |
---|---|---|
committer | Michael A. Kowalski <makowalski@nvidia.com> | 2020-12-04 05:01:59 +0300 |
commit | 871fda82e662d889046e37061b582758f705a2af (patch) | |
tree | e0100e6a57a34740b3aff5a2320cdf9cdce41df2 /source/blender/io/usd/import/usd_prim_iterator.cc | |
parent | 754add813cded02fafb4dffaaffa665271548b09 (diff) |
USD importer: instancing improvements.
Added new USDDataCache class for caching prototype mesh data.
No longer using a global static cache for prototype meshes.
Now precomputing the prototype meshes in a USDDataCache
instance which is passed as an argument to
USDXformableReade::create_objects(). These changes simplify
the code, provide better support for thread safety and circumvent
potential issues with dangling pointers in the previous
implementation.
Diffstat (limited to 'source/blender/io/usd/import/usd_prim_iterator.cc')
-rw-r--r-- | source/blender/io/usd/import/usd_prim_iterator.cc | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/source/blender/io/usd/import/usd_prim_iterator.cc b/source/blender/io/usd/import/usd_prim_iterator.cc index 7f6f311e90a..18d4bc11d46 100644 --- a/source/blender/io/usd/import/usd_prim_iterator.cc +++ b/source/blender/io/usd/import/usd_prim_iterator.cc @@ -20,6 +20,7 @@ #include "usd_prim_iterator.h" #include "usd.h" +#include "usd_data_cache.h" #include "usd_importer_context.h" #include "usd_reader_camera.h" #include "usd_reader_light.h" @@ -41,23 +42,24 @@ namespace blender::io::usd { -USDPrimIterator::USDPrimIterator(pxr::UsdStageRefPtr stage) : stage_(stage) +USDPrimIterator::USDPrimIterator(pxr::UsdStageRefPtr stage, + const USDImporterContext &context, + Main *bmain) + : stage_(stage), context_(context), bmain_(bmain) { } -void USDPrimIterator::create_object_readers(const USDImporterContext &context, - std::vector<USDXformableReader *> &r_readers) const +void USDPrimIterator::create_object_readers(std::vector<USDXformableReader *> &r_readers) const { if (!stage_) { return; } std::vector<USDXformableReader *> child_readers; - create_object_readers(stage_->GetPseudoRoot(), context, r_readers, child_readers); + create_object_readers(stage_->GetPseudoRoot(), context_, r_readers, child_readers); } void USDPrimIterator::create_prototype_object_readers( - const USDImporterContext &context, std::map<pxr::SdfPath, USDXformableReader *> &r_proto_readers) const { if (!stage_) { @@ -70,7 +72,7 @@ void USDPrimIterator::create_prototype_object_readers( std::vector<USDXformableReader *> proto_readers; std::vector<USDXformableReader *> child_readers; - create_object_readers(proto_prim, context, proto_readers, child_readers); + create_object_readers(proto_prim, context_, proto_readers, child_readers); for (USDXformableReader *reader : proto_readers) { if (reader) { @@ -168,6 +170,45 @@ void USDPrimIterator::create_object_readers(const pxr::UsdPrim &prim, } } +void USDPrimIterator::cache_prototype_data(USDDataCache &r_cache) const +{ + if (!stage_) { + return; + } + + std::vector<pxr::UsdPrim> protos = stage_->GetMasters(); + + for (const pxr::UsdPrim &proto_prim : protos) { + std::vector<USDXformableReader *> proto_readers; + std::vector<USDXformableReader *> child_readers; + + create_object_readers(proto_prim, context_, proto_readers, child_readers); + + for (USDXformableReader *reader : proto_readers) { + if (reader) { + pxr::UsdPrim reader_prim = reader->prim(); + if (reader_prim) { + + if (USDMeshReaderBase *mesh_reader = dynamic_cast<USDMeshReaderBase *>(reader)) { + Mesh *proto_mesh = mesh_reader->create_mesh(bmain_, 0.0); + if (proto_mesh) { + /* TODO(makowalski): Do we want to decrement the mesh's use count to 0? + * Might have a small memory leak otherwise. Also, check if mesh is + * already in cache before adding? */ + r_cache.add_prototype_mesh(reader_prim.GetPath(), proto_mesh); + } + } + } + } + } + + /* Clean up the readers. */ + for (USDXformableReader *reader : proto_readers) { + delete reader; + } + } +} + void USDPrimIterator::debug_traverse_stage(const pxr::UsdStageRefPtr &usd_stage) { if (!usd_stage) { |