WIP: Volume grid attribute support in geometry nodes #110044
|
@ -232,6 +232,10 @@ static bool add_builtin_type_custom_data_layer_from_init(CustomData &custom_data
|
|||
&custom_data, data_type, const_cast<void *>(init.data), domain_num, init.sharing_info);
|
||||
return stored_data != nullptr;
|
||||
}
|
||||
case AttributeInit::Type::Grid:
|
||||
case AttributeInit::Type::MoveGrid:
|
||||
case AttributeInit::Type::SharedGrid:
|
||||
return false;
|
||||
}
|
||||
|
||||
BLI_assert_unreachable();
|
||||
|
@ -317,6 +321,10 @@ static bool add_custom_data_layer_from_attribute_init(const AttributeIDRef &attr
|
|||
init.sharing_info);
|
||||
break;
|
||||
}
|
||||
case AttributeInit::Type::Grid:
|
||||
case AttributeInit::Type::MoveGrid:
|
||||
case AttributeInit::Type::SharedGrid:
|
||||
break;
|
||||
}
|
||||
return old_layer_num < custom_data.totlayer;
|
||||
}
|
||||
|
|
|
@ -661,14 +661,14 @@ bool try_capture_field_on_geometry(GeometryComponent &component,
|
|||
}
|
||||
|
||||
attributes.remove(attribute_id);
|
||||
if (attributes.add(attribute_id, domain, data_type, bke::AttributeInitMoveGrid(grid))) {
|
||||
if (attributes.add(
|
||||
attribute_id, domain, data_type, bke::AttributeInitMoveGrid(grid.grid_.get())))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* If the name corresponds to a builtin attribute, removing the attribute might fail if
|
||||
* it's required, and adding the attribute might fail if the domain or type is incorrect. */
|
||||
type.destruct_n(buffer, domain_size);
|
||||
MEM_freeN(buffer);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,17 +13,45 @@
|
|||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_parameter_pack_utils.hh"
|
||||
|
||||
/* Note: version header included here to enable correct forward declaration of some types. No other
|
||||
* OpenVDB headers should be included here, especially openvdb.h, to avoid affecting other
|
||||
* compilation units. */
|
||||
#ifdef WITH_OPENVDB
|
||||
# include <openvdb/openvdb.h>
|
||||
# include <openvdb/version.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
/* Forward declaration for basic OpenVDB types. */
|
||||
namespace openvdb {
|
||||
OPENVDB_USE_VERSION_NAMESPACE
|
||||
namespace OPENVDB_VERSION_NAME {
|
||||
|
||||
using Index = uint32_t;
|
||||
class GridBase;
|
||||
template<typename TreeType> class Grid;
|
||||
class ValueMask;
|
||||
template<typename... Types> class TypeList;
|
||||
|
||||
namespace tree {
|
||||
template<typename T, Index Log2Dim> class LeafNode;
|
||||
template<typename ChildNodeType, Index Log2Dim> class InternalNode;
|
||||
template<typename ChildNodeType> class RootNode;
|
||||
template<typename RootNodeType> class Tree;
|
||||
|
||||
/* Forward-declared version of Tree4, can't use the actual Tree4 alias because it can't be
|
||||
* forward-declared. */
|
||||
template<typename T, Index N1 = 5, Index N2 = 4, Index N3 = 3> struct Tree4Fwd {
|
||||
using Type = openvdb::tree::Tree<openvdb::tree::RootNode<
|
||||
openvdb::tree::InternalNode<openvdb::tree::InternalNode<openvdb::tree::LeafNode<T, N3>, N2>,
|
||||
N1>>>;
|
||||
};
|
||||
} // namespace tree
|
||||
} // namespace OPENVDB_VERSION_NAME
|
||||
} // namespace openvdb
|
||||
#endif
|
||||
|
||||
namespace blender {
|
||||
|
||||
namespace volume {
|
||||
template<typename T> class Grid;
|
||||
template<typename T> class MutableGrid;
|
||||
} // namespace volume
|
||||
|
||||
/* XXX OpenVDB expects some math functions on vector types. */
|
||||
template<typename T, int Size> inline VecBase<T, Size> Abs(VecBase<T, Size> v)
|
||||
{
|
||||
|
@ -41,17 +69,12 @@ template<int Size> inline VecBase<uint32_t, Size> Abs(VecBase<uint32_t, Size> v)
|
|||
|
||||
namespace volume {
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Tree and Grid types for Blender CPP types
|
||||
* \{ */
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
|
||||
namespace grid_types {
|
||||
|
||||
template<typename ValueType>
|
||||
using TreeCommon = typename openvdb::tree::Tree4<ValueType, 5, 4, 3>::Type;
|
||||
template<typename ValueType> using GridCommon = typename openvdb::Grid<TreeCommon<ValueType>>;
|
||||
using TreeCommon = typename openvdb::tree::Tree4Fwd<ValueType, 5, 4, 3>::Type;
|
||||
template<typename ValueType> using GridCommon = openvdb::Grid<TreeCommon<ValueType>>;
|
||||
|
||||
/* TODO add more as needed. */
|
||||
/* TODO could use template magic to generate all from 1 list, but not worth it for now. */
|
||||
|
@ -121,22 +144,18 @@ using SupportedGridTypes = openvdb::TypeList<BoolGrid,
|
|||
TopologyGrid>;
|
||||
|
||||
} // namespace grid_types
|
||||
|
||||
#endif
|
||||
|
||||
/** \} */
|
||||
template<typename T> class Grid;
|
||||
template<typename T> class MutableGrid;
|
||||
|
||||
/* Mask defined by active voxels of the grid. */
|
||||
class GridMask {
|
||||
#ifdef WITH_OPENVDB
|
||||
openvdb::MaskGrid::ConstPtr grid_;
|
||||
|
||||
static const openvdb::MaskGrid::ConstPtr empty_grid()
|
||||
{
|
||||
static openvdb::MaskGrid::ConstPtr grid = openvdb::MaskGrid::create();
|
||||
return grid;
|
||||
}
|
||||
using GridPtr = std::shared_ptr<grid_types::MaskGrid>;
|
||||
GridPtr grid_;
|
||||
|
||||
static GridPtr empty_grid();
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
@ -159,7 +178,7 @@ class GridMask {
|
|||
}
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
GridMask(const openvdb::MaskGrid::ConstPtr &grid) : grid_(grid) {}
|
||||
GridMask(const GridPtr &grid) : grid_(grid) {}
|
||||
#endif
|
||||
|
||||
static GridMask from_bools(const volume::GridMask &full_mask,
|
||||
|
@ -169,7 +188,7 @@ class GridMask {
|
|||
int64_t min_voxel_count() const;
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
const openvdb::MaskGrid::ConstPtr &grid() const
|
||||
const GridPtr &grid() const
|
||||
{
|
||||
return grid_;
|
||||
}
|
||||
|
@ -185,7 +204,8 @@ class GridMask {
|
|||
class GGrid {
|
||||
public:
|
||||
#ifdef WITH_OPENVDB
|
||||
openvdb::GridBase::ConstPtr grid_ = nullptr;
|
||||
using GridPtr = std::shared_ptr<const openvdb::GridBase>;
|
||||
GridPtr grid_ = nullptr;
|
||||
#endif
|
||||
|
||||
int64_t voxel_count() const;
|
||||
|
@ -201,7 +221,8 @@ class GGrid {
|
|||
class GMutableGrid {
|
||||
public:
|
||||
#ifdef WITH_OPENVDB
|
||||
openvdb::GridBase::Ptr grid_ = nullptr;
|
||||
using GridPtr = std::shared_ptr<openvdb::GridBase>;
|
||||
GridPtr grid_ = nullptr;
|
||||
#endif
|
||||
|
||||
operator GGrid() const
|
||||
|
@ -356,14 +377,15 @@ template<typename Func> void field_to_static_type(const CPPType &type, Func func
|
|||
}
|
||||
|
||||
/* Helper function to evaluate a function with a static field type. */
|
||||
template<typename Func> void grid_to_static_type(const openvdb::GridBase::Ptr &grid, Func func)
|
||||
template<typename Func>
|
||||
void grid_to_static_type(const std::shared_ptr<openvdb::GridBase> &grid, Func func)
|
||||
{
|
||||
grid->apply<grid_types::SupportedGridTypes>(func);
|
||||
}
|
||||
|
||||
/* Helper function to evaluate a function with a static field type. */
|
||||
template<typename Func>
|
||||
void grid_to_static_type(const openvdb::GridBase::ConstPtr &grid, Func func)
|
||||
void grid_to_static_type(const std::shared_ptr<const openvdb::GridBase> &grid, Func func)
|
||||
{
|
||||
grid->apply<grid_types::SupportedGridTypes>(func);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
/** \file
|
||||
* \ingroup bli
|
||||
*/
|
||||
|
||||
#include "BLI_cpp_type.hh"
|
||||
#include "BLI_math_base.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_parameter_pack_utils.hh"
|
||||
#include "BLI_volume.hh"
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
# include <openvdb/openvdb.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Warning: Avoid including this inside header files.
|
||||
* OpenVDB is heavily templated and exposing this can affect build times severely.
|
||||
*/
|
||||
|
||||
namespace blender {
|
||||
|
||||
namespace volume {
|
||||
|
||||
} // namespace volume
|
||||
|
||||
} // namespace blender
|
|
@ -377,6 +377,7 @@ set(SRC
|
|||
BLI_virtual_array.hh
|
||||
BLI_virtual_vector_array.hh
|
||||
BLI_volume.hh
|
||||
BLI_volume_openvdb.hh
|
||||
BLI_voronoi_2d.h
|
||||
BLI_voxel.h
|
||||
BLI_winstuff.h
|
||||
|
|
|
@ -8,11 +8,20 @@
|
|||
|
||||
#include "BLI_cpp_type.hh"
|
||||
#include "BLI_math_base.hh"
|
||||
#include "BLI_volume.hh"
|
||||
#include "BLI_volume_openvdb.hh"
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
# include <openvdb/openvdb.h>
|
||||
#endif
|
||||
|
||||
namespace blender::volume {
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
GridMask::GridPtr GridMask::empty_grid()
|
||||
{
|
||||
static GridPtr grid = grid_types::MaskGrid::create();
|
||||
return grid;
|
||||
}
|
||||
|
||||
GridMask GridMask::from_bools(const volume::GridMask &full_mask,
|
||||
const volume::Grid<bool> &selection)
|
||||
|
|
|
@ -121,7 +121,8 @@ static Vector<GGrid> get_volume_field_context_inputs(
|
|||
if (!grid) {
|
||||
const CPPType &type = field_input.cpp_type();
|
||||
const void *default_value = type.default_value();
|
||||
grid = GMutableGrid::create(scope, type, default_value);
|
||||
grid = GMutableGrid::create(type, default_value);
|
||||
scope.add_value<GGrid::GridPtr>(std::move(grid.grid_));
|
||||
}
|
||||
field_context_inputs.append(grid);
|
||||
}
|
||||
|
@ -573,7 +574,8 @@ Vector<GGrid> evaluate_volume_fields(ResourceScope &scope,
|
|||
if (mask.is_empty()) {
|
||||
for (const int i : fields_to_evaluate.index_range()) {
|
||||
const CPPType &type = fields_to_evaluate[i].cpp_type();
|
||||
r_grids[i] = GMutableGrid::create(scope, type);
|
||||
r_grids[i] = GMutableGrid::create(type);
|
||||
scope.add_value<GGrid::GridPtr>(std::move(r_grids[i].grid_));
|
||||
}
|
||||
return r_grids;
|
||||
}
|
||||
|
@ -613,8 +615,9 @@ Vector<GGrid> evaluate_volume_fields(ResourceScope &scope,
|
|||
}
|
||||
case FieldNodeType::Constant: {
|
||||
const FieldConstant &field_constant = static_cast<const FieldConstant &>(field.node());
|
||||
r_grids[out_index] = GMutableGrid::create(
|
||||
scope, field_constant.type(), field_constant.value().get());
|
||||
r_grids[out_index] = GMutableGrid::create(field_constant.type(),
|
||||
field_constant.value().get());
|
||||
scope.add_value<GGrid::GridPtr>(std::move(r_grids[out_index].grid_));
|
||||
break;
|
||||
}
|
||||
case FieldNodeType::Operation: {
|
||||
|
|
|
@ -314,8 +314,8 @@ void evaluate_procedure_on_varying_volume_fields(ResourceScope &scope,
|
|||
GMutableGrid dst_grid = get_dst_grid(out_index);
|
||||
if (!dst_grid) {
|
||||
/* Create a destination grid for the computed result. */
|
||||
dst_grid = GMutableGrid::create(
|
||||
scope, type, mask, type.default_value(), type.default_value());
|
||||
dst_grid = GMutableGrid::create(type, mask, type.default_value(), type.default_value());
|
||||
scope.add_value<GMutableGrid::GridPtr>(std::move(dst_grid.grid_));
|
||||
r_grids[out_index] = dst_grid;
|
||||
}
|
||||
else {
|
||||
|
|
Loading…
Reference in New Issue