[Bf-blender-cvs] [871fda82e66] usd-importer-T81257: USD importer: instancing improvements.
Michael A. Kowalski
noreply at git.blender.org
Fri Dec 4 03:39:51 CET 2020
Commit: 871fda82e662d889046e37061b582758f705a2af
Author: Michael A. Kowalski
Date: Thu Dec 3 21:01:59 2020 -0500
Branches: usd-importer-T81257
https://developer.blender.org/rB871fda82e662d889046e37061b582758f705a2af
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.
===================================================================
M source/blender/io/usd/CMakeLists.txt
A source/blender/io/usd/import/usd_data_cache.cc
A source/blender/io/usd/import/usd_data_cache.h
M source/blender/io/usd/import/usd_importer_context.h
M source/blender/io/usd/import/usd_prim_iterator.cc
M source/blender/io/usd/import/usd_prim_iterator.h
M source/blender/io/usd/import/usd_reader_camera.cc
M source/blender/io/usd/import/usd_reader_camera.h
M source/blender/io/usd/import/usd_reader_light.cc
M source/blender/io/usd/import/usd_reader_light.h
M source/blender/io/usd/import/usd_reader_mesh_base.cc
M source/blender/io/usd/import/usd_reader_mesh_base.h
M source/blender/io/usd/import/usd_reader_xform.cc
M source/blender/io/usd/import/usd_reader_xform.h
M source/blender/io/usd/import/usd_reader_xformable.h
M source/blender/io/usd/intern/usd_capi.cc
===================================================================
diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt
index dc22045476a..6d693401b6d 100644
--- a/source/blender/io/usd/CMakeLists.txt
+++ b/source/blender/io/usd/CMakeLists.txt
@@ -54,6 +54,7 @@ set(INC_SYS
set(SRC
+ import/usd_data_cache.cc
import/usd_import_util.cc
import/usd_material_importer.cc
import/usd_prim_iterator.cc
@@ -75,6 +76,7 @@ set(SRC
intern/usd_writer_transform.cc
usd.h
+ import/usd_data_cache.h
import/usd_importer_context.h
import/usd_import_util.h
import/usd_material_importer.h
diff --git a/source/blender/io/usd/import/usd_reader_xform.h b/source/blender/io/usd/import/usd_data_cache.cc
similarity index 52%
copy from source/blender/io/usd/import/usd_reader_xform.h
copy to source/blender/io/usd/import/usd_data_cache.cc
index 4be0f2d1273..55558aba517 100644
--- a/source/blender/io/usd/import/usd_reader_xform.h
+++ b/source/blender/io/usd/import/usd_data_cache.cc
@@ -16,31 +16,42 @@
* The Original Code is Copyright (C) 2020 Blender Foundation.
* All rights reserved.
*/
-#pragma once
-#include "usd_reader_xformable.h"
+#include "usd_data_cache.h"
-#include <pxr/usd/usdGeom/xform.h>
+#include <iostream>
namespace blender::io::usd {
-/* Wraps the UsdGeomXform schema. Creates a Blender Empty object. */
-
-class USDXformReader : public USDXformableReader {
-
- pxr::UsdGeomXform xform_;
-
- public:
- USDXformReader(const pxr::UsdPrim &prim, const USDImporterContext &context);
-
- bool valid() const override;
-
- bool can_merge_with_parent() const override
- {
- return false;
+USDDataCache::USDDataCache()
+{
+}
+
+USDDataCache::~USDDataCache()
+{
+ /* TODO(makowalski): decrement use count and/or delete the cached data? */
+}
+
+bool USDDataCache::add_prototype_mesh(const pxr::SdfPath path, Mesh *mesh)
+{
+ /* TODO(makowalsk): should we increment mesh use count? */
+ return prototype_meshes_.insert(std::make_pair(path, mesh)).second;
+}
+
+void USDDataCache::clear_protype_mesh(const pxr::SdfPath &path)
+{
+ /* TODO(makowalsk): should we decrement mesh use count or delete mesh? */
+ prototype_meshes_.erase(path);
+}
+
+Mesh *USDDataCache::get_prototype_mesh(const pxr::SdfPath &path) const
+{
+ std::map<pxr::SdfPath, Mesh *>::const_iterator it = prototype_meshes_.find(path);
+ if (it != prototype_meshes_.end()) {
+ return it->second;
}
- void create_object(Main *bmain, double time) override;
-};
+ return nullptr;
+}
} // namespace blender::io::usd
diff --git a/source/blender/io/usd/import/usd_reader_xform.h b/source/blender/io/usd/import/usd_data_cache.h
similarity index 55%
copy from source/blender/io/usd/import/usd_reader_xform.h
copy to source/blender/io/usd/import/usd_data_cache.h
index 4be0f2d1273..6f3767387f6 100644
--- a/source/blender/io/usd/import/usd_reader_xform.h
+++ b/source/blender/io/usd/import/usd_data_cache.h
@@ -18,29 +18,43 @@
*/
#pragma once
-#include "usd_reader_xformable.h"
+#include <map>
-#include <pxr/usd/usdGeom/xform.h>
+#include <pxr/usd/sdf/path.h>
-namespace blender::io::usd {
+struct Mesh;
-/* Wraps the UsdGeomXform schema. Creates a Blender Empty object. */
+namespace blender::io::usd {
-class USDXformReader : public USDXformableReader {
+/* Caches data imported from USD, typically shared data for instanced primitives. */
- pxr::UsdGeomXform xform_;
+class USDDataCache {
+ protected:
+ /* Shared meshes for instancing. */
+ std::map<pxr::SdfPath, Mesh *> prototype_meshes_;
public:
- USDXformReader(const pxr::UsdPrim &prim, const USDImporterContext &context);
+ USDDataCache();
- bool valid() const override;
+ ~USDDataCache();
+
+ const std::map<pxr::SdfPath, Mesh *> &prototype_meshes() const
+ {
+ return prototype_meshes_;
+ }
- bool can_merge_with_parent() const override
+ void clear_prototype_meshes()
{
- return false;
+ /* TODO(makowalsk): should we decrement mesh use counts or delete meshes? */
+ prototype_meshes_.clear();
}
- void create_object(Main *bmain, double time) override;
+ bool add_prototype_mesh(const pxr::SdfPath path, Mesh *mesh);
+
+ void clear_protype_mesh(const pxr::SdfPath &path);
+
+ Mesh *get_prototype_mesh(const pxr::SdfPath &path) const;
+
};
} // namespace blender::io::usd
diff --git a/source/blender/io/usd/import/usd_importer_context.h b/source/blender/io/usd/import/usd_importer_context.h
index 0970fd9e789..49750a55dfc 100644
--- a/source/blender/io/usd/import/usd_importer_context.h
+++ b/source/blender/io/usd/import/usd_importer_context.h
@@ -31,7 +31,6 @@ typedef std::map<pxr::SdfPath, USDXformableReader *> ObjectReaderMap;
struct USDImporterContext {
const pxr::TfToken stage_up_axis;
const USDImportParams import_params;
- ObjectReaderMap *proto_readers;
};
} // namespace blender::io::usd
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) {
diff --git a/source/blender/io/usd/import/usd_prim_iterator.h b/source/blender/io/usd/import/usd_prim_iterator.h
index 672dbb098c6..1605d919051 100644
--- a/source/blender/io/usd/import/usd_prim_iterator.h
+++ b/source/blender/io/usd/import/usd_prim_iterator.h
@@ -18,30 +18,36 @@
*/
#pragma once
-#include "pxr/usd/usd/common.h"
+#include "usd_importer_context.h"
+
+#include <pxr/usd/usd/common.h>
#include <map>
#include <vector>
+struct Main;
+
namespace blender::io::usd {
-struct USDImporterContext;
+class USDDataCache;
class USDXformableReader;
class USDPrimIterator {
protected:
pxr::UsdStageRefPtr stage_;
+ USDImporterContext context_;
+ Main *bmain_;
public:
- USDPrimIterator(pxr::UsdStageRefPtr stage);
+ USDPrimIterator(pxr::UsdStageRefPtr stage, const USDImporterContext &context, Main *bmain);
- void create_object_readers(const USDImporterContext &context,
- std::vector<USDXformableReader *> &r_readers) const;
+ void create_object_readers(std::vector<USDXformableReader *> &r_readers) const;
void create_prototype_object_readers(
- const USDImporterContext &context,
std::map<pxr::SdfPath, USDXformableReader *> &r_proto_readers) const;
+ void cache_prototype_data(USDDataCache &r_cache) const;
+
void debug_traverse_stage() const;
static USDXformableReader *get_object_reader(const pxr::UsdPrim &prim,
diff --git a/source/blender/io/usd/import/usd_reader_camera.cc b/source/blender/io/usd/import/usd_reader_camera.cc
index 6ad2b55dcb0..418d6a4ee77 100644
--- a/source/blender/io/usd/import/usd_reader_camera.cc
+++ b/source/blender/io/usd/import/usd_reader_camera.cc
@@ -43,7 +43,7 @@ bool USDCameraReader::valid() const
return static_cast<bool>(camera_);
}
-void USDCameraReader::create_object(Main *bmain, double time)
+void USDCameraReader::create_object(Main *bmain, double time, USDDataCache *data_cache)
{
if (!this->valid()
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list