diff options
Diffstat (limited to 'source/blender/modifiers/intern/MOD_nodes_evaluator.cc')
-rw-r--r-- | source/blender/modifiers/intern/MOD_nodes_evaluator.cc | 111 |
1 files changed, 54 insertions, 57 deletions
diff --git a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc index a312872f5d9..70d2bd9c7f5 100644 --- a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc +++ b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc @@ -568,15 +568,15 @@ class GeometryNodesEvaluator { } /* Count the number of potential users for this socket. */ socket.foreach_target_socket( - [&, this](const DInputSocket target_socket) { + [&, this](const DInputSocket target_socket, + const DOutputSocket::TargetSocketPathInfo &UNUSED(path_info)) { const DNode target_node = target_socket.node(); if (!this->node_states_.contains_as(target_node)) { /* The target node is not computed because it is not computed to the output. */ return; } output_state.potential_users += 1; - }, - {}); + }); if (output_state.potential_users == 0) { /* If it does not have any potential users, it is unused. It might become required again in * `schedule_initial_nodes`. */ @@ -1257,43 +1257,61 @@ class GeometryNodesEvaluator { { BLI_assert(value_to_forward.get() != nullptr); - Vector<DSocket> sockets_to_log_to; - sockets_to_log_to.append(from_socket); - - Vector<DInputSocket> to_sockets; - auto handle_target_socket_fn = [&, this](const DInputSocket to_socket) { - if (this->should_forward_to_socket(to_socket)) { - to_sockets.append(to_socket); - } - }; - auto handle_skipped_socket_fn = [&](const DSocket socket) { - sockets_to_log_to.append(socket); - }; - from_socket.foreach_target_socket(handle_target_socket_fn, handle_skipped_socket_fn); - LinearAllocator<> &allocator = local_allocators_.local(); - const CPPType &from_type = *value_to_forward.type(); - Vector<DInputSocket> to_sockets_same_type; - for (const DInputSocket &to_socket : to_sockets) { - const CPPType &to_type = *get_socket_cpp_type(to_socket); - if (from_type == to_type) { - /* All target sockets that do not need a conversion will be handled afterwards. */ - to_sockets_same_type.append(to_socket); - /* Multi input socket values are logged once all values are available. */ - if (!to_socket->is_multi_input_socket()) { - sockets_to_log_to.append(to_socket); - } - continue; - } - this->forward_to_socket_with_different_type( - allocator, value_to_forward, from_socket, to_socket, to_type); - } - - this->log_socket_value(sockets_to_log_to, value_to_forward); + Vector<DSocket> log_original_value_sockets; + Vector<DInputSocket> forward_original_value_sockets; + log_original_value_sockets.append(from_socket); + from_socket.foreach_target_socket( + [&](const DInputSocket to_socket, const DOutputSocket::TargetSocketPathInfo &path_info) { + if (!this->should_forward_to_socket(to_socket)) { + return; + } + BLI_assert(to_socket == path_info.sockets.last()); + GMutablePointer current_value = value_to_forward; + for (const DSocket &next_socket : path_info.sockets) { + const DNode next_node = next_socket.node(); + const bool is_last_socket = to_socket == next_socket; + const bool do_conversion_if_necessary = is_last_socket || + next_node->is_group_output_node() || + (next_node->is_group_node() && + !next_node->is_muted()); + if (do_conversion_if_necessary) { + const CPPType &next_type = *get_socket_cpp_type(next_socket); + if (*current_value.type() != next_type) { + void *buffer = allocator.allocate(next_type.size(), next_type.alignment()); + this->convert_value(*current_value.type(), next_type, current_value.get(), buffer); + if (current_value.get() != value_to_forward.get()) { + current_value.destruct(); + } + current_value = {next_type, buffer}; + } + } + if (current_value.get() == value_to_forward.get()) { + /* Log the original value at the current socket. */ + log_original_value_sockets.append(next_socket); + } + else { + /* Multi-input sockets are logged when all values are available. */ + if (!(next_socket->is_input() && next_socket->as_input().is_multi_input_socket())) { + /* Log the converted value at the socket. */ + this->log_socket_value({next_socket}, current_value); + } + } + } + if (current_value.get() == value_to_forward.get()) { + /* The value has not been converted, so forward the original value. */ + forward_original_value_sockets.append(to_socket); + } + else { + /* The value has been converted. */ + this->add_value_to_input_socket(to_socket, from_socket, current_value); + } + }); + this->log_socket_value(log_original_value_sockets, value_to_forward); this->forward_to_sockets_with_same_type( - allocator, to_sockets_same_type, value_to_forward, from_socket); + allocator, forward_original_value_sockets, value_to_forward, from_socket); } bool should_forward_to_socket(const DInputSocket socket) @@ -1312,27 +1330,6 @@ class GeometryNodesEvaluator { return target_input_state.usage != ValueUsage::Unused; } - void forward_to_socket_with_different_type(LinearAllocator<> &allocator, - const GPointer value_to_forward, - const DOutputSocket from_socket, - const DInputSocket to_socket, - const CPPType &to_type) - { - const CPPType &from_type = *value_to_forward.type(); - - /* Allocate a buffer for the converted value. */ - void *buffer = allocator.allocate(to_type.size(), to_type.alignment()); - GMutablePointer value{to_type, buffer}; - - this->convert_value(from_type, to_type, value_to_forward.get(), buffer); - - /* Multi input socket values are logged once all values are available. */ - if (!to_socket->is_multi_input_socket()) { - this->log_socket_value({to_socket}, value); - } - this->add_value_to_input_socket(to_socket, from_socket, value); - } - void forward_to_sockets_with_same_type(LinearAllocator<> &allocator, Span<DInputSocket> to_sockets, GMutablePointer value_to_forward, |