Nodes: Move ValueOrField struct into blenkernel

This struct is currently defined in the `functions` module but not actually used there. It's only used by the geometry nodes module, with an indirect dependency from blenkernel via simulation zone baking. This scope is problematic when adding grids as socket data, which should not be part of the functions module.

The `ValueOrField` struct is now moved to blenkernel, so it can be more easily extended to other kinds of data that might be passed around by geometry nodes sockets in future. No functional changes.

Pull Request: https://projects.blender.org/blender/blender/pulls/115087
This commit is contained in:
Lukas Tönne
2023-11-18 13:11:39 +01:00
parent 0b11c591ec
commit c845233d1c
25 changed files with 301 additions and 301 deletions

View File

@@ -0,0 +1,70 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup bke
*/
#pragma once
#include "FN_field.hh"
namespace blender::bke {
/* -------------------------------------------------------------------- */
/** \name Value or Field Class
*
* Utility class that wraps a single value and a field, to simplify accessing both of the types.
* \{ */
template<typename T> struct ValueOrField {
using Field = fn::Field<T>;
/** Value that is used when the field is empty. */
T value{};
Field field;
ValueOrField() = default;
ValueOrField(T value) : value(std::move(value)) {}
ValueOrField(Field field) : field(std::move(field)) {}
bool is_field() const
{
return bool(this->field);
}
Field as_field() const
{
if (this->field) {
return this->field;
}
return fn::make_constant_field(this->value);
}
T as_value() const
{
if (this->field) {
/* This returns a default value when the field is not constant. */
return fn::evaluate_constant_field(this->field);
}
return this->value;
}
friend std::ostream &operator<<(std::ostream &stream, const ValueOrField<T> &value_or_field)
{
if (value_or_field.field) {
stream << "ValueOrField<T>";
}
else {
stream << value_or_field.value;
}
return stream;
}
};
/** \} */
} // namespace blender::bke

View File

@@ -0,0 +1,142 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup bke
*/
#pragma once
#include "BKE_node_socket_value.hh"
#include "FN_field.hh"
namespace blender::bke {
/* -------------------------------------------------------------------- */
/** \name Socket Value CPP Type Class
*
* Contains information about how to deal with a `ValueOrField<T>` generically.
* \{ */
class ValueOrFieldCPPType {
private:
void (*construct_from_value_)(void *dst, const void *value);
void (*construct_from_field_)(void *dst, fn::GField field);
const fn::GField *(*get_field_ptr_)(const void *value_or_field);
bool (*is_field_)(const void *value_or_field);
fn::GField (*as_field_)(const void *value_or_field);
public:
/** The #ValueOrField<T> itself. */
const CPPType &self;
/** The type stored in the field. */
const CPPType &value;
template<typename ValueType> ValueOrFieldCPPType(TypeTag<ValueType> /*value_type*/);
void construct_from_value(void *dst, const void *value) const
{
construct_from_value_(dst, value);
}
void construct_from_field(void *dst, fn::GField field) const
{
construct_from_field_(dst, field);
}
const void *get_value_ptr(const void *value_or_field) const
{
static_assert(offsetof(ValueOrField<int>, value) == 0);
return value_or_field;
}
void *get_value_ptr(void *value_or_field) const
{
static_assert(offsetof(ValueOrField<int>, value) == 0);
return value_or_field;
}
const fn::GField *get_field_ptr(const void *value_or_field) const
{
return get_field_ptr_(value_or_field);
}
bool is_field(const void *value_or_field) const
{
return is_field_(value_or_field);
}
fn::GField as_field(const void *value_or_field) const
{
return as_field_(value_or_field);
}
/**
* Try to find the #ValueOrFieldCPPType that corresponds to a #CPPType.
*/
static const ValueOrFieldCPPType *get_from_self(const CPPType &self);
/**
* Try to find the #ValueOrFieldCPPType that wraps a #ValueOrField containing the given value
* type. This only works when the type has been created with #FN_FIELD_CPP_TYPE_MAKE.
*/
static const ValueOrFieldCPPType *get_from_value(const CPPType &value);
template<typename ValueType> static const ValueOrFieldCPPType &get()
{
static const ValueOrFieldCPPType &type =
ValueOrFieldCPPType::get_impl<std::decay_t<ValueType>>();
return type;
}
private:
template<typename ValueType> static const ValueOrFieldCPPType &get_impl();
void register_self();
};
template<typename ValueType>
inline ValueOrFieldCPPType::ValueOrFieldCPPType(TypeTag<ValueType> /*value_type*/)
: self(CPPType::get<ValueOrField<ValueType>>()), value(CPPType::get<ValueType>())
{
using T = ValueType;
construct_from_value_ = [](void *dst, const void *value_or_field) {
new (dst) ValueOrField<T>(*(const T *)value_or_field);
};
construct_from_field_ = [](void *dst, fn::GField field) {
new (dst) ValueOrField<T>(fn::Field<T>(std::move(field)));
};
get_field_ptr_ = [](const void *value_or_field) -> const fn::GField * {
return &((ValueOrField<T> *)value_or_field)->field;
};
is_field_ = [](const void *value_or_field) {
return ((ValueOrField<T> *)value_or_field)->is_field();
};
as_field_ = [](const void *value_or_field) -> fn::GField {
return ((ValueOrField<T> *)value_or_field)->as_field();
};
this->register_self();
}
/** \} */
} // namespace blender::bke
/**
* Create a new #ValueOrFieldCPPType that can be accessed through `ValueOrFieldCPPType::get<T>()`.
*/
#define SOCKET_VALUE_CPP_TYPE_MAKE(VALUE_TYPE) \
BLI_CPP_TYPE_MAKE(blender::bke::ValueOrField<VALUE_TYPE>, CPPTypeFlags::Printable) \
template<> \
const blender::bke::ValueOrFieldCPPType & \
blender::bke::ValueOrFieldCPPType::get_impl<VALUE_TYPE>() \
{ \
static blender::bke::ValueOrFieldCPPType type{blender::TypeTag<VALUE_TYPE>{}}; \
return type; \
}
/** Register a #ValueOrFieldCPPType created with #FN_FIELD_CPP_TYPE_MAKE. */
#define SOCKET_VALUE_CPP_TYPE_REGISTER(VALUE_TYPE) \
blender::bke::ValueOrFieldCPPType::get<VALUE_TYPE>()

View File

@@ -234,6 +234,7 @@ set(SRC
intern/nla.cc
intern/node.cc
intern/node_runtime.cc
intern/node_socket_value_cpp_type.cc
intern/node_tree_anonymous_attributes.cc
intern/node_tree_dot_export.cc
intern/node_tree_field_inferencing.cc
@@ -454,6 +455,8 @@ set(SRC
BKE_node.h
BKE_node.hh
BKE_node_runtime.hh
BKE_node_socket_value.hh
BKE_node_socket_value_cpp_type.hh
BKE_node_tree_anonymous_attributes.hh
BKE_node_tree_dot_export.hh
BKE_node_tree_interface.hh

View File

@@ -5,10 +5,9 @@
#include "BKE_bake_items_socket.hh"
#include "BKE_geometry_fields.hh"
#include "BKE_node.h"
#include "BKE_node.hh"
#include "FN_field_cpp_type.hh"
#include "BKE_node_socket_value_cpp_type.hh"
namespace blender::bke::bake {
@@ -49,8 +48,8 @@ Array<std::unique_ptr<BakeItem>> move_socket_values_to_bake_items(const Span<voi
break;
}
case SOCK_STRING: {
const fn::ValueOrField<std::string> &value =
*static_cast<const fn::ValueOrField<std::string> *>(socket_value);
const ValueOrField<std::string> &value = *static_cast<const ValueOrField<std::string> *>(
socket_value);
bake_items[i] = std::make_unique<StringBakeItem>(value.as_value());
break;
}
@@ -61,8 +60,7 @@ Array<std::unique_ptr<BakeItem>> move_socket_values_to_bake_items(const Span<voi
case SOCK_ROTATION:
case SOCK_RGBA: {
const CPPType &type = get_socket_cpp_type(socket_type);
const fn::ValueOrFieldCPPType &value_or_field_type =
*fn::ValueOrFieldCPPType::get_from_self(type);
const ValueOrFieldCPPType &value_or_field_type = *ValueOrFieldCPPType::get_from_self(type);
const CPPType &base_type = value_or_field_type.value;
if (!value_or_field_type.is_field(socket_value)) {
const void *value = value_or_field_type.get_value_ptr(socket_value);
@@ -146,8 +144,7 @@ Array<std::unique_ptr<BakeItem>> move_socket_values_to_bake_items(const Span<voi
case SOCK_BOOLEAN:
case SOCK_ROTATION:
case SOCK_RGBA: {
const fn::ValueOrFieldCPPType &value_or_field_type = *fn::ValueOrFieldCPPType::get_from_self(
type);
const ValueOrFieldCPPType &value_or_field_type = *ValueOrFieldCPPType::get_from_self(type);
const CPPType &base_type = value_or_field_type.value;
if (const auto *item = dynamic_cast<const PrimitiveBakeItem *>(&bake_item)) {
if (item->type() == base_type) {
@@ -169,7 +166,7 @@ Array<std::unique_ptr<BakeItem>> move_socket_values_to_bake_items(const Span<voi
}
case SOCK_STRING: {
if (const auto *item = dynamic_cast<const StringBakeItem *>(&bake_item)) {
new (r_value) fn::ValueOrField<std::string>(item->value());
new (r_value) ValueOrField<std::string>(item->value());
return true;
}
return false;

View File

@@ -2,12 +2,17 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_color.hh"
#include "BLI_cpp_type_make.hh"
#include "BLI_cpp_types_make.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_math_quaternion_types.hh"
#include "BLI_math_vector_types.hh"
#include "BKE_cpp_types.hh"
#include "BKE_geometry_set.hh"
#include "BKE_instances.hh"
#include "BKE_node_socket_value_cpp_type.hh"
#include "DNA_meshdata_types.h"
@@ -52,3 +57,34 @@ void BKE_cpp_types_init()
BLI_CPP_TYPE_REGISTER(blender::bke::AnonymousAttributeSet);
}
SOCKET_VALUE_CPP_TYPE_MAKE(float);
SOCKET_VALUE_CPP_TYPE_MAKE(blender::float2);
SOCKET_VALUE_CPP_TYPE_MAKE(blender::float3);
SOCKET_VALUE_CPP_TYPE_MAKE(blender::ColorGeometry4f);
SOCKET_VALUE_CPP_TYPE_MAKE(blender::ColorGeometry4b);
SOCKET_VALUE_CPP_TYPE_MAKE(blender::math::Quaternion);
SOCKET_VALUE_CPP_TYPE_MAKE(bool);
SOCKET_VALUE_CPP_TYPE_MAKE(int8_t);
SOCKET_VALUE_CPP_TYPE_MAKE(int32_t);
SOCKET_VALUE_CPP_TYPE_MAKE(blender::int2);
SOCKET_VALUE_CPP_TYPE_MAKE(std::string);
BLI_VECTOR_CPP_TYPE_MAKE(blender::bke::ValueOrField<std::string>);
void FN_register_cpp_types()
{
SOCKET_VALUE_CPP_TYPE_REGISTER(float);
SOCKET_VALUE_CPP_TYPE_REGISTER(blender::float2);
SOCKET_VALUE_CPP_TYPE_REGISTER(blender::float3);
SOCKET_VALUE_CPP_TYPE_REGISTER(blender::ColorGeometry4f);
SOCKET_VALUE_CPP_TYPE_REGISTER(blender::ColorGeometry4b);
SOCKET_VALUE_CPP_TYPE_REGISTER(blender::math::Quaternion);
SOCKET_VALUE_CPP_TYPE_REGISTER(bool);
SOCKET_VALUE_CPP_TYPE_REGISTER(int8_t);
SOCKET_VALUE_CPP_TYPE_REGISTER(int32_t);
SOCKET_VALUE_CPP_TYPE_REGISTER(blender::int2);
SOCKET_VALUE_CPP_TYPE_REGISTER(std::string);
BLI_VECTOR_CPP_TYPE_REGISTER(blender::bke::ValueOrField<std::string>);
}

View File

@@ -2,9 +2,13 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "FN_field_cpp_type.hh"
/** \file
* \ingroup bke
*/
namespace blender::fn {
#include "BKE_node_socket_value_cpp_type.hh"
namespace blender::bke {
static auto &get_from_self_map()
{
@@ -38,4 +42,4 @@ const ValueOrFieldCPPType *ValueOrFieldCPPType::get_from_value(const CPPType &va
return type;
}
} // namespace blender::fn
} // namespace blender::bke

View File

@@ -88,7 +88,6 @@
#include "NOD_socket_declarations_geometry.hh"
#include "FN_field.hh"
#include "FN_field_cpp_type.hh"
#include "GEO_fillet_curves.hh"

View File

@@ -19,6 +19,7 @@
#include "BKE_mesh.hh"
#include "BKE_mesh_wrapper.hh"
#include "BKE_modifier.hh"
#include "BKE_node_socket_value_cpp_type.hh"
#include "BKE_object_types.hh"
#include "BKE_volume.hh"
#include "BKE_volume_openvdb.hh"
@@ -43,8 +44,6 @@
#include "RNA_access.hh"
#include "RNA_enum_types.hh"
#include "FN_field_cpp_type.hh"
#include "bmesh.h"
#include "spreadsheet_data_source_geometry.hh"

View File

@@ -10,9 +10,7 @@ set(INC_SYS
)
set(SRC
intern/cpp_types.cc
intern/field.cc
intern/field_cpp_type.cc
intern/lazy_function.cc
intern/lazy_function_execute.cc
intern/lazy_function_graph.cc
@@ -26,8 +24,6 @@ set(SRC
intern/multi_function_procedure_optimization.cc
FN_field.hh
FN_field_cpp_type.hh
FN_field_cpp_type_make.hh
FN_init.h
FN_lazy_function.hh
FN_lazy_function_execute.hh

View File

@@ -544,59 +544,6 @@ class IndexFieldInput final : public FieldInput {
/** \} */
/* -------------------------------------------------------------------- */
/** \name Value or Field Class
*
* Utility class that wraps a single value and a field, to simplify accessing both of the types.
* \{ */
template<typename T> struct ValueOrField {
/** Value that is used when the field is empty. */
T value{};
Field<T> field;
ValueOrField() = default;
ValueOrField(T value) : value(std::move(value)) {}
ValueOrField(Field<T> field) : field(std::move(field)) {}
bool is_field() const
{
return bool(this->field);
}
Field<T> as_field() const
{
if (this->field) {
return this->field;
}
return make_constant_field(this->value);
}
T as_value() const
{
if (this->field) {
/* This returns a default value when the field is not constant. */
return evaluate_constant_field(this->field);
}
return this->value;
}
friend std::ostream &operator<<(std::ostream &stream, const ValueOrField<T> &value_or_field)
{
if (value_or_field.field) {
stream << "ValueOrField<T>";
}
else {
stream << value_or_field.value;
}
return stream;
}
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name #FieldNode Inline Methods
* \{ */

View File

@@ -1,95 +0,0 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
/** \file
* \ingroup fn
*/
#include "FN_field.hh"
namespace blender::fn {
/**
* Contains information about how to deal with a `ValueOrField<T>` generically.
*/
class ValueOrFieldCPPType {
private:
void (*construct_from_value_)(void *dst, const void *value);
void (*construct_from_field_)(void *dst, GField field);
const GField *(*get_field_ptr_)(const void *value_or_field);
bool (*is_field_)(const void *value_or_field);
GField (*as_field_)(const void *value_or_field);
public:
/** The #ValueOrField<T> itself. */
const CPPType &self;
/** The type stored in the field. */
const CPPType &value;
template<typename ValueType> ValueOrFieldCPPType(TypeTag<ValueType> /*value_type*/);
void construct_from_value(void *dst, const void *value) const
{
construct_from_value_(dst, value);
}
void construct_from_field(void *dst, GField field) const
{
construct_from_field_(dst, field);
}
const void *get_value_ptr(const void *value_or_field) const
{
static_assert(offsetof(ValueOrField<int>, value) == 0);
return value_or_field;
}
void *get_value_ptr(void *value_or_field) const
{
static_assert(offsetof(ValueOrField<int>, value) == 0);
return value_or_field;
}
const GField *get_field_ptr(const void *value_or_field) const
{
return get_field_ptr_(value_or_field);
}
bool is_field(const void *value_or_field) const
{
return is_field_(value_or_field);
}
GField as_field(const void *value_or_field) const
{
return as_field_(value_or_field);
}
/**
* Try to find the #ValueOrFieldCPPType that corresponds to a #CPPType.
*/
static const ValueOrFieldCPPType *get_from_self(const CPPType &self);
/**
* Try to find the #ValueOrFieldCPPType that wraps a #ValueOrField containing the given value
* type. This only works when the type has been created with #FN_FIELD_CPP_TYPE_MAKE.
*/
static const ValueOrFieldCPPType *get_from_value(const CPPType &value);
template<typename ValueType> static const ValueOrFieldCPPType &get()
{
static const ValueOrFieldCPPType &type =
ValueOrFieldCPPType::get_impl<std::decay_t<ValueType>>();
return type;
}
private:
template<typename ValueType> static const ValueOrFieldCPPType &get_impl();
void register_self();
};
} // namespace blender::fn

View File

@@ -1,50 +0,0 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "FN_field_cpp_type.hh"
namespace blender::fn {
template<typename ValueType>
inline ValueOrFieldCPPType::ValueOrFieldCPPType(TypeTag<ValueType> /*value_type*/)
: self(CPPType::get<ValueOrField<ValueType>>()), value(CPPType::get<ValueType>())
{
using T = ValueType;
construct_from_value_ = [](void *dst, const void *value_or_field) {
new (dst) ValueOrField<T>(*(const T *)value_or_field);
};
construct_from_field_ = [](void *dst, GField field) {
new (dst) ValueOrField<T>(Field<T>(std::move(field)));
};
get_field_ptr_ = [](const void *value_or_field) -> const GField * {
return &((ValueOrField<T> *)value_or_field)->field;
};
is_field_ = [](const void *value_or_field) {
return ((ValueOrField<T> *)value_or_field)->is_field();
};
as_field_ = [](const void *value_or_field) -> GField {
return ((ValueOrField<T> *)value_or_field)->as_field();
};
this->register_self();
}
} // namespace blender::fn
/**
* Create a new #ValueOrFieldCPPType that can be accessed through `ValueOrFieldCPPType::get<T>()`.
*/
#define FN_FIELD_CPP_TYPE_MAKE(VALUE_TYPE) \
BLI_CPP_TYPE_MAKE(blender::fn::ValueOrField<VALUE_TYPE>, CPPTypeFlags::Printable) \
template<> \
const blender::fn::ValueOrFieldCPPType & \
blender::fn::ValueOrFieldCPPType::get_impl<VALUE_TYPE>() \
{ \
static blender::fn::ValueOrFieldCPPType type{blender::TypeTag<VALUE_TYPE>{}}; \
return type; \
}
/** Register a #ValueOrFieldCPPType created with #FN_FIELD_CPP_TYPE_MAKE. */
#define FN_FIELD_CPP_TYPE_REGISTER(VALUE_TYPE) blender::fn::ValueOrFieldCPPType::get<VALUE_TYPE>()

View File

@@ -1,44 +0,0 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_color.hh"
#include "BLI_cpp_type_make.hh"
#include "BLI_cpp_types_make.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_math_quaternion_types.hh"
#include "BLI_math_vector_types.hh"
#include "FN_field_cpp_type_make.hh"
#include "FN_init.h"
FN_FIELD_CPP_TYPE_MAKE(float);
FN_FIELD_CPP_TYPE_MAKE(blender::float2);
FN_FIELD_CPP_TYPE_MAKE(blender::float3);
FN_FIELD_CPP_TYPE_MAKE(blender::ColorGeometry4f);
FN_FIELD_CPP_TYPE_MAKE(blender::ColorGeometry4b);
FN_FIELD_CPP_TYPE_MAKE(blender::math::Quaternion);
FN_FIELD_CPP_TYPE_MAKE(bool);
FN_FIELD_CPP_TYPE_MAKE(int8_t);
FN_FIELD_CPP_TYPE_MAKE(int32_t);
FN_FIELD_CPP_TYPE_MAKE(blender::int2);
FN_FIELD_CPP_TYPE_MAKE(std::string);
BLI_VECTOR_CPP_TYPE_MAKE(blender::fn::ValueOrField<std::string>);
void FN_register_cpp_types()
{
FN_FIELD_CPP_TYPE_REGISTER(float);
FN_FIELD_CPP_TYPE_REGISTER(blender::float2);
FN_FIELD_CPP_TYPE_REGISTER(blender::float3);
FN_FIELD_CPP_TYPE_REGISTER(blender::ColorGeometry4f);
FN_FIELD_CPP_TYPE_REGISTER(blender::ColorGeometry4b);
FN_FIELD_CPP_TYPE_REGISTER(blender::math::Quaternion);
FN_FIELD_CPP_TYPE_REGISTER(bool);
FN_FIELD_CPP_TYPE_REGISTER(int8_t);
FN_FIELD_CPP_TYPE_REGISTER(int32_t);
FN_FIELD_CPP_TYPE_REGISTER(blender::int2);
FN_FIELD_CPP_TYPE_REGISTER(std::string);
BLI_VECTOR_CPP_TYPE_REGISTER(blender::fn::ValueOrField<std::string>);
}

View File

@@ -90,7 +90,6 @@
#include "NOD_node_declaration.hh"
#include "FN_field.hh"
#include "FN_field_cpp_type.hh"
#include "FN_lazy_function_execute.hh"
#include "FN_lazy_function_graph_executor.hh"
#include "FN_multi_function.hh"

View File

@@ -8,13 +8,13 @@
#include "BLI_math_quaternion_types.hh"
#include "FN_field.hh"
#include "FN_field_cpp_type.hh"
#include "FN_lazy_function.hh"
#include "FN_multi_function_builder.hh"
#include "BKE_attribute_math.hh"
#include "BKE_geometry_fields.hh"
#include "BKE_geometry_set.hh"
#include "BKE_node_socket_value_cpp_type.hh"
#include "DNA_node_types.h"
@@ -47,6 +47,7 @@ using bke::MeshComponent;
using bke::MutableAttributeAccessor;
using bke::PointCloudComponent;
using bke::SpanAttributeWriter;
using bke::ValueOrField;
using bke::VolumeComponent;
using fn::Field;
using fn::FieldContext;
@@ -54,7 +55,6 @@ using fn::FieldEvaluator;
using fn::FieldInput;
using fn::FieldOperation;
using fn::GField;
using fn::ValueOrField;
using geo_eval_log::NamedAttributeUsage;
using geo_eval_log::NodeWarningType;
@@ -109,8 +109,8 @@ class GeoNodeExecParams {
const int index = this->get_input_index(identifier);
const bNodeSocket &input_socket = node_.input_by_identifier(identifier);
const CPPType &value_type = *input_socket.typeinfo->geometry_nodes_cpp_type;
const fn::ValueOrFieldCPPType &value_or_field_type = *fn::ValueOrFieldCPPType::get_from_self(
value_type);
const bke::ValueOrFieldCPPType &value_or_field_type =
*bke::ValueOrFieldCPPType::get_from_self(value_type);
return value_or_field_type.as_field(params_.try_get_input_data_ptr(index));
}
else {

View File

@@ -7,6 +7,7 @@
#include "MEM_guardedalloc.h"
#include "BKE_node.hh"
#include "BKE_node_socket_value.hh"
#include "NOD_geometry_exec.hh"
#include "NOD_register.hh"

View File

@@ -102,7 +102,7 @@ class LazyFunctionForSimulationInputNode final : public LazyFunction {
BLI_assert_unreachable();
}
if (!params.output_was_set(0)) {
params.set_output(0, fn::ValueOrField<float>(delta_time));
params.set_output(0, bke::ValueOrField<float>(delta_time));
}
}

View File

@@ -15,6 +15,7 @@
#include "BKE_curves.hh"
#include "BKE_instances.hh"
#include "BKE_modifier.hh"
#include "BKE_node_socket_value_cpp_type.hh"
#include "BKE_object.hh"
#include "BKE_scene.h"
@@ -27,8 +28,6 @@
#include "NOD_socket.hh"
#include "NOD_zone_socket_items.hh"
#include "FN_field_cpp_type.hh"
#include "DNA_curves_types.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
@@ -407,8 +406,8 @@ static void mix_simulation_state(const NodeSimulationItem &item,
case SOCK_ROTATION:
case SOCK_RGBA: {
const CPPType &type = get_simulation_item_cpp_type(item);
const fn::ValueOrFieldCPPType &value_or_field_type = *fn::ValueOrFieldCPPType::get_from_self(
type);
const bke::ValueOrFieldCPPType &value_or_field_type =
*bke::ValueOrFieldCPPType::get_from_self(type);
if (value_or_field_type.is_field(prev) || value_or_field_type.is_field(next)) {
/* Fields are evaluated on geometries and are mixed there. */
break;

View File

@@ -15,8 +15,8 @@ static void node_declare(NodeDeclarationBuilder &b)
static void node_geo_exec(GeoNodeExecParams params)
{
Vector<fn::ValueOrField<std::string>> strings =
params.extract_input<Vector<fn::ValueOrField<std::string>>>("Strings");
Vector<bke::ValueOrField<std::string>> strings =
params.extract_input<Vector<bke::ValueOrField<std::string>>>("Strings");
const std::string delim = params.extract_input<std::string>("Delimiter");
std::string output;

View File

@@ -12,8 +12,6 @@
#include "RNA_enum_types.hh"
#include "FN_field_cpp_type.hh"
namespace blender::nodes::node_geo_switch_cc {
NODE_STORAGE_FUNCS(NodeSwitch)
@@ -230,7 +228,7 @@ class LazyFunctionForSwitchNode : public LazyFunction {
}
const CPPType &type = *outputs_[0].type;
const fn::ValueOrFieldCPPType &value_or_field_type = *fn::ValueOrFieldCPPType::get_from_self(
const bke::ValueOrFieldCPPType &value_or_field_type = *bke::ValueOrFieldCPPType::get_from_self(
type);
const CPPType &value_type = value_or_field_type.value;
const MultiFunction &switch_multi_function = this->get_switch_multi_function(value_type);

View File

@@ -22,9 +22,9 @@
#include "BKE_geometry_set.hh"
#include "BKE_idprop.hh"
#include "BKE_node_runtime.hh"
#include "BKE_node_socket_value_cpp_type.hh"
#include "BKE_type_conversions.hh"
#include "FN_field_cpp_type.hh"
#include "FN_lazy_function_execute.hh"
namespace lf = blender::fn::lazy_function;
@@ -339,12 +339,12 @@ static void init_socket_cpp_value_from_property(const IDProperty &property,
else if (property.type == IDP_DOUBLE) {
value = float(IDP_Double(&property));
}
new (r_value) fn::ValueOrField<float>(value);
new (r_value) bke::ValueOrField<float>(value);
break;
}
case SOCK_INT: {
int value = IDP_Int(&property);
new (r_value) fn::ValueOrField<int>(value);
new (r_value) bke::ValueOrField<int>(value);
break;
}
case SOCK_VECTOR: {
@@ -360,7 +360,7 @@ static void init_socket_cpp_value_from_property(const IDProperty &property,
BLI_assert(property.subtype == IDP_DOUBLE);
value = float3(double3(static_cast<const double *>(property_array)));
}
new (r_value) fn::ValueOrField<float3>(value);
new (r_value) bke::ValueOrField<float3>(value);
break;
}
case SOCK_RGBA: {
@@ -377,12 +377,12 @@ static void init_socket_cpp_value_from_property(const IDProperty &property,
vec = float4(double4(static_cast<const double *>(property_array)));
}
ColorGeometry4f value(vec);
new (r_value) fn::ValueOrField<ColorGeometry4f>(value);
new (r_value) bke::ValueOrField<ColorGeometry4f>(value);
break;
}
case SOCK_BOOLEAN: {
const bool value = IDP_Bool(&property);
new (r_value) fn::ValueOrField<bool>(value);
new (r_value) bke::ValueOrField<bool>(value);
break;
}
case SOCK_ROTATION: {
@@ -399,12 +399,12 @@ static void init_socket_cpp_value_from_property(const IDProperty &property,
vec = float3(double3(static_cast<const double *>(property_array)));
}
const math::EulerXYZ euler_value = math::EulerXYZ(vec);
new (r_value) fn::ValueOrField<math::Quaternion>(math::to_quaternion(euler_value));
new (r_value) bke::ValueOrField<math::Quaternion>(math::to_quaternion(euler_value));
break;
}
case SOCK_STRING: {
std::string value = IDP_String(&property);
new (r_value) fn::ValueOrField<std::string>(std::move(value));
new (r_value) bke::ValueOrField<std::string>(std::move(value));
break;
}
case SOCK_OBJECT: {
@@ -501,7 +501,7 @@ static void initialize_group_input(const bNodeTree &tree,
if (attribute_name && bke::allow_procedural_attribute_access(*attribute_name)) {
fn::GField attribute_field = bke::AttributeFieldInput::Create(*attribute_name,
*typeinfo->base_cpp_type);
const auto *value_or_field_cpp_type = fn::ValueOrFieldCPPType::get_from_self(
const auto *value_or_field_cpp_type = bke::ValueOrFieldCPPType::get_from_self(
*typeinfo->geometry_nodes_cpp_type);
BLI_assert(value_or_field_cpp_type != nullptr);
value_or_field_cpp_type->construct_from_field(r_value, std::move(attribute_field));
@@ -512,7 +512,7 @@ static void initialize_group_input(const bNodeTree &tree,
StringRef layer_name = IDP_String(property_layer_name);
const fn::GField selection_field(
std::make_shared<bke::NamedLayerSelectionFieldInput>(layer_name), 0);
const auto *value_or_field_cpp_type = fn::ValueOrFieldCPPType::get_from_self(
const auto *value_or_field_cpp_type = bke::ValueOrFieldCPPType::get_from_self(
*typeinfo->geometry_nodes_cpp_type);
BLI_assert(value_or_field_cpp_type != nullptr);
value_or_field_cpp_type->construct_from_field(r_value, std::move(selection_field));
@@ -563,7 +563,7 @@ static MultiValueMap<eAttrDomain, OutputAttributeInfo> find_output_attributes_to
const int index = socket->index();
const GPointer value = output_values[index];
const auto *value_or_field_type = fn::ValueOrFieldCPPType::get_from_self(*value.type());
const auto *value_or_field_type = bke::ValueOrFieldCPPType::get_from_self(*value.type());
BLI_assert(value_or_field_type != nullptr);
const fn::GField field = value_or_field_type->as_field(value.get());

View File

@@ -39,11 +39,11 @@
#include "BKE_compute_contexts.hh"
#include "BKE_geometry_set.hh"
#include "BKE_node_socket_value_cpp_type.hh"
#include "BKE_node_tree_anonymous_attributes.hh"
#include "BKE_node_tree_zones.hh"
#include "BKE_type_conversions.hh"
#include "FN_field_cpp_type.hh"
#include "FN_lazy_function_execute.hh"
#include "FN_lazy_function_graph_executor.hh"
@@ -57,8 +57,8 @@ namespace blender::nodes {
namespace aai = bke::anonymous_attribute_inferencing;
using bke::bNodeTreeZone;
using bke::bNodeTreeZones;
using fn::ValueOrField;
using fn::ValueOrFieldCPPType;
using bke::ValueOrField;
using bke::ValueOrFieldCPPType;
static const CPPType *get_socket_cpp_type(const bNodeSocketType &typeinfo)
{

View File

@@ -8,10 +8,9 @@
#include "BKE_compute_contexts.hh"
#include "BKE_curves.hh"
#include "BKE_node_runtime.hh"
#include "BKE_node_socket_value_cpp_type.hh"
#include "BKE_viewer_path.hh"
#include "FN_field_cpp_type.hh"
#include "DNA_modifier_types.h"
#include "DNA_space_types.h"
@@ -181,7 +180,7 @@ void GeoTreeLogger::log_value(const bNode &node, const bNodeSocket &socket, cons
const bke::GeometrySet &geometry = *value.get<bke::GeometrySet>();
store_logged_value(this->allocator->construct<GeometryInfoLog>(geometry));
}
else if (const auto *value_or_field_type = fn::ValueOrFieldCPPType::get_from_self(type)) {
else if (const auto *value_or_field_type = bke::ValueOrFieldCPPType::get_from_self(type)) {
const void *value_or_field = value.get();
const CPPType &base_type = value_or_field_type->value;
if (value_or_field_type->is_field(value_or_field)) {

View File

@@ -12,6 +12,7 @@
#include "BKE_geometry_fields.hh"
#include "BKE_node.hh"
#include "BKE_node_runtime.hh"
#include "BKE_node_socket_value.hh"
namespace blender::nodes {
@@ -920,24 +921,24 @@ namespace implicit_field_inputs {
void position(const bNode & /*node*/, void *r_value)
{
new (r_value) fn::ValueOrField<float3>(bke::AttributeFieldInput::Create<float3>("position"));
new (r_value) bke::ValueOrField<float3>(bke::AttributeFieldInput::Create<float3>("position"));
}
void normal(const bNode & /*node*/, void *r_value)
{
new (r_value)
fn::ValueOrField<float3>(fn::Field<float3>(std::make_shared<bke::NormalFieldInput>()));
bke::ValueOrField<float3>(fn::Field<float3>(std::make_shared<bke::NormalFieldInput>()));
}
void index(const bNode & /*node*/, void *r_value)
{
new (r_value) fn::ValueOrField<int>(fn::Field<int>(std::make_shared<fn::IndexFieldInput>()));
new (r_value) bke::ValueOrField<int>(fn::Field<int>(std::make_shared<fn::IndexFieldInput>()));
}
void id_or_index(const bNode & /*node*/, void *r_value)
{
new (r_value)
fn::ValueOrField<int>(fn::Field<int>(std::make_shared<bke::IDAttributeFieldInput>()));
bke::ValueOrField<int>(fn::Field<int>(std::make_shared<bke::IDAttributeFieldInput>()));
}
} // namespace implicit_field_inputs

View File

@@ -23,6 +23,7 @@
#include "BKE_lib_id.h"
#include "BKE_node.hh"
#include "BKE_node_runtime.hh"
#include "BKE_node_socket_value.hh"
#include "BKE_node_tree_update.hh"
#include "DNA_collection_types.h"
@@ -37,10 +38,8 @@
#include "NOD_socket.hh"
#include "NOD_socket_declarations.hh"
#include "FN_field.hh"
using namespace blender;
using blender::fn::ValueOrField;
using blender::bke::ValueOrField;
using blender::nodes::SocketDeclarationPtr;
bNodeSocket *node_add_socket_from_template(bNodeTree *ntree,