Blender V5.0
BKE_node_runtime.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#pragma once
10
11#include <memory>
12
13#include "BLI_cache_mutex.hh"
16#include "BLI_mutex.hh"
17#include "BLI_set.hh"
19#include "BLI_utility_mixins.hh"
20#include "BLI_vector.hh"
21#include "BLI_vector_set.hh"
22
23#include "DNA_node_types.h"
24
25#include "BKE_node.hh"
27
29
30struct bNode;
31struct bNodeSocket;
32struct bNodeTree;
33
34namespace blender::nodes {
37class NodeDeclaration;
42namespace aal = anonymous_attribute_lifetime;
43namespace gizmos {
45}
46} // namespace blender::nodes
47namespace blender::bke {
48struct bNodeType;
49class bNodeTreeZones;
50} // namespace blender::bke
51
55
56namespace blender::bke {
57
63
65 int32_t operator()(const bNode *value) const
66 {
67 return value->identifier;
68 }
69};
71
73 std::string tooltip;
74};
75
81 private:
82 int to_node_id_;
83 int input_socket_index_;
84 int input_link_index_;
85
86 public:
88 explicit NodeLinkKey(const bNodeLink &link);
89
90 bNodeLink *try_find(bNodeTree &ntree) const;
91 const bNodeLink *try_find(const bNodeTree &ntree) const;
92
93 uint64_t hash() const
94 {
95 return get_default_hash(this->to_node_id_, this->input_socket_index_, this->input_link_index_);
96 }
97
99 to_node_id_,
100 input_socket_index_,
101 input_link_index_);
102};
103
113
121 public:
127 uint32_t changed_flag = 0;
133
138 uint8_t runtime_flag = 0;
139
145
147 std::unique_ptr<LoggedZoneGraphs> logged_zone_graphs;
148
155
163 void (*progress)(void *, float progress) = nullptr;
165 void (*stats_draw)(void *, const char *str) = nullptr;
166 bool (*test_break)(void *) = nullptr;
167 void (*update_draw)(void *) = nullptr;
168 void *tbh = nullptr, *prh = nullptr, *sdh = nullptr, *udh = nullptr;
169
170 /* End legacy execution data. */
171
173 std::unique_ptr<nodes::FieldInferencingInterface> field_inferencing_interface;
177 std::unique_ptr<node_tree_reference_lifetimes::ReferenceLifetimesInfo> reference_lifetimes_info;
178 std::unique_ptr<nodes::gizmos::TreeGizmoPropagation> gizmo_propagation;
179 std::unique_ptr<nodes::StructureTypeInterface> structure_type_interface;
180
187
194 std::unique_ptr<nodes::GeometryNodesLazyFunctionGraphInfo>
196
202
209
215 std::atomic<bool> topology_cache_exists = false;
220 mutable std::atomic<int> allow_use_dirty_topology_cache = 0;
221
223 std::shared_ptr<bNodeTreeZones> tree_zones;
224
229 std::shared_ptr<bNodeTreeZones> last_valid_zones;
231
237
244 std::unique_ptr<nodes::GeometryNodesEvalDependencies> geometry_nodes_eval_dependencies;
245
251
265};
266
319
321 float min_y;
322 float max_y;
323 bool fill_node_end = false;
324};
325
327 public:
333 std::optional<float> header_center_y;
334 std::optional<bNodePanelExtent> content_extent;
337};
338
421
423
428
430 private:
431 const bNodeTree &tree_;
432
433 public:
435 {
436 tree_.runtime->allow_use_dirty_topology_cache.fetch_add(1);
437 }
438
440 {
441 tree_.runtime->allow_use_dirty_topology_cache.fetch_sub(1);
442 }
443};
444
445/* If result is not true then this means that the last node tree editing operation was not covered
446 * by the topology cache update ensure call. All derivative information about topology is not
447 * available. You should call "tree.ensure_topology_cache();" first.
448 */
450{
451 if (!tree.runtime->topology_cache_exists) {
452 return false;
453 }
454 if (tree.runtime->allow_use_dirty_topology_cache.load() > 0) {
455 return true;
456 }
457 if (tree.runtime->topology_cache_mutex.is_dirty()) {
458 return false;
459 }
460 return true;
461}
462
463inline bool topology_cache_is_available(const bNode &node)
464{
465 const bNodeTree *ntree = node.runtime->owner_tree;
466 if (ntree == nullptr) {
467 return false;
468 }
469 return topology_cache_is_available(*ntree);
470}
471
472inline bool topology_cache_is_available(const bNodeSocket &socket)
473{
474 const bNode *node = socket.runtime->owner_node;
475 if (node == nullptr) {
476 return false;
477 }
478 return topology_cache_is_available(*node);
479}
480
481} // namespace node_tree_runtime
482
486
490
491} // namespace blender::bke
492
493/* -------------------------------------------------------------------- */
496
497inline blender::Span<const bNode *> bNodeTree::all_nodes() const
498{
499 return this->runtime->nodes_by_id.as_span();
500}
501
502inline blender::Span<bNode *> bNodeTree::all_nodes()
503{
504 return this->runtime->nodes_by_id;
505}
506
507inline bNode *bNodeTree::node_by_id(const int32_t identifier)
508{
509 BLI_assert(identifier >= 0);
510 bNode *const *node = this->runtime->nodes_by_id.lookup_key_ptr_as(identifier);
511 return node ? *node : nullptr;
512}
513
514inline const bNode *bNodeTree::node_by_id(const int32_t identifier) const
515{
516 BLI_assert(identifier >= 0);
517 const bNode *const *node = this->runtime->nodes_by_id.lookup_key_ptr_as(identifier);
518 return node ? *node : nullptr;
519}
520
521inline blender::Span<bNode *> bNodeTree::nodes_by_type(const blender::StringRefNull type_idname)
522{
524 return this->runtime->nodes_by_type.lookup(blender::bke::node_type_find(type_idname.c_str()));
525}
526
527inline blender::Span<const bNode *> bNodeTree::nodes_by_type(
528 const blender::StringRefNull type_idname) const
529{
531 return this->runtime->nodes_by_type.lookup(blender::bke::node_type_find(type_idname.c_str()));
532}
533
534inline blender::Span<const bNode *> bNodeTree::toposort_left_to_right() const
535{
537 return this->runtime->toposort_left_to_right;
538}
539
540inline blender::Span<const bNode *> bNodeTree::toposort_right_to_left() const
541{
543 return this->runtime->toposort_right_to_left;
544}
545
546inline blender::Span<bNode *> bNodeTree::toposort_left_to_right()
547{
549 return this->runtime->toposort_left_to_right;
550}
551
552inline blender::Span<bNode *> bNodeTree::toposort_right_to_left()
553{
555 return this->runtime->toposort_right_to_left;
556}
557
558inline blender::Span<const bNode *> bNodeTree::group_nodes() const
559{
561 return this->runtime->group_nodes;
562}
563
564inline blender::Span<bNode *> bNodeTree::group_nodes()
565{
567 return this->runtime->group_nodes;
568}
569
570inline bool bNodeTree::has_available_link_cycle() const
571{
573 return this->runtime->has_available_link_cycle;
574}
575
576inline bool bNodeTree::has_undefined_nodes_or_sockets() const
577{
579 return this->runtime->has_undefined_nodes_or_sockets;
580}
581
582inline bNode *bNodeTree::group_output_node()
583{
585 return this->runtime->group_output_node;
586}
587
588inline const bNode *bNodeTree::group_output_node() const
589{
591 return this->runtime->group_output_node;
592}
593
594inline blender::Span<bNode *> bNodeTree::group_input_nodes()
595{
596 return this->nodes_by_type("NodeGroupInput");
597}
598
599inline blender::Span<const bNode *> bNodeTree::group_input_nodes() const
600{
601 return this->nodes_by_type("NodeGroupInput");
602}
603
604inline blender::Span<const bNodeSocket *> bNodeTree::all_input_sockets() const
605{
607 return this->runtime->input_sockets;
608}
609
610inline blender::Span<bNodeSocket *> bNodeTree::all_input_sockets()
611{
613 return this->runtime->input_sockets;
614}
615
616inline blender::Span<const bNodeSocket *> bNodeTree::all_output_sockets() const
617{
619 return this->runtime->output_sockets;
620}
621
622inline blender::Span<bNodeSocket *> bNodeTree::all_output_sockets()
623{
625 return this->runtime->output_sockets;
626}
627
628inline blender::Span<const bNodeSocket *> bNodeTree::all_sockets() const
629{
631 return this->runtime->sockets;
632}
633
634inline blender::Span<bNodeSocket *> bNodeTree::all_sockets()
635{
637 return this->runtime->sockets;
638}
639
640inline blender::Span<bNode *> bNodeTree::root_frames() const
641{
643 return this->runtime->root_frames;
644}
645
646inline blender::Span<bNodeLink *> bNodeTree::all_links()
647{
649 return this->runtime->links;
650}
651
652inline blender::Span<const bNodeLink *> bNodeTree::all_links() const
653{
655 return this->runtime->links;
656}
657
658inline blender::MutableSpan<bNestedNodeRef> bNodeTree::nested_node_refs_span()
659{
660 return {this->nested_node_refs, this->nested_node_refs_num};
661}
662
663inline blender::Span<bNestedNodeRef> bNodeTree::nested_node_refs_span() const
664{
665 return {this->nested_node_refs, this->nested_node_refs_num};
666}
667
668inline void bNodeTree::ensure_interface_cache() const
669{
670 this->tree_interface.ensure_items_cache();
671}
672
673inline blender::Span<bNodeTreeInterfaceSocket *> bNodeTree::interface_inputs()
674{
675 BLI_assert(this->tree_interface.items_cache_is_available());
676 return this->tree_interface.runtime->inputs_;
677}
678
679inline blender::Span<const bNodeTreeInterfaceSocket *> bNodeTree::interface_inputs() const
680{
681 BLI_assert(this->tree_interface.items_cache_is_available());
682 return this->tree_interface.runtime->inputs_.as_span();
683}
684
685inline blender::Span<bNodeTreeInterfaceSocket *> bNodeTree::interface_outputs()
686{
687 BLI_assert(this->tree_interface.items_cache_is_available());
688 return this->tree_interface.runtime->outputs_;
689}
690
691inline blender::Span<const bNodeTreeInterfaceSocket *> bNodeTree::interface_outputs() const
692{
693 BLI_assert(this->tree_interface.items_cache_is_available());
694 return this->tree_interface.runtime->outputs_.as_span();
695}
696
697inline blender::Span<bNodeTreeInterfaceItem *> bNodeTree::interface_items()
698{
699 BLI_assert(this->tree_interface.items_cache_is_available());
700 return this->tree_interface.runtime->items_;
701}
702
703inline blender::Span<const bNodeTreeInterfaceItem *> bNodeTree::interface_items() const
704{
705 BLI_assert(this->tree_interface.items_cache_is_available());
706 return this->tree_interface.runtime->items_.as_span();
707}
708
709inline int bNodeTree::interface_input_index(const bNodeTreeInterfaceSocket &io_socket) const
710{
711 BLI_assert(this->tree_interface.items_cache_is_available());
712 return this->tree_interface.runtime->inputs_.index_of_as(&io_socket);
713}
714
715inline int bNodeTree::interface_output_index(const bNodeTreeInterfaceSocket &io_socket) const
716{
717 BLI_assert(this->tree_interface.items_cache_is_available());
718 return this->tree_interface.runtime->outputs_.index_of_as(&io_socket);
719}
720
721inline int bNodeTree::interface_item_index(const bNodeTreeInterfaceItem &io_item) const
722{
723 BLI_assert(this->tree_interface.items_cache_is_available());
724 return this->tree_interface.runtime->items_.index_of_as(&io_item);
725}
726
728
729/* -------------------------------------------------------------------- */
732
733inline int bNode::index() const
734{
735 const int index = this->runtime->index_in_tree;
736 /* The order of nodes should always be consistent with the `nodes_by_id` vector. */
737 BLI_assert(index ==
738 this->runtime->owner_tree->runtime->nodes_by_id.index_of_as(this->identifier));
739 return index;
740}
741
742inline blender::Span<bNodeSocket *> bNode::input_sockets()
743{
745 return this->runtime->inputs;
746}
747
748inline blender::Span<bNodeSocket *> bNode::output_sockets()
749{
751 return this->runtime->outputs;
752}
753
754inline blender::Span<const bNodeSocket *> bNode::input_sockets() const
755{
757 return this->runtime->inputs;
758}
759
760inline blender::Span<const bNodeSocket *> bNode::output_sockets() const
761{
763 return this->runtime->outputs;
764}
765
766inline blender::IndexRange bNode::input_socket_indices_in_tree() const
767{
769 const int num_inputs = this->runtime->inputs.size();
770 if (num_inputs == 0) {
771 return {};
772 }
773 return blender::IndexRange::from_begin_size(this->input_socket(0).index_in_tree(), num_inputs);
774}
775
776inline blender::IndexRange bNode::output_socket_indices_in_tree() const
777{
779 const int num_outputs = this->runtime->outputs.size();
780 if (num_outputs == 0) {
781 return {};
782 }
783 return blender::IndexRange::from_begin_size(this->output_socket(0).index_in_tree(), num_outputs);
784}
785
786inline blender::IndexRange bNode::input_socket_indices_in_all_inputs() const
787{
789 const int num_inputs = this->runtime->inputs.size();
790 if (num_inputs == 0) {
791 return {};
792 }
793 return blender::IndexRange::from_begin_size(this->input_socket(0).index_in_all_inputs(),
794 num_inputs);
795}
796
797inline blender::IndexRange bNode::output_socket_indices_in_all_outputs() const
798{
800 const int num_outputs = this->runtime->outputs.size();
801 if (num_outputs == 0) {
802 return {};
803 }
804 return blender::IndexRange::from_begin_size(this->output_socket(0).index_in_all_outputs(),
805 num_outputs);
806}
807
808inline bNodeSocket &bNode::input_socket(int index)
809{
811 return *this->runtime->inputs[index];
812}
813
814inline bNodeSocket &bNode::output_socket(int index)
815{
817 return *this->runtime->outputs[index];
818}
819
820inline const bNodeSocket &bNode::input_socket(int index) const
821{
823 return *this->runtime->inputs[index];
824}
825
826inline const bNodeSocket &bNode::output_socket(int index) const
827{
829 return *this->runtime->outputs[index];
830}
831
832inline const bNodeSocket *bNode::input_by_identifier(blender::StringRef identifier) const
833{
835 return this->runtime->inputs_by_identifier.lookup_default_as(identifier, nullptr);
836}
837
838inline const bNodeSocket *bNode::output_by_identifier(blender::StringRef identifier) const
839{
841 return this->runtime->outputs_by_identifier.lookup_default_as(identifier, nullptr);
842}
843
844inline bNodeSocket *bNode::input_by_identifier(blender::StringRef identifier)
845{
847 return this->runtime->inputs_by_identifier.lookup_default_as(identifier, nullptr);
848}
849
850inline bNodeSocket *bNode::output_by_identifier(blender::StringRef identifier)
851{
853 return this->runtime->outputs_by_identifier.lookup_default_as(identifier, nullptr);
854}
855
856inline const bNodeTree &bNode::owner_tree() const
857{
859 return *this->runtime->owner_tree;
860}
861
862inline bNodeTree &bNode::owner_tree()
863{
865 return *this->runtime->owner_tree;
866}
867
868inline blender::StringRefNull bNode::label_or_name() const
869{
870 if (this->label[0] == '\0') {
871 return this->name;
872 }
873 return this->label;
874}
875
876inline bool bNode::is_muted() const
877{
878 return this->flag & NODE_MUTED;
879}
880
881inline bool bNode::is_reroute() const
882{
883 return this->type_legacy == NODE_REROUTE;
884}
885
886inline bool bNode::is_frame() const
887{
888 return this->type_legacy == NODE_FRAME;
889}
890
891inline bool bNode::is_group() const
892{
894}
895
896inline bool bNode::is_custom_group() const
897{
898 return this->type_legacy == NODE_CUSTOM_GROUP;
899}
900
901inline bool bNode::is_group_input() const
902{
903 return this->type_legacy == NODE_GROUP_INPUT;
904}
905
906inline bool bNode::is_group_output() const
907{
908 return this->type_legacy == NODE_GROUP_OUTPUT;
909}
910
911inline bool bNode::is_undefined() const
912{
914}
915
916inline bool bNode::is_type(const blender::StringRef query_idname) const
917{
918 return this->typeinfo->is_type(query_idname);
919}
920
921inline blender::Span<bNodeLink> bNode::internal_links() const
922{
923 return this->runtime->internal_links;
924}
925
926inline bool bNode::is_dangling_reroute() const
927{
929 return this->runtime->is_dangling_reroute;
930}
931
932inline blender::Span<bNode *> bNode::direct_children_in_frame() const
933{
935 BLI_assert(this->is_frame());
936 return this->runtime->direct_children_in_frame;
937}
938
939inline const blender::nodes::NodeDeclaration *bNode::declaration() const
940{
941 return this->runtime->declaration;
942}
943
944inline blender::Span<bNodePanelState> bNode::panel_states() const
945{
947}
948
949inline blender::MutableSpan<bNodePanelState> bNode::panel_states()
950{
952}
953
955
956/* -------------------------------------------------------------------- */
959
960inline bool bNodeLink::is_muted() const
961{
962 return this->flag & NODE_LINK_MUTED;
963}
964
965inline bool bNodeLink::is_available() const
966{
967 return this->fromsock->is_available() && this->tosock->is_available();
968}
969
970inline bool bNodeLink::is_used() const
971{
972 return !this->is_muted() && this->is_available();
973}
974
976
977/* -------------------------------------------------------------------- */
980
981inline int bNodeSocket::index() const
982{
984 return this->runtime->index_in_node;
985}
986
987inline int bNodeSocket::index_in_tree() const
988{
990 return this->runtime->index_in_all_sockets;
991}
992
993inline int bNodeSocket::index_in_all_inputs() const
994{
996 BLI_assert(this->is_input());
997 return this->runtime->index_in_inout_sockets;
998}
999
1000inline int bNodeSocket::index_in_all_outputs() const
1001{
1003 BLI_assert(this->is_output());
1004 return this->runtime->index_in_inout_sockets;
1005}
1006
1007inline bool bNodeSocket::is_user_hidden() const
1008{
1009 return (this->flag & SOCK_HIDDEN) != 0;
1010}
1011
1012inline bool bNodeSocket::is_inactive() const
1013{
1014 /* Gray out inputs that do not affect the output of the node currently.
1015 * Don't gray out any inputs if the node has no outputs (in which case no input can affect the
1016 * output). Otherwise, viewer node inputs would be inactive. */
1017 return this->is_input() && !this->affects_node_output() &&
1018 !this->owner_node().output_sockets().is_empty();
1019}
1020
1021inline bool bNodeSocket::is_available() const
1022{
1023 return (this->flag & SOCK_UNAVAIL) == 0;
1024}
1025
1026inline bool bNodeSocket::is_panel_collapsed() const
1027{
1028 return (this->flag & SOCK_PANEL_COLLAPSED) != 0;
1029}
1030
1031inline bool bNodeSocket::is_visible() const
1032{
1033 return !this->is_user_hidden() && this->is_available() && this->inferred_socket_visibility();
1034}
1035
1036inline bool bNodeSocket::is_icon_visible() const
1037{
1038 return this->is_visible() &&
1039 (this->owner_node().flag & NODE_COLLAPSED || !this->is_panel_collapsed());
1040}
1041
1042inline bool bNodeSocket::may_be_field() const
1043{
1044 return ELEM(this->runtime->inferred_structure_type,
1045 blender::nodes::StructureType::Field,
1046 blender::nodes::StructureType::Dynamic);
1047}
1048
1049inline bNode &bNodeSocket::owner_node()
1050{
1052 return *this->runtime->owner_node;
1053}
1054
1055inline const bNodeTree &bNodeSocket::owner_tree() const
1056{
1058 return *this->runtime->owner_node->runtime->owner_tree;
1059}
1060
1061inline bNodeTree &bNodeSocket::owner_tree()
1062{
1064 return *this->runtime->owner_node->runtime->owner_tree;
1065}
1066
1067inline blender::Span<const bNodeSocket *> bNodeSocket::logically_linked_sockets() const
1068{
1070 return this->runtime->logically_linked_sockets;
1071}
1072
1073inline blender::Span<const bNodeLink *> bNodeSocket::directly_linked_links() const
1074{
1076 return this->runtime->directly_linked_links;
1077}
1078
1079inline blender::Span<bNodeLink *> bNodeSocket::directly_linked_links()
1080{
1082 return this->runtime->directly_linked_links;
1083}
1084
1085inline blender::Span<const bNodeSocket *> bNodeSocket::directly_linked_sockets() const
1086{
1088 return this->runtime->directly_linked_sockets;
1089}
1090
1091inline blender::Span<bNodeSocket *> bNodeSocket::directly_linked_sockets()
1092{
1094 return this->runtime->directly_linked_sockets;
1095}
1096
1097inline bool bNodeSocket::is_directly_linked() const
1098{
1099 return !this->directly_linked_links().is_empty();
1100}
1101
1102inline bool bNodeSocket::is_logically_linked() const
1103{
1104 return !this->logically_linked_sockets().is_empty();
1105}
1106
1107inline const bNodeSocket *bNodeSocket::internal_link_input() const
1108{
1110 BLI_assert(this->in_out == SOCK_OUT);
1111 return this->runtime->internal_link_input;
1112}
1113
1114template<typename T> T *bNodeSocket::default_value_typed()
1115{
1116 return static_cast<T *>(this->default_value);
1117}
1118
1119template<typename T> const T *bNodeSocket::default_value_typed() const
1120{
1121 return static_cast<const T *>(this->default_value);
1122}
1123
1124inline bool bNodeSocket::is_input() const
1125{
1126 return this->in_out == SOCK_IN;
1127}
1128
1129inline bool bNodeSocket::is_output() const
1130{
1131 return this->in_out == SOCK_OUT;
1132}
1133
1134inline bool bNodeSocket::is_multi_input() const
1135{
1136 return this->flag & SOCK_MULTI_INPUT;
1137}
1138
1139inline const bNode &bNodeSocket::owner_node() const
1140{
1142 return *this->runtime->owner_node;
1143}
1144
1146
1147/* -------------------------------------------------------------------- */
1150
1151inline bool bNodePanelState::is_collapsed() const
1152{
1153 return flag & NODE_PANEL_COLLAPSED;
1154}
1155
1156inline bool bNodePanelState::is_parent_collapsed() const
1157{
1159}
1160
1161inline bool bNodePanelState::has_visible_content() const
1162{
1164}
1165
#define NODE_REROUTE
Definition BKE_node.hh:813
#define NODE_CUSTOM_GROUP
Definition BKE_node.hh:816
#define NODE_GROUP_OUTPUT
Definition BKE_node.hh:815
#define NODE_GROUP
Definition BKE_node.hh:811
#define NODE_FRAME
Definition BKE_node.hh:812
#define NODE_GROUP_INPUT
Definition BKE_node.hh:814
#define BLI_assert(a)
Definition BLI_assert.h:46
#define ELEM(...)
@ NODE_COLLAPSED
@ NODE_MUTED
@ SOCK_OUT
@ SOCK_IN
@ NODE_LINK_MUTED
@ SOCK_MULTI_INPUT
@ SOCK_PANEL_COLLAPSED
@ SOCK_HIDDEN
@ SOCK_UNAVAIL
struct bNode bNode
@ NODE_PANEL_COLLAPSED
@ NODE_PANEL_PARENT_COLLAPSED
@ NODE_PANEL_CONTENT_VISIBLE
unsigned long long int uint64_t
static constexpr IndexRange from_begin_size(const int64_t begin, const int64_t size)
NonCopyable(const NonCopyable &other)=delete
NonMovable(NonMovable &&other)=delete
constexpr const char * c_str() const
std::optional< float > header_center_y
std::optional< bNodePanelExtent > content_extent
Array< bNodePanelRuntime > panels
Map< StringRefNull, bNodeSocket * > outputs_by_identifier
Vector< bNode * > direct_children_in_frame
Vector< bNodeSocket * > outputs
Map< StringRefNull, bNodeSocket * > inputs_by_identifier
Vector< bNodeSocket * > inputs
nodes::NodeDeclaration * declaration
Vector< bNodeLink > internal_links
Vector< bNodeSocket * > logically_linked_skipped_sockets
Vector< bNodeSocket * > directly_linked_sockets
Vector< bNodeSocket * > logically_linked_sockets
Vector< bNodeLink * > directly_linked_links
nodes::StructureType inferred_structure_type
const nodes::SocketDeclaration * declaration
MultiValueMap< NodeLinkKey, NodeLinkError > link_errors
std::unique_ptr< LoggedZoneGraphs > logged_zone_graphs
void(* stats_draw)(void *, const char *str)
Vector< bNodeSocket * > output_sockets
std::unique_ptr< node_tree_reference_lifetimes::ReferenceLifetimesInfo > reference_lifetimes_info
Array< FieldSocketState > field_states
Vector< bNodeSocket * > sockets
CacheMutex geometry_nodes_lazy_function_graph_info_mutex
std::unique_ptr< nodes::StructureTypeInterface > structure_type_interface
std::unique_ptr< nodes::gizmos::TreeGizmoPropagation > gizmo_propagation
Set< const bNodeSocket * > sockets_on_active_gizmo_paths
std::unique_ptr< nodes::GeometryNodesLazyFunctionGraphInfo > geometry_nodes_lazy_function_graph_info
Map< bNodeInstanceKey, bNodePreview > previews
Map< int32_t, VectorSet< std::string > > shader_node_errors
std::atomic< bool > topology_cache_exists
MultiValueMap< const bNodeType *, bNode * > nodes_by_type
std::shared_ptr< bNodeTreeZones > tree_zones
void(* progress)(void *, float progress)
std::unique_ptr< nodes::FieldInferencingInterface > field_inferencing_interface
std::unique_ptr< nodes::GeometryNodesEvalDependencies > geometry_nodes_eval_dependencies
std::shared_ptr< bNodeTreeZones > last_valid_zones
blender::Array< nodes::socket_usage_inference::SocketUsage > inferenced_socket_usage
std::atomic< int > allow_use_dirty_topology_cache
Vector< bNodeSocket * > input_sockets
KDTree_3d * tree
#define str(s)
#define T
bool topology_cache_is_available(const bNodeTree &tree)
void preprocess_geometry_node_tree_for_evaluation(bNodeTree &tree_cow)
CustomIDVectorSet< bNode *, NodeIDGetter > NodeIDVectorSet
bNodeType NodeTypeUndefined
Definition node.cc:126
bNodeType * node_type_find(StringRef idname)
Definition node.cc:2379
uint64_t get_default_hash(const T &v, const Args &...args)
Definition BLI_hash.hh:233
VecBase< float, 2 > float2
VectorSet< T, InlineBufferCapacity, DefaultProbingStrategy, CustomIDHash< T, GetIDFn >, CustomIDEqual< T, GetIDFn > > CustomIDVectorSet
std::mutex Mutex
Definition BLI_mutex.hh:47
bNodeSocketRuntimeHandle * runtime
void * default_value
bNodeTreeRuntimeHandle * runtime
int nested_node_refs_num
bNestedNodeRef * nested_node_refs
bNodeTreeInterface tree_interface
bNodeTypeHandle * typeinfo
int num_panel_states
char name[64]
bNodePanelState * panel_states_array
int16_t type_legacy
bNodeRuntimeHandle * runtime
char label[64]
int32_t identifier
Map< int, std::string > graph_by_zone_id
int32_t operator()(const bNode *value) const
bNodeLink * try_find(bNodeTree &ntree) const
NodeLinkKey(const bNodeLink &link)
BLI_STRUCT_EQUALITY_OPERATORS_3(NodeLinkKey, to_node_id_, input_socket_index_, input_link_index_)