[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