Blender  V2.93
NOD_node_tree_ref.hh
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 #pragma once
18 
47 #include "BLI_array.hh"
48 #include "BLI_function_ref.hh"
49 #include "BLI_linear_allocator.hh"
50 #include "BLI_map.hh"
51 #include "BLI_multi_value_map.hh"
52 #include "BLI_string_ref.hh"
53 #include "BLI_timeit.hh"
54 #include "BLI_utility_mixins.hh"
55 #include "BLI_vector.hh"
56 
57 #include "BKE_node.h"
58 
59 #include "DNA_node_types.h"
60 
61 #include "RNA_access.h"
62 
63 namespace blender::nodes {
64 
65 class SocketRef;
66 class InputSocketRef;
67 class OutputSocketRef;
68 class NodeRef;
69 class NodeTreeRef;
70 class LinkRef;
71 class InternalLinkRef;
72 
74  protected:
77  bool is_input_;
78  int id_;
79  int index_;
82 
83  /* These sockets are linked directly, i.e. with a single link in between. */
85  /* These sockets are linked when reroutes, muted links and muted nodes have been taken into
86  * account. */
88  /* These are the sockets that have been skipped when searching for logically linked sockets.
89  * That includes for example the input and output socket of an intermediate reroute node. */
91 
92  friend NodeTreeRef;
93 
94  public:
99 
100  bool is_directly_linked() const;
101  bool is_logically_linked() const;
102 
103  const NodeRef &node() const;
104  const NodeTreeRef &tree() const;
105 
106  int id() const;
107  int index() const;
108 
109  bool is_input() const;
110  bool is_output() const;
111 
112  const SocketRef &as_base() const;
113  const InputSocketRef &as_input() const;
114  const OutputSocketRef &as_output() const;
115 
116  PointerRNA *rna() const;
117 
118  StringRefNull idname() const;
119  StringRefNull name() const;
120  StringRefNull identifier() const;
121  bNodeSocketType *typeinfo() const;
122 
123  bNodeSocket *bsocket() const;
124  bNode *bnode() const;
125  bNodeTree *btree() const;
126 
127  bool is_available() const;
128  bool is_undefined() const;
129 
130  void *default_value() const;
131  template<typename T> T *default_value() const;
132 };
133 
135  public:
136  friend NodeTreeRef;
137 
140 
141  bool is_multi_input_socket() const;
142 
143  private:
144  void foreach_logical_origin(FunctionRef<void(const OutputSocketRef &)> origin_fn,
145  FunctionRef<void(const SocketRef &)> skipped_fn,
146  bool only_follow_first_input_link,
147  Vector<const InputSocketRef *> &handled_sockets) const;
148 };
149 
151  public:
152  friend NodeTreeRef;
153 
156 
157  private:
158  void foreach_logical_target(FunctionRef<void(const InputSocketRef &)> target_fn,
159  FunctionRef<void(const SocketRef &)> skipped_fn,
160  Vector<const OutputSocketRef *> &handled_sockets) const;
161 };
162 
164  private:
165  NodeTreeRef *tree_;
166  bNode *bnode_;
167  PointerRNA rna_;
168  int id_;
169  Vector<InputSocketRef *> inputs_;
170  Vector<OutputSocketRef *> outputs_;
171  Vector<InternalLinkRef *> internal_links_;
172 
173  friend NodeTreeRef;
174 
175  public:
176  const NodeTreeRef &tree() const;
177 
181 
182  const InputSocketRef &input(int index) const;
183  const OutputSocketRef &output(int index) const;
184 
185  bNode *bnode() const;
186  bNodeTree *btree() const;
187 
188  PointerRNA *rna() const;
189  StringRefNull idname() const;
190  StringRefNull name() const;
191  bNodeType *typeinfo() 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_;
249 
250  public:
252  ~NodeTreeRef();
253 
256  Span<const NodeRef *> nodes_by_type(const bNodeType *nodetype) const;
257 
261 
263 
264  bool has_link_cycles() const;
265  bool has_undefined_nodes_or_sockets() const;
266 
267  bNodeTree *btree() const;
268  StringRefNull name() const;
269 
270  std::string to_dot() const;
271 
272  private:
273  /* Utility functions used during construction. */
274  InputSocketRef &find_input_socket(Map<bNode *, NodeRef *> &node_mapping,
275  bNode *bnode,
276  bNodeSocket *bsocket);
277  OutputSocketRef &find_output_socket(Map<bNode *, NodeRef *> &node_mapping,
278  bNode *bnode,
279  bNodeSocket *bsocket);
280 
281  void create_linked_socket_caches();
282 };
283 
285 
286 const NodeTreeRef &get_tree_ref_from_map(NodeTreeRefMap &node_tree_refs, bNodeTree &btree);
287 
288 namespace node_tree_ref_types {
290 using nodes::NodeRef;
291 using nodes::NodeTreeRef;
294 using nodes::SocketRef;
295 } // namespace node_tree_ref_types
296 
297 /* --------------------------------------------------------------------
298  * SocketRef inline methods.
299  */
300 
302 {
304 }
305 
307 {
309 }
310 
312 {
314 }
315 
317 {
318  return directly_linked_links_;
319 }
320 
321 inline bool SocketRef::is_directly_linked() const
322 {
323  return directly_linked_sockets_.size() > 0;
324 }
325 
327 {
328  return logically_linked_sockets_.size() > 0;
329 }
330 
331 inline const NodeRef &SocketRef::node() const
332 {
333  return *node_;
334 }
335 
336 inline const NodeTreeRef &SocketRef::tree() const
337 {
338  return node_->tree();
339 }
340 
341 inline int SocketRef::id() const
342 {
343  return id_;
344 }
345 
346 inline int SocketRef::index() const
347 {
348  return index_;
349 }
350 
351 inline bool SocketRef::is_input() const
352 {
353  return is_input_;
354 }
355 
356 inline bool SocketRef::is_output() const
357 {
358  return !is_input_;
359 }
360 
361 inline const SocketRef &SocketRef::as_base() const
362 {
363  return *this;
364 }
365 
366 inline const InputSocketRef &SocketRef::as_input() const
367 {
368  BLI_assert(this->is_input());
369  return static_cast<const InputSocketRef &>(*this);
370 }
371 
373 {
374  BLI_assert(this->is_output());
375  return static_cast<const OutputSocketRef &>(*this);
376 }
377 
378 inline PointerRNA *SocketRef::rna() const
379 {
380  return const_cast<PointerRNA *>(&rna_);
381 }
382 
384 {
385  return bsocket_->idname;
386 }
387 
389 {
390  return bsocket_->name;
391 }
392 
394 {
395  return bsocket_->identifier;
396 }
397 
399 {
400  return bsocket_->typeinfo;
401 }
402 
404 {
405  return bsocket_;
406 }
407 
408 inline bNode *SocketRef::bnode() const
409 {
410  return node_->bnode();
411 }
412 
414 {
415  return node_->btree();
416 }
417 
418 inline bool SocketRef::is_available() const
419 {
420  return (bsocket_->flag & SOCK_UNAVAIL) == 0;
421 }
422 
423 inline bool SocketRef::is_undefined() const
424 {
426 }
427 
428 inline void *SocketRef::default_value() const
429 {
430  return bsocket_->default_value;
431 }
432 
433 template<typename T> inline T *SocketRef::default_value() const
434 {
435  return (T *)bsocket_->default_value;
436 }
437 
438 /* --------------------------------------------------------------------
439  * InputSocketRef inline methods.
440  */
441 
443 {
444  return logically_linked_sockets_.as_span().cast<const OutputSocketRef *>();
445 }
446 
448 {
449  return directly_linked_sockets_.cast<const OutputSocketRef *>();
450 }
451 
453 {
454  return bsocket_->flag & SOCK_MULTI_INPUT;
455 }
456 
457 /* --------------------------------------------------------------------
458  * OutputSocketRef inline methods.
459  */
460 
462 {
463  return logically_linked_sockets_.as_span().cast<const InputSocketRef *>();
464 }
465 
467 {
468  return directly_linked_sockets_.cast<const InputSocketRef *>();
469 }
470 
471 /* --------------------------------------------------------------------
472  * NodeRef inline methods.
473  */
474 
475 inline const NodeTreeRef &NodeRef::tree() const
476 {
477  return *tree_;
478 }
479 
481 {
482  return inputs_;
483 }
484 
486 {
487  return outputs_;
488 }
489 
491 {
492  return internal_links_;
493 }
494 
495 inline const InputSocketRef &NodeRef::input(int index) const
496 {
497  return *inputs_[index];
498 }
499 
500 inline const OutputSocketRef &NodeRef::output(int index) const
501 {
502  return *outputs_[index];
503 }
504 
505 inline bNode *NodeRef::bnode() const
506 {
507  return bnode_;
508 }
509 
510 inline bNodeTree *NodeRef::btree() const
511 {
512  return tree_->btree();
513 }
514 
515 inline PointerRNA *NodeRef::rna() const
516 {
517  return const_cast<PointerRNA *>(&rna_);
518 }
519 
521 {
522  return bnode_->idname;
523 }
524 
526 {
527  return bnode_->name;
528 }
529 
531 {
532  return bnode_->typeinfo;
533 }
534 
535 inline int NodeRef::id() const
536 {
537  return id_;
538 }
539 
540 inline bool NodeRef::is_reroute_node() const
541 {
542  return bnode_->type == NODE_REROUTE;
543 }
544 
545 inline bool NodeRef::is_group_node() const
546 {
547  return bnode_->type == NODE_GROUP || bnode_->type == NODE_CUSTOM_GROUP;
548 }
549 
550 inline bool NodeRef::is_group_input_node() const
551 {
552  return bnode_->type == NODE_GROUP_INPUT;
553 }
554 
555 inline bool NodeRef::is_group_output_node() const
556 {
557  return bnode_->type == NODE_GROUP_OUTPUT;
558 }
559 
560 inline bool NodeRef::is_frame() const
561 {
562  return bnode_->type == NODE_FRAME;
563 }
564 
565 inline bool NodeRef::is_undefined() const
566 {
567  return bnode_->typeinfo == &NodeTypeUndefined;
568 }
569 
570 inline bool NodeRef::is_muted() const
571 {
572  return (bnode_->flag & NODE_MUTED) != 0;
573 }
574 
575 inline void *NodeRef::storage() const
576 {
577  return bnode_->storage;
578 }
579 
580 template<typename T> inline T *NodeRef::storage() const
581 {
582  return (T *)bnode_->storage;
583 }
584 
585 /* --------------------------------------------------------------------
586  * LinkRef inline methods.
587  */
588 
589 inline const OutputSocketRef &LinkRef::from() const
590 {
591  return *from_;
592 }
593 
594 inline const InputSocketRef &LinkRef::to() const
595 {
596  return *to_;
597 }
598 
599 inline bNodeLink *LinkRef::blink() const
600 {
601  return blink_;
602 }
603 
604 inline bool LinkRef::is_muted() const
605 {
606  return blink_->flag & NODE_LINK_MUTED;
607 }
608 
609 /* --------------------------------------------------------------------
610  * InternalLinkRef inline methods.
611  */
612 
614 {
615  return *from_;
616 }
617 
619 {
620  return *to_;
621 }
622 
624 {
625  return blink_;
626 }
627 
628 /* --------------------------------------------------------------------
629  * NodeTreeRef inline methods.
630  */
631 
633 {
634  return nodes_by_id_;
635 }
636 
638 {
639  const bNodeType *nodetype = nodeTypeFind(idname.c_str());
640  return this->nodes_by_type(nodetype);
641 }
642 
644 {
645  return nodes_by_type_.lookup(nodetype);
646 }
647 
649 {
650  return sockets_by_id_;
651 }
652 
654 {
655  return input_sockets_;
656 }
657 
659 {
660  return output_sockets_;
661 }
662 
664 {
665  return links_;
666 }
667 
669 {
670  return btree_;
671 }
672 
674 {
675  return btree_->id.name + 2;
676 }
677 
678 } // namespace blender::nodes
#define NODE_REROUTE
Definition: BKE_node.h:873
#define NODE_CUSTOM_GROUP
Definition: BKE_node.h:876
struct bNodeType NodeTypeUndefined
Definition: node.cc:98
struct bNodeType * nodeTypeFind(const char *idname)
Definition: node.cc:1254
struct bNodeSocketType NodeSocketTypeUndefined
Definition: node.cc:99
#define NODE_FRAME
Definition: BKE_node.h:872
#define NODE_GROUP_INPUT
Definition: BKE_node.h:874
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define final(a, b, c)
Definition: BLI_hash.h:35
#define NODE_MUTED
@ SOCK_MULTI_INPUT
@ SOCK_UNAVAIL
#define NODE_LINK_MUTED
NODE_GROUP_OUTPUT
NODE_GROUP
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(int index) const
Span< const InternalLinkRef * > internal_links() const
PointerRNA * rna() const
bNodeType * typeinfo() const
Span< const InputSocketRef * > inputs() const
const InputSocketRef & input(int index) const
bNodeTree * btree() const
Span< const OutputSocketRef * > outputs() const
StringRefNull idname() const
StringRefNull name() const
const NodeTreeRef & tree() const
Span< const OutputSocketRef * > output_sockets() const
Span< const SocketRef * > sockets() const
bool has_undefined_nodes_or_sockets() 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
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
PointerRNA * rna() 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:283
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:221
struct bNodeType * typeinfo
char name[64]
short type
void * storage
char idname[64]