69 std::optional<Span<bool>> top_level_ignored_inputs_;
74 const std::optional<
Span<bool>> top_level_ignored_inputs = std::nullopt)
75 : root_tree_(
tree), top_level_ignored_inputs_(top_level_ignored_inputs)
77 scope_.allocator().provide_buffer(scope_buffer_);
78 root_tree_.ensure_topology_cache();
79 root_tree_.ensure_interface_cache();
80 this->ensure_animation_data_processed(root_tree_);
82 for (
const bNode *node : root_tree_.group_input_nodes()) {
83 for (
const int i : root_tree_.interface_inputs().index_range()) {
85 if (!socket.is_directly_linked()) {
92 const void *input_value =
nullptr;
93 if (!this->treat_socket_as_unknown(socket_in_context)) {
94 if (tree_input_values.has_value()) {
95 input_value = (*tree_input_values)[
i].get();
98 all_socket_values_.add_new(socket_in_context, input_value);
105 for (
const bNode *node : root_tree_.all_nodes()) {
106 if (node->is_group_input()) {
111 for (
const bNodeSocket *socket : node->output_sockets()) {
112 all_socket_usages_.add_new({
nullptr, socket},
true);
119 for (
const bNode *node : root_tree_.group_input_nodes()) {
130 const std::optional<bool> is_used = all_socket_usages_.lookup_try(socket);
131 if (is_used.has_value()) {
134 if (socket->is_output() && !socket->is_directly_linked()) {
138 if (socket->owner_tree().has_available_link_cycle()) {
143 usage_tasks_.push(socket);
145 while (!usage_tasks_.is_empty()) {
147 this->usage_task(socket);
148 if (&socket == &usage_tasks_.peek()) {
154 return all_socket_usages_.lookup(socket);
159 const std::optional<const void *> value = all_socket_values_.lookup_try(socket);
160 if (value.has_value()) {
163 if (socket->owner_tree().has_available_link_cycle()) {
168 value_tasks_.push(socket);
170 while (!value_tasks_.is_empty()) {
172 this->value_task(socket);
173 if (&socket == &value_tasks_.peek()) {
179 return all_socket_values_.lookup(socket);
185 if (all_socket_usages_.
contains(socket)) {
188 const bNode &node = socket->owner_node();
189 if (!socket->is_available()) {
190 all_socket_usages_.
add_new(socket,
false);
193 if (node.is_undefined() && !node.is_custom_group()) {
194 all_socket_usages_.
add_new(socket,
false);
197 if (socket->is_input()) {
198 this->usage_task__input(socket);
201 this->usage_task__output(socket);
205 void usage_task__input(
const SocketInContext &socket)
207 const NodeInContext node = socket.owner_node();
209 if (node->is_muted()) {
210 this->usage_task__input__muted_node(socket);
214 switch (node->type_legacy) {
217 this->usage_task__input__group_node(socket);
221 this->usage_task__input__group_output_node(socket);
225 this->usage_task__input__generic_switch(socket, switch__is_socket_selected);
229 this->usage_task__input__generic_switch(socket, index_switch__is_socket_selected);
233 this->usage_task__input__generic_switch(socket, menu_switch__is_socket_selected);
237 this->usage_task__input__generic_switch(socket, mix_node__is_socket_selected);
241 this->usage_task__input__generic_switch(socket, shader_mix_node__is_socket_selected);
245 this->usage_task__input__simulation_input_node(socket);
249 this->usage_task__input__repeat_input_node(socket);
253 this->usage_task__input__foreach_element_input_node(socket);
257 this->usage_task__input__foreach_element_output_node(socket);
261 this->usage_task__input__capture_attribute_node(socket);
272 this->usage_task__input__output_node(socket);
276 this->usage_task__input__fallback(socket);
282 void usage_task__input__output_node(
const SocketInContext &socket)
284 all_socket_usages_.add_new(socket,
true);
291 void usage_task__input__generic_switch(
292 const SocketInContext &socket,
293 const FunctionRef<
bool(
const SocketInContext &socket,
const void *condition)>
296 const NodeInContext node = socket.owner_node();
297 BLI_assert(node->input_sockets().size() >= 1);
298 BLI_assert(node->output_sockets().size() >= 1);
300 if (socket->type ==
SOCK_CUSTOM &&
STREQ(socket->idname,
"NodeSocketVirtual")) {
301 all_socket_usages_.add_new(socket,
false);
304 const SocketInContext output_socket{socket.context,
305 this->get_first_available_bsocket(node->output_sockets())};
306 const std::optional<bool> output_is_used = all_socket_usages_.lookup_try(output_socket);
307 if (!output_is_used.has_value()) {
308 this->push_usage_task(output_socket);
311 if (!*output_is_used) {
312 all_socket_usages_.add_new(socket,
false);
315 const SocketInContext condition_socket{
316 socket.context, this->get_first_available_bsocket(node->input_sockets())};
317 if (socket == condition_socket) {
318 all_socket_usages_.add_new(socket,
true);
322 if (condition_value ==
nullptr) {
324 all_socket_usages_.add_new(socket,
true);
327 const bool is_used = is_selected_socket(socket, condition_value);
328 all_socket_usages_.add_new(socket, is_used);
331 const bNodeSocket *get_first_available_bsocket(
const Span<const bNodeSocket *> sockets)
const
334 if (socket->is_available()) {
341 void usage_task__input__group_node(
const SocketInContext &socket)
343 const NodeInContext node = socket.owner_node();
346 all_socket_usages_.add_new(socket,
false);
349 group->ensure_topology_cache();
350 if (group->has_available_link_cycle()) {
351 all_socket_usages_.add_new(socket,
false);
354 this->ensure_animation_data_processed(*group);
358 const ComputeContext &group_context = compute_context_cache_.for_group_node(
359 socket.context, node->identifier, &node->owner_tree());
360 Vector<const bNodeSocket *> dependent_sockets;
361 for (
const bNode *group_input_node : group->group_input_nodes()) {
362 const bNodeSocket &group_input_socket = group_input_node->output_socket(socket->index());
363 if (group_input_socket.is_directly_linked()) {
366 dependent_sockets.
append(&group_input_socket);
369 this->usage_task__with_dependent_sockets(socket, dependent_sockets, {}, &group_context);
372 void usage_task__input__group_output_node(
const SocketInContext &socket)
374 const int output_i = socket->index();
375 if (socket.context ==
nullptr) {
377 all_socket_usages_.add_new(socket,
true);
381 const bke::GroupNodeComputeContext &group_context =
382 *
static_cast<const bke::GroupNodeComputeContext *
>(socket.context);
383 const bNodeSocket &group_node_output = group_context.node()->output_socket(output_i);
384 this->usage_task__with_dependent_sockets(
385 socket, {&group_node_output}, {}, group_context.parent());
388 void usage_task__output(
const SocketInContext &socket)
391 Vector<const bNodeSocket *> dependent_sockets;
392 for (
const bNodeLink *link : socket->directly_linked_links()) {
393 if (link->is_used()) {
394 dependent_sockets.
append(link->tosock);
397 this->usage_task__with_dependent_sockets(socket, dependent_sockets, {}, socket.context);
400 void usage_task__input__simulation_input_node(
const SocketInContext &socket)
402 const NodeInContext node = socket.owner_node();
408 if (!sim_output_node) {
409 all_socket_usages_.add_new(socket,
false);
414 dependent_sockets.
extend(node->output_sockets());
415 dependent_sockets.
extend(sim_output_node->output_sockets());
416 this->usage_task__with_dependent_sockets(socket, dependent_sockets, {}, socket.context);
419 void usage_task__input__repeat_input_node(
const SocketInContext &socket)
421 const NodeInContext node = socket.owner_node();
427 if (!repeat_output_node) {
428 all_socket_usages_.add_new(socket,
false);
434 dependent_sockets.
extend(node->output_sockets());
435 dependent_sockets.
extend(repeat_output_node->output_sockets());
436 this->usage_task__with_dependent_sockets(socket, dependent_sockets, {}, socket.context);
439 void usage_task__input__foreach_element_output_node(
const SocketInContext &socket)
441 const NodeInContext node = socket.owner_node();
442 this->usage_task__with_dependent_sockets(
443 socket, {&node->output_by_identifier(socket->identifier)}, {}, socket.context);
446 void usage_task__input__capture_attribute_node(
const SocketInContext &socket)
448 const NodeInContext node = socket.owner_node();
449 this->usage_task__with_dependent_sockets(
450 socket, {&node->output_socket(socket->index())}, {}, socket.context);
453 void usage_task__input__fallback(
const SocketInContext &socket)
455 Vector<const bNodeSocket *> dependent_boolean_inputs;
458 if (
const SocketDeclaration *socket_decl = socket->runtime->declaration) {
459 for (
const PanelDeclaration *panel_decl = socket_decl->parent; panel_decl;
460 panel_decl = panel_decl->parent)
462 if (
const SocketDeclaration *panel_toggle_decl = panel_decl->panel_input_decl()) {
463 if (panel_toggle_decl != socket_decl) {
464 dependent_boolean_inputs.
append(
465 &socket->owner_node().socket_by_decl(*panel_toggle_decl));
470 this->usage_task__with_dependent_sockets(
471 socket, socket->owner_node().output_sockets(), dependent_boolean_inputs, socket.context);
474 void usage_task__input__foreach_element_input_node(
const SocketInContext &socket)
476 const NodeInContext node = socket.owner_node();
482 if (!foreach_output_node) {
483 all_socket_usages_.add_new(socket,
false);
487 if (StringRef(socket->identifier).startswith(
"Input_")) {
488 dependent_sockets.
append(&node->output_by_identifier(socket->identifier));
492 dependent_sockets.
extend(node->output_sockets());
493 dependent_sockets.
extend(foreach_output_node->output_sockets());
495 this->usage_task__with_dependent_sockets(socket, dependent_sockets, {}, socket.context);
498 void usage_task__input__muted_node(
const SocketInContext &socket)
500 const NodeInContext node = socket.owner_node();
501 Vector<const bNodeSocket *> dependent_sockets;
502 for (
const bNodeLink &internal_link : node->internal_links()) {
503 if (internal_link.fromsock != socket.socket) {
506 dependent_sockets.
append(internal_link.tosock);
508 this->usage_task__with_dependent_sockets(socket, dependent_sockets, {}, socket.context);
515 void usage_task__with_dependent_sockets(
const SocketInContext &socket,
516 const Span<const bNodeSocket *> dependent_outputs,
517 const Span<const bNodeSocket *> condition_inputs,
518 const ComputeContext *dependent_socket_context)
521 SocketInContext next_unknown_output;
522 bool any_output_used =
false;
523 for (
const bNodeSocket *dependent_socket_ptr : dependent_outputs) {
524 const SocketInContext dependent_socket{dependent_socket_context, dependent_socket_ptr};
525 const std::optional<bool> is_used = all_socket_usages_.lookup_try(dependent_socket);
526 if (!is_used.has_value() && !next_unknown_output) {
527 next_unknown_output = dependent_socket;
530 if (is_used.value_or(
false)) {
531 any_output_used =
true;
535 if (next_unknown_output) {
539 this->push_usage_task(next_unknown_output);
542 if (!any_output_used) {
543 all_socket_usages_.add_new(socket,
false);
546 bool all_condition_inputs_true =
true;
547 for (
const bNodeSocket *condition_input_ptr : condition_inputs) {
548 const SocketInContext condition_input{dependent_socket_context, condition_input_ptr};
550 if (condition_value ==
nullptr) {
555 const bool condition = *
static_cast<const bool *
>(condition_value);
557 all_condition_inputs_true =
false;
561 all_socket_usages_.add_new(socket, all_condition_inputs_true);
564 void value_task(
const SocketInContext &socket)
566 if (all_socket_values_.contains(socket)) {
570 const bNode &node = socket->owner_node();
571 if (node.is_undefined() && !node.is_custom_group()) {
572 all_socket_values_.add_new(socket,
nullptr);
575 const CPPType *base_type = socket->
typeinfo->base_cpp_type;
578 all_socket_values_.add_new(socket,
nullptr);
581 if (socket->is_input()) {
582 this->value_task__input(socket);
585 this->value_task__output(socket);
589 void value_task__output(
const SocketInContext &socket)
591 const NodeInContext node = socket.owner_node();
592 if (node->is_muted()) {
593 this->value_task__output__muted_node(socket);
596 switch (node->type_legacy) {
599 this->value_task__output__group_node(socket);
603 this->value_task__output__group_input_node(socket);
607 this->value_task__output__reroute_node(socket);
611 this->value_task__output__generic_switch(socket, switch__is_socket_selected);
615 this->value_task__output__generic_switch(socket, index_switch__is_socket_selected);
619 this->value_task__output__generic_switch(socket, menu_switch__is_socket_selected);
623 this->value_task__output__generic_switch(socket, mix_node__is_socket_selected);
627 this->value_task__output__generic_switch(socket, shader_mix_node__is_socket_selected);
631 this->value_task__output__float_math(socket);
635 this->value_task__output__vector_math(socket);
639 this->value_task__output__integer_math(socket);
643 this->value_task__output__boolean_math(socket);
647 if (node->typeinfo->build_multi_function) {
648 this->value_task__output__multi_function_node(socket);
656 all_socket_values_.add_new(socket,
nullptr);
659 void value_task__output__group_node(
const SocketInContext &socket)
661 const NodeInContext node = socket.owner_node();
664 all_socket_values_.add_new(socket,
nullptr);
667 group->ensure_topology_cache();
668 if (group->has_available_link_cycle()) {
669 all_socket_values_.add_new(socket,
nullptr);
672 this->ensure_animation_data_processed(*group);
673 const bNode *group_output_node = group->group_output_node();
674 if (!group_output_node) {
676 all_socket_values_.add_new(socket,
nullptr);
679 const ComputeContext &group_context = compute_context_cache_.for_group_node(
680 socket.context, node->identifier, &node->owner_tree());
681 const SocketInContext socket_in_group{&group_context,
682 &group_output_node->input_socket(socket->index())};
683 const std::optional<const void *> value = all_socket_values_.lookup_try(socket_in_group);
684 if (!value.has_value()) {
685 this->push_value_task(socket_in_group);
688 all_socket_values_.add_new(socket, *value);
691 void value_task__output__group_input_node(
const SocketInContext &socket)
696 const bke::GroupNodeComputeContext &group_context =
697 *
static_cast<const bke::GroupNodeComputeContext *
>(socket.context);
698 const SocketInContext group_node_input{group_context.parent(),
699 &group_context.node()->input_socket(socket->index())};
700 const std::optional<const void *> value = all_socket_values_.lookup_try(group_node_input);
701 if (!value.has_value()) {
702 this->push_value_task(group_node_input);
705 all_socket_values_.add_new(socket, *value);
708 void value_task__output__reroute_node(
const SocketInContext &socket)
710 const SocketInContext input_socket = socket.owner_node().input_socket(0);
711 const std::optional<const void *> value = all_socket_values_.lookup_try(input_socket);
712 if (!value.has_value()) {
713 this->push_value_task(input_socket);
716 all_socket_values_.add_new(socket, *value);
719 void value_task__output__float_math(
const SocketInContext &socket)
721 const NodeInContext node = socket.owner_node();
725 this->value_task__output__generic_eval(
726 socket, [&](
const Span<const void *>
inputs) -> std::optional<const void *> {
727 const std::optional<float> a =
inputs[0] ? std::optional(*
static_cast<const float *
>(
730 const std::optional<float>
b =
inputs[1] ? std::optional(*
static_cast<const float *
>(
733 if (a == 0.0f ||
b == 0.0f) {
734 return &scope_.construct<
float>(0.0f);
736 if (a.has_value() &&
b.has_value()) {
737 return &scope_.construct<
float>(*a * *
b);
744 this->value_task__output__multi_function_node(socket);
750 void value_task__output__vector_math(
const SocketInContext &socket)
752 const NodeInContext node = socket.owner_node();
756 this->value_task__output__generic_eval(
757 socket, [&](
const Span<const void *>
inputs) -> std::optional<const void *> {
758 const std::optional<float3> a =
inputs[0] ?
762 const std::optional<float3>
b =
inputs[1] ?
767 return &scope_.construct<
float3>(0.0f);
769 if (a.has_value() &&
b.has_value()) {
770 return &scope_.construct<
float3>(*a * *
b);
777 this->value_task__output__generic_eval(
778 socket, [&](
const Span<const void *>
inputs) -> std::optional<const void *> {
779 const std::optional<float3> a =
inputs[0] ?
785 *
static_cast<const float *
>(
inputs[3])) :
787 if (a ==
float3(0.0f) || scale == 0.0f) {
788 return &scope_.construct<
float3>(0.0f);
790 if (a.has_value() &&
scale.has_value()) {
798 this->value_task__output__multi_function_node(socket);
804 void value_task__output__integer_math(
const SocketInContext &socket)
806 const NodeInContext node = socket.owner_node();
810 this->value_task__output__generic_eval(
811 socket, [&](
const Span<const void *>
inputs) -> std::optional<const void *> {
812 const std::optional<int> a =
inputs[0] ? std::optional(
813 *
static_cast<const int *
>(
inputs[0])) :
815 const std::optional<int>
b =
inputs[1] ? std::optional(
816 *
static_cast<const int *
>(
inputs[1])) :
818 if (a == 0 ||
b == 0) {
819 return &scope_.construct<
int>(0);
821 if (a.has_value() &&
b.has_value()) {
822 return &scope_.construct<
int>(*a * *
b);
829 this->value_task__output__multi_function_node(socket);
835 void value_task__output__boolean_math(
const SocketInContext &socket)
837 const NodeInContext node = socket.owner_node();
840 const auto handle_binary_op =
841 [&](FunctionRef<std::optional<bool>(std::optional<bool>, std::optional<bool>)> fn) {
842 this->value_task__output__generic_eval(
843 socket, [&](
const Span<const void *>
inputs) -> std::optional<const void *> {
844 const std::optional<bool> a =
inputs[0] ? std::optional(*
static_cast<const bool *
>(
847 const std::optional<bool>
b =
inputs[1] ? std::optional(*
static_cast<const bool *
>(
850 const std::optional<bool>
result = fn(a,
b);
852 return &scope_.construct<
bool>(*result);
860 [](
const std::optional<bool> &a,
const std::optional<bool> &
b) -> std::optional<bool> {
861 if (a ==
false ||
b ==
false) {
864 if (a.has_value() &&
b.has_value()) {
873 [](
const std::optional<bool> &a,
const std::optional<bool> &
b) -> std::optional<bool> {
874 if (a ==
true ||
b ==
true) {
877 if (a.has_value() &&
b.has_value()) {
886 [](
const std::optional<bool> &a,
const std::optional<bool> &
b) -> std::optional<bool> {
887 if (a ==
false ||
b ==
false) {
890 if (a.has_value() &&
b.has_value()) {
899 [](
const std::optional<bool> &a,
const std::optional<bool> &
b) -> std::optional<bool> {
900 if (a ==
true ||
b ==
true) {
903 if (a.has_value() &&
b.has_value()) {
912 [](
const std::optional<bool> &a,
const std::optional<bool> &
b) -> std::optional<bool> {
913 if (a ==
false ||
b ==
true) {
916 if (a.has_value() &&
b.has_value()) {
925 [](
const std::optional<bool> &a,
const std::optional<bool> &
b) -> std::optional<bool> {
926 if (a ==
false ||
b ==
true) {
929 if (a.has_value() &&
b.has_value()) {
937 this->value_task__output__multi_function_node(socket);
947 void value_task__output__generic_switch(
948 const SocketInContext &socket,
949 const FunctionRef<
bool(
const SocketInContext &socket,
const void *condition)>
952 const NodeInContext node = socket.owner_node();
953 BLI_assert(node->input_sockets().size() >= 1);
954 BLI_assert(node->output_sockets().size() >= 1);
956 const SocketInContext condition_socket{
957 socket.context, this->get_first_available_bsocket(node->input_sockets())};
958 const std::optional<const void *> condition_value = all_socket_values_.lookup_try(
960 if (!condition_value.has_value()) {
961 this->push_value_task(condition_socket);
964 if (!*condition_value) {
966 all_socket_values_.add_new(socket,
nullptr);
969 Vector<const bNodeSocket *> selected_inputs;
970 for (
const int input_i :
971 node->input_sockets().index_range().drop_front(condition_socket->index() + 1))
973 const SocketInContext input_socket = node.input_socket(input_i);
974 if (!input_socket->is_available()) {
977 if (input_socket->type ==
SOCK_CUSTOM &&
STREQ(input_socket->idname,
"NodeSocketVirtual")) {
980 const bool is_selected = is_selected_socket(input_socket, *condition_value);
982 selected_inputs.
append(input_socket.socket);
986 all_socket_values_.add_new(socket,
nullptr);
989 if (selected_inputs.
size() == 1) {
991 const SocketInContext selected_input{socket.context, selected_inputs[0]};
992 const std::optional<const void *> input_value = all_socket_values_.lookup_try(
994 if (!input_value.has_value()) {
995 this->push_value_task(selected_input);
998 all_socket_values_.add_new(socket, *input_value);
1003 if (node->typeinfo->build_multi_function) {
1005 this->value_task__output__multi_function_node(socket);
1009 all_socket_values_.add_new(socket,
nullptr);
1012 void value_task__output__generic_eval(
1013 const SocketInContext &socket,
1014 const FunctionRef<std::optional<const void *>(Span<const void *>
inputs)> eval_fn)
1016 const NodeInContext node = socket.owner_node();
1017 const int inputs_num = node->input_sockets().size();
1019 Array<const void *, 16> input_values(inputs_num,
nullptr);
1020 std::optional<int> next_unknown_input_index;
1021 for (
const int input_i : IndexRange(inputs_num)) {
1022 const SocketInContext input_socket = node.input_socket(input_i);
1023 if (!input_socket->is_available()) {
1026 const std::optional<const void *> input_value = all_socket_values_.lookup_try(input_socket);
1027 if (!input_value.has_value()) {
1028 next_unknown_input_index = input_i;
1031 input_values[input_i] = *input_value;
1033 const std::optional<const void *> output_value = eval_fn(input_values);
1034 if (output_value.has_value()) {
1036 all_socket_values_.add_new(socket, *output_value);
1039 if (!next_unknown_input_index.has_value()) {
1042 all_socket_values_.add_new(socket,
nullptr);
1046 const SocketInContext next_input = node.input_socket(*next_unknown_input_index);
1047 this->push_value_task(next_input);
1050 void value_task__output__multi_function_node(
const SocketInContext &socket)
1052 const NodeInContext node = socket.owner_node();
1053 const int inputs_num = node->input_sockets().size();
1056 Vector<const void *> input_values(inputs_num);
1057 for (
const int input_i : IndexRange(inputs_num)) {
1058 const SocketInContext input_socket = node.input_socket(input_i);
1059 const std::optional<const void *> input_value = all_socket_values_.lookup_try(input_socket);
1060 if (!input_value.has_value()) {
1061 this->push_value_task(input_socket);
1064 if (*input_value ==
nullptr) {
1065 all_socket_values_.add_new(socket,
nullptr);
1068 input_values[input_i] = *input_value;
1072 NodeMultiFunctionBuilder builder{*node.node, node->owner_tree()};
1073 node->typeinfo->build_multi_function(builder);
1074 const mf::MultiFunction &fn = builder.function();
1077 const IndexMask
mask(1);
1081 for (
const int input_i : IndexRange(inputs_num)) {
1082 const SocketInContext input_socket = node.input_socket(input_i);
1083 if (!input_socket->is_available()) {
1086 params.add_readonly_single_input(
1087 GPointer(input_socket->typeinfo->base_cpp_type, input_values[input_i]));
1089 for (
const int output_i : node->output_sockets().index_range()) {
1090 const SocketInContext output_socket = node.output_socket(output_i);
1091 if (!output_socket->is_available()) {
1095 const CPPType &base_type = *output_socket->typeinfo->base_cpp_type;
1096 void *value = scope_.allocate_owned(base_type);
1097 params.add_uninitialized_single_output(GMutableSpan(base_type, value, 1));
1098 all_socket_values_.add_new(output_socket, value);
1106 void value_task__output__muted_node(
const SocketInContext &socket)
1108 const NodeInContext node = socket.owner_node();
1110 SocketInContext input_socket;
1111 for (
const bNodeLink &internal_link : node->internal_links()) {
1112 if (internal_link.tosock == socket.socket) {
1113 input_socket = SocketInContext{socket.context, internal_link.fromsock};
1117 if (!input_socket) {
1119 all_socket_values_.add_new(socket,
nullptr);
1122 const std::optional<const void *> input_value = all_socket_values_.lookup_try(input_socket);
1123 if (!input_value.has_value()) {
1124 this->push_value_task(input_socket);
1127 const void *converted_value = this->convert_type_if_necessary(
1128 *input_value, *input_socket.socket, *socket.socket);
1129 all_socket_values_.add_new(socket, converted_value);
1132 void value_task__input(
const SocketInContext &socket)
1134 if (socket->is_multi_input()) {
1136 all_socket_values_.add_new(socket,
nullptr);
1140 const Span<const bNodeLink *> connected_links = socket->directly_linked_links();
1141 for (
const bNodeLink *link : connected_links) {
1142 if (!link->is_used()) {
1145 if (link->fromnode->is_dangling_reroute()) {
1152 this->value_task__input__unlinked(socket);
1155 this->value_task__input__linked({socket.context, source_link->
fromsock}, socket);
1158 void value_task__input__unlinked(
const SocketInContext &socket)
1160 if (this->treat_socket_as_unknown(socket)) {
1161 all_socket_values_.add_new(socket,
nullptr);
1164 if (animated_sockets_.contains(socket.socket)) {
1166 all_socket_values_.add_new(socket,
nullptr);
1169 if (
const SocketDeclaration *socket_decl = socket.socket->runtime->declaration) {
1172 all_socket_values_.add_new(socket,
nullptr);
1177 void *value_buffer = scope_.allocate_owned(*socket->typeinfo->base_cpp_type);
1178 socket->typeinfo->get_base_cpp_value(socket->default_value, value_buffer);
1179 all_socket_values_.add_new(socket, value_buffer);
1182 void value_task__input__linked(
const SocketInContext &from_socket,
1183 const SocketInContext &to_socket)
1185 const std::optional<const void *> from_value = all_socket_values_.lookup_try(from_socket);
1186 if (!from_value.has_value()) {
1187 this->push_value_task(from_socket);
1190 const void *converted_value = this->convert_type_if_necessary(
1191 *from_value, *from_socket.socket, *to_socket.socket);
1192 all_socket_values_.add_new(to_socket, converted_value);
1195 const void *convert_type_if_necessary(
const void *src,
1202 const CPPType *from_type = from_socket.
typeinfo->base_cpp_type;
1211 if (!conversions.is_convertible(*from_type, *
to_type)) {
1214 void *dst = scope_.allocate_owned(*
to_type);
1215 conversions.convert_to_uninitialized(*from_type, *
to_type, src, dst);
1219 static bool switch__is_socket_selected(
const SocketInContext &socket,
const void *condition)
1221 const bool is_true = *
static_cast<const bool *
>(condition);
1222 const int selected_index = is_true ? 2 : 1;
1223 return socket->index() == selected_index;
1226 static bool index_switch__is_socket_selected(
const SocketInContext &socket,
1227 const void *condition)
1229 const int index = *
static_cast<const int *
>(condition);
1230 return socket->index() == index + 1;
1233 static bool menu_switch__is_socket_selected(
const SocketInContext &socket,
const void *condition)
1236 socket->owner_node().storage);
1237 const int menu_value = *
static_cast<const int *
>(condition);
1242 static bool mix_node__is_socket_selected(
const SocketInContext &socket,
const void *condition)
1245 socket.owner_node()->storage);
1251 bool only_a =
false;
1252 bool only_b =
false;
1254 const float3 mix_factor = *
static_cast<const float3 *
>(condition);
1256 only_a = mix_factor.
x <= 0.0f && mix_factor.
y <= 0.0f && mix_factor.
z <= 0.0f;
1257 only_b = mix_factor.
x >= 1.0f && mix_factor.
y >= 1.0f && mix_factor.
z >= 1.0f;
1260 only_a =
float3{0.0f, 0.0f, 0.0f} == mix_factor;
1261 only_b =
float3{1.0f, 1.0f, 1.0f} == mix_factor;
1265 const float mix_factor = *
static_cast<const float *
>(condition);
1267 only_a = mix_factor <= 0.0f;
1268 only_b = mix_factor >= 1.0f;
1271 only_a = mix_factor == 0.0f;
1272 only_b = mix_factor == 1.0f;
1276 if (
STREQ(socket->name,
"B")) {
1281 if (
STREQ(socket->name,
"A")) {
1288 static bool shader_mix_node__is_socket_selected(
const SocketInContext &socket,
1289 const void *condition)
1291 const float mix_factor = *
static_cast<const float *
>(condition);
1292 if (mix_factor == 0.0f) {
1293 if (
STREQ(socket->identifier,
"Shader_001")) {
1297 else if (mix_factor == 1.0f) {
1298 if (
STREQ(socket->identifier,
"Shader")) {
1305 void push_usage_task(
const SocketInContext &socket)
1307 usage_tasks_.push(socket);
1310 void push_value_task(
const SocketInContext &socket)
1312 value_tasks_.push(socket);
1317 if (!trees_with_handled_animation_data_.add(&
tree)) {
1324 static std::regex pattern(R
"#(nodes\["(.*)"\].inputs\[(\d+)\].default_value)#");
1325 MultiValueMap<StringRef, int> animated_inputs_by_node_name;
1326 auto handle_rna_path = [&](
const char *rna_path) {
1328 if (!std::regex_match(rna_path, match, pattern)) {
1331 const StringRef node_name{match[1].first, match[1].second - match[1].first};
1332 const int socket_index = std::stoi(match[2]);
1333 animated_inputs_by_node_name.
add(node_name, socket_index);
1337 if (
tree.adt->action) {
1339 tree.adt->action->wrap(),
tree.adt->slot_handle, [&](
const FCurve &fcurve) {
1340 handle_rna_path(fcurve.rna_path);
1345 handle_rna_path(driver->rna_path);
1349 if (!animated_inputs_by_node_name.
is_empty()) {
1350 for (
const bNode *node :
tree.all_nodes()) {
1351 const Span<int> animated_inputs = animated_inputs_by_node_name.
lookup(node->name);
1352 const Span<const bNodeSocket *> input_sockets = node->input_sockets();
1353 for (
const int socket_index : animated_inputs) {
1354 if (socket_index < 0 || socket_index >= input_sockets.
size()) {
1359 const bNodeSocket &socket = *input_sockets[socket_index];
1360 animated_sockets_.add(&socket);
1366 bool treat_socket_as_unknown(
const SocketInContext &socket)
const
1368 if (!top_level_ignored_inputs_.has_value()) {
1371 if (socket.context) {
1374 if (socket->is_output()) {
1377 return (*top_level_ignored_inputs_)[socket->index_in_all_inputs()];