61 struct SocketToCheck {
63 BundlePath bundle_path;
69 auto add_if_new = [&](
const SocketInContext &socket, BundlePath bundle_path) {
70 if (added_sockets.
add(socket)) {
71 sockets_to_check.
push({socket, std::move(bundle_path)});
75 add_if_new(start_socket, {});
79 while (!sockets_to_check.
is_empty()) {
80 const SocketToCheck socket_to_check = sockets_to_check.
pop();
82 const BundlePath &bundle_path = socket_to_check.bundle_path;
84 if (socket->is_input()) {
85 if (node->is_muted()) {
86 for (
const bNodeLink &link : node->internal_links()) {
87 if (link.fromsock == socket.
socket) {
88 add_if_new({socket.
context, link.tosock}, bundle_path);
93 if (bundle_path.is_empty() && handle_possible_target_socket_fn(socket)) {
94 found_targets.add(socket);
100 if (node->is_reroute()) {
104 if (node->is_group()) {
106 group->ensure_topology_cache();
109 for (
const bNode *input_node : group->group_input_nodes()) {
110 if (
const bNodeSocket *group_input_socket = input_node->output_by_identifier(
113 if (group_input_socket->is_directly_linked()) {
114 add_if_new({&group_compute_context, group_input_socket}, bundle_path);
121 if (node->is_group_output()) {
125 const bNodeTree *caller_group = group_context->tree();
126 const bNode *caller_group_node = group_context->node();
127 if (caller_group && caller_group_node) {
128 caller_group->ensure_topology_cache();
129 if (
const bNodeSocket *output_socket = caller_group_node->output_by_identifier(
132 add_if_new({group_context->parent(), output_socket}, bundle_path);
138 if (node->is_type(
"NodeCombineBundle")) {
140 BundlePath new_bundle_path = bundle_path;
141 new_bundle_path.append(storage.items[socket->index()].name);
142 add_if_new(node.
output_socket(0), std::move(new_bundle_path));
145 if (node->is_type(
"NodeSeparateBundle")) {
146 if (bundle_path.is_empty()) {
149 const StringRef last_key = bundle_path.last();
151 for (
const int output_i :
IndexRange(storage.items_num)) {
152 if (last_key == storage.items[output_i].name) {
153 add_if_new(node.
output_socket(output_i), bundle_path.as_span().drop_back(1));
158 if (node->is_type(
"NodeClosureOutput")) {
160 const StringRef key = closure_storage.output_items.items[socket->index()].name;
163 for (
const auto &target_socket : target_sockets) {
164 const NodeInContext evaluate_node = target_socket.owner_node();
167 for (
const int i :
IndexRange(evaluate_storage.output_items.items_num)) {
169 if (key == item.
name) {
176 if (node->is_type(
"NodeEvaluateClosure")) {
177 if (socket->index() == 0) {
181 const StringRef key = evaluate_storage.input_items.items[socket->index() - 1].name;
185 const bNodeTree &closure_tree = origin_socket->owner_tree();
187 if (!closure_tree_zones) {
190 const auto &closure_output_node = origin_socket.owner_node();
192 closure_output_node->identifier);
197 if (!closure_input_node) {
206 closure_output_node->identifier,
207 origin_socket.context_hash(),
208 origin_socket.context});
213 closure_output_node->storage);
214 for (
const int i :
IndexRange(closure_output_storage.input_items.items_num)) {
216 if (key == item.
name) {
217 add_if_new({&closure_context, &closure_input_node->output_socket(
i)}, bundle_path);
223 if (node->is_type(
"GeometryNodeSimulationInput")) {
226 add_if_new({&simulation_compute_context, &node->output_socket(socket->index() + 1)},
230 if (node->is_type(
"GeometryNodeSimulationOutput")) {
231 const int output_index = socket->index();
232 if (output_index >= 1) {
234 add_if_new({socket.
context->
parent(), &node->output_socket(output_index - 1)},
239 if (node->is_type(
"GeometryNodeRepeatInput")) {
240 const int index = socket->index();
244 add_if_new({&repeat_compute_context, &node->output_socket(index)}, bundle_path);
246 if (
const bNode *repeat_output_node = node->owner_tree().node_by_id(
247 storage.output_node_id))
249 add_if_new({socket.
context, &repeat_output_node->output_socket(index - 1)},
255 if (node->is_type(
"GeometryNodeRepeatOutput")) {
257 add_if_new({socket.
context->
parent(), &node->output_socket(socket->index())}, bundle_path);
260 for (
const bNodeSocket *output_socket : node->output_sockets()) {
266 if (bundle_decl->pass_through_input_index == socket->index()) {
267 add_if_new({socket.
context, output_socket}, bundle_path);
278 for (
const bNodeLink *link : socket->directly_linked_links()) {
290 zones_to_enter, compute_context_cache, socket.
context);
291 if (!compute_context) {
294 add_if_new({compute_context, to_socket}, bundle_path);
331 struct SocketToCheck {
333 BundlePath bundle_path;
339 auto add_if_new = [&](
const SocketInContext &socket, BundlePath bundle_path) {
340 if (added_sockets.
add(socket)) {
341 sockets_to_check.
push({socket, std::move(bundle_path)});
345 add_if_new(start_socket, {});
349 while (!sockets_to_check.
is_empty()) {
350 const SocketToCheck socket_to_check = sockets_to_check.
pop();
352 const BundlePath &bundle_path = socket_to_check.bundle_path;
355 if (socket->is_input()) {
356 if (bundle_path.is_empty() && handle_possible_origin_socket_fn(socket)) {
357 found_origins.add(socket);
368 for (
const bNodeLink *link : socket->directly_linked_links()) {
380 if (
const auto *evaluate_closure_context =
383 const std::optional<nodes::ClosureSourceLocation> &source_location =
384 evaluate_closure_context->closure_source_location();
388 compute_context = source_location->compute_context;
391 compute_context = compute_context->
parent();
394 add_if_new({compute_context, from_socket}, bundle_path);
398 if (node->is_muted()) {
399 for (
const bNodeLink &link : node->internal_links()) {
400 if (link.tosock == socket.
socket) {
401 add_if_new({socket.
context, link.fromsock}, bundle_path);
406 if (bundle_path.is_empty() && handle_possible_origin_socket_fn(socket)) {
407 found_origins.add(socket);
413 if (node->is_reroute()) {
417 if (node->is_group()) {
419 group->ensure_topology_cache();
420 if (
const bNode *group_output_node = group->group_output_node()) {
423 if (
const bNodeSocket *group_output_socket = group_output_node->input_by_identifier(
426 add_if_new({&group_compute_context, group_output_socket}, bundle_path);
432 if (node->is_group_input()) {
436 const bNodeTree *caller_group = group_context->tree();
437 const bNode *caller_group_node = group_context->node();
438 if (caller_group && caller_group_node) {
439 caller_group->ensure_topology_cache();
440 if (
const bNodeSocket *input_socket = caller_group_node->input_by_identifier(
443 add_if_new({group_context->parent(), input_socket}, bundle_path);
449 if (node->is_type(
"NodeJoinBundle")) {
453 if (node->is_type(
"NodeEvaluateClosure")) {
455 const StringRef key = evaluate_storage.output_items.items[socket->index()].name;
459 const bNodeTree &closure_tree = origin_socket->owner_tree();
460 const NodeInContext closure_output_node = origin_socket.owner_node();
469 closure_output_node->identifier,
470 origin_socket.context_hash(),
471 origin_socket.context});
475 for (
const int i :
IndexRange(closure_storage.output_items.items_num)) {
477 if (key == item.
name) {
478 add_if_new({&closure_context, &closure_output_node->input_socket(
i)}, bundle_path);
484 if (node->is_type(
"NodeClosureInput")) {
486 const bNode *closure_output_node = node->owner_tree().node_by_id(
487 input_storage.output_node_id);
488 if (!closure_output_node) {
493 const StringRef key = output_storage.input_items.items[socket->index()].name;
494 const bNodeSocket &closure_output_socket = closure_output_node->output_socket(0);
496 {socket.
context, &closure_output_socket},
497 compute_context_cache,
501 const NodeInContext target_node = target_socket.owner_node();
504 for (
const int i :
IndexRange(evaluate_storage.input_items.items_num)) {
506 if (key == item.
name) {
513 if (node->is_type(
"NodeCombineBundle")) {
514 if (bundle_path.is_empty()) {
517 const StringRef last_key = bundle_path.last();
519 for (
const int input_i :
IndexRange(storage.items_num)) {
520 if (last_key == storage.items[input_i].name) {
521 add_if_new(node.
input_socket(input_i), bundle_path.as_span().drop_back(1));
526 if (node->is_type(
"NodeSeparateBundle")) {
528 BundlePath new_bundle_path = bundle_path;
529 new_bundle_path.append(storage.items[socket->index()].name);
530 add_if_new(node.
input_socket(0), std::move(new_bundle_path));
533 if (node->is_type(
"GeometryNodeSimulationInput")) {
534 const int output_index = socket->index();
535 if (output_index >= 1) {
537 add_if_new({socket.
context->
parent(), &node->input_socket(output_index - 1)},
542 if (node->is_type(
"GeometryNodeSimulationOutput")) {
545 add_if_new({&simulation_compute_context, &node->input_socket(socket->index() + 1)},
549 if (node->is_type(
"GeometryNodeRepeatInput")) {
550 const int index = socket->index();
553 add_if_new({socket.
context->
parent(), &node->input_socket(index)}, bundle_path);
557 if (node->is_type(
"GeometryNodeRepeatOutput")) {
558 const int index = socket->index();
561 add_if_new({&repeat_compute_context, &node->input_socket(index)}, bundle_path);
563 if (
const bNode *repeat_input_node = zone_type.get_corresponding_input(node->owner_tree(),
566 add_if_new({socket.
context, &repeat_input_node->input_socket(index + 1)}, bundle_path);
572 if (bundle_decl->pass_through_input_index) {
573 const int input_index = *bundle_decl->pass_through_input_index;
574 add_if_new(node.
input_socket(input_index), bundle_path);
const EvaluateClosureComputeContext & for_evaluate_closure(const ComputeContext *parent, int32_t node_id, const bNodeTree *tree=nullptr, const std::optional< nodes::ClosureSourceLocation > &closure_source_location=std::nullopt)
const GroupNodeComputeContext & for_group_node(const ComputeContext *parent, int32_t node_id, const bNodeTree *tree=nullptr)
const RepeatZoneComputeContext & for_repeat_zone(const ComputeContext *parent, int32_t output_node_id, int iteration)
const SimulationZoneComputeContext & for_simulation_zone(const ComputeContext *parent, int output_node_id)