Refactor: Geometry Nodes: use SocketValueVariant instead of raw pointers

Refactor to get us closer to being able to remove `bNodeSocketType::geometry_nodes_cpp_type`
which is always `SocketValueVariant` now.

Pull Request: https://projects.blender.org/blender/blender/pulls/144419
This commit is contained in:
Jacques Lucke
2025-08-12 16:03:09 +02:00
parent 4204609770
commit 951d2d2b3a
12 changed files with 50 additions and 99 deletions

View File

@@ -218,6 +218,7 @@ template<typename T> inline SocketValueVariant SocketValueVariant::From(T &&valu
template<typename T> inline void SocketValueVariant::set(T &&value)
{
static_assert(!is_same_any_v<std::decay_t<T>, SocketValueVariant, bke::SocketValueVariant *>);
this->store_impl<std::decay_t<T>>(std::forward<T>(value));
}

View File

@@ -288,7 +288,7 @@ Array<std::unique_ptr<BakeItem>> move_socket_values_to_bake_items(
if (!stype) {
return std::nullopt;
}
if (!stype->geometry_nodes_cpp_type) {
if (!stype->geometry_nodes_default_value) {
return std::nullopt;
}
if (std::optional<SocketValueVariant> child_value_variant =

View File

@@ -15,9 +15,8 @@
namespace blender::nodes {
struct BundleItemSocketValue {
/** The type of data referenced. It uses #bNodeSocketType::geometry_nodes_cpp_type. */
/** The type of referenced data. */
const bke::bNodeSocketType *type;
/** Non-owning pointer to the value. The memory is owned by the Bundle directly. */
bke::SocketValueVariant value;
};

View File

@@ -4,6 +4,8 @@
#pragma once
#include "BKE_node_socket_value.hh"
#include "NOD_geometry_nodes_closure_fwd.hh"
#include "NOD_geometry_nodes_closure_location.hh"
#include "NOD_geometry_nodes_closure_signature.hh"
@@ -60,14 +62,14 @@ class Closure : public ImplicitSharingMixin {
std::unique_ptr<ResourceScope> scope_;
const fn::lazy_function::LazyFunction &function_;
ClosureFunctionIndices indices_;
Vector<const void *> default_input_values_;
Vector<bke::SocketValueVariant> default_input_values_;
public:
Closure(std::shared_ptr<ClosureSignature> signature,
std::unique_ptr<ResourceScope> scope,
const fn::lazy_function::LazyFunction &function,
ClosureFunctionIndices indices,
Vector<const void *> default_input_values,
Vector<bke::SocketValueVariant> default_input_values,
std::optional<ClosureSourceLocation> source_location,
std::shared_ptr<ClosureEvalLog> eval_log)
: signature_(signature),
@@ -105,7 +107,7 @@ class Closure : public ImplicitSharingMixin {
return eval_log_;
}
const void *default_input_value(const int index) const
const bke::SocketValueVariant &default_input_value(const int index) const
{
return default_input_values_[index];
}

View File

@@ -127,14 +127,6 @@ static bool node_insert_link(bke::NodeInsertLinkParams &params)
params.ntree, params.node, params.node, params.link);
}
static const CPPType &get_item_cpp_type(const eNodeSocketDatatype socket_type)
{
const bke::bNodeSocketType *typeinfo = bke::node_socket_type_find_static(socket_type);
BLI_assert(typeinfo);
BLI_assert(typeinfo->geometry_nodes_cpp_type);
return *typeinfo->geometry_nodes_cpp_type;
}
static void draw_bake_items(const bContext *C, uiLayout *layout, PointerRNA node_ptr)
{
bNodeTree &tree = *reinterpret_cast<bNodeTree *>(node_ptr.owner_id);
@@ -229,11 +221,10 @@ class LazyFunctionForBakeNode final : public LazyFunction {
const NodeGeometryBakeItem &item = bake_items_[i];
const bNodeSocket &input_bsocket = node.input_socket(i);
const bNodeSocket &output_bsocket = node.output_socket(i);
const CPPType &type = get_item_cpp_type(eNodeSocketDatatype(item.socket_type));
lf_index_by_bsocket[input_bsocket.index_in_tree()] = inputs_.append_and_get_index_as(
item.name, type, lf::ValueUsage::Maybe);
item.name, CPPType::get<SocketValueVariant>(), lf::ValueUsage::Maybe);
lf_index_by_bsocket[output_bsocket.index_in_tree()] = outputs_.append_and_get_index_as(
item.name, type);
item.name, CPPType::get<SocketValueVariant>());
}
bake_socket_config_ = make_bake_socket_config(bake_items_);

View File

@@ -115,7 +115,7 @@ static void node_geo_exec(GeoNodeExecParams params)
for (const int i : IndexRange(storage.items_num)) {
const NodeCombineBundleItem &item = storage.items[i];
const bke::bNodeSocketType *stype = bke::node_socket_type_find_static(item.socket_type);
if (!stype || !stype->geometry_nodes_cpp_type) {
if (!stype || !stype->geometry_nodes_default_value) {
continue;
}
const StringRef name = item.name;

View File

@@ -229,7 +229,7 @@ class LazyFunctionForIndexSwitchNode : public LazyFunction {
const eNodeSocketDatatype data_type = eNodeSocketDatatype(storage.data_type);
const bNodeSocket &index_socket = node.input_socket(0);
const bNodeSocket &output_socket = node.output_socket(0);
const CPPType &cpp_type = *output_socket.typeinfo->geometry_nodes_cpp_type;
const CPPType &cpp_type = CPPType::get<SocketValueVariant>();
debug_name_ = node.name;
can_be_field_ = socket_type_supports_fields(data_type);

View File

@@ -226,7 +226,6 @@ class LazyFunctionForMenuSwitchNode : public LazyFunction {
const bNode &node_;
bool can_be_field_ = false;
const NodeEnumDefinition &enum_def_;
const CPPType *cpp_type_;
const CPPType *field_base_type_;
public:
@@ -239,7 +238,6 @@ class LazyFunctionForMenuSwitchNode : public LazyFunction {
can_be_field_ = socket_type_supports_fields(data_type);
const bke::bNodeSocketType *socket_type = bke::node_socket_type_find_static(data_type);
BLI_assert(socket_type != nullptr);
cpp_type_ = socket_type->geometry_nodes_cpp_type;
field_base_type_ = socket_type->base_cpp_type;
MutableSpan<int> lf_index_by_bsocket = lf_graph_info.mapping.lf_index_by_bsocket;
@@ -249,10 +247,11 @@ class LazyFunctionForMenuSwitchNode : public LazyFunction {
for (const int i : enum_def_.items().index_range()) {
const NodeEnumItem &enum_item = enum_def_.items()[i];
lf_index_by_bsocket[node.input_socket(i + 1).index_in_tree()] =
inputs_.append_and_get_index_as(enum_item.name, *cpp_type_, lf::ValueUsage::Maybe);
inputs_.append_and_get_index_as(
enum_item.name, CPPType::get<bke::SocketValueVariant>(), lf::ValueUsage::Maybe);
}
lf_index_by_bsocket[node.output_socket(0).index_in_tree()] = outputs_.append_and_get_index_as(
"Value", *cpp_type_);
"Value", CPPType::get<bke::SocketValueVariant>());
}
void execute_impl(lf::Params &params, const lf::Context & /*context*/) const override
@@ -272,15 +271,14 @@ class LazyFunctionForMenuSwitchNode : public LazyFunction {
const NodeEnumItem &enum_item = enum_def_.items_array[i];
const int input_index = i + 1;
if (enum_item.identifier == condition) {
void *value_to_forward = params.try_get_input_data_ptr_or_request(input_index);
SocketValueVariant *value_to_forward =
params.try_get_input_data_ptr_or_request<SocketValueVariant>(input_index);
if (value_to_forward == nullptr) {
/* Try again when the value is available. */
return;
}
void *output_ptr = params.get_output_data_ptr(0);
cpp_type_->move_construct(value_to_forward, output_ptr);
params.output_set(0);
params.set_output(0, std::move(*value_to_forward));
}
else {
params.set_input_unused(input_index);

View File

@@ -127,7 +127,7 @@ static void node_geo_exec(GeoNodeExecParams params)
continue;
}
const bke::bNodeSocketType *stype = bke::node_socket_type_find_static(item.socket_type);
if (!stype || !stype->geometry_nodes_cpp_type) {
if (!stype || !stype->geometry_nodes_default_value) {
continue;
}
const BundleItemValue *value = bundle->lookup(name);

View File

@@ -49,19 +49,6 @@
namespace blender::nodes::node_geo_simulation_cc {
static const CPPType &get_simulation_item_cpp_type(const eNodeSocketDatatype socket_type)
{
const bke::bNodeSocketType *typeinfo = bke::node_socket_type_find_static(socket_type);
BLI_assert(typeinfo);
BLI_assert(typeinfo->geometry_nodes_cpp_type);
return *typeinfo->geometry_nodes_cpp_type;
}
static const CPPType &get_simulation_item_cpp_type(const NodeSimulationItem &item)
{
return get_simulation_item_cpp_type(eNodeSocketDatatype(item.socket_type));
}
static bke::bake::BakeSocketConfig make_bake_socket_config(
const Span<NodeSimulationItem> node_simulation_items)
{
@@ -269,12 +256,10 @@ class LazyFunctionForSimulationInputNode final : public LazyFunction {
const bNodeSocket &input_bsocket = node.input_socket(i);
const bNodeSocket &output_bsocket = node.output_socket(i + 1);
const CPPType &type = get_simulation_item_cpp_type(item);
lf_index_by_bsocket[input_bsocket.index_in_tree()] = inputs_.append_and_get_index_as(
item.name, type, lf::ValueUsage::Maybe);
item.name, CPPType::get<SocketValueVariant>(), lf::ValueUsage::Maybe);
lf_index_by_bsocket[output_bsocket.index_in_tree()] = outputs_.append_and_get_index_as(
item.name, type);
item.name, CPPType::get<SocketValueVariant>());
}
}
@@ -521,7 +506,7 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction {
const bNodeSocket &skip_bsocket = node.input_socket(0);
skip_input_index_ = inputs_.append_and_get_index_as(
"Skip", *skip_bsocket.typeinfo->geometry_nodes_cpp_type, lf::ValueUsage::Maybe);
"Skip", CPPType::get<SocketValueVariant>(), lf::ValueUsage::Maybe);
lf_index_by_bsocket[skip_bsocket.index_in_tree()] = skip_input_index_;
skip_inputs_offset_ = inputs_.size();
@@ -529,8 +514,7 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction {
/* Add the skip inputs that are linked to the simulation input node. */
for (const int i : simulation_items_.index_range()) {
const NodeSimulationItem &item = simulation_items_[i];
const CPPType &type = get_simulation_item_cpp_type(item);
inputs_.append_as(item.name, type, lf::ValueUsage::Maybe);
inputs_.append_as(item.name, CPPType::get<SocketValueVariant>(), lf::ValueUsage::Maybe);
}
solve_inputs_offset_ = inputs_.size();
@@ -541,12 +525,10 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction {
const bNodeSocket &input_bsocket = node.input_socket(i + 1);
const bNodeSocket &output_bsocket = node.output_socket(i);
const CPPType &type = get_simulation_item_cpp_type(item);
lf_index_by_bsocket[input_bsocket.index_in_tree()] = inputs_.append_and_get_index_as(
item.name, type, lf::ValueUsage::Maybe);
item.name, CPPType::get<SocketValueVariant>(), lf::ValueUsage::Maybe);
lf_index_by_bsocket[output_bsocket.index_in_tree()] = outputs_.append_and_get_index_as(
item.name, type);
item.name, CPPType::get<SocketValueVariant>());
}
}

View File

@@ -124,7 +124,7 @@ class LazyFunctionForSwitchNode : public LazyFunction {
}
}
BLI_assert(socket_type != nullptr);
const CPPType &cpp_type = *socket_type->geometry_nodes_cpp_type;
const CPPType &cpp_type = CPPType::get<SocketValueVariant>();
base_type_ = socket_type->base_cpp_type;
debug_name_ = node.name;

View File

@@ -149,14 +149,14 @@ class LazyFunctionForClosureZone : public LazyFunction {
lf::Graph &lf_graph = closure_scope->construct<lf::Graph>("Closure Graph");
lf::FunctionNode &lf_body_node = lf_graph.add_function(*body_fn_.function);
ClosureFunctionIndices closure_indices;
Vector<const void *> default_input_values;
Vector<bke::SocketValueVariant> default_input_values;
for (const int i : IndexRange(storage.input_items.items_num)) {
const NodeClosureInputItem &item = storage.input_items.items[i];
const bNodeSocket &bsocket = zone_.input_node()->output_socket(i);
const CPPType &cpp_type = *bsocket.typeinfo->geometry_nodes_cpp_type;
lf::GraphInputSocket &lf_graph_input = lf_graph.add_input(cpp_type, item.name);
lf::GraphInputSocket &lf_graph_input = lf_graph.add_input(
CPPType::get<bke::SocketValueVariant>(), item.name);
lf_graph.add_link(lf_graph_input, lf_body_node.input(body_fn_.indices.inputs.main[i]));
lf::GraphOutputSocket &lf_graph_input_usage = lf_graph.add_output(
@@ -164,9 +164,7 @@ class LazyFunctionForClosureZone : public LazyFunction {
lf_graph.add_link(lf_body_node.output(body_fn_.indices.outputs.input_usages[i]),
lf_graph_input_usage);
void *default_value = closure_scope->allocate_owned(cpp_type);
construct_socket_default_value(*bsocket.typeinfo, default_value);
default_input_values.append(default_value);
default_input_values.append(*bsocket.typeinfo->geometry_nodes_default_value);
}
closure_indices.inputs.main = lf_graph.graph_inputs().index_range().take_back(
storage.input_items.items_num);
@@ -175,10 +173,9 @@ class LazyFunctionForClosureZone : public LazyFunction {
for (const int i : IndexRange(storage.output_items.items_num)) {
const NodeClosureOutputItem &item = storage.output_items.items[i];
const bNodeSocket &bsocket = zone_.output_node()->input_socket(i);
const CPPType &cpp_type = *bsocket.typeinfo->geometry_nodes_cpp_type;
lf::GraphOutputSocket &lf_graph_output = lf_graph.add_output(cpp_type, item.name);
lf::GraphOutputSocket &lf_graph_output = lf_graph.add_output(
CPPType::get<bke::SocketValueVariant>(), item.name);
lf_graph.add_link(lf_body_node.output(body_fn_.indices.outputs.main[i]), lf_graph_output);
lf::GraphInputSocket &lf_graph_output_usage = lf_graph.add_input(
@@ -192,11 +189,11 @@ class LazyFunctionForClosureZone : public LazyFunction {
storage.output_items.items_num);
for (const int i : zone_.border_links.index_range()) {
const CPPType &cpp_type = *zone_.border_links[i]->tosock->typeinfo->geometry_nodes_cpp_type;
void *input_ptr = params.try_get_input_data_ptr(zone_info_.indices.inputs.border_links[i]);
void *stored_ptr = closure_scope->allocate_owned(cpp_type);
cpp_type.move_construct(input_ptr, stored_ptr);
lf_body_node.input(body_fn_.indices.inputs.border_links[i]).set_default_value(stored_ptr);
bke::SocketValueVariant *input_ptr = params.try_get_input_data_ptr<bke::SocketValueVariant>(
zone_info_.indices.inputs.border_links[i]);
bke::SocketValueVariant &stored_ptr = closure_scope->construct<bke::SocketValueVariant>(
std::move(*input_ptr));
lf_body_node.input(body_fn_.indices.inputs.border_links[i]).set_default_value(&stored_ptr);
}
for (const auto &item : body_fn_.indices.inputs.reference_sets.items()) {
@@ -287,7 +284,7 @@ class LazyFunctionForEvaluateClosureNode : public LazyFunction {
for (const int i : bnode.input_sockets().index_range().drop_back(1)) {
const bNodeSocket &bsocket = bnode.input_socket(i);
indices_.inputs.main.append(inputs_.append_and_get_index_as(
bsocket.name, *bsocket.typeinfo->geometry_nodes_cpp_type, lf::ValueUsage::Maybe));
bsocket.name, CPPType::get<bke::SocketValueVariant>(), lf::ValueUsage::Maybe));
indices_.outputs.input_usages.append(
outputs_.append_and_get_index_as("Usage", CPPType::get<bool>()));
}
@@ -295,8 +292,8 @@ class LazyFunctionForEvaluateClosureNode : public LazyFunction {
inputs_[indices_.inputs.main[0]].usage = lf::ValueUsage::Used;
for (const int i : bnode.output_sockets().index_range().drop_back(1)) {
const bNodeSocket &bsocket = bnode.output_socket(i);
indices_.outputs.main.append(outputs_.append_and_get_index_as(
bsocket.name, *bsocket.typeinfo->geometry_nodes_cpp_type));
indices_.outputs.main.append(
outputs_.append_and_get_index_as(bsocket.name, CPPType::get<bke::SocketValueVariant>()));
indices_.inputs.output_usages.append(
inputs_.append_and_get_index_as("Usage", CPPType::get<bool>(), lf::ValueUsage::Maybe));
if (bke::node_tree_reference_lifetimes::can_contain_referenced_data(
@@ -572,9 +569,7 @@ class LazyFunctionForEvaluateClosureNode : public LazyFunction {
else {
/* Use the default value if the provided input value is not compatible with what the
* closure expects. */
const void *default_value = closure.default_input_value(*mapped_i);
BLI_assert(default_value);
lf_to.set_default_value(default_value);
lf_to.set_default_value(&closure.default_input_value(*mapped_i));
lf_usage_output.set_default_value(&static_false);
continue;
}
@@ -588,12 +583,6 @@ class LazyFunctionForEvaluateClosureNode : public LazyFunction {
}
}
auto get_output_default_value = [&](const bke::bNodeSocketType &type) {
void *fallback_value = eval_storage.scope.allocate_owned(*type.geometry_nodes_cpp_type);
construct_socket_default_value(type, fallback_value);
return fallback_value;
};
for (const int output_item_i : IndexRange(node_storage.output_items.items_num)) {
lf::GraphOutputSocket &lf_main_output =
*lf_graph_outputs[indices_.outputs.main[output_item_i]];
@@ -615,8 +604,7 @@ class LazyFunctionForEvaluateClosureNode : public LazyFunction {
}
else {
/* The socket types are not compatible, so use the default value. */
void *fallback_value = get_output_default_value(main_output_type);
lf_main_output.set_default_value(fallback_value);
lf_main_output.set_default_value(main_output_type.geometry_nodes_default_value);
continue;
}
}
@@ -626,8 +614,7 @@ class LazyFunctionForEvaluateClosureNode : public LazyFunction {
lf_closure_node.input(closure_indices.inputs.output_usages[*mapped_i]));
}
else {
void *fallback_value = get_output_default_value(main_output_type);
lf_main_output.set_default_value(fallback_value);
lf_main_output.set_default_value(main_output_type.geometry_nodes_default_value);
}
}
@@ -637,8 +624,7 @@ class LazyFunctionForEvaluateClosureNode : public LazyFunction {
/* Handled already. */
continue;
}
const void *default_value = closure.default_input_value(i);
lf_closure_input.set_default_value(default_value);
lf_closure_input.set_default_value(&closure.default_input_value(i));
}
static const bke::GeometryNodesReferenceSet static_empty_reference_set;
@@ -732,10 +718,7 @@ class LazyFunctionForEvaluateClosureNode : public LazyFunction {
continue;
}
}
void *default_output_value = eval_storage.scope.allocate_owned(
*output_type.geometry_nodes_cpp_type);
construct_socket_default_value(output_type, default_output_value);
lf_main_output.set_default_value(default_output_value);
lf_main_output.set_default_value(output_type.geometry_nodes_default_value);
}
static constexpr bool static_false = false;
@@ -818,12 +801,9 @@ void evaluate_closure_eagerly(const Closure &closure, ClosureEagerEvalParams &pa
for (const int main_input_i : indices.inputs.main.index_range()) {
const int lf_input_i = indices.inputs.main[main_input_i];
if (!lf_input_values[lf_input_i]) {
const bke::bNodeSocketType &type = *signature.inputs[main_input_i].type;
const CPPType &cpp_type = *type.geometry_nodes_cpp_type;
const void *default_value = closure.default_input_value(main_input_i);
void *value = allocator.allocate(cpp_type);
cpp_type.copy_construct(default_value, value);
lf_input_values[lf_input_i] = {cpp_type, value};
bke::SocketValueVariant &value = scope.construct<bke::SocketValueVariant>(
closure.default_input_value(main_input_i));
lf_input_values[lf_input_i] = &value;
}
lf_output_values[indices.outputs.input_usages[main_input_i]] = allocator.allocate<bool>();
}
@@ -843,10 +823,8 @@ void evaluate_closure_eagerly(const Closure &closure, ClosureEagerEvalParams &pa
}
/** Set main outputs. */
for (const int main_output_i : indices.outputs.main.index_range()) {
const bke::bNodeSocketType &type = *signature.outputs[main_output_i].type;
const CPPType &cpp_type = *type.geometry_nodes_cpp_type;
lf_output_values[indices.outputs.main[main_output_i]] = {cpp_type,
allocator.allocate(cpp_type)};
lf_output_values[indices.outputs.main[main_output_i]] =
allocator.allocate<bke::SocketValueVariant>();
}
lf::BasicParams lf_params{