Refactor: Geometry Nodes: extract function to create compute context for zone

This functionality was duplicated in two places and #137403 adds another place
where it is needed.
This commit is contained in:
Jacques Lucke
2025-04-15 10:36:51 +02:00
parent 59e6cfb43b
commit e02a88929f
3 changed files with 65 additions and 49 deletions

View File

@@ -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<ObjectAndModifier> 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);

View File

@@ -344,6 +344,52 @@ std::optional<ObjectAndModifier> 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<const NodeGeometryRepeatOutput *>(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<const NodeGeometryForeachGeometryElementOutput *>(
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<const bke::bNodeTreeZone *> 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<const ComputeContext *> compute_context_for_tree_path(
const SpaceNode &snode,
bke::ComputeContextCache &compute_context_cache,
@@ -371,31 +417,9 @@ std::optional<const ComputeContext *> compute_context_for_tree_path(
}
const Vector<const blender::bke::bNodeTreeZone *> 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<const NodeGeometryRepeatOutput *>(
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<const NodeGeometryForeachGeometryElementOutput *>(
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);
}

View File

@@ -794,30 +794,9 @@ static void find_tree_zone_hash_recursive(
const ComputeContext *current,
Map<const bNodeTreeZone *, ComputeContextHash> &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<const NodeGeometryRepeatOutput *>(
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<const NodeGeometryForeachGeometryElementOutput *>(
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) {