diff --git a/source/blender/editors/include/ED_node.hh b/source/blender/editors/include/ED_node.hh index 76d08d5808a..c4560054af2 100644 --- a/source/blender/editors/include/ED_node.hh +++ b/source/blender/editors/include/ED_node.hh @@ -26,6 +26,10 @@ struct rctf; struct NodesModifierData; struct uiLayout; +namespace blender::bke { +class bNodeTreeZone; +} + namespace blender::ed::space_node { void tree_update(const bContext *C); @@ -87,6 +91,15 @@ std::optional get_modifier_for_node_editor(const SpaceNode &s bke::ComputeContextCache &compute_context_cache, const ComputeContext *parent_compute_context); +/** + * Creates a compute context for the given zone. It takes e.g. the current inspection index into + * account. + */ +[[nodiscard]] const ComputeContext *compute_context_for_zone( + const bke::bNodeTreeZone &zone, + bke::ComputeContextCache &compute_context_cache, + const ComputeContext *parent_compute_context); + void ui_template_node_asset_menu_items(uiLayout &layout, const bContext &C, StringRef catalog_path); diff --git a/source/blender/editors/space_node/space_node.cc b/source/blender/editors/space_node/space_node.cc index abbd048fa48..c14cb09dc3c 100644 --- a/source/blender/editors/space_node/space_node.cc +++ b/source/blender/editors/space_node/space_node.cc @@ -344,6 +344,52 @@ std::optional get_modifier_for_node_editor(const SpaceNode &s return ObjectAndModifier{object, used_modifier}; } +const ComputeContext *compute_context_for_zone(const bke::bNodeTreeZone &zone, + bke::ComputeContextCache &compute_context_cache, + const ComputeContext *parent_compute_context) +{ + if (!zone.output_node) { + return nullptr; + } + const bNode &output_node = *zone.output_node; + switch (output_node.type_legacy) { + case GEO_NODE_SIMULATION_OUTPUT: { + return &compute_context_cache.for_simulation_zone(parent_compute_context, *zone.output_node); + } + case GEO_NODE_REPEAT_OUTPUT: { + const auto &storage = *static_cast(output_node.storage); + return &compute_context_cache.for_repeat_zone( + parent_compute_context, *zone.output_node, storage.inspection_index); + } + case GEO_NODE_FOREACH_GEOMETRY_ELEMENT_OUTPUT: { + const auto &storage = *static_cast( + output_node.storage); + return &compute_context_cache.for_foreach_geometry_element_zone( + parent_compute_context, *zone.output_node, storage.inspection_index); + } + case GEO_NODE_CLOSURE_OUTPUT: { + /* TODO: Need to find a place where this closure is evaluated. */ + return nullptr; + } + } + return nullptr; +} + +static const ComputeContext *compute_context_for_zones( + const Span zones, + bke::ComputeContextCache &compute_context_cache, + const ComputeContext *parent_compute_context) +{ + const ComputeContext *current = parent_compute_context; + for (const bke::bNodeTreeZone *zone : zones) { + current = compute_context_for_zone(*zone, compute_context_cache, current); + if (!current) { + return nullptr; + } + } + return current; +} + std::optional compute_context_for_tree_path( const SpaceNode &snode, bke::ComputeContextCache &compute_context_cache, @@ -371,31 +417,9 @@ std::optional compute_context_for_tree_path( } const Vector zone_stack = tree_zones->get_zone_stack_for_node(group_node->identifier); - for (const blender::bke::bNodeTreeZone *zone : zone_stack) { - switch (zone->output_node->type_legacy) { - case GEO_NODE_SIMULATION_OUTPUT: { - current = &compute_context_cache.for_simulation_zone(current, *zone->output_node); - break; - } - case GEO_NODE_REPEAT_OUTPUT: { - const auto &storage = *static_cast( - zone->output_node->storage); - current = &compute_context_cache.for_repeat_zone( - current, *zone->output_node, storage.inspection_index); - break; - } - case GEO_NODE_FOREACH_GEOMETRY_ELEMENT_OUTPUT: { - const auto &storage = *static_cast( - zone->output_node->storage); - current = &compute_context_cache.for_foreach_geometry_element_zone( - current, *zone->output_node, storage.inspection_index); - break; - } - case GEO_NODE_CLOSURE_OUTPUT: { - // TODO: Need to find a place where this closure is evaluated. - return std::nullopt; - } - } + current = compute_context_for_zones(zone_stack, compute_context_cache, current); + if (!current) { + return std::nullopt; } current = &compute_context_cache.for_group_node(current, *group_node, *tree); } diff --git a/source/blender/nodes/intern/geometry_nodes_log.cc b/source/blender/nodes/intern/geometry_nodes_log.cc index 478963cc38e..2eee41f00a1 100644 --- a/source/blender/nodes/intern/geometry_nodes_log.cc +++ b/source/blender/nodes/intern/geometry_nodes_log.cc @@ -794,30 +794,9 @@ static void find_tree_zone_hash_recursive( const ComputeContext *current, Map &r_hash_by_zone) { - switch (zone.output_node->type_legacy) { - case GEO_NODE_SIMULATION_OUTPUT: { - current = &compute_context_cache.for_simulation_zone(current, *zone.output_node); - break; - } - case GEO_NODE_REPEAT_OUTPUT: { - const auto &storage = *static_cast( - zone.output_node->storage); - current = &compute_context_cache.for_repeat_zone( - current, *zone.output_node, storage.inspection_index); - break; - } - case GEO_NODE_FOREACH_GEOMETRY_ELEMENT_OUTPUT: { - const auto &storage = *static_cast( - zone.output_node->storage); - current = &compute_context_cache.for_foreach_geometry_element_zone( - current, *zone.output_node, storage.inspection_index); - break; - } - case GEO_NODE_CLOSURE_OUTPUT: { - /* Can't find hashes for closure zones. Nodes in these zones may be evaluated in different - * contexts based on where the closures are called. */ - return; - } + current = ed::space_node::compute_context_for_zone(zone, compute_context_cache, current); + if (!current) { + return; } r_hash_by_zone.add_new(&zone, current->hash()); for (const bNodeTreeZone *child_zone : zone.child_zones) {