[Bf-blender-cvs] [89505acb2f5] new-object-types: Volumes: more elegant C <-> C++ integration for grids, without casting

Brecht Van Lommel noreply at git.blender.org
Thu Jan 23 22:38:07 CET 2020


Commit: 89505acb2f5ca08ef296df5106aee1c494895efd
Author: Brecht Van Lommel
Date:   Thu Jan 23 22:14:06 2020 +0100
Branches: new-object-types
https://developer.blender.org/rB89505acb2f5ca08ef296df5106aee1c494895efd

Volumes: more elegant C <-> C++ integration for grids, without casting

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

M	source/blender/blenkernel/BKE_volume.h
M	source/blender/blenkernel/intern/volume.cc
M	source/blender/blenloader/intern/readfile.c
M	source/blender/makesdna/DNA_volume_types.h

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

diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h
index 04040a17783..f984463672e 100644
--- a/source/blender/blenkernel/BKE_volume.h
+++ b/source/blender/blenkernel/BKE_volume.h
@@ -93,6 +93,10 @@ VolumeGrid *BKE_volume_grid_for_write(struct Volume *volume, int grid_index);
 
 const char *BKE_volume_grid_name(const struct VolumeGrid *grid);
 
+/* Grid Voxels */
+
+bool BKE_volume_grid_bounds(const struct VolumeGrid *grid, float min[3], float max[3]);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 7c738f41779..89a9419f343 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -45,11 +45,13 @@
 #ifdef WITH_OPENVDB
 #  include <openvdb/openvdb.h>
 
-#endif
+struct VolumeGrid {
+  openvdb::GridBase::Ptr vdb;
+};
 
-/* For casting from C to OpenVDB data structures. */
-#define OPENVDB_GRIDS_CAST(vdb_grids) (*(openvdb::GridPtrVec *)(vdb_grids))
-#define OPENVDB_GRID_CAST(grid) (*(openvdb::GridBase *)(grid))
+struct VolumeGridVector : public std::vector<VolumeGrid> {
+};
+#endif
 
 /* Volume datablock */
 
@@ -66,8 +68,8 @@ void BKE_volume_init(Volume *volume)
 void BKE_volume_init_grids(Volume *volume)
 {
 #ifdef WITH_OPENVDB
-  if (volume->vdb_grids == NULL) {
-    volume->vdb_grids = OBJECT_GUARDED_NEW(openvdb::GridPtrVec);
+  if (volume->grids == NULL) {
+    volume->grids = OBJECT_GUARDED_NEW(VolumeGridVector);
   }
 #else
   UNUSED_VARS(volume);
@@ -94,9 +96,9 @@ void BKE_volume_copy_data(Main *UNUSED(bmain),
 
   volume_dst->mat = (Material **)MEM_dupallocN(volume_src->mat);
 #ifdef WITH_OPENVDB
-  if (volume_src->vdb_grids) {
-    const openvdb::GridPtrVec &grids_src = OPENVDB_GRIDS_CAST(volume_src->vdb_grids);
-    volume_dst->vdb_grids = OBJECT_GUARDED_NEW(openvdb::GridPtrVec, grids_src);
+  if (volume_src->grids) {
+    const VolumeGridVector &grids_src = *(volume_src->grids);
+    volume_dst->grids = OBJECT_GUARDED_NEW(VolumeGridVector, grids_src);
   }
 #endif
 }
@@ -119,15 +121,14 @@ void BKE_volume_free(Volume *volume)
   BKE_volume_batch_cache_free(volume);
   MEM_SAFE_FREE(volume->mat);
 #ifdef WITH_OPENVDB
-  OBJECT_GUARDED_SAFE_DELETE(volume->vdb_grids, openvdb::GridPtrVec);
+  OBJECT_GUARDED_SAFE_DELETE(volume->grids, VolumeGridVector);
 #endif
 }
 
 void BKE_volume_reload(Main *bmain, Volume *volume)
 {
 #ifdef WITH_OPENVDB
-  openvdb::GridPtrVec &grids = OPENVDB_GRIDS_CAST(volume->vdb_grids);
-  grids.clear();
+  volume->grids->clear();
 
   /* Get absolute file path. */
   char filepath[FILE_MAX];
@@ -139,17 +140,26 @@ void BKE_volume_reload(Main *bmain, Volume *volume)
 
   /* Open OpenVDB file. */
   openvdb::io::File file(filepath);
+  openvdb::GridPtrVec vdb_grids;
+
   try {
     file.setCopyMaxBytes(0);
     file.open();
-    grids = *(file.readAllGridMetadata());
-    /* TODO: need to filter out NULL grids from vector? or check for NULL everywhere? */
+    vdb_grids = *(file.readAllGridMetadata());
   }
-  /* Mostly to catch exceptions related to Blosc not being supported. */
   catch (const openvdb::IoError &e) {
     /* TODO: report error to user. */
     std::cerr << e.what() << '\n';
   }
+
+  /* Add grids read from file to own vector, filtering out any NULL pointers. */
+  for (const openvdb::GridBase::Ptr vdb_grid : vdb_grids) {
+    if (vdb_grid) {
+      VolumeGrid grid;
+      grid.vdb = vdb_grid;
+      volume->grids->push_back(std::move(grid));
+    }
+  }
 #else
   UNUSED_VARS(bmain, volume);
 #endif
@@ -177,25 +187,14 @@ BoundBox *BKE_volume_boundbox_get(Object *ob)
       /* TODO: this is quite expensive, how often is it computed? Is there a faster
        * way without actually reading grids? We should ensure copy-on-write does not
        * compute this over and over for static files. */
-      const openvdb::GridBase &grid = OPENVDB_GRID_CAST(BKE_volume_grid_for_read(volume, i));
-      if (grid.empty()) {
-        continue;
-      }
-
-      openvdb::CoordBBox coordbbox = grid.evalActiveVoxelBoundingBox();
-      openvdb::BBoxd bbox = grid.transform().indexToWorld(coordbbox);
-
+      const VolumeGrid *grid = BKE_volume_grid_for_read(volume, i);
       float grid_min[3], grid_max[3];
-      grid_min[0] = (float)bbox.min().x();
-      grid_min[1] = (float)bbox.min().y();
-      grid_min[2] = (float)bbox.min().z();
-      grid_max[0] = (float)bbox.max().x();
-      grid_max[1] = (float)bbox.max().y();
-      grid_max[2] = (float)bbox.max().z();
-
-      DO_MIN(min, grid_min);
-      DO_MAX(max, grid_max);
-      have_minmax = true;
+
+      if (BKE_volume_grid_bounds(grid, grid_min, grid_max)) {
+        DO_MIN(min, grid_min);
+        DO_MAX(max, grid_max);
+        have_minmax = true;
+      }
     }
 
     if (!have_minmax) {
@@ -269,8 +268,7 @@ void BKE_volume_batch_cache_free(Volume *volume)
 int BKE_volume_num_grids(Volume *volume)
 {
 #ifdef WITH_OPENVDB
-  const openvdb::GridPtrVec &grids = OPENVDB_GRIDS_CAST(volume->vdb_grids);
-  return grids.size();
+  return volume->grids->size();
 #else
   UNUSED_VARS(volume);
   return 0;
@@ -280,8 +278,7 @@ int BKE_volume_num_grids(Volume *volume)
 const VolumeGrid *BKE_volume_grid_for_metadata(Volume *volume, int grid_index)
 {
 #ifdef WITH_OPENVDB
-  const openvdb::GridPtrVec &grids = OPENVDB_GRIDS_CAST(volume->vdb_grids);
-  return (const VolumeGrid *)grids.at(grid_index).get();
+  return &volume->grids->at(grid_index);
 #else
   UNUSED_VARS(volume, grid_index);
   return NULL;
@@ -310,17 +307,47 @@ VolumeGrid *BKE_volume_grid_for_write(Volume *volume, int grid_index)
 #endif
 }
 
-const char *BKE_volume_grid_name(const VolumeGrid *grid_)
+/* Grid Metadata */
+
+const char *BKE_volume_grid_name(const VolumeGrid *volume_grid)
 {
 #ifdef WITH_OPENVDB
   /* Don't use grid.getName() since it copies the string, we want a pointer to the
    * original so it doesn't get freed out of scope. */
-  const openvdb::GridBase &grid = OPENVDB_GRID_CAST(grid_);
-  openvdb::StringMetadata::ConstPtr name_meta = grid.getMetadata<openvdb::StringMetadata>(
+  const openvdb::GridBase::Ptr &grid = volume_grid->vdb;
+  openvdb::StringMetadata::ConstPtr name_meta = grid->getMetadata<openvdb::StringMetadata>(
       openvdb::GridBase::META_GRID_NAME);
   return (name_meta) ? name_meta->value().c_str() : "";
 #else
-  UNUSED_VARS(volume, grid_index);
+  UNUSED_VARS(volume_grid);
   return "density";
 #endif
 }
+
+/* Grid Voxels */
+
+bool BKE_volume_grid_bounds(const VolumeGrid *volume_grid, float min[3], float max[3])
+{
+#ifdef WITH_OPENVDB
+  const openvdb::GridBase::Ptr &grid = volume_grid->vdb;
+  if (grid->empty()) {
+    INIT_MINMAX(min, max);
+    return false;
+  }
+
+  openvdb::CoordBBox coordbbox = grid->evalActiveVoxelBoundingBox();
+  openvdb::BBoxd bbox = grid->transform().indexToWorld(coordbbox);
+
+  min[0] = (float)bbox.min().x();
+  min[1] = (float)bbox.min().y();
+  min[2] = (float)bbox.min().z();
+  max[0] = (float)bbox.max().x();
+  max[1] = (float)bbox.max().y();
+  max[2] = (float)bbox.max().z();
+  return true;
+#else
+  UNUSED_VARS(volume_grid);
+  INIT_MINMAX(min, max);
+  return false;
+#endif
+}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 252df7f3cd4..1bf2c2453f6 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2112,8 +2112,8 @@ void blo_make_volume_pointer_map(FileData *fd, Main *oldmain)
 
   Volume *volume = oldmain->volumes.first;
   for (; volume; volume = volume->id.next) {
-    if (volume->vdb_grids) {
-      oldnewmap_insert(fd->volumemap, volume->vdb_grids, volume->vdb_grids, 0);
+    if (volume->grids) {
+      oldnewmap_insert(fd->volumemap, volume->grids, volume->grids, 0);
     }
   }
 }
@@ -2133,7 +2133,7 @@ void blo_end_volume_pointer_map(FileData *fd, Main *oldmain)
   }
 
   for (; volume; volume = volume->id.next) {
-    volume->vdb_grids = newvolumeadr(fd, volume->vdb_grids);
+    volume->grids = newvolumeadr(fd, volume->grids);
   }
 }
 
@@ -9327,8 +9327,8 @@ static void direct_link_volume(FileData *fd, Volume *volume)
   direct_link_animdata(fd, volume->adt);
 
   volume->packedfile = direct_link_packedfile(fd, volume->packedfile);
-  volume->vdb_grids = (fd->volumemap) ? newvolumeadr(fd, volume->vdb_grids) : NULL;
-  BKE_volume_init_grids(volume->vdb_grids);
+  volume->grids = (fd->volumemap) ? newvolumeadr(fd, volume->grids) : NULL;
+  BKE_volume_init_grids(volume->grids);
 
   /* materials */
   volume->mat = newdataadr(fd, volume->mat);
diff --git a/source/blender/makesdna/DNA_volume_types.h b/source/blender/makesdna/DNA_volume_types.h
index c27e2d63035..e5b491e1468 100644
--- a/source/blender/makesdna/DNA_volume_types.h
+++ b/source/blender/makesdna/DNA_volume_types.h
@@ -28,6 +28,7 @@
 #include "DNA_ID.h"
 
 struct PackedFile;
+struct VolumeGridVector;
 
 typedef struct Volume {
   ID id;
@@ -41,7 +42,7 @@ typedef struct Volume {
 
   /* OpenVDB Voxel Grids */
   int active_grid;
-  void *vdb_grids;
+  struct VolumeGridVector *grids;
 
   /* Material */
   struct Material **mat;



More information about the Bf-blender-cvs mailing list