Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2020-10-05 11:29:34 +0300
committerJacques Lucke <jacques@blender.org>2020-10-05 11:29:34 +0300
commita4f8b2ad7653cac8a5f7821ce7ee9af44b13a758 (patch)
tree73c8a83d11ea4461546648602234b0626c11367d
parent3e101759b1b726e3cc16c69b2619cd1d82b00a8e (diff)
Volumes: more generic way to handle different openvdb types
Reviewers: brecht Differential Revision: https://developer.blender.org/D9093
-rw-r--r--source/blender/blenkernel/BKE_volume.h37
-rw-r--r--source/blender/blenkernel/intern/volume.cc51
-rw-r--r--source/blender/blenkernel/intern/volume_render.cc123
3 files changed, 91 insertions, 120 deletions
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::Int32Grid>(grid, coarse);
- break;
- }
- case VOLUME_GRID_INT64: {
- return get_bounding_boxes<openvdb::Int64Grid>(grid, coarse);
- break;
- }
- case VOLUME_GRID_MASK: {
- return get_bounding_boxes<openvdb::MaskGrid>(grid, coarse);
- break;
- }
- case VOLUME_GRID_VECTOR_FLOAT: {
- return get_bounding_boxes<openvdb::Vec3fGrid>(grid, coarse);
- break;
- }
- case VOLUME_GRID_VECTOR_DOUBLE: {
- return get_bounding_boxes<openvdb::Vec3dGrid>(grid, coarse);
- break;
- }
- case VOLUME_GRID_VECTOR_INT: {
- return get_bounding_boxes<openvdb::Vec3IGrid>(grid, coarse);
- break;
- }
- case VOLUME_GRID_STRING: {
- return get_bounding_boxes<openvdb::StringGrid>(grid, coarse);
- break;
- }
- case VOLUME_GRID_POINTS:
- case VOLUME_GRID_UNKNOWN: {
- break;
- }
- }
- return {};
+ GetBoundingBoxesOp op{grid, coarse};
+ return BKE_volume_grid_type_operation(grid_type, op);
}
static void boxes_to_center_points(blender::Span<openvdb::CoordBBox> boxes,
@@ -462,7 +415,7 @@ void BKE_volume_grid_wireframe(const Volume *volume,
else {
blender::Vector<openvdb::CoordBBox> boxes = get_bounding_boxes(
BKE_volume_grid_type(volume_grid),
- grid,
+ *grid,
volume->display.wireframe_detail == VOLUME_WIREFRAME_COARSE);
blender::Vector<blender::float3> verts;
@@ -517,7 +470,7 @@ void BKE_volume_grid_selection_surface(const Volume *volume,
#ifdef WITH_OPENVDB
openvdb::GridBase::ConstPtr grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
blender::Vector<openvdb::CoordBBox> boxes = get_bounding_boxes(
- BKE_volume_grid_type(volume_grid), grid, true);
+ BKE_volume_grid_type(volume_grid), *grid, true);
blender::Vector<blender::float3> verts;
blender::Vector<std::array<int, 3>> tris;