[Bf-blender-cvs] [63a9f24b55d] master: Volumes: simplify volumes in modifiers or on load

Jacques Lucke noreply at git.blender.org
Tue Oct 20 11:01:12 CEST 2020


Commit: 63a9f24b55d0b5d84d625bdbb44d498fb1f2ae01
Author: Jacques Lucke
Date:   Tue Oct 20 11:00:16 2020 +0200
Branches: master
https://developer.blender.org/rB63a9f24b55d0b5d84d625bdbb44d498fb1f2ae01

Volumes: simplify volumes in modifiers or on load

This changes how the simplify volumes setting works. Before, it only
affeted viewport rendering. This was an issue, because all internal
computations would still have to happen on the high resolution volumes.
With this patch, the simplify setting already affects file loading and
procedural generation of volumes.

Rendering does not have to care about the simplify option anymore,
it just gets the correct simplified version from the depsgraph.

Reviewers: brecht

Differential Revision: https://developer.blender.org/D9176

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

M	source/blender/blenkernel/BKE_volume.h
M	source/blender/blenkernel/BKE_volume_render.h
M	source/blender/blenkernel/intern/volume.cc
M	source/blender/blenkernel/intern/volume_render.cc
M	source/blender/draw/intern/draw_cache_impl_volume.c
M	source/blender/makesdna/DNA_volume_types.h
M	source/blender/modifiers/intern/MOD_mesh_to_volume.cc
M	source/blender/modifiers/intern/MOD_volume_displace.cc

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

diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h
index 2a272d06986..12c37ec56e0 100644
--- a/source/blender/blenkernel/BKE_volume.h
+++ b/source/blender/blenkernel/BKE_volume.h
@@ -140,6 +140,10 @@ struct VolumeGrid *BKE_volume_grid_add(struct Volume *volume,
                                        VolumeGridType type);
 void BKE_volume_grid_remove(struct Volume *volume, struct VolumeGrid *grid);
 
+/* Simplify */
+int BKE_volume_simplify_level(const struct Depsgraph *depsgraph);
+float BKE_volume_simplify_factor(const struct Depsgraph *depsgraph);
+
 /* File Save */
 bool BKE_volume_save(struct Volume *volume,
                      struct Main *bmain,
@@ -166,16 +170,7 @@ openvdb::GridBase::Ptr BKE_volume_grid_openvdb_for_write(const struct Volume *vo
                                                          struct VolumeGrid *grid,
                                                          const bool clear);
 
-template<typename GridType>
-typename GridType::Ptr BKE_volume_grid_openvdb_for_write(const struct Volume *volume,
-                                                         struct VolumeGrid *grid,
-                                                         const bool clear)
-{
-  openvdb::GridBase::Ptr openvdb_grid = BKE_volume_grid_openvdb_for_write(volume, grid, clear);
-  BLI_assert(openvdb_grid->isType<GridType>());
-  typename GridType::Ptr typed_openvdb_grid = openvdb::gridPtrCast<GridType>(openvdb_grid);
-  return typed_openvdb_grid;
-}
+VolumeGridType BKE_volume_grid_type_openvdb(const openvdb::GridBase::Ptr &grid);
 
 template<typename OpType>
 auto BKE_volume_grid_type_operation(const VolumeGridType grid_type, OpType &&op)
@@ -212,4 +207,9 @@ auto BKE_volume_grid_type_operation(const VolumeGridType grid_type, OpType &&op)
   return op.template operator()<openvdb::FloatGrid>();
 }
 
+openvdb::GridBase::Ptr BKE_volume_grid_create_with_changed_resolution(
+    const VolumeGridType grid_type,
+    const openvdb::GridBase &old_grid,
+    const float resolution_factor);
+
 #endif
diff --git a/source/blender/blenkernel/BKE_volume_render.h b/source/blender/blenkernel/BKE_volume_render.h
index 815374105f5..d7553ccb10b 100644
--- a/source/blender/blenkernel/BKE_volume_render.h
+++ b/source/blender/blenkernel/BKE_volume_render.h
@@ -44,7 +44,6 @@ typedef struct DenseFloatVolumeGrid {
 
 bool BKE_volume_grid_dense_floats(const struct Volume *volume,
                                   struct VolumeGrid *volume_grid,
-                                  const float resolution_factor,
                                   DenseFloatVolumeGrid *r_dense_grid);
 void BKE_volume_dense_float_grid_clear(DenseFloatVolumeGrid *dense_grid);
 
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 32f6a94aa7f..64d053c0e30 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -29,6 +29,7 @@
 #include "BLI_compiler_compat.h"
 #include "BLI_fileops.h"
 #include "BLI_ghash.h"
+#include "BLI_map.hh"
 #include "BLI_math.h"
 #include "BLI_path_util.h"
 #include "BLI_string.h"
@@ -70,6 +71,7 @@ static CLG_LogRef LOG = {"bke.volume"};
 
 #  include <openvdb/openvdb.h>
 #  include <openvdb/points/PointDataGrid.h>
+#  include <openvdb/tools/GridTransformer.h>
 
 /* Global Volume File Cache
  *
@@ -115,12 +117,32 @@ static struct VolumeFileCache {
     {
     }
 
+    /* Returns the original grid or a simplified version depending on the given #simplify_level. */
+    openvdb::GridBase::Ptr simplified_grid(const int simplify_level)
+    {
+      BLI_assert(simplify_level >= 0);
+      if (simplify_level == 0 || !is_loaded) {
+        return grid;
+      }
+
+      std::lock_guard<std::mutex> lock(mutex);
+      return simplified_grids.lookup_or_add_cb(simplify_level, [&]() {
+        const float resolution_factor = 1.0f / (1 << simplify_level);
+        const VolumeGridType grid_type = BKE_volume_grid_type_openvdb(grid);
+        return BKE_volume_grid_create_with_changed_resolution(grid_type, *grid, resolution_factor);
+      });
+    }
+
     /* Unique key: filename + grid name. */
     std::string filepath;
     std::string grid_name;
 
     /* OpenVDB grid. */
     openvdb::GridBase::Ptr grid;
+
+    /* Simplified versions of #grid. The integer key is the simplification level. */
+    blender::Map<int, openvdb::GridBase::Ptr> simplified_grids;
+
     /* Has the grid tree been loaded? */
     bool is_loaded;
     /* Error message if an error occured during loading. */
@@ -224,6 +246,7 @@ static struct VolumeFileCache {
       /* 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.simplified_grids.clear();
       entry.is_loaded = false;
     }
   }
@@ -241,7 +264,8 @@ static struct VolumeFileCache {
  * stored in the global cache. Procedurally generated grids are not. */
 
 struct VolumeGrid {
-  VolumeGrid(const VolumeFileCache::Entry &template_entry) : entry(NULL), is_loaded(false)
+  VolumeGrid(const VolumeFileCache::Entry &template_entry, const int simplify_level)
+      : entry(NULL), simplify_level(simplify_level), is_loaded(false)
   {
     entry = GLOBAL_CACHE.add_metadata_user(template_entry);
   }
@@ -251,7 +275,10 @@ struct VolumeGrid {
   }
 
   VolumeGrid(const VolumeGrid &other)
-      : entry(other.entry), local_grid(other.local_grid), is_loaded(other.is_loaded)
+      : entry(other.entry),
+        simplify_level(other.simplify_level),
+        local_grid(other.local_grid),
+        is_loaded(other.is_loaded)
   {
     if (entry) {
       GLOBAL_CACHE.copy_user(*entry, is_loaded);
@@ -360,8 +387,8 @@ 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 = grid()->getMetadata<openvdb::StringMetadata>(
-        openvdb::GridBase::META_GRID_NAME);
+    openvdb::StringMetadata::ConstPtr name_meta =
+        main_grid()->getMetadata<openvdb::StringMetadata>(openvdb::GridBase::META_GRID_NAME);
     return (name_meta) ? name_meta->value().c_str() : "";
   }
 
@@ -379,7 +406,22 @@ struct VolumeGrid {
     return is_loaded;
   }
 
-  const openvdb::GridBase::Ptr &grid() const
+  openvdb::GridBase::Ptr grid() const
+  {
+    if (entry) {
+      return entry->simplified_grid(simplify_level);
+    }
+    return local_grid;
+  }
+
+  void set_simplify_level(const int simplify_level)
+  {
+    BLI_assert(simplify_level >= 0);
+    this->simplify_level = simplify_level;
+  }
+
+ private:
+  const openvdb::GridBase::Ptr &main_grid() const
   {
     return (entry) ? entry->grid : local_grid;
   }
@@ -388,6 +430,9 @@ struct VolumeGrid {
   /* File cache entry when grid comes directly from a file and may be shared
    * with other volume datablocks. */
   VolumeFileCache::Entry *entry;
+  /* If this volume grid is in the global file cache, we can reference a simplified version of it,
+   * instead of the original high resolution grid. */
+  int simplify_level = 0;
   /* 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()
@@ -761,7 +806,7 @@ bool BKE_volume_load(Volume *volume, Main *bmain)
   for (const openvdb::GridBase::Ptr &vdb_grid : vdb_grids) {
     if (vdb_grid) {
       VolumeFileCache::Entry template_entry(grids.filepath, vdb_grid);
-      grids.emplace_back(template_entry);
+      grids.emplace_back(template_entry, volume->runtime.default_simplify_level);
     }
   }
 
@@ -906,6 +951,17 @@ bool BKE_volume_is_points_only(const Volume *volume)
 
 /* Dependency Graph */
 
+static void volume_update_simplify_level(Volume *volume, const Depsgraph *depsgraph)
+{
+  const int simplify_level = BKE_volume_simplify_level(depsgraph);
+  if (volume->runtime.grids) {
+    for (VolumeGrid &grid : *volume->runtime.grids) {
+      grid.set_simplify_level(simplify_level);
+    }
+  }
+  volume->runtime.default_simplify_level = simplify_level;
+}
+
 static Volume *volume_evaluate_modifiers(struct Depsgraph *depsgraph,
                                          struct Scene *scene,
                                          Object *object,
@@ -956,6 +1012,8 @@ static Volume *volume_evaluate_modifiers(struct Depsgraph *depsgraph,
 
 void BKE_volume_eval_geometry(struct Depsgraph *depsgraph, Volume *volume)
 {
+  volume_update_simplify_level(volume, depsgraph);
+
   /* TODO: can we avoid modifier re-evaluation when frame did not change? */
   int frame = volume_sequence_frame(depsgraph, volume);
   if (frame != volume->runtime.frame) {
@@ -1157,11 +1215,9 @@ const char *BKE_volume_grid_name(const VolumeGrid *volume_grid)
 #endif
 }
 
-VolumeGridType BKE_volume_grid_type(const VolumeGrid *volume_grid)
-{
 #ifdef WITH_OPENVDB
-  const openvdb::GridBase::Ptr &grid = volume_grid->grid();
-
+VolumeGridType BKE_volume_grid_type_openvdb(const openvdb::GridBase::Ptr &grid)
+{
   if (grid->isType<openvdb::FloatGrid>()) {
     return VOLUME_GRID_FLOAT;
   }
@@ -1195,10 +1251,16 @@ VolumeGridType BKE_volume_grid_type(const VolumeGrid *volume_grid)
   if (grid->isType<openvdb::points::PointDataGrid>()) {
     return VOLUME_GRID_POINTS;
   }
-#else
-  UNUSED_VARS(volume_grid);
+  return VOLUME_GRID_UNKNOWN;
+}
 #endif
 
+VolumeGridType BKE_volume_grid_type(const VolumeGrid *volume_grid)
+{
+#ifdef WITH_OPENVDB
+  const openvdb::GridBase::Ptr grid = volume_grid->grid();
+  return BKE_volume_grid_type_openvdb(grid);
+#endif
   return VOLUME_GRID_UNKNOWN;
 }
 
@@ -1229,7 +1291,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->grid();
+  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
@@ -1253,7 +13

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list