[Bf-blender-cvs] [8d86ab9e242] new-object-types: Volumes: add wireframe display using OpenVDB tree nodes

Brecht Van Lommel noreply at git.blender.org
Sun Feb 16 19:28:17 CET 2020


Commit: 8d86ab9e2427b4a81dd596234c64ec329dc0c881
Author: Brecht Van Lommel
Date:   Sun Feb 16 12:25:19 2020 +0100
Branches: new-object-types
https://developer.blender.org/rB8d86ab9e2427b4a81dd596234c64ec329dc0c881

Volumes: add wireframe display using OpenVDB tree nodes

With display option for none / bounds / coarse / fine wireframe. This is
particularly useful in heavy scenes, where you might not want to load any
voxel data for the viewport.

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

M	release/scripts/startup/bl_ui/properties_data_volume.py
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/engines/workbench/workbench_forward.c
M	source/blender/draw/engines/workbench/workbench_volume.c
M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_cache.h
M	source/blender/draw/intern/draw_cache_impl.h
M	source/blender/draw/intern/draw_cache_impl_displist.c
M	source/blender/draw/intern/draw_cache_impl_volume.c
M	source/blender/makesdna/DNA_volume_types.h
M	source/blender/makesrna/intern/rna_volume.c

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

diff --git a/release/scripts/startup/bl_ui/properties_data_volume.py b/release/scripts/startup/bl_ui/properties_data_volume.py
index 30124681123..d5357243793 100644
--- a/release/scripts/startup/bl_ui/properties_data_volume.py
+++ b/release/scripts/startup/bl_ui/properties_data_volume.py
@@ -110,7 +110,6 @@ class DATA_PT_volume_grids(DataButtonsPanel, Panel):
 
 class DATA_PT_volume_viewport_display(DataButtonsPanel, Panel):
     bl_label = "Viewport Display"
-    bl_options = {'DEFAULT_CLOSED'}
     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
 
     def draw(self, context):
@@ -120,7 +119,8 @@ class DATA_PT_volume_viewport_display(DataButtonsPanel, Panel):
 
         volume = context.volume
         display = volume.display
-        layout.prop(display, "density_scale")
+        layout.prop(display, "density")
+        layout.prop(display, "wireframe_type")
 
 
 class DATA_PT_custom_props_volume(DataButtonsPanel, PropertyPanel, Panel):
diff --git a/source/blender/blenkernel/BKE_volume_render.h b/source/blender/blenkernel/BKE_volume_render.h
index 902b835306a..acc2236f313 100644
--- a/source/blender/blenkernel/BKE_volume_render.h
+++ b/source/blender/blenkernel/BKE_volume_render.h
@@ -50,6 +50,16 @@ void BKE_volume_grid_dense_voxels(const struct Volume *volume,
                                   const size_t max[3],
                                   float *voxels);
 
+/* Wireframe */
+
+typedef void (*BKE_volume_wireframe_cb)(
+    void *userdata, float (*verts)[3], int (*edges)[2], int totvert, int totedge);
+
+void BKE_volume_grid_wireframe(const struct Volume *volume,
+                               struct VolumeGrid *volume_grid,
+                               BKE_volume_wireframe_cb cb,
+                               void *cb_userdata);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 47ea3a32c3e..f8ebee61a48 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -434,7 +434,8 @@ void BKE_volume_init(Volume *volume)
   volume->frame_offset = 0;
   volume->frame_duration = 0;
   /* TODO: why is this needed for common volume files? */
-  volume->display.density_scale = 10.0f;
+  volume->display.density = 10.0f;
+  volume->display.wireframe_type = VOLUME_WIREFRAME_COARSE;
   BKE_volume_init_grids(volume);
 }
 
@@ -1080,18 +1081,16 @@ 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? */
-  /* TODO: coarse bounding box from tree instead of voxels may be enough? */
   const openvdb::GridBase::Ptr &grid = volume_grid->vdb;
   BLI_assert(BKE_volume_grid_is_loaded(volume_grid));
 
-  if (grid->empty()) {
+  openvdb::CoordBBox coordbbox;
+  if (!grid->baseTree().evalLeafBoundingBox(coordbbox)) {
     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();
diff --git a/source/blender/blenkernel/intern/volume_render.cc b/source/blender/blenkernel/intern/volume_render.cc
index ef48bbf2a79..8e03895a794 100644
--- a/source/blender/blenkernel/intern/volume_render.cc
+++ b/source/blender/blenkernel/intern/volume_render.cc
@@ -22,9 +22,13 @@
  *  \ingroup bke
  */
 
+#include "MEM_guardedalloc.h"
+
 #include "BLI_math_matrix.h"
 #include "BLI_math_vector.h"
 
+#include "DNA_volume_types.h"
+
 #include "BKE_volume.h"
 #include "BKE_volume_render.h"
 
@@ -161,3 +165,180 @@ void BKE_volume_grid_dense_voxels(const Volume *volume,
   UNUSED_VARS(volume, volume_grid, min, max, voxels);
 #endif
 }
+
+/* Wireframe */
+
+#ifdef WITH_OPENVDB
+struct VolumeWireframe {
+  std::vector<openvdb::Vec3f> verts;
+  std::vector<openvdb::Vec2I> edges;
+
+  template<typename GridType>
+  void add_grid(openvdb::GridBase::ConstPtr gridbase, 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);
+    const openvdb::math::Transform &transform = grid->transform();
+    const int depth = (coarse) ? 2 : 3;
+
+    NodeCIter iter = grid->tree().cbeginNode();
+    iter.setMaxDepth(depth);
+
+    for (; iter; ++iter) {
+      if (iter.getDepth() == depth) {
+        openvdb::CoordBBox coordbbox;
+
+        if (depth == 2) {
+          /* Internal node at depth 2. */
+          const Depth2Type *node = nullptr;
+          iter.getNode(node);
+          if (node) {
+            node->evalActiveBoundingBox(coordbbox, false);
+          }
+          else {
+            continue;
+          }
+        }
+        else {
+          /* Leaf node. */
+          if (!iter.getBoundingBox(coordbbox)) {
+            continue;
+          }
+        }
+
+        /* +1 to convert from exclusive to include bounds. */
+        coordbbox.max() = coordbbox.max().offsetBy(1);
+        openvdb::BBoxd bbox = transform.indexToWorld(coordbbox);
+        add_node(bbox);
+      }
+    }
+  }
+
+  void add_node(const openvdb::BBoxd &bbox)
+  {
+    /* TODO: deduplicate edges, hide flat edges? */
+    openvdb::Vec3f min = bbox.min();
+    openvdb::Vec3f max = bbox.max();
+
+    const int vert_offset = verts.size();
+    const int edge_offset = edges.size();
+
+    /* Create vertices. */
+    verts.resize(vert_offset + 8);
+    verts[vert_offset + 0] = openvdb::Vec3f(min[0], min[1], min[2]);
+    verts[vert_offset + 1] = openvdb::Vec3f(max[0], min[1], min[2]);
+    verts[vert_offset + 2] = openvdb::Vec3f(max[0], max[1], min[2]);
+    verts[vert_offset + 3] = openvdb::Vec3f(min[0], max[1], min[2]);
+    verts[vert_offset + 4] = openvdb::Vec3f(min[0], min[1], max[2]);
+    verts[vert_offset + 5] = openvdb::Vec3f(max[0], min[1], max[2]);
+    verts[vert_offset + 6] = openvdb::Vec3f(max[0], max[1], max[2]);
+    verts[vert_offset + 7] = openvdb::Vec3f(min[0], max[1], max[2]);
+
+    /* Create edges. */
+    const int box_edges[12][2] = {{0, 1},
+                                  {1, 2},
+                                  {2, 3},
+                                  {3, 0},
+                                  {4, 5},
+                                  {5, 6},
+                                  {6, 7},
+                                  {7, 4},
+                                  {0, 4},
+                                  {1, 5},
+                                  {2, 6},
+                                  {3, 7}};
+
+    edges.resize(edge_offset + 12);
+    for (int i = 0; i < 12; i++) {
+      edges[edge_offset + i] = openvdb::Vec2I(vert_offset + box_edges[i][0],
+                                              vert_offset + box_edges[i][1]);
+    }
+  }
+};
+#endif
+
+void BKE_volume_grid_wireframe(const Volume *volume,
+                               VolumeGrid *volume_grid,
+                               BKE_volume_wireframe_cb cb,
+                               void *cb_userdata)
+{
+#ifdef WITH_OPENVDB
+  VolumeWireframe wireframe;
+
+  if (volume->display.wireframe_type == VOLUME_WIREFRAME_NONE) {
+    /* Nothing. */
+  }
+  else if (volume->display.wireframe_type == VOLUME_WIREFRAME_BOUNDS) {
+    /* Bounding box. */
+    float min[3], max[3];
+    BKE_volume_grid_bounds(volume_grid, min, max);
+
+    openvdb::BBoxd bbox(min, max);
+    wireframe.add_node(bbox);
+  }
+  else {
+    /* Tree nodes. */
+    openvdb::GridBase::ConstPtr grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
+    const bool coarse = (volume->display.wireframe_type == VOLUME_WIREFRAME_COARSE);
+
+    switch (BKE_volume_grid_type(volume_grid)) {
+      case VOLUME_GRID_BOOLEAN: {
+        wireframe.add_grid<openvdb::BoolGrid>(grid, coarse);
+        break;
+      }
+      case VOLUME_GRID_FLOAT: {
+        wireframe.add_grid<openvdb::FloatGrid>(grid, coarse);
+        break;
+      }
+      case VOLUME_GRID_DOUBLE: {
+        wireframe.add_grid<openvdb::DoubleGrid>(grid, coarse);
+        break;
+      }
+      case VOLUME_GRID_INT: {
+        wireframe.add_grid<openvdb::Int32Grid>(grid, coarse);
+        break;
+      }
+      case VOLUME_GRID_INT64: {
+        wireframe.add_grid<openvdb::Int64Grid>(grid, coarse);
+        break;
+      }
+      case VOLUME_GRID_MASK: {
+        wireframe.add_grid<openvdb::MaskGrid>(grid, coarse);
+        break;
+      }
+      case VOLUME_GRID_VECTOR_FLOAT: {
+        wireframe.add_grid<openvdb::Vec3fGrid>(grid, coarse);
+        break;
+      }
+      case VOLUME_GRID_VECTOR_DOUBLE: {
+        wireframe.add_grid<openvdb::Vec3dGrid>(grid, coarse);
+        break;
+      }
+      case VOLUME_GRID_VECTOR_INT: {
+        wireframe.add_grid<openvdb::Vec3IGrid>(grid, coarse);
+        break;
+      }
+      case VOLUME_GRID_STRING: {
+        wireframe.add_grid<openvdb::StringGrid>(grid, coarse);
+        break;
+      }
+      case VOLUME_GRID_UNKNOWN: {
+        break;
+      }
+    }
+  }
+
+  cb(cb_userdata,
+     (float(*)[3])wireframe.verts.data(),
+     (int(*)[2])wireframe.edges.data(),
+     wireframe.verts.size(),
+     wireframe.edges.size());
+#else
+  UNUSED_VARS(volume, volume_grid);
+  cb(cb_userdata, NULL, NULL, 0, 0);
+#endif
+}
diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c
index df16506d917..f0bb85750f5 100644
--- a/source/blender/draw/engines/workbench/workbench_forward.c
+++ b/source/blender/draw/engines/workbench/workbench_forward.c
@@ -779,7 +779,9 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
   }
   else if (ob->type == OB_VOLUME) {
     /* Volume object. */
-    workbench_volume_cache_populate(vedata, scene, ob, NULL);
+    if (!(is_wire || (wpd->shading.type == OB_WIRE))) {
+      workbench_volume_cache_populate(vedata, scene, ob, NULL);
+    }
   }
 }
 
diff -

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list