[Bf-blender-cvs] [a4f8b2ad765] master: Volumes: more generic way to handle different openvdb types

Jacques Lucke noreply at git.blender.org
Mon Oct 5 10:31:53 CEST 2020


Commit: a4f8b2ad7653cac8a5f7821ce7ee9af44b13a758
Author: Jacques Lucke
Date:   Mon Oct 5 10:29:34 2020 +0200
Branches: master
https://developer.blender.org/rBa4f8b2ad7653cac8a5f7821ce7ee9af44b13a758

Volumes: more generic way to handle different openvdb types

Reviewers: brecht

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

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

M	source/blender/blenkernel/BKE_volume.h
M	source/blender/blenkernel/intern/volume.cc
M	source/blender/blenkernel/intern/volume_render.cc

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

diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h
index 4481c1b4332..8e192aa7741 100644
--- a/source/blender/blenkernel/BKE_volume.h
+++ b/source/blender/blenkernel/BKE_volume.h
@@ -151,6 +151,8 @@ void BKE_volume_grid_remove(struct Volume *volume, struct VolumeGrid *grid);
 
 #if defined(__cplusplus) && defined(WITH_OPENVDB)
 #  include <openvdb/openvdb.h>
+#  include <openvdb/points/PointDataGrid.h>
+
 openvdb::GridBase::ConstPtr BKE_volume_grid_openvdb_for_metadata(const struct VolumeGrid *grid);
 openvdb::GridBase::ConstPtr BKE_volume_grid_openvdb_for_read(const struct Volume *volume,
                                                              struct VolumeGrid *grid);
@@ -169,4 +171,39 @@ typename GridType::Ptr BKE_volume_grid_openvdb_for_write(const struct Volume *vo
   return typed_openvdb_grid;
 }
 
+template<typename OpType>
+auto BKE_volume_grid_type_operation(const VolumeGridType grid_type, OpType &&op)
+{
+  switch (grid_type) {
+    case VOLUME_GRID_FLOAT:
+      return op.template operator()<openvdb::FloatGrid>();
+    case VOLUME_GRID_VECTOR_FLOAT:
+      return op.template operator()<openvdb::Vec3fGrid>();
+    case VOLUME_GRID_BOOLEAN:
+      return op.template operator()<openvdb::BoolGrid>();
+    case VOLUME_GRID_DOUBLE:
+      return op.template operator()<openvdb::DoubleGrid>();
+    case VOLUME_GRID_INT:
+      return op.template operator()<openvdb::Int32Grid>();
+    case VOLUME_GRID_INT64:
+      return op.template operator()<openvdb::Int64Grid>();
+    case VOLUME_GRID_VECTOR_INT:
+      return op.template operator()<openvdb::Vec3IGrid>();
+    case VOLUME_GRID_VECTOR_DOUBLE:
+      return op.template operator()<openvdb::Vec3dGrid>();
+    case VOLUME_GRID_STRING:
+      return op.template operator()<openvdb::StringGrid>();
+    case VOLUME_GRID_MASK:
+      return op.template operator()<openvdb::MaskGrid>();
+    case VOLUME_GRID_POINTS:
+      return op.template operator()<openvdb::points::PointDataGrid>();
+    case VOLUME_GRID_UNKNOWN:
+      break;
+  }
+
+  /* Should never be called. */
+  BLI_assert(!"should never be reached");
+  return op.template operator()<openvdb::FloatGrid>();
+}
+
 #endif
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 79ed3d3d08d..6090c0fec20 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -1291,47 +1291,28 @@ Volume *BKE_volume_copy_for_eval(Volume *volume_src, bool reference)
   return result;
 }
 
+struct CreateGridOp {
+  template<typename GridType> typename openvdb::GridBase::Ptr operator()()
+  {
+    if constexpr (std::is_same_v<GridType, openvdb::points::PointDataGrid>) {
+      return {};
+    }
+    else {
+      return GridType::create();
+    }
+  }
+};
+
 VolumeGrid *BKE_volume_grid_add(Volume *volume, const char *name, VolumeGridType type)
 {
 #ifdef WITH_OPENVDB
   VolumeGridVector &grids = *volume->runtime.grids;
   BLI_assert(BKE_volume_grid_find(volume, name) == NULL);
+  BLI_assert(type != VOLUME_GRID_UNKNOWN);
 
-  openvdb::GridBase::Ptr vdb_grid;
-  switch (type) {
-    case VOLUME_GRID_FLOAT:
-      vdb_grid = openvdb::FloatGrid::create();
-      break;
-    case VOLUME_GRID_VECTOR_FLOAT:
-      vdb_grid = openvdb::Vec3fGrid::create();
-      break;
-    case VOLUME_GRID_BOOLEAN:
-      vdb_grid = openvdb::BoolGrid::create();
-      break;
-    case VOLUME_GRID_DOUBLE:
-      vdb_grid = openvdb::DoubleGrid::create();
-      break;
-    case VOLUME_GRID_INT:
-      vdb_grid = openvdb::Int32Grid::create();
-      break;
-    case VOLUME_GRID_INT64:
-      vdb_grid = openvdb::Int64Grid::create();
-      break;
-    case VOLUME_GRID_VECTOR_INT:
-      vdb_grid = openvdb::Vec3IGrid::create();
-      break;
-    case VOLUME_GRID_VECTOR_DOUBLE:
-      vdb_grid = openvdb::Vec3dGrid::create();
-      break;
-    case VOLUME_GRID_STRING:
-      vdb_grid = openvdb::StringGrid::create();
-      break;
-    case VOLUME_GRID_MASK:
-      vdb_grid = openvdb::MaskGrid::create();
-      break;
-    case VOLUME_GRID_POINTS:
-    case VOLUME_GRID_UNKNOWN:
-      return NULL;
+  openvdb::GridBase::Ptr vdb_grid = BKE_volume_grid_type_operation(type, CreateGridOp{});
+  if (!vdb_grid) {
+    return NULL;
   }
 
   vdb_grid->setName(name);
diff --git a/source/blender/blenkernel/intern/volume_render.cc b/source/blender/blenkernel/intern/volume_render.cc
index fb5d16e3288..8e8cfb5945a 100644
--- a/source/blender/blenkernel/intern/volume_render.cc
+++ b/source/blender/blenkernel/intern/volume_render.cc
@@ -46,55 +46,45 @@
  * resolution_factor is 1/2, the resolution on each axis is halved. The transform of the returned
  * grid is adjusted to match the original grid. */
 template<typename GridType>
-static typename GridType::Ptr create_grid_with_changed_resolution(
-    const openvdb::GridBase &old_grid, const float resolution_factor)
+static typename GridType::Ptr create_grid_with_changed_resolution(const GridType &old_grid,
+                                                                  const float resolution_factor)
 {
   BLI_assert(resolution_factor > 0.0f);
-  BLI_assert(old_grid.isType<GridType>());
 
   openvdb::Mat4R xform;
   xform.setToScale(openvdb::Vec3d(resolution_factor));
   openvdb::tools::GridTransformer transformer{xform};
 
   typename GridType::Ptr new_grid = GridType::create();
-  transformer.transformGrid<openvdb::tools::BoxSampler>(static_cast<const GridType &>(old_grid),
-                                                        *new_grid);
+  transformer.transformGrid<openvdb::tools::BoxSampler>(old_grid, *new_grid);
   new_grid->transform() = old_grid.transform();
   new_grid->transform().preScale(1.0f / resolution_factor);
   return new_grid;
 }
 
+struct CreateGridWithChangedResolutionOp {
+  const openvdb::GridBase &grid;
+  const float resolution_factor;
+
+  template<typename GridType> typename openvdb::GridBase::Ptr operator()()
+  {
+    if constexpr (std::is_same_v<GridType, openvdb::StringGrid>) {
+      return {};
+    }
+    else {
+      return create_grid_with_changed_resolution(static_cast<const GridType &>(grid),
+                                                 resolution_factor);
+    }
+  }
+};
+
 static openvdb::GridBase::Ptr create_grid_with_changed_resolution(
     const VolumeGridType grid_type,
     const openvdb::GridBase &old_grid,
     const float resolution_factor)
 {
-  switch (grid_type) {
-    case VOLUME_GRID_BOOLEAN:
-      return create_grid_with_changed_resolution<openvdb::BoolGrid>(old_grid, resolution_factor);
-    case VOLUME_GRID_FLOAT:
-      return create_grid_with_changed_resolution<openvdb::FloatGrid>(old_grid, resolution_factor);
-    case VOLUME_GRID_DOUBLE:
-      return create_grid_with_changed_resolution<openvdb::DoubleGrid>(old_grid, resolution_factor);
-    case VOLUME_GRID_INT:
-      return create_grid_with_changed_resolution<openvdb::Int32Grid>(old_grid, resolution_factor);
-    case VOLUME_GRID_INT64:
-      return create_grid_with_changed_resolution<openvdb::Int64Grid>(old_grid, resolution_factor);
-    case VOLUME_GRID_MASK:
-      return create_grid_with_changed_resolution<openvdb::MaskGrid>(old_grid, resolution_factor);
-    case VOLUME_GRID_VECTOR_FLOAT:
-      return create_grid_with_changed_resolution<openvdb::Vec3fGrid>(old_grid, resolution_factor);
-    case VOLUME_GRID_VECTOR_DOUBLE:
-      return create_grid_with_changed_resolution<openvdb::Vec3dGrid>(old_grid, resolution_factor);
-    case VOLUME_GRID_VECTOR_INT:
-      return create_grid_with_changed_resolution<openvdb::Vec3IGrid>(old_grid, resolution_factor);
-    case VOLUME_GRID_STRING:
-    case VOLUME_GRID_POINTS:
-    case VOLUME_GRID_UNKNOWN:
-      /* Can't do this. */
-      break;
-  }
-  return {};
+  CreateGridWithChangedResolutionOp op{old_grid, resolution_factor};
+  return BKE_volume_grid_type_operation(grid_type, op);
 }
 
 template<typename GridType, typename VoxelType>
@@ -216,19 +206,17 @@ void BKE_volume_dense_float_grid_clear(DenseFloatVolumeGrid *dense_grid)
 
 /** Returns bounding boxes that approximate the shape of the volume stored in the grid. */
 template<typename GridType>
-static blender::Vector<openvdb::CoordBBox> get_bounding_boxes(openvdb::GridBase::ConstPtr gridbase,
+static blender::Vector<openvdb::CoordBBox> get_bounding_boxes(const GridType &grid,
                                                               const bool coarse)
 {
   using TreeType = typename GridType::TreeType;
   using Depth2Type = typename TreeType::RootNodeType::ChildNodeType::ChildNodeType;
   using NodeCIter = typename TreeType::NodeCIter;
-  using GridConstPtr = typename GridType::ConstPtr;
 
-  GridConstPtr grid = openvdb::gridConstPtrCast<GridType>(gridbase);
   blender::Vector<openvdb::CoordBBox> boxes;
   const int depth = coarse ? 2 : 3;
 
-  NodeCIter iter = grid->tree().cbeginNode();
+  NodeCIter iter = grid.tree().cbeginNode();
   iter.setMaxDepth(depth);
 
   for (; iter; ++iter) {
@@ -264,57 +252,22 @@ static blender::Vector<openvdb::CoordBBox> get_bounding_boxes(openvdb::GridBase:
   return boxes;
 }
 
+struct GetBoundingBoxesOp {
+  const openvdb::GridBase &grid;
+  const bool coarse;
+
+  template<typename GridType> blender::Vector<openvdb::CoordBBox> operator()()
+  {
+    return get_bounding_boxes(static_cast<const GridType &>(grid), coarse);
+  }
+};
+
 static blender::Vector<openvdb::CoordBBox> get_bounding_boxes(VolumeGridType grid_type,
-                                                              openvdb::GridBase::ConstPtr grid,
+                                                              const openvdb::GridBase &grid,
                                                               const bool coarse)
 {
-  switch (grid_type) {
-    case VOLUME_GRID_BOOLEAN: {
-      return get_bounding_boxes<openvdb::BoolGrid>(grid, coarse);
-      break;
-    }
-    case VOLUME_GRID_FLOAT: {
-      return get_bounding_boxes<openvdb::FloatGrid>(grid, coarse);
-      break;
-    }
-    case VOLUME_GRID_DOUBLE: {
-      return get_bounding_boxes<openvdb::DoubleGrid>(grid, coarse);
-      break;
-    }
-    case VOLUME_GRID_INT: {
-      return get_bounding_boxes<openvdb::Int32G

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list