From 7c5f7434f2a276f0edb2b03b7b371a4e5b362b89 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 12 Aug 2025 07:59:18 +0200 Subject: [PATCH] Refactor: Geometry Nodes: use SocketValueVariant in bake api This simplifies the bake API used by Geometry Nodes by using `SocketValueVariant` instead of raw pointers. This is possible now, because all socket types use `SocketValueVariant` under the hood. Pull Request: https://projects.blender.org/blender/blender/pulls/144410 --- .../blenkernel/BKE_bake_items_socket.hh | 17 +- .../blenkernel/intern/bake_items_socket.cc | 197 ++++++++-------- .../nodes/geometry/node_geometry_util.hh | 4 +- .../nodes/geometry/nodes/node_geo_bake.cc | 110 ++++----- .../geometry/nodes/node_geo_simulation.cc | 215 +++++++----------- 5 files changed, 231 insertions(+), 312 deletions(-) diff --git a/source/blender/blenkernel/BKE_bake_items_socket.hh b/source/blender/blenkernel/BKE_bake_items_socket.hh index a6aecd8f661..73e8a6c0ff7 100644 --- a/source/blender/blenkernel/BKE_bake_items_socket.hh +++ b/source/blender/blenkernel/BKE_bake_items_socket.hh @@ -14,6 +14,7 @@ #include "BKE_bake_items.hh" #include "BKE_geometry_fields.hh" +#include "BKE_node_socket_value.hh" namespace blender::bke::bake { @@ -42,7 +43,9 @@ struct BakeSocketConfig { * be in a moved-from state afterwards. */ Array> move_socket_values_to_bake_items( - Span socket_values, const BakeSocketConfig &config, BakeDataBlockMap *data_block_map); + MutableSpan socket_values, + const BakeSocketConfig &config, + BakeDataBlockMap *data_block_map); /** * Create socket values from bake items. @@ -52,26 +55,22 @@ Array> move_socket_values_to_bake_items( * * \param make_attribute_field: A function that creates a field input for any anonymous attributes * being created for the baked data. - * \param r_socket_values: The caller is expected to allocate (but not construct) the output - * values. All socket values are constructed in this function. */ -void move_bake_items_to_socket_values( +Vector move_bake_items_to_socket_values( Span bake_items, const BakeSocketConfig &config, BakeDataBlockMap *data_block_map, FunctionRef(int socket_index, const CPPType &)> - make_attribute_field, - Span r_socket_values); + make_attribute_field); /** * Similar to #move_bake_items_to_socket_values, but does not change the bake items. Hence, this * should be used when the bake items are still used later on. */ -void copy_bake_items_to_socket_values( +Vector copy_bake_items_to_socket_values( Span bake_items, const BakeSocketConfig &config, BakeDataBlockMap *data_block_map, - FunctionRef(int, const CPPType &)> make_attribute_field, - Span r_socket_values); + FunctionRef(int, const CPPType &)> make_attribute_field); } // namespace blender::bke::bake diff --git a/source/blender/blenkernel/intern/bake_items_socket.cc b/source/blender/blenkernel/intern/bake_items_socket.cc index f3f8136c48b..4e4a1ab9edf 100644 --- a/source/blender/blenkernel/intern/bake_items_socket.cc +++ b/source/blender/blenkernel/intern/bake_items_socket.cc @@ -41,21 +41,19 @@ static void capture_field_on_geometry_components(GeometrySet &geometry, static std::unique_ptr move_common_socket_value_to_bake_item( const bNodeSocketType &stype, - void *socket_value, + SocketValueVariant &socket_value, std::optional name, Vector &r_geometry_bake_items) { switch (stype.type) { case SOCK_GEOMETRY: { - GeometrySet geometry = - static_cast(socket_value)->extract(); + GeometrySet geometry = socket_value.extract(); auto item = std::make_unique(std::move(geometry)); r_geometry_bake_items.append(item.get()); return item; } case SOCK_STRING: { - auto &value_variant = *static_cast(socket_value); - return std::make_unique(value_variant.extract()); + return std::make_unique(socket_value.extract()); } case SOCK_FLOAT: case SOCK_VECTOR: @@ -64,14 +62,13 @@ static std::unique_ptr move_common_socket_value_to_bake_item( case SOCK_ROTATION: case SOCK_MATRIX: case SOCK_RGBA: { - auto &value_variant = *static_cast(socket_value); - if (value_variant.is_context_dependent_field()) { + if (socket_value.is_context_dependent_field()) { /* Not supported here because it's not known which geometry this field belongs to. */ return {}; } #ifdef WITH_OPENVDB - if (value_variant.is_volume_grid()) { - bke::GVolumeGrid grid = value_variant.get(); + if (socket_value.is_volume_grid()) { + bke::GVolumeGrid grid = socket_value.get(); if (name) { grid.get_for_write().set_name(*name); } @@ -82,26 +79,29 @@ static std::unique_ptr move_common_socket_value_to_bake_item( UNUSED_VARS(name); #endif - value_variant.convert_to_single(); - GPointer value = value_variant.get_single_ptr(); + socket_value.convert_to_single(); + GPointer value = socket_value.get_single_ptr(); return std::make_unique(*value.type(), value.get()); } case SOCK_BUNDLE: { - auto &value_variant = *static_cast(socket_value); - nodes::BundlePtr bundle_ptr = value_variant.extract(); + nodes::BundlePtr bundle_ptr = socket_value.extract(); auto bundle_bake_item = std::make_unique(); if (bundle_ptr) { const nodes::Bundle &bundle = *bundle_ptr; for (const nodes::Bundle::StoredItem &bundle_item : bundle.items()) { - if (const auto *socket_value = std::get_if( + if (const auto *item_socket_value = std::get_if( &bundle_item.value.value)) { if (std::unique_ptr bake_item = move_common_socket_value_to_bake_item( - *socket_value->type, socket_value->value, std::nullopt, r_geometry_bake_items)) + *item_socket_value->type, + *static_cast(item_socket_value->value), + std::nullopt, + r_geometry_bake_items)) { - bundle_bake_item->items.append(BundleBakeItem::Item{ - bundle_item.key, - BundleBakeItem::SocketValue{socket_value->type->idname, std::move(bake_item)}}); + bundle_bake_item->items.append( + BundleBakeItem::Item{bundle_item.key, + BundleBakeItem::SocketValue{item_socket_value->type->idname, + std::move(bake_item)}}); } } else if (const auto *internal_value = std::get_if( @@ -124,9 +124,10 @@ static std::unique_ptr move_common_socket_value_to_bake_item( } } -Array> move_socket_values_to_bake_items(const Span socket_values, - const BakeSocketConfig &config, - BakeDataBlockMap *data_block_map) +Array> move_socket_values_to_bake_items( + MutableSpan socket_values, + const BakeSocketConfig &config, + BakeDataBlockMap *data_block_map) { BLI_assert(socket_values.size() == config.types.size()); BLI_assert(socket_values.size() == config.geometries_by_attribute.size()); @@ -141,8 +142,7 @@ Array> move_socket_values_to_bake_items(const Span(socket_value)->extract(); + GeometrySet geometry = socket_values[i].extract(); auto geometry_item = std::make_unique(std::move(geometry)); geometry_bake_items.append(geometry_item.get()); bake_items[i] = std::move(geometry_item); @@ -151,7 +151,7 @@ Array> move_socket_values_to_bake_items(const Span> move_socket_values_to_bake_items(const Span(socket_value); - if (value_variant.is_context_dependent_field()) { - const fn::GField &field = value_variant.get(); + if (socket_value.is_context_dependent_field()) { + const fn::GField &field = socket_value.get(); const AttrDomain domain = config.domains[i]; const std::string attribute_name = ".bake_" + std::to_string(i); const Span geometry_indices = config.geometries_by_attribute[i]; @@ -216,24 +215,22 @@ Array> move_socket_values_to_bake_items(const Span copy_bake_item_to_socket_value( const BakeItem &bake_item, const eNodeSocketDatatype socket_type, const FunctionRef(const CPPType &type)> make_attribute_field, BakeDataBlockMap *data_block_map, - Map &r_attribute_map, - void *r_value) + Map &r_attribute_map) { switch (socket_type) { case SOCK_GEOMETRY: { if (const auto *item = dynamic_cast(&bake_item)) { bke::GeometrySet geometry = item->geometry; GeometryBakeItem::try_restore_data_blocks(geometry, data_block_map); - SocketValueVariant::ConstructIn(r_value, std::move(geometry)); - return true; + return SocketValueVariant::From(std::move(geometry)); } - return false; + return std::nullopt; } case SOCK_FLOAT: case SOCK_VECTOR: @@ -245,21 +242,20 @@ Array> move_socket_values_to_bake_items(const Span(&bake_item)) { if (item->type() == base_type) { - auto *value_variant = new (r_value) SocketValueVariant(); - value_variant->store_single(socket_type, item->value()); - return true; + SocketValueVariant value_variant; + value_variant.store_single(socket_type, item->value()); + return value_variant; } - return false; + return std::nullopt; } if (const auto *item = dynamic_cast(&bake_item)) { if (!make_attribute_field) { - return false; + return std::nullopt; } std::shared_ptr attribute_field = make_attribute_field(base_type); r_attribute_map.add(item->name(), attribute_field->attribute_name()); fn::GField field{attribute_field}; - SocketValueVariant::ConstructIn(r_value, std::move(field)); - return true; + return SocketValueVariant::From(std::move(field)); } #ifdef WITH_OPENVDB if (const auto *item = dynamic_cast(&bake_item)) { @@ -268,23 +264,21 @@ Array> move_socket_values_to_bake_items(const Span grid_socket_type = grid_type_to_socket_type( grid_type); if (!grid_socket_type) { - return false; + return std::nullopt; } if (grid_socket_type == socket_type) { - bke::SocketValueVariant::ConstructIn(r_value, *item->grid); - return true; + return bke::SocketValueVariant::From(*item->grid); } - return false; + return std::nullopt; } #endif - return false; + return std::nullopt; } case SOCK_STRING: { if (const auto *item = dynamic_cast(&bake_item)) { - new (r_value) SocketValueVariant(std::string(item->value())); - return true; + return SocketValueVariant(std::string(item->value())); } - return false; + return std::nullopt; } case SOCK_BUNDLE: { if (const auto *item = dynamic_cast(&bake_item)) { @@ -294,23 +288,20 @@ Array> move_socket_values_to_bake_items(const Span(&item.value)) { const bNodeSocketType *stype = node_socket_type_find(socket_value->socket_idname); if (!stype) { - return false; + return std::nullopt; } if (!stype->geometry_nodes_cpp_type) { - return false; + return std::nullopt; } - BUFFER_FOR_CPP_TYPE_VALUE(*stype->geometry_nodes_cpp_type, buffer); - if (!copy_bake_item_to_socket_value(*socket_value->value, - stype->type, - {}, - data_block_map, - r_attribute_map, - buffer)) + if (std::optional child_value_variant = + copy_bake_item_to_socket_value( + *socket_value->value, stype->type, {}, data_block_map, r_attribute_map)) { - return false; + bundle.add(item.key, nodes::BundleItemSocketValue{stype, &*child_value_variant}); + } + else { + return std::nullopt; } - bundle.add(item.key, nodes::BundleItemSocketValue{stype, buffer}); - stype->geometry_nodes_cpp_type->destruct(buffer); } if (const auto *internal_value = std::get_if(&item.value)) { @@ -324,15 +315,14 @@ Array> move_socket_values_to_bake_items(const Span geometries, @@ -366,95 +356,98 @@ static void rename_attributes(const Span geometries, } } -static void default_initialize_socket_value(const eNodeSocketDatatype socket_type, void *r_value) +static SocketValueVariant default_initialize_socket_value(const eNodeSocketDatatype socket_type) { const bke::bNodeSocketType *typeinfo = bke::node_socket_type_find_static(socket_type); - if (typeinfo->geometry_nodes_default_cpp_value) { - typeinfo->geometry_nodes_cpp_type->copy_construct(typeinfo->geometry_nodes_default_cpp_value, - r_value); - } - else { - typeinfo->geometry_nodes_cpp_type->value_initialize(r_value); - } + return *static_cast(typeinfo->geometry_nodes_default_cpp_value); } -void move_bake_items_to_socket_values( +Vector move_bake_items_to_socket_values( const Span bake_items, const BakeSocketConfig &config, BakeDataBlockMap *data_block_map, - FunctionRef(int, const CPPType &)> make_attribute_field, - const Span r_socket_values) + FunctionRef(int, const CPPType &)> make_attribute_field) { Map attribute_map; - - Vector geometries; + Vector socket_values; + socket_values.reserve(bake_items.size()); for (const int i : bake_items.index_range()) { const eNodeSocketDatatype socket_type = config.types[i]; BakeItem *bake_item = bake_items[i]; - void *r_socket_value = r_socket_values[i]; if (bake_item == nullptr) { - default_initialize_socket_value(socket_type, r_socket_value); + socket_values.append(default_initialize_socket_value(socket_type)); continue; } - if (!copy_bake_item_to_socket_value( + if (std::optional socket_value = copy_bake_item_to_socket_value( *bake_item, socket_type, [&](const CPPType &attr_type) { return make_attribute_field(i, attr_type); }, data_block_map, - attribute_map, - r_socket_value)) + attribute_map)) { - default_initialize_socket_value(socket_type, r_socket_value); + socket_values.append(std::move(*socket_value)); + } + else { + socket_values.append(default_initialize_socket_value(socket_type)); continue; } if (socket_type == SOCK_GEOMETRY) { auto &item = *static_cast(bake_item); item.geometry.clear(); - geometries.append( - static_cast(r_socket_value)->get_single_ptr().get()); } } - rename_attributes(geometries, attribute_map); + for (SocketValueVariant &socket_value : socket_values) { + if (socket_value.valid_for_socket(SOCK_GEOMETRY)) { + GeometrySet *geometry = socket_value.get_single_ptr().get(); + rename_attributes({geometry}, attribute_map); + } + } + + return socket_values; } -void copy_bake_items_to_socket_values( +Vector copy_bake_items_to_socket_values( const Span bake_items, const BakeSocketConfig &config, BakeDataBlockMap *data_block_map, - FunctionRef(int, const CPPType &)> make_attribute_field, - const Span r_socket_values) + FunctionRef(int, const CPPType &)> make_attribute_field) { Map attribute_map; - Vector geometries; + Vector socket_values; + socket_values.reserve(bake_items.size()); for (const int i : bake_items.index_range()) { const eNodeSocketDatatype socket_type = config.types[i]; const BakeItem *bake_item = bake_items[i]; - void *r_socket_value = r_socket_values[i]; if (bake_item == nullptr) { - default_initialize_socket_value(socket_type, r_socket_value); + socket_values.append(default_initialize_socket_value(socket_type)); continue; } - if (!copy_bake_item_to_socket_value( + + if (std::optional socket_value = copy_bake_item_to_socket_value( *bake_item, socket_type, [&](const CPPType &attr_type) { return make_attribute_field(i, attr_type); }, data_block_map, - attribute_map, - r_socket_value)) + attribute_map)) { - default_initialize_socket_value(socket_type, r_socket_value); - continue; + socket_values.append(std::move(*socket_value)); } - if (socket_type == SOCK_GEOMETRY) { - geometries.append( - static_cast(r_socket_value)->get_single_ptr().get()); + else { + socket_values.append(default_initialize_socket_value(socket_type)); } } - rename_attributes(geometries, attribute_map); + for (SocketValueVariant &socket_value : socket_values) { + if (socket_value.valid_for_socket(SOCK_GEOMETRY)) { + GeometrySet *geometry = socket_value.get_single_ptr().get(); + rename_attributes({geometry}, attribute_map); + } + } + + return socket_values; } } // namespace blender::bke::bake diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh index 3076f41661e..c923635532d 100644 --- a/source/blender/nodes/geometry/node_geometry_util.hh +++ b/source/blender/nodes/geometry/node_geometry_util.hh @@ -56,8 +56,8 @@ void get_closest_in_bvhtree(bke::BVHTreeFromMesh &tree_data, MutableSpan r_positions); void mix_baked_data_item(eNodeSocketDatatype socket_type, - void *prev, - const void *next, + SocketValueVariant &prev, + const SocketValueVariant &next, const float factor); namespace enums { diff --git a/source/blender/nodes/geometry/nodes/node_geo_bake.cc b/source/blender/nodes/geometry/nodes/node_geo_bake.cc index ca23687788e..5c27a7c7300 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_bake.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_bake.cc @@ -315,17 +315,13 @@ class LazyFunctionForBakeNode final : public LazyFunction { /* Wait for inputs to be computed. */ return; } - Array output_values(bake_items_.size()); + Vector output_values = this->move_bake_state_to_values( + std::move(*bake_state), + data_block_map, + *user_data.call_data->self_object(), + *user_data.compute_context); for (const int i : bake_items_.index_range()) { - output_values[i] = params.get_output_data_ptr(i); - } - this->move_bake_state_to_values(std::move(*bake_state), - data_block_map, - *user_data.call_data->self_object(), - *user_data.compute_context, - output_values); - for (const int i : bake_items_.index_range()) { - params.output_set(i); + params.set_output(i, std::move(output_values[i])); } } @@ -349,17 +345,13 @@ class LazyFunctionForBakeNode final : public LazyFunction { bke::bake::BakeDataBlockMap *data_block_map, const bake::BakeStateRef &bake_state) const { - Array output_values(bake_items_.size()); + Vector values = this->copy_bake_state_to_values( + bake_state, + data_block_map, + *user_data.call_data->self_object(), + *user_data.compute_context); for (const int i : bake_items_.index_range()) { - output_values[i] = params.get_output_data_ptr(i); - } - this->copy_bake_state_to_values(bake_state, - data_block_map, - *user_data.call_data->self_object(), - *user_data.compute_context, - output_values); - for (const int i : bake_items_.index_range()) { - params.output_set(i); + params.set_output(i, std::move(values[i])); } } @@ -371,51 +363,39 @@ class LazyFunctionForBakeNode final : public LazyFunction { const bake::BakeStateRef &next_state, const float mix_factor) const { - Array output_values(bake_items_.size()); - for (const int i : bake_items_.index_range()) { - output_values[i] = params.get_output_data_ptr(i); - } - this->copy_bake_state_to_values( - prev_state, data_block_map, self_object, compute_context, output_values); - - Array next_values(bake_items_.size()); - LinearAllocator<> allocator; - for (const int i : bake_items_.index_range()) { - const CPPType &type = *outputs_[i].type; - next_values[i] = allocator.allocate(type); - } - this->copy_bake_state_to_values( - next_state, data_block_map, self_object, compute_context, next_values); - + Vector output_values = this->copy_bake_state_to_values( + prev_state, data_block_map, self_object, compute_context); + Vector next_values = this->copy_bake_state_to_values( + next_state, data_block_map, self_object, compute_context); for (const int i : bake_items_.index_range()) { mix_baked_data_item(eNodeSocketDatatype(bake_items_[i].socket_type), output_values[i], next_values[i], mix_factor); } - for (const int i : bake_items_.index_range()) { - const CPPType &type = *outputs_[i].type; - type.destruct(next_values[i]); - } - - for (const int i : bake_items_.index_range()) { - params.output_set(i); + params.set_output(i, std::move(output_values[i])); } } std::optional get_bake_state_from_inputs( lf::Params ¶ms, bke::bake::BakeDataBlockMap *data_block_map) const { - Array input_values(bake_items_.size()); + Array input_value_pointers(bake_items_.size()); for (const int i : bake_items_.index_range()) { - input_values[i] = params.try_get_input_data_ptr_or_request(i); + input_value_pointers[i] = params.try_get_input_data_ptr_or_request( + i); } - if (input_values.as_span().contains(nullptr)) { + if (input_value_pointers.as_span().contains(nullptr)) { /* Wait for inputs to be computed. */ return std::nullopt; } + Array input_values(bake_items_.size()); + for (const int i : bake_items_.index_range()) { + input_values[i] = std::move(*input_value_pointers[i]); + } + Array> bake_items = bake::move_socket_values_to_bake_items( input_values, bake_socket_config_, data_block_map); @@ -430,11 +410,10 @@ class LazyFunctionForBakeNode final : public LazyFunction { return bake_state; } - void move_bake_state_to_values(bake::BakeState bake_state, - bke::bake::BakeDataBlockMap *data_block_map, - const Object &self_object, - const ComputeContext &compute_context, - Span r_output_values) const + Vector move_bake_state_to_values(bake::BakeState bake_state, + bke::bake::BakeDataBlockMap *data_block_map, + const Object &self_object, + const ComputeContext &compute_context) const { Vector bake_items; for (const NodeGeometryBakeItem &item : bake_items_) { @@ -442,35 +421,26 @@ class LazyFunctionForBakeNode final : public LazyFunction { item.identifier); bake_items.append(bake_item ? bake_item->get() : nullptr); } - bake::move_bake_items_to_socket_values( - bake_items, - bake_socket_config_, - data_block_map, - [&](const int i, const CPPType &type) { + return bake::move_bake_items_to_socket_values( + bake_items, bake_socket_config_, data_block_map, [&](const int i, const CPPType &type) { return this->make_attribute_field(self_object, compute_context, bake_items_[i], type); - }, - r_output_values); + }); } - void copy_bake_state_to_values(const bake::BakeStateRef &bake_state, - bke::bake::BakeDataBlockMap *data_block_map, - const Object &self_object, - const ComputeContext &compute_context, - Span r_output_values) const + Vector copy_bake_state_to_values(const bake::BakeStateRef &bake_state, + bke::bake::BakeDataBlockMap *data_block_map, + const Object &self_object, + const ComputeContext &compute_context) const { Vector bake_items; for (const NodeGeometryBakeItem &item : bake_items_) { const bake::BakeItem *const *bake_item = bake_state.items_by_id.lookup_ptr(item.identifier); bake_items.append(bake_item ? *bake_item : nullptr); } - bake::copy_bake_items_to_socket_values( - bake_items, - bake_socket_config_, - data_block_map, - [&](const int i, const CPPType &type) { + return bake::copy_bake_items_to_socket_values( + bake_items, bake_socket_config_, data_block_map, [&](const int i, const CPPType &type) { return this->make_attribute_field(self_object, compute_context, bake_items_[i], type); - }, - r_output_values); + }); } std::shared_ptr make_attribute_field(const Object &self_object, diff --git a/source/blender/nodes/geometry/nodes/node_geo_simulation.cc b/source/blender/nodes/geometry/nodes/node_geo_simulation.cc index 1ab2a47ead5..7ec60eea6ae 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_simulation.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_simulation.cc @@ -103,13 +103,13 @@ static std::shared_ptr make_attribute_field( std::move(attribute_name), type, std::move(socket_inspection_name)); } -static void move_simulation_state_to_values(const Span node_simulation_items, - bke::bake::BakeState zone_state, - const Object &self_object, - const ComputeContext &compute_context, - const bNode &node, - bke::bake::BakeDataBlockMap *data_block_map, - Span r_output_values) +static Vector move_simulation_state_to_values( + const Span node_simulation_items, + bke::bake::BakeState zone_state, + const Object &self_object, + const ComputeContext &compute_context, + const bNode &node, + bke::bake::BakeDataBlockMap *data_block_map) { const bke::bake::BakeSocketConfig config = make_bake_socket_config(node_simulation_items); Vector bake_items; @@ -119,24 +119,20 @@ static void move_simulation_state_to_values(const Span node_ bake_items.append(bake_item ? bake_item->get() : nullptr); } - bke::bake::move_bake_items_to_socket_values( - bake_items, - config, - data_block_map, - [&](const int i, const CPPType &type) { + return bke::bake::move_bake_items_to_socket_values( + bake_items, config, data_block_map, [&](const int i, const CPPType &type) { return make_attribute_field( self_object, compute_context, node, node_simulation_items[i], type); - }, - r_output_values); + }); } -static void copy_simulation_state_to_values(const Span node_simulation_items, - const bke::bake::BakeStateRef &zone_state, - const Object &self_object, - const ComputeContext &compute_context, - const bNode &node, - bke::bake::BakeDataBlockMap *data_block_map, - Span r_output_values) +static Vector copy_simulation_state_to_values( + const Span node_simulation_items, + const bke::bake::BakeStateRef &zone_state, + const Object &self_object, + const ComputeContext &compute_context, + const bNode &node, + bke::bake::BakeDataBlockMap *data_block_map) { const bke::bake::BakeSocketConfig config = make_bake_socket_config(node_simulation_items); Vector bake_items; @@ -146,20 +142,16 @@ static void copy_simulation_state_to_values(const Span node_ bake_items.append(bake_item ? *bake_item : nullptr); } - bke::bake::copy_bake_items_to_socket_values( - bake_items, - config, - data_block_map, - [&](const int i, const CPPType &type) { + return bke::bake::copy_bake_items_to_socket_values( + bake_items, config, data_block_map, [&](const int i, const CPPType &type) { return make_attribute_field( self_object, compute_context, node, node_simulation_items[i], type); - }, - r_output_values); + }); } static bke::bake::BakeState move_values_to_simulation_state( const Span node_simulation_items, - const Span input_values, + MutableSpan input_values, bke::bake::BakeDataBlockMap *data_block_map) { const bke::bake::BakeSocketConfig config = make_bake_socket_config(node_simulation_items); @@ -347,19 +339,15 @@ class LazyFunctionForSimulationInputNode final : public LazyFunction { bke::bake::BakeDataBlockMap *data_block_map, const bke::bake::BakeStateRef &zone_state) const { - Array outputs(simulation_items_.size()); + Vector output_values = copy_simulation_state_to_values( + simulation_items_, + zone_state, + *user_data.call_data->self_object(), + *user_data.compute_context, + node_, + data_block_map); for (const int i : simulation_items_.index_range()) { - outputs[i] = params.get_output_data_ptr(i + 1); - } - copy_simulation_state_to_values(simulation_items_, - zone_state, - *user_data.call_data->self_object(), - *user_data.compute_context, - node_, - data_block_map, - outputs); - for (const int i : simulation_items_.index_range()) { - params.output_set(i + 1); + params.set_output(i + 1, std::move(output_values[i])); } } @@ -368,19 +356,15 @@ class LazyFunctionForSimulationInputNode final : public LazyFunction { bke::bake::BakeDataBlockMap *data_block_map, bke::bake::BakeState zone_state) const { - Array outputs(simulation_items_.size()); + Vector output_values = move_simulation_state_to_values( + simulation_items_, + std::move(zone_state), + *user_data.call_data->self_object(), + *user_data.compute_context, + node_, + data_block_map); for (const int i : simulation_items_.index_range()) { - outputs[i] = params.get_output_data_ptr(i + 1); - } - move_simulation_state_to_values(simulation_items_, - std::move(zone_state), - *user_data.call_data->self_object(), - *user_data.compute_context, - node_, - data_block_map, - outputs); - for (const int i : simulation_items_.index_range()) { - params.output_set(i + 1); + params.set_output(i + 1, std::move(output_values[i])); } } @@ -388,14 +372,19 @@ class LazyFunctionForSimulationInputNode final : public LazyFunction { const GeoNodesUserData &user_data, bke::bake::BakeDataBlockMap *data_block_map) const { - Array input_values(inputs_.size()); + Array input_value_pointers(inputs_.size()); for (const int i : inputs_.index_range()) { - input_values[i] = params.try_get_input_data_ptr_or_request(i); + input_value_pointers[i] = params.try_get_input_data_ptr_or_request(i); } - if (input_values.as_span().contains(nullptr)) { + if (input_value_pointers.as_span().contains(nullptr)) { /* Wait for inputs to be computed. */ return; } + Array input_values(inputs_.size()); + for (const int i : inputs_.index_range()) { + input_values[i] = std::move(*input_value_pointers[i]); + } + /* Instead of outputting the initial values directly, convert them to a simulation state and * then back. This ensures that some geometry processing happens on the data consistently (e.g. * removing anonymous attributes). */ @@ -639,19 +628,15 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction { bke::bake::BakeDataBlockMap *data_block_map, const bke::bake::BakeStateRef &state) const { - Array output_values(simulation_items_.size()); + Vector output_values = copy_simulation_state_to_values( + simulation_items_, + state, + *user_data.call_data->self_object(), + *user_data.compute_context, + node_, + data_block_map); for (const int i : simulation_items_.index_range()) { - output_values[i] = params.get_output_data_ptr(i); - } - copy_simulation_state_to_values(simulation_items_, - state, - *user_data.call_data->self_object(), - *user_data.compute_context, - node_, - data_block_map, - output_values); - for (const int i : simulation_items_.index_range()) { - params.output_set(i); + params.set_output(i, std::move(output_values[i])); } } @@ -663,46 +648,19 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction { const bke::bake::BakeStateRef &next_state, const float mix_factor) const { - Array output_values(simulation_items_.size()); - for (const int i : simulation_items_.index_range()) { - output_values[i] = params.get_output_data_ptr(i); - } - copy_simulation_state_to_values(simulation_items_, - prev_state, - self_object, - compute_context, - node_, - data_block_map, - output_values); - - Array next_values(simulation_items_.size()); - LinearAllocator<> allocator; - for (const int i : simulation_items_.index_range()) { - const CPPType &type = *outputs_[i].type; - next_values[i] = allocator.allocate(type); - } - copy_simulation_state_to_values(simulation_items_, - next_state, - self_object, - compute_context, - node_, - data_block_map, - next_values); + Vector output_values = copy_simulation_state_to_values( + simulation_items_, prev_state, self_object, compute_context, node_, data_block_map); + Vector next_values = copy_simulation_state_to_values( + simulation_items_, next_state, self_object, compute_context, node_, data_block_map); for (const int i : simulation_items_.index_range()) { mix_baked_data_item(eNodeSocketDatatype(simulation_items_[i].socket_type), output_values[i], next_values[i], mix_factor); } - for (const int i : simulation_items_.index_range()) { - const CPPType &type = *outputs_[i].type; - type.destruct(next_values[i]); - } - - for (const int i : simulation_items_.index_range()) { - params.output_set(i); + params.set_output(i, std::move(output_values[i])); } } @@ -716,20 +674,15 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction { /* Wait for inputs to be computed. */ return; } - - Array output_values(simulation_items_.size()); + Vector output_values = move_simulation_state_to_values( + simulation_items_, + std::move(*bake_state), + *user_data.call_data->self_object(), + *user_data.compute_context, + node_, + data_block_map); for (const int i : simulation_items_.index_range()) { - output_values[i] = params.get_output_data_ptr(i); - } - move_simulation_state_to_values(simulation_items_, - std::move(*bake_state), - *user_data.call_data->self_object(), - *user_data.compute_context, - node_, - data_block_map, - output_values); - for (const int i : simulation_items_.index_range()) { - params.output_set(i); + params.set_output(i, std::move(output_values[i])); } } @@ -764,15 +717,21 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction { { /* Choose which set of input parameters to use. The others are ignored. */ const int params_offset = skip ? skip_inputs_offset_ : solve_inputs_offset_; - Array input_values(simulation_items_.size()); + Array input_value_pointers(simulation_items_.size()); for (const int i : simulation_items_.index_range()) { - input_values[i] = params.try_get_input_data_ptr_or_request(i + params_offset); + input_value_pointers[i] = params.try_get_input_data_ptr_or_request( + i + params_offset); } - if (input_values.as_span().contains(nullptr)) { + if (input_value_pointers.as_span().contains(nullptr)) { /* Wait for inputs to be computed. */ return std::nullopt; } + Array input_values(simulation_items_.size()); + for (const int i : simulation_items_.index_range()) { + input_values[i] = std::move(*input_value_pointers[i]); + } + return move_values_to_simulation_state(simulation_items_, input_values, data_block_map); } }; @@ -979,14 +938,14 @@ std::unique_ptr get_simulation_output_lazy_function( } void mix_baked_data_item(const eNodeSocketDatatype socket_type, - void *prev, - const void *next, + SocketValueVariant &prev, + const SocketValueVariant &next, const float factor) { switch (socket_type) { case SOCK_GEOMETRY: { - GeometrySet &prev_geo = *static_cast(prev); - const GeometrySet &next_geo = *static_cast(next); + GeometrySet &prev_geo = *prev.get_single_ptr().get(); + const GeometrySet &next_geo = *next.get_single_ptr().get(); prev_geo = geometry::mix_geometries(std::move(prev_geo), next_geo, factor); break; } @@ -998,20 +957,18 @@ void mix_baked_data_item(const eNodeSocketDatatype socket_type, case SOCK_RGBA: case SOCK_MATRIX: { const CPPType &type = *bke::socket_type_to_geo_nodes_base_cpp_type(socket_type); - SocketValueVariant prev_value_variant = *static_cast(prev); - SocketValueVariant next_value_variant = *static_cast(next); - if (prev_value_variant.is_context_dependent_field() || - next_value_variant.is_context_dependent_field()) - { + if (prev.is_context_dependent_field() || next.is_context_dependent_field()) { /* Fields are evaluated on geometries and are mixed there. */ break; } - prev_value_variant.convert_to_single(); - next_value_variant.convert_to_single(); + prev.convert_to_single(); - void *prev_value = prev_value_variant.get_single_ptr().get(); - const void *next_value = next_value_variant.get_single_ptr().get(); + SocketValueVariant next_copy = next; + next_copy.convert_to_single(); + + void *prev_value = prev.get_single_ptr().get(); + const void *next_value = next_copy.get_single_ptr().get(); bke::attribute_math::convert_to_static_type(type, [&](auto dummy) { using T = decltype(dummy);