Geometry Nodes: initial Volume Grid socket support #115270
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user