Geometry Nodes: initial Volume Grid socket support #115270

Merged
Jacques Lucke merged 193 commits from LukasTonne/blender:volume-grid-sockets into main 2023-12-20 22:33:26 +01:00
4 changed files with 42 additions and 42 deletions
Showing only changes of commit 8c9ad29d46 - Show all commits

View File

@ -391,41 +391,33 @@ template<typename T> struct FieldValueGridImpl {
#endif /* WITH_OPENVDB */
namespace detail {
/* Utility class to make #is_field_value_grid_v work. */
struct FieldValueGridBase {
};
} // namespace detail
template<typename T>
struct FieldValueGrid : public ImplicitSharingMixin, public detail::FieldValueGridBase {
template<typename T> struct FieldValueGrid : public ImplicitSharingMixin {
using FieldValueType = T;
using GridType = FieldValueGridImpl<T>;
/* XXX Grid could be stored by-value as well, but that makes it harder to use some OpenVDB API
* functions. The actual data is in the tree, which is always a shared_ptr anyway. */
std::shared_ptr<GridType> grid;
FieldValueGrid() : grid(nullptr) {}
FieldValueGrid(const FieldValueGrid<T> &other) : grid(other.grid) {}
FieldValueGrid(const std::shared_ptr<GridType> &grid) : grid(grid) {}
/* Takes ownership of the grid, which must not be shared. */
FieldValueGrid(const std::shared_ptr<GridType> &grid) : grid(grid)
{
BLI_assert(grid);
}
virtual ~FieldValueGrid() = default;
FieldValueGrid<T> &operator=(const FieldValueGrid<T> &other)
{
this->grid = other.grid;
return *this;
}
FieldValueGrid<T> &operator=(const std::shared_ptr<GridType> &grid)
{
this->grid = grid;
return *this;
}
void delete_self() override
{
delete this;
}
void delete_data_only() override
{
this->grid.reset();
}
bool operator==(const FieldValueGrid<T> &other) const
{
return this->grid == other.grid;
@ -435,11 +427,6 @@ struct FieldValueGrid : public ImplicitSharingMixin, public detail::FieldValueGr
return this->grid != other.grid;
}
operator bool() const
{
return bool(this->grid);
}
GridType &operator*()
{
return *this->grid;
@ -469,11 +456,6 @@ struct FieldValueGrid : public ImplicitSharingMixin, public detail::FieldValueGr
namespace blender::bke::grid_types {
/** True when T is any FieldValueGrid<...> type. */
template<typename T>
static constexpr bool is_field_value_grid_v = std::is_base_of_v<detail::FieldValueGridBase, T> &&
!std::is_same_v<detail::FieldValueGridBase, T>;
template<typename T> bool get_background_value(const FieldValueGrid<T> &grid, T &r_value)
{
#ifdef WITH_OPENVDB
@ -490,16 +472,20 @@ template<typename T> bool get_background_value(const FieldValueGrid<T> &grid, T
#endif /* WITH_OPENVDB */
}
template<typename T> FieldValueGrid<T> make_empty_grid(const T background_value)
template<typename T> FieldValueGrid<T> *make_empty_grid(const T background_value)
{
#ifdef WITH_OPENVDB
using GridType = typename FieldValueGrid<T>::GridType;
std::shared_ptr<GridType> grid;
if constexpr (std::is_same_v<T, std::string>) {
return nullptr;
grid = nullptr;
}
else {
using Converter = GridConverter<T>;
return FieldValueGrid<T>::GridType::create(Converter::single_value_to_grid(background_value));
grid = GridType::create(Converter::single_value_to_grid(background_value));
}
return new FieldValueGrid<T>(grid);
#else
return nullptr;
#endif /* WITH_OPENVDB */

View File

@ -8,6 +8,8 @@
#pragma once
#include "BLI_implicit_sharing_ptr.hh"
#include "BKE_grid_types.hh"
#include "FN_field.hh"
@ -23,11 +25,12 @@ namespace blender::bke {
template<typename T> struct ValueOrField {
using Field = fn::Field<T>;
using Grid = typename grid_types::FieldValueGrid<T>;
using GridPtr = ImplicitSharingPtr<Grid>;
/** Value that is used when the field is empty. */
T value{};
Field field;
Grid grid;
GridPtr grid;
ValueOrField() = default;
@ -35,11 +38,13 @@ template<typename T> struct ValueOrField {
ValueOrField(Field field) : field(std::move(field)) {}
ValueOrField(Grid grid) : grid(std::move(grid)) {}
ValueOrField(const GridPtr &grid) : grid(std::move(grid)) {}
~ValueOrField()
{
grid.remove_user_and_delete_if_last();
// if (grid) {
// grid->remove_user_and_delete_if_last();
// }
}
bool is_field() const
@ -60,7 +65,7 @@ template<typename T> struct ValueOrField {
return fn::make_constant_field(this->value);
}
Grid as_grid() const
GridPtr as_grid() const
{
if (this->grid) {
return this->grid;
@ -77,7 +82,7 @@ template<typename T> struct ValueOrField {
if (this->grid) {
/* Returns the grid background value. */
T value;
if (grid_types::get_background_value(this->grid, value)) {
if (grid_types::get_background_value(*this->grid, value)) {
return value;
}
}

View File

@ -11,6 +11,7 @@
#include "BKE_cpp_types.hh"
#include "BKE_geometry_set.hh"
#include "BKE_grid_types.hh"
#include "BKE_instances.hh"
#include "BKE_node_socket_value_cpp_type.hh"
@ -37,6 +38,9 @@ BLI_CPP_TYPE_MAKE(MStringProperty, CPPTypeFlags::None);
BLI_CPP_TYPE_MAKE(blender::bke::AnonymousAttributeSet, CPPTypeFlags::None);
BLI_CPP_TYPE_MAKE(blender::bke::grid_types::FieldValueGrid<float>, CPPTypeFlags::None);
BLI_CPP_TYPE_MAKE(blender::bke::grid_types::FieldValueGrid<blender::float3>, CPPTypeFlags::None);
void BKE_cpp_types_init()
{
blender::register_cpp_types();
@ -56,6 +60,9 @@ void BKE_cpp_types_init()
BLI_CPP_TYPE_REGISTER(MStringProperty);
BLI_CPP_TYPE_REGISTER(blender::bke::AnonymousAttributeSet);
BLI_CPP_TYPE_REGISTER(blender::bke::grid_types::FieldValueGrid<float>);
BLI_CPP_TYPE_REGISTER(blender::bke::grid_types::FieldValueGrid<blender::float3>);
}
SOCKET_VALUE_CPP_TYPE_MAKE(float);

View File

@ -163,6 +163,8 @@ class GeoNodeExecParams {
template<typename T> void set_output(StringRef identifier, T &&value)
{
using StoredT = std::decay_t<T>;
using GridType = bke::grid_types::FieldValueGrid<T>;
if constexpr (is_field_base_type_v<StoredT>) {
this->set_output(identifier, ValueOrField<StoredT>(std::forward<T>(value)));
}
@ -170,15 +172,15 @@ class GeoNodeExecParams {
using BaseType = typename StoredT::base_type;
this->set_output(identifier, ValueOrField<BaseType>(std::forward<T>(value)));
}
else if constexpr (std::is_same_v<std::decay_t<StoredT>, GField>) {
else if constexpr (std::is_same_v<StoredT, GField>) {
bke::attribute_math::convert_to_static_type(value.cpp_type(), [&](auto dummy) {
using ValueT = decltype(dummy);
Field<ValueT> value_typed(std::forward<T>(value));
this->set_output(identifier, ValueOrField<ValueT>(std::move(value_typed)));
});
}
else if constexpr (bke::grid_types::is_field_value_grid_v<StoredT>) {
using BaseType = typename StoredT::FieldValueType;
else if constexpr (std::is_same_v<StoredT, ImplicitSharingPtr<GridType>>) {
using BaseType = typename GridType::FieldValueType;
this->set_output(identifier, ValueOrField<BaseType>(std::forward<T>(value)));
}
else {