[Bf-blender-cvs] [5e6119ddca1] blender-v2.90-release: Cycles: load OpenVDB file earlier in Blender export

Brecht Van Lommel noreply at git.blender.org
Thu Aug 6 16:31:20 CEST 2020


Commit: 5e6119ddca1fc637a6658cd58e9c04f40f155314
Author: Brecht Van Lommel
Date:   Thu Aug 6 13:55:50 2020 +0200
Branches: blender-v2.90-release
https://developer.blender.org/rB5e6119ddca1fc637a6658cd58e9c04f40f155314

Cycles: load OpenVDB file earlier in Blender export

In an upcoming bugfix we'll use OpenVDB data structures directly to build mesh
for sparse OpenVDB volumes, loading them OpenVDB grids earlier and removing any
references to Blender data structures makes that easier.

This also makes changes to Blender volumes to support this, so Cycles can take
ownership of a grid without Blender having to keep its own reference to it.
This should also be useful in a future Python API.

Ref D8401

===================================================================

M	intern/cycles/blender/blender_volume.cpp
M	intern/cycles/render/image.cpp
M	intern/cycles/render/image.h
M	source/blender/blenkernel/intern/volume.cc

===================================================================

diff --git a/intern/cycles/blender/blender_volume.cpp b/intern/cycles/blender/blender_volume.cpp
index 80591e0eec8..d0e1e4d6131 100644
--- a/intern/cycles/blender/blender_volume.cpp
+++ b/intern/cycles/blender/blender_volume.cpp
@@ -217,43 +217,29 @@ static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Mesh *mesh, float
 class BlenderVolumeLoader : public VDBImageLoader {
  public:
   BlenderVolumeLoader(BL::BlendData &b_data, BL::Volume &b_volume, const string &grid_name)
-      : VDBImageLoader(grid_name), b_data(b_data), b_volume(b_volume), unload(false)
-  {
-  }
-
-  bool load_metadata(ImageMetaData &metadata) override
+      : VDBImageLoader(grid_name), b_volume(b_volume)
   {
     b_volume.grids.load(b_data.ptr.data);
-    BL::VolumeGrid b_volume_grid = find_grid();
-
-    if (!b_volume_grid) {
-      return false;
-    }
-
-    unload = !b_volume_grid.is_loaded();
 
 #ifdef WITH_OPENVDB
-    Volume *volume = (Volume *)b_volume.ptr.data;
-    VolumeGrid *volume_grid = (VolumeGrid *)b_volume_grid.ptr.data;
-    grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
-#endif
+    BL::Volume::grids_iterator b_grid_iter;
+    for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) {
+      BL::VolumeGrid b_volume_grid(*b_grid_iter);
+      if (b_volume_grid.name() == grid_name) {
+        const bool unload = !b_volume_grid.is_loaded();
 
-    return VDBImageLoader::load_metadata(metadata);
-  }
+        Volume *volume = (Volume *)b_volume.ptr.data;
+        VolumeGrid *volume_grid = (VolumeGrid *)b_volume_grid.ptr.data;
+        grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
 
-  bool load_pixels(const ImageMetaData &metadata,
-                   void *pixels,
-                   const size_t pixel_size,
-                   const bool associate_alpha) override
-  {
-    b_volume.grids.load(b_data.ptr.data);
-    BL::VolumeGrid b_volume_grid = find_grid();
+        if (unload) {
+          b_volume_grid.unload();
+        }
 
-    if (!b_volume_grid) {
-      return false;
+        break;
+      }
     }
-
-    return VDBImageLoader::load_pixels(metadata, pixels, pixel_size, associate_alpha);
+#endif
   }
 
   bool equals(const ImageLoader &other) const override
@@ -263,36 +249,7 @@ class BlenderVolumeLoader : public VDBImageLoader {
     return b_volume == other_loader.b_volume && grid_name == other_loader.grid_name;
   }
 
-  void cleanup() override
-  {
-    VDBImageLoader::cleanup();
-
-    BL::VolumeGrid b_volume_grid = find_grid();
-    if (b_volume_grid && unload) {
-      b_volume_grid.unload();
-    }
-  }
-
-  /* Find grid with matching name. Grid point not stored in the class since
-   * grids may be unloaded before we load the pixels, for example for motion
-   * blur where we move between frames. */
-  BL::VolumeGrid find_grid()
-  {
-#ifdef WITH_OPENVDB
-    BL::Volume::grids_iterator b_grid_iter;
-    for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) {
-      if (b_grid_iter->name() == grid_name) {
-        return *b_grid_iter;
-      }
-    }
-#endif
-
-    return BL::VolumeGrid(PointerRNA_NULL);
-  }
-
-  BL::BlendData b_data;
   BL::Volume b_volume;
-  bool unload;
 };
 
 static void sync_volume_object(BL::BlendData &b_data, BL::Object &b_ob, Scene *scene, Mesh *mesh)
@@ -342,7 +299,7 @@ static void sync_volume_object(BL::BlendData &b_data, BL::Object &b_ob, Scene *s
       ImageParams params;
       params.frame = b_volume.grids.frame();
 
-      attr->data_voxel() = scene->image_manager->add_image(loader, params);
+      attr->data_voxel() = scene->image_manager->add_image(loader, params, false);
     }
   }
 }
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 8d187814d64..691eb162dd0 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -362,9 +362,11 @@ ImageHandle ImageManager::add_image(const string &filename,
   return handle;
 }
 
-ImageHandle ImageManager::add_image(ImageLoader *loader, const ImageParams &params)
+ImageHandle ImageManager::add_image(ImageLoader *loader,
+                                    const ImageParams &params,
+                                    const bool builtin)
 {
-  const int slot = add_image_slot(loader, params, true);
+  const int slot = add_image_slot(loader, params, builtin);
 
   ImageHandle handle;
   handle.tile_slots.push_back(slot);
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index fffe7c5152a..47be0ee559a 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -169,7 +169,7 @@ class ImageManager {
   ImageHandle add_image(const string &filename,
                         const ImageParams &params,
                         const vector<int> &tiles);
-  ImageHandle add_image(ImageLoader *loader, const ImageParams &params);
+  ImageHandle add_image(ImageLoader *loader, const ImageParams &params, const bool builtin = true);
 
   void device_update(Device *device, Scene *scene, Progress &progress);
   void device_update_slot(Device *device, Scene *scene, int slot, Progress *progress);
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 48b920c8a05..633ad250a67 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -218,7 +218,9 @@ static struct VolumeFileCache {
       cache.erase(entry);
     }
     else if (entry.num_tree_users == 0) {
-      entry.grid->clear();
+      /* Note we replace the grid rather than clearing, so that if there is
+       * any other shared pointer to the grid it will keep the tree. */
+      entry.grid = entry.grid->copyGridWithNewTree();
       entry.is_loaded = false;
     }
   }
@@ -239,15 +241,14 @@ struct VolumeGrid {
   VolumeGrid(const VolumeFileCache::Entry &template_entry) : entry(NULL), is_loaded(false)
   {
     entry = GLOBAL_CACHE.add_metadata_user(template_entry);
-    vdb = entry->grid;
   }
 
-  VolumeGrid(const openvdb::GridBase::Ptr &vdb) : vdb(vdb), entry(NULL), is_loaded(true)
+  VolumeGrid(const openvdb::GridBase::Ptr &grid) : entry(NULL), local_grid(grid), is_loaded(true)
   {
   }
 
   VolumeGrid(const VolumeGrid &other)
-      : vdb(other.vdb), entry(other.entry), is_loaded(other.is_loaded)
+      : entry(other.entry), local_grid(other.local_grid), is_loaded(other.is_loaded)
   {
     if (entry) {
       GLOBAL_CACHE.copy_user(*entry, is_loaded);
@@ -330,7 +331,7 @@ struct VolumeGrid {
   void clear_reference(const char *UNUSED(volume_name))
   {
     /* Clear any reference to a grid in the file cache. */
-    vdb = vdb->copyGridWithNewTree();
+    local_grid = grid()->copyGridWithNewTree();
     if (entry) {
       GLOBAL_CACHE.remove_user(*entry, is_loaded);
       entry = NULL;
@@ -344,7 +345,7 @@ struct VolumeGrid {
      * file cache. Load file grid into memory first if needed. */
     load(volume_name, filepath);
     /* TODO: avoid deep copy if we are the only user. */
-    vdb = vdb->deepCopyGrid();
+    local_grid = grid()->deepCopyGrid();
     if (entry) {
       GLOBAL_CACHE.remove_user(*entry, is_loaded);
       entry = NULL;
@@ -356,7 +357,7 @@ struct VolumeGrid {
   {
     /* Don't use vdb.getName() since it copies the string, we want a pointer to the
      * original so it doesn't get freed out of scope. */
-    openvdb::StringMetadata::ConstPtr name_meta = vdb->getMetadata<openvdb::StringMetadata>(
+    openvdb::StringMetadata::ConstPtr name_meta = grid()->getMetadata<openvdb::StringMetadata>(
         openvdb::GridBase::META_GRID_NAME);
     return (name_meta) ? name_meta->value().c_str() : "";
   }
@@ -371,10 +372,22 @@ struct VolumeGrid {
     }
   }
 
-  /* OpenVDB grid. */
-  openvdb::GridBase::Ptr vdb;
-  /* File cache entry. */
+  const bool grid_is_loaded() const
+  {
+    return is_loaded;
+  }
+
+  const openvdb::GridBase::Ptr &grid() const
+  {
+    return (entry) ? entry->grid : local_grid;
+  }
+
+ protected:
+  /* File cache entry when grid comes directly from a file and may be shared
+   * with other volume datablocks. */
   VolumeFileCache::Entry *entry;
+  /* OpenVDB grid if it's not shared through the file cache. */
+  openvdb::GridBase::Ptr local_grid;
   /* Indicates if the tree has been loaded for this grid. Note that vdb.tree()
    * may actually be loaded by another user while this is false. But only after
    * calling load() and is_loaded changes to true is it safe to access. */
@@ -1047,7 +1060,7 @@ void BKE_volume_grid_unload(const Volume *volume, VolumeGrid *grid)
 bool BKE_volume_grid_is_loaded(const VolumeGrid *grid)
 {
 #ifdef WITH_OPENVDB
-  return grid->is_loaded;
+  return grid->grid_is_loaded();
 #else
   UNUSED_VARS(grid);
   return true;
@@ -1069,7 +1082,7 @@ const char *BKE_volume_grid_name(const VolumeGrid *volume_grid)
 VolumeGridType BKE_volume_grid_type(const VolumeGrid *volume_grid)
 {
 #ifdef WITH_OPENVDB
-  const openvdb::GridBase::Ptr &grid = volume_grid->vdb;
+  const openvdb::GridBase::Ptr &grid = volume_grid->grid();
 
   if (grid->isType<openvdb::FloatGrid>()) {
     return VOLUME_GRID_FLOAT;
@@ -1138,7 +1151,7 @@ int BKE_volume_grid_channels(const VolumeGrid *grid)
 void BKE_volume_grid_transform_matrix(const VolumeGrid *volume_grid, float mat[4][4])
 {
 #ifdef WITH_OPENVDB
-  const openvdb::GridBase::Ptr &grid = volume_grid->vdb;
+  const openvdb::GridBase::Ptr &grid = volume_grid->grid();
   const openvdb::math::Transform &transform = grid->transform();
 
   /* Perspective not supported for now, getAffineMap() will leave out the
@@ -1162,7 +1175,7 @@ bool BKE_volume_grid_bounds(const VolumeGrid *volume_grid, float min[3], float m
 {
 #ifdef WITH_OPENVDB
   /* TODO: we can get this from grid metadata in some cases? */
-  const openvdb::GridBase::Ptr &grid = volume_grid->vdb;
+  const openvdb::GridBase::Ptr &grid = volume_grid->grid();
   BLI_assert(BKE_volume_grid_is_loaded(volume_grid));
 
   openvdb::CoordBBox coordbbox;
@@ -1287,14 +1300,14 @@ void BKE_volume_grid_remove(Volume *volume, VolumeGrid *grid)
 #ifdef WITH_OPENVDB
 openvdb::GridBase::ConstPtr BKE_volume_grid_openvdb_for_metadata(const VolumeGrid *grid)
 {
-  return grid->vdb;


@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list