diff --git a/source/blender/editors/space_node/space_node.cc b/source/blender/editors/space_node/space_node.cc index 27e45151811..bb58db9ad6d 100644 --- a/source/blender/editors/space_node/space_node.cc +++ b/source/blender/editors/space_node/space_node.cc @@ -413,6 +413,7 @@ const ComputeContext *compute_context_for_zone(const bke::bNodeTreeZone &zone, source_location.compute_context_hash = parent_compute_context ? parent_compute_context->hash() : ComputeContextHash{}; + source_location.compute_context = parent_compute_context; return compute_context_for_closure_evaluation(parent_compute_context, output_node.output_socket(0), compute_context_cache, diff --git a/source/blender/nodes/NOD_geometry_nodes_closure_location.hh b/source/blender/nodes/NOD_geometry_nodes_closure_location.hh index 491fc8ab5f1..47e551a06e3 100644 --- a/source/blender/nodes/NOD_geometry_nodes_closure_location.hh +++ b/source/blender/nodes/NOD_geometry_nodes_closure_location.hh @@ -29,6 +29,8 @@ struct ClosureSourceLocation { const bNodeTree *tree; int closure_output_node_id; ComputeContextHash compute_context_hash; + /** Optional actual compute context. If it is set, its hash should be the same as above. */ + const ComputeContext *compute_context = nullptr; }; struct ClosureEvalLog { diff --git a/source/blender/nodes/intern/shader_nodes_inline.cc b/source/blender/nodes/intern/shader_nodes_inline.cc index 82c80b30e11..9a31ce19517 100644 --- a/source/blender/nodes/intern/shader_nodes_inline.cc +++ b/source/blender/nodes/intern/shader_nodes_inline.cc @@ -723,7 +723,8 @@ class ShaderNodesInliner { closure_output_node.identifier, closure_zone_value->closure_creation_context ? closure_zone_value->closure_creation_context->hash() : - ComputeContextHash{}}; + ComputeContextHash{}, + closure_zone_value->closure_creation_context}; const bke::EvaluateClosureComputeContext &closure_eval_context = compute_context_cache_.for_evaluate_closure(socket.context, evaluate_closure_node->identifier, diff --git a/source/blender/nodes/intern/sync_sockets.cc b/source/blender/nodes/intern/sync_sockets.cc index b68bc77dcc9..da81579b43d 100644 --- a/source/blender/nodes/intern/sync_sockets.cc +++ b/source/blender/nodes/intern/sync_sockets.cc @@ -68,6 +68,9 @@ static BundleSyncState get_sync_state_separate_bundle( bke::ComputeContextCache compute_context_cache; const ComputeContext *current_context = ed::space_node::compute_context_for_edittree_socket( snode, compute_context_cache, *src_bundle_socket); + if (!current_context) { + return {NodeSyncState::NoSyncSource}; + } const LinkedBundleSignatures linked_signatures = gather_linked_origin_bundle_signatures( current_context, *src_bundle_socket, compute_context_cache); if (linked_signatures.items.is_empty()) { @@ -103,6 +106,9 @@ static BundleSyncState get_sync_state_combine_bundle( bke::ComputeContextCache compute_context_cache; const ComputeContext *current_context = ed::space_node::compute_context_for_edittree_socket( snode, compute_context_cache, *src_bundle_socket); + if (!current_context) { + return {NodeSyncState::NoSyncSource}; + } const LinkedBundleSignatures linked_signatures = gather_linked_target_bundle_signatures( current_context, *src_bundle_socket, compute_context_cache); if (linked_signatures.items.is_empty()) { @@ -137,6 +143,9 @@ static ClosureSyncState get_sync_state_closure_output( bke::ComputeContextCache compute_context_cache; const ComputeContext *current_context = ed::space_node::compute_context_for_edittree_socket( snode, compute_context_cache, *src_closure_socket); + if (!current_context) { + return {NodeSyncState::NoSyncSource}; + } const LinkedClosureSignatures linked_signatures = gather_linked_target_closure_signatures( current_context, *src_closure_socket, compute_context_cache); if (linked_signatures.items.is_empty()) { @@ -171,6 +180,9 @@ static ClosureSyncState get_sync_state_evaluate_closure( bke::ComputeContextCache compute_context_cache; const ComputeContext *current_context = ed::space_node::compute_context_for_edittree_socket( snode, compute_context_cache, *src_closure_socket); + if (!current_context) { + return {NodeSyncState::NoSyncSource}; + } const LinkedClosureSignatures linked_signatures = gather_linked_origin_closure_signatures( current_context, *src_closure_socket, compute_context_cache); if (linked_signatures.items.is_empty()) { diff --git a/source/blender/nodes/intern/trace_values.cc b/source/blender/nodes/intern/trace_values.cc index 7ec67b53789..2a371397543 100644 --- a/source/blender/nodes/intern/trace_values.cc +++ b/source/blender/nodes/intern/trace_values.cc @@ -204,7 +204,8 @@ static Vector find_target_sockets_through_contexts( &node->owner_tree(), ClosureSourceLocation{&closure_tree, closure_output_node->identifier, - origin_socket.context_hash()}); + origin_socket.context_hash(), + origin_socket.context}); if (closure_context.is_recursive()) { continue; } @@ -373,17 +374,22 @@ static Vector find_origin_sockets_through_contexts( if (!zones->link_between_zones_is_allowed(from_zone, to_zone)) { continue; } - const Vector zones_to_enter = zones->get_zones_to_enter( - from_zone, to_zone); const ComputeContext *compute_context = socket.context; - for (int i = zones_to_enter.size() - 1; i >= 0; i--) { - if (!compute_context) { - /* There must be a compute context when we are in a zone. */ - BLI_assert_unreachable(); - return found_origins.extract_vector(); + for (const bke::bNodeTreeZone *zone = to_zone; zone != from_zone; zone = zone->parent_zone) + { + if (const auto *evaluate_closure_context = + dynamic_cast(compute_context)) + { + const std::optional &source_location = + evaluate_closure_context->closure_source_location(); + /* This is expected to be available during value tracing. */ + BLI_assert(source_location); + BLI_assert(source_location->compute_context); + compute_context = source_location->compute_context; + } + else { + compute_context = compute_context->parent(); } - /* Each zone corresponds to one compute context level. */ - compute_context = compute_context->parent(); } add_if_new({compute_context, from_socket}, bundle_path); } @@ -457,7 +463,8 @@ static Vector find_origin_sockets_through_contexts( &node->owner_tree(), ClosureSourceLocation{&closure_tree, closure_output_node->identifier, - origin_socket.context_hash()}); + origin_socket.context_hash(), + origin_socket.context}); if (closure_context.is_recursive()) { continue; }