Blender  V3.3
NOD_node_tree_ref.hh
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #pragma once
4 
33 #include "BLI_array.hh"
34 #include "BLI_function_ref.hh"
35 #include "BLI_linear_allocator.hh"
36 #include "BLI_map.hh"
37 #include "BLI_multi_value_map.hh"
38 #include "BLI_string_ref.hh"
39 #include "BLI_timeit.hh"
40 #include "BLI_utility_mixins.hh"
41 #include "BLI_vector.hh"
42 
43 #include "BKE_node.h"
44 #include "BKE_node_runtime.hh"
45 
46 #include "DNA_node_types.h"
47 
48 #include "RNA_access.h"
49 
50 namespace blender::nodes {
51 
52 class SocketRef;
53 class InputSocketRef;
54 class OutputSocketRef;
55 class NodeRef;
56 class NodeTreeRef;
57 class LinkRef;
58 class InternalLinkRef;
59 
61 
63  protected:
66  bool is_input_;
67  int id_;
68  int index_;
70 
71  /* These sockets are linked directly, i.e. with a single link in between. */
73  /* These sockets are linked when reroutes, muted links and muted nodes have been taken into
74  * account. */
76  /* These are the sockets that have been skipped when searching for logically linked sockets.
77  * That includes for example the input and output socket of an intermediate reroute node. */
79 
80  friend NodeTreeRef;
81 
82  public:
87 
88  bool is_directly_linked() const;
89  bool is_logically_linked() const;
90 
91  const NodeRef &node() const;
92  const NodeTreeRef &tree() const;
93 
94  int id() const;
95  int index() const;
96 
97  bool is_input() const;
98  bool is_output() const;
99 
100  const SocketRef &as_base() const;
101  const InputSocketRef &as_input() const;
102  const OutputSocketRef &as_output() const;
103 
104  PointerRNA rna() const;
105 
106  StringRefNull idname() const;
107  StringRefNull name() const;
108  StringRefNull identifier() const;
109  bNodeSocketType *typeinfo() const;
110 
111  bNodeSocket *bsocket() const;
112  bNode *bnode() const;
113  bNodeTree *btree() const;
114 
115  bool is_available() const;
116  bool is_undefined() const;
117 
118  void *default_value() const;
119  template<typename T> T *default_value() const;
120 };
121 
123  public:
124  friend NodeTreeRef;
125 
128 
129  bool is_multi_input_socket() const;
130 
131  private:
132  void foreach_logical_origin(FunctionRef<void(const OutputSocketRef &)> origin_fn,
133  FunctionRef<void(const SocketRef &)> skipped_fn,
134  bool only_follow_first_input_link,
135  Vector<const InputSocketRef *> &seen_sockets_stack) const;
136 };
137 
139  public:
140  friend NodeTreeRef;
141 
144 
145  private:
146  void foreach_logical_target(FunctionRef<void(const InputSocketRef &)> target_fn,
147  FunctionRef<void(const SocketRef &)> skipped_fn,
148  Vector<const OutputSocketRef *> &seen_sockets_stack) const;
149 };
150 
152  private:
153  NodeTreeRef *tree_;
154  bNode *bnode_;
155  int id_;
156  Vector<InputSocketRef *> inputs_;
157  Vector<OutputSocketRef *> outputs_;
158  Vector<InternalLinkRef *> internal_links_;
159  SocketIndexByIdentifierMap *input_index_by_identifier_;
160  SocketIndexByIdentifierMap *output_index_by_identifier_;
161 
162  friend NodeTreeRef;
163 
164  public:
165  const NodeTreeRef &tree() const;
166 
171 
172  const InputSocketRef &input(int index) const;
173  const OutputSocketRef &output(int index) const;
174 
175  const InputSocketRef &input_by_identifier(StringRef identifier) const;
176  const OutputSocketRef &output_by_identifier(StringRef identifier) const;
177 
178  bool any_input_is_directly_linked() const;
179  bool any_output_is_directly_linked() const;
181 
182  bNode *bnode() const;
183  bNodeTree *btree() const;
184 
185  PointerRNA rna() const;
186  StringRefNull idname() const;
187  StringRefNull name() const;
188  StringRefNull label() const;
190  bNodeType *typeinfo() const;
191  const NodeDeclaration *declaration() const;
192 
193  int id() const;
194 
195  bool is_reroute_node() const;
196  bool is_group_node() const;
197  bool is_group_input_node() const;
198  bool is_group_output_node() const;
199  bool is_muted() const;
200  bool is_frame() const;
201  bool is_undefined() const;
202 
203  void *storage() const;
204  template<typename T> T *storage() const;
205 };
206 
208  private:
209  OutputSocketRef *from_;
210  InputSocketRef *to_;
211  bNodeLink *blink_;
212 
213  friend NodeTreeRef;
214 
215  public:
216  const OutputSocketRef &from() const;
217  const InputSocketRef &to() const;
218 
219  bNodeLink *blink() const;
220 
221  bool is_muted() const;
222 };
223 
225  private:
226  InputSocketRef *from_;
227  OutputSocketRef *to_;
228  bNodeLink *blink_;
229 
230  friend NodeTreeRef;
231 
232  public:
233  const InputSocketRef &from() const;
234  const OutputSocketRef &to() const;
235 
236  bNodeLink *blink() const;
237 };
238 
240  private:
241  LinearAllocator<> allocator_;
242  bNodeTree *btree_;
243  Vector<NodeRef *> nodes_by_id_;
244  Vector<SocketRef *> sockets_by_id_;
245  Vector<InputSocketRef *> input_sockets_;
246  Vector<OutputSocketRef *> output_sockets_;
247  Vector<LinkRef *> links_;
250  const NodeRef *group_output_node_ = nullptr;
251 
252  public:
254  ~NodeTreeRef();
255 
258  Span<const NodeRef *> nodes_by_type(const bNodeType *nodetype) const;
259 
263 
265 
266  const NodeRef *find_node(const bNode &bnode) const;
267 
271  const NodeRef *group_output_node() const;
272 
276  bool has_link_cycles() const;
277  bool has_undefined_nodes_or_sockets() const;
278 
279  enum class ToposortDirection {
280  LeftToRight,
281  RightToLeft,
282  };
283 
284  struct ToposortResult {
291  bool has_cycle = false;
292  };
293 
298  ToposortResult toposort(ToposortDirection direction) const;
299 
300  bNodeTree *btree() const;
301  StringRefNull name() const;
302 
303  std::string to_dot() const;
304 
305  private:
306  /* Utility functions used during construction. */
307  InputSocketRef &find_input_socket(Map<bNode *, NodeRef *> &node_mapping,
308  bNode *bnode,
309  bNodeSocket *bsocket);
310  OutputSocketRef &find_output_socket(Map<bNode *, NodeRef *> &node_mapping,
311  bNode *bnode,
312  bNodeSocket *bsocket);
313 
314  void create_linked_socket_caches();
315  void create_socket_identifier_maps();
316 };
317 
319 
320 const NodeTreeRef &get_tree_ref_from_map(NodeTreeRefMap &node_tree_refs, bNodeTree &btree);
321 
322 namespace node_tree_ref_types {
324 using nodes::NodeRef;
325 using nodes::NodeTreeRef;
328 using nodes::SocketRef;
329 } // namespace node_tree_ref_types
330 
331 /* -------------------------------------------------------------------- */
336 {
338 }
339 
341 {
343 }
344 
346 {
348 }
349 
351 {
352  return directly_linked_links_;
353 }
354 
355 inline bool SocketRef::is_directly_linked() const
356 {
357  return directly_linked_sockets_.size() > 0;
358 }
359 
361 {
362  return logically_linked_sockets_.size() > 0;
363 }
364 
365 inline const NodeRef &SocketRef::node() const
366 {
367  return *node_;
368 }
369 
370 inline const NodeTreeRef &SocketRef::tree() const
371 {
372  return node_->tree();
373 }
374 
375 inline int SocketRef::id() const
376 {
377  return id_;
378 }
379 
380 inline int SocketRef::index() const
381 {
382  return index_;
383 }
384 
385 inline bool SocketRef::is_input() const
386 {
387  return is_input_;
388 }
389 
390 inline bool SocketRef::is_output() const
391 {
392  return !is_input_;
393 }
394 
395 inline const SocketRef &SocketRef::as_base() const
396 {
397  return *this;
398 }
399 
400 inline const InputSocketRef &SocketRef::as_input() const
401 {
402  BLI_assert(this->is_input());
403  return static_cast<const InputSocketRef &>(*this);
404 }
405 
407 {
408  BLI_assert(this->is_output());
409  return static_cast<const OutputSocketRef &>(*this);
410 }
411 
413 {
414  return bsocket_->idname;
415 }
416 
418 {
419  return bsocket_->name;
420 }
421 
423 {
424  return bsocket_->identifier;
425 }
426 
428 {
429  return bsocket_->typeinfo;
430 }
431 
433 {
434  return bsocket_;
435 }
436 
437 inline bNode *SocketRef::bnode() const
438 {
439  return node_->bnode();
440 }
441 
443 {
444  return node_->btree();
445 }
446 
447 inline bool SocketRef::is_available() const
448 {
449  return (bsocket_->flag & SOCK_UNAVAIL) == 0;
450 }
451 
452 inline bool SocketRef::is_undefined() const
453 {
455 }
456 
457 inline void *SocketRef::default_value() const
458 {
459  return bsocket_->default_value;
460 }
461 
462 template<typename T> inline T *SocketRef::default_value() const
463 {
464  return (T *)bsocket_->default_value;
465 }
466 
469 /* -------------------------------------------------------------------- */
474 {
475  return logically_linked_sockets_.as_span().cast<const OutputSocketRef *>();
476 }
477 
479 {
480  return directly_linked_sockets_.cast<const OutputSocketRef *>();
481 }
482 
484 {
485  return bsocket_->flag & SOCK_MULTI_INPUT;
486 }
487 
490 /* -------------------------------------------------------------------- */
495 {
496  return logically_linked_sockets_.as_span().cast<const InputSocketRef *>();
497 }
498 
500 {
501  return directly_linked_sockets_.cast<const InputSocketRef *>();
502 }
503 
506 /* -------------------------------------------------------------------- */
510 inline const NodeTreeRef &NodeRef::tree() const
511 {
512  return *tree_;
513 }
514 
516 {
517  return inputs_;
518 }
519 
521 {
522  return outputs_;
523 }
524 
526 {
527  return in_out == SOCK_IN ? inputs_.as_span().cast<const SocketRef *>() :
528  outputs_.as_span().cast<const SocketRef *>();
529 }
530 
532 {
533  return internal_links_;
534 }
535 
536 inline const InputSocketRef &NodeRef::input(int index) const
537 {
538  return *inputs_[index];
539 }
540 
541 inline const OutputSocketRef &NodeRef::output(int index) const
542 {
543  return *outputs_[index];
544 }
545 
547 {
548  const int index = input_index_by_identifier_->lookup_as(identifier);
549  return this->input(index);
550 }
551 
553 {
554  const int index = output_index_by_identifier_->lookup_as(identifier);
555  return this->output(index);
556 }
557 
558 inline bNode *NodeRef::bnode() const
559 {
560  return bnode_;
561 }
562 
563 inline bNodeTree *NodeRef::btree() const
564 {
565  return tree_->btree();
566 }
567 
569 {
570  return bnode_->idname;
571 }
572 
574 {
575  return bnode_->name;
576 }
577 
579 {
580  return bnode_->label;
581 }
582 
584 {
585  const StringRefNull label = this->label();
586  if (!label.is_empty()) {
587  return label;
588  }
589  return this->name();
590 }
591 
593 {
594  return bnode_->typeinfo;
595 }
596 
597 /* Returns a pointer because not all nodes have declarations currently. */
599 {
600  nodeDeclarationEnsure(this->tree().btree(), bnode_);
601  return bnode_->runtime->declaration;
602 }
603 
604 inline int NodeRef::id() const
605 {
606  return id_;
607 }
608 
609 inline bool NodeRef::is_reroute_node() const
610 {
611  return bnode_->type == NODE_REROUTE;
612 }
613 
614 inline bool NodeRef::is_group_node() const
615 {
616  return bnode_->type == NODE_GROUP || bnode_->type == NODE_CUSTOM_GROUP;
617 }
618 
619 inline bool NodeRef::is_group_input_node() const
620 {
621  return bnode_->type == NODE_GROUP_INPUT;
622 }
623 
624 inline bool NodeRef::is_group_output_node() const
625 {
626  return bnode_->type == NODE_GROUP_OUTPUT;
627 }
628 
629 inline bool NodeRef::is_frame() const
630 {
631  return bnode_->type == NODE_FRAME;
632 }
633 
634 inline bool NodeRef::is_undefined() const
635 {
636  return bnode_->typeinfo == &NodeTypeUndefined;
637 }
638 
639 inline bool NodeRef::is_muted() const
640 {
641  return (bnode_->flag & NODE_MUTED) != 0;
642 }
643 
644 inline void *NodeRef::storage() const
645 {
646  return bnode_->storage;
647 }
648 
649 template<typename T> inline T *NodeRef::storage() const
650 {
651  return (T *)bnode_->storage;
652 }
653 
656 /* -------------------------------------------------------------------- */
660 inline const OutputSocketRef &LinkRef::from() const
661 {
662  return *from_;
663 }
664 
665 inline const InputSocketRef &LinkRef::to() const
666 {
667  return *to_;
668 }
669 
670 inline bNodeLink *LinkRef::blink() const
671 {
672  return blink_;
673 }
674 
675 inline bool LinkRef::is_muted() const
676 {
677  return blink_->flag & NODE_LINK_MUTED;
678 }
679 
682 /* -------------------------------------------------------------------- */
687 {
688  return *from_;
689 }
690 
692 {
693  return *to_;
694 }
695 
697 {
698  return blink_;
699 }
700 
703 /* -------------------------------------------------------------------- */
708 {
709  return nodes_by_id_;
710 }
711 
713 {
714  const bNodeType *nodetype = nodeTypeFind(idname.c_str());
715  return this->nodes_by_type(nodetype);
716 }
717 
719 {
720  return nodes_by_type_.lookup(nodetype);
721 }
722 
724 {
725  return sockets_by_id_;
726 }
727 
729 {
730  return input_sockets_;
731 }
732 
734 {
735  return output_sockets_;
736 }
737 
739 {
740  return links_;
741 }
742 
744 {
745  return group_output_node_;
746 }
747 
749 {
750  return btree_;
751 }
752 
754 {
755  return btree_->id.name + 2;
756 }
757 
760 } // namespace blender::nodes
#define NODE_REROUTE
Definition: BKE_node.h:986
#define NODE_CUSTOM_GROUP
Definition: BKE_node.h:989
struct bNodeType NodeTypeUndefined
Definition: node.cc:111
struct bNodeType * nodeTypeFind(const char *idname)
Definition: node.cc:1327
struct bNodeSocketType NodeSocketTypeUndefined
Definition: node.cc:112
bool nodeDeclarationEnsure(struct bNodeTree *ntree, struct bNode *node)
Definition: node.cc:3731
#define NODE_FRAME
Definition: BKE_node.h:985
#define NODE_GROUP_INPUT
Definition: BKE_node.h:987
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define final(a, b, c)
Definition: BLI_hash.h:21
#define NODE_MUTED
eNodeSocketInOut
@ SOCK_IN
@ SOCK_MULTI_INPUT
@ SOCK_UNAVAIL
#define NODE_LINK_MUTED
NODE_GROUP_OUTPUT
NODE_GROUP
const Value & lookup_as(const ForwardKey &key) const
Definition: BLI_map.hh:493
constexpr bool is_empty() const
constexpr const char * c_str() const
Span< const OutputSocketRef * > directly_linked_sockets() const
Span< const OutputSocketRef * > logically_linked_sockets() const
const InputSocketRef & from() const
const OutputSocketRef & to() const
bNodeLink * blink() const
const OutputSocketRef & from() const
const InputSocketRef & to() const
const OutputSocketRef & output_by_identifier(StringRef identifier) const
bool any_output_is_directly_linked() const
const OutputSocketRef & output(int index) const
Span< const InternalLinkRef * > internal_links() const
bNodeType * typeinfo() const
PointerRNA rna() const
Span< const InputSocketRef * > inputs() const
const InputSocketRef & input(int index) const
bNodeTree * btree() const
Span< const OutputSocketRef * > outputs() const
StringRefNull label_or_name() const
const NodeDeclaration * declaration() const
const InputSocketRef & input_by_identifier(StringRef identifier) const
Span< const SocketRef * > sockets(eNodeSocketInOut in_out) const
StringRefNull idname() const
StringRefNull name() const
const NodeTreeRef & tree() const
StringRefNull label() const
bool any_socket_is_directly_linked(eNodeSocketInOut in_out) const
bool any_input_is_directly_linked() const
Span< const OutputSocketRef * > output_sockets() const
Span< const SocketRef * > sockets() const
ToposortResult toposort(ToposortDirection direction) const
bool has_undefined_nodes_or_sockets() const
const NodeRef * group_output_node() const
const NodeRef * find_node(const bNode &bnode) const
NodeTreeRef(bNodeTree *btree)
std::string to_dot() const
Span< const LinkRef * > links() const
Span< const NodeRef * > nodes() const
StringRefNull name() const
Span< const InputSocketRef * > input_sockets() const
Span< const NodeRef * > nodes_by_type(StringRefNull idname) const
Span< const InputSocketRef * > directly_linked_sockets() const
Span< const InputSocketRef * > logically_linked_sockets() const
const NodeRef & node() const
Vector< LinkRef * > directly_linked_links_
Span< const SocketRef * > logically_linked_sockets() const
const OutputSocketRef & as_output() const
PointerRNA rna() const
bNodeSocketType * typeinfo() const
Span< const SocketRef * > directly_linked_sockets() const
StringRefNull idname() const
MutableSpan< const SocketRef * > directly_linked_sockets_
Span< const SocketRef * > logically_linked_skipped_sockets() const
const NodeTreeRef & tree() const
MutableSpan< const SocketRef * > logically_linked_skipped_sockets_
bNodeSocket * bsocket() const
const SocketRef & as_base() const
StringRefNull identifier() const
const InputSocketRef & as_input() const
Span< const LinkRef * > directly_linked_links() const
MutableSpan< const SocketRef * > logically_linked_sockets_
StringRefNull name() const
#define T
Map< bNodeTree *, std::unique_ptr< const NodeTreeRef > > NodeTreeRefMap
const NodeTreeRef & get_tree_ref_from_map(NodeTreeRefMap &node_tree_refs, bNodeTree &btree)
char name[66]
Definition: DNA_ID.h:378
Defines a socket type.
Definition: BKE_node.h:143
char name[64]
void * default_value
struct bNodeSocketType * typeinfo
char identifier[64]
char idname[64]
Defines a node type.
Definition: BKE_node.h:226
struct bNodeType * typeinfo
char name[64]
short type
bNodeRuntimeHandle * runtime
void * storage
char idname[64]
char label[64]