[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