Blender  V3.3
node_common.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2007 Blender Foundation. All rights reserved. */
3 
8 #include <cstddef>
9 #include <cstring>
10 
11 #include "DNA_node_types.h"
12 
13 #include "BLI_listbase.h"
14 #include "BLI_map.hh"
15 #include "BLI_multi_value_map.hh"
16 #include "BLI_set.hh"
17 #include "BLI_stack.hh"
18 #include "BLI_string.h"
19 #include "BLI_string_ref.hh"
20 #include "BLI_utildefines.h"
21 
22 #include "BLT_translation.h"
23 
24 #include "BKE_node.h"
25 #include "BKE_node_tree_update.h"
26 
27 #include "RNA_types.h"
28 
29 #include "MEM_guardedalloc.h"
30 
31 #include "NOD_common.h"
32 #include "node_common.h"
33 #include "node_util.h"
34 
35 using blender::Map;
37 using blender::Set;
38 using blender::Stack;
39 using blender::StringRef;
40 using blender::Vector;
41 
42 /* -------------------------------------------------------------------- */
46 static bNodeSocket *find_matching_socket(ListBase &sockets, StringRef identifier)
47 {
48  LISTBASE_FOREACH (bNodeSocket *, socket, &sockets) {
49  if (socket->identifier == identifier) {
50  return socket;
51  }
52  }
53  return nullptr;
54 }
55 
56 bNodeSocket *node_group_find_input_socket(bNode *groupnode, const char *identifier)
57 {
58  return find_matching_socket(groupnode->inputs, identifier);
59 }
60 
61 bNodeSocket *node_group_find_output_socket(bNode *groupnode, const char *identifier)
62 {
63  return find_matching_socket(groupnode->outputs, identifier);
64 }
65 
66 void node_group_label(const bNodeTree *UNUSED(ntree), const bNode *node, char *label, int maxlen)
67 {
68  BLI_strncpy(label, (node->id) ? node->id->name + 2 : IFACE_("Missing Data-Block"), maxlen);
69 }
70 
71 bool node_group_poll_instance(bNode *node, bNodeTree *nodetree, const char **disabled_hint)
72 {
73  if (node->typeinfo->poll(node->typeinfo, nodetree, disabled_hint)) {
74  bNodeTree *grouptree = (bNodeTree *)node->id;
75  if (grouptree) {
76  return nodeGroupPoll(nodetree, grouptree, disabled_hint);
77  }
78 
79  return true; /* without a linked node tree, group node is always ok */
80  }
81 
82  return false;
83 }
84 
85 bool nodeGroupPoll(bNodeTree *nodetree, bNodeTree *grouptree, const char **r_disabled_hint)
86 {
87  bool valid = true;
88 
89  /* unspecified node group, generally allowed
90  * (if anything, should be avoided on operator level)
91  */
92  if (grouptree == nullptr) {
93  return true;
94  }
95 
96  if (nodetree == grouptree) {
97  *r_disabled_hint = TIP_("Nesting a node group inside of itself is not allowed");
98  return false;
99  }
100 
101  LISTBASE_FOREACH (bNode *, node, &grouptree->nodes) {
102  if (node->typeinfo->poll_instance &&
103  !node->typeinfo->poll_instance(node, nodetree, r_disabled_hint)) {
104  valid = false;
105  break;
106  }
107  }
108  return valid;
109 }
110 
112  bNode &node,
113  const bNodeSocket &interface_socket,
114  const eNodeSocketInOut in_out)
115 {
117  &node,
118  in_out,
119  interface_socket.idname,
120  interface_socket.identifier,
121  interface_socket.name);
122 
123  if (interface_socket.typeinfo->interface_init_socket) {
124  interface_socket.typeinfo->interface_init_socket(
125  &node_tree, &interface_socket, &node, socket, "interface");
126  }
127 }
128 
130  bNode &node,
131  bNodeSocket &socket_to_update,
132  const bNodeSocket &interface_socket)
133 {
134  strcpy(socket_to_update.name, interface_socket.name);
135 
136  const int mask = SOCK_HIDE_VALUE;
137  socket_to_update.flag = (socket_to_update.flag & ~mask) | (interface_socket.flag & mask);
138 
139  /* Update socket type if necessary */
140  if (socket_to_update.typeinfo != interface_socket.typeinfo) {
141  nodeModifySocketType(&node_tree, &node, &socket_to_update, interface_socket.idname);
142  }
143 
144  if (interface_socket.typeinfo->interface_verify_socket) {
145  interface_socket.typeinfo->interface_verify_socket(
146  &node_tree, &interface_socket, &node, &socket_to_update, "interface");
147  }
148 }
149 
157  bNode &node,
158  const ListBase &interface_sockets,
159  ListBase &verify_lb,
160  const eNodeSocketInOut in_out,
161  const bool ensure_extend_socket_exists)
162 {
163  ListBase old_sockets = verify_lb;
164  Vector<bNodeSocket *> ordered_old_sockets = old_sockets;
165  BLI_listbase_clear(&verify_lb);
166 
167  LISTBASE_FOREACH (const bNodeSocket *, interface_socket, &interface_sockets) {
168  bNodeSocket *matching_socket = find_matching_socket(old_sockets, interface_socket->identifier);
169  if (matching_socket) {
170  /* If a socket with the same identifier exists in the previous socket list, update it
171  * with the correct name, type, etc. Then move it from the old list to the new one. */
172  update_socket_to_match_interface(node_tree, node, *matching_socket, *interface_socket);
173  BLI_remlink(&old_sockets, matching_socket);
174  BLI_addtail(&verify_lb, matching_socket);
175  }
176  else {
177  /* If there was no socket with the same identifier already, simply create a new socket
178  * based on the interface socket, which will already add it to the new list. */
179  add_new_socket_from_interface(node_tree, node, *interface_socket, in_out);
180  }
181  }
182 
183  if (ensure_extend_socket_exists) {
184  bNodeSocket *last_socket = static_cast<bNodeSocket *>(old_sockets.last);
185  if (last_socket != nullptr && STREQ(last_socket->identifier, "__extend__")) {
186  BLI_remlink(&old_sockets, last_socket);
187  BLI_addtail(&verify_lb, last_socket);
188  }
189  else {
190  nodeAddSocket(&node_tree, &node, in_out, "NodeSocketVirtual", "__extend__", "");
191  }
192  }
193 
194  /* Remove leftover sockets that didn't match the node group's interface. */
195  LISTBASE_FOREACH_MUTABLE (bNodeSocket *, unused_socket, &old_sockets) {
196  nodeRemoveSocket(&node_tree, &node, unused_socket);
197  }
198 
199  {
200  /* Check if new sockets match the old sockets. */
201  int index;
202  LISTBASE_FOREACH_INDEX (bNodeSocket *, new_socket, &verify_lb, index) {
203  if (index < ordered_old_sockets.size()) {
204  if (ordered_old_sockets[index] != new_socket) {
206  break;
207  }
208  }
209  }
210  }
211 }
212 
214 {
215  /* check inputs and outputs, and remove or insert them */
216  if (node->id == nullptr) {
218  }
219  else if ((ID_IS_LINKED(node->id) && (node->id->tag & LIB_TAG_MISSING))) {
220  /* Missing data-block, leave sockets unchanged so that when it comes back
221  * the links remain valid. */
222  }
223  else {
224  bNodeTree *ngroup = (bNodeTree *)node->id;
225  group_verify_socket_list(*ntree, *node, ngroup->inputs, node->inputs, SOCK_IN, false);
226  group_verify_socket_list(*ntree, *node, ngroup->outputs, node->outputs, SOCK_OUT, false);
227  }
228 }
229 
232 /* -------------------------------------------------------------------- */
237 {
238  NodeFrame *data = MEM_cnew<NodeFrame>("frame node storage");
239  node->storage = data;
240 
241  data->flag |= NODE_FRAME_SHRINK;
242 
243  data->label_size = 20;
244 }
245 
247 {
248  /* frame type is used for all tree types, needs dynamic allocation */
249  bNodeType *ntype = MEM_cnew<bNodeType>("frame node type");
250  ntype->free_self = (void (*)(bNodeType *))MEM_freeN;
251 
252  node_type_base(ntype, NODE_FRAME, "Frame", NODE_CLASS_LAYOUT);
255  node_type_size(ntype, 150, 100, 0);
256  ntype->flag |= NODE_BACKGROUND;
257 
258  nodeRegisterType(ntype);
259 }
260 
263 /* -------------------------------------------------------------------- */
268 {
269  /* NOTE: Cannot use socket templates for this, since it would reset the socket type
270  * on each file read via the template verification procedure.
271  */
272  nodeAddStaticSocket(ntree, node, SOCK_IN, SOCK_RGBA, PROP_NONE, "Input", "Input");
273  nodeAddStaticSocket(ntree, node, SOCK_OUT, SOCK_RGBA, PROP_NONE, "Output", "Output");
274 }
275 
277 {
278  /* frame type is used for all tree types, needs dynamic allocation */
279  bNodeType *ntype = MEM_cnew<bNodeType>("frame node type");
280  ntype->free_self = (void (*)(bNodeType *))MEM_freeN;
281 
282  node_type_base(ntype, NODE_REROUTE, "Reroute", NODE_CLASS_LAYOUT);
284 
285  nodeRegisterType(ntype);
286 }
287 
289  bNodeSocket *start_socket,
291  Map<bNode *, const bNodeSocketType *> &r_reroute_types)
292 {
293  Stack<bNode *> nodes_to_check;
294  for (bNodeLink *link : links_map.lookup(start_socket)) {
295  if (link->tonode->type == NODE_REROUTE) {
296  nodes_to_check.push(link->tonode);
297  }
298  if (link->fromnode->type == NODE_REROUTE) {
299  nodes_to_check.push(link->fromnode);
300  }
301  }
302  const bNodeSocketType *current_type = start_socket->typeinfo;
303  while (!nodes_to_check.is_empty()) {
304  bNode *reroute_node = nodes_to_check.pop();
305  BLI_assert(reroute_node->type == NODE_REROUTE);
306  if (r_reroute_types.add(reroute_node, current_type)) {
307  for (bNodeLink *link : links_map.lookup((bNodeSocket *)reroute_node->inputs.first)) {
308  if (link->fromnode->type == NODE_REROUTE) {
309  nodes_to_check.push(link->fromnode);
310  }
311  }
312  for (bNodeLink *link : links_map.lookup((bNodeSocket *)reroute_node->outputs.first)) {
313  if (link->tonode->type == NODE_REROUTE) {
314  nodes_to_check.push(link->tonode);
315  }
316  }
317  }
318  }
319 }
320 
322 {
323  /* Contains nodes that are linked to at least one reroute node. */
324  Set<bNode *> nodes_linked_with_reroutes;
325  /* Contains all links that are linked to at least one reroute node. */
327  /* Build acceleration data structures for the algorithm below. */
328  LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
329  if (link->fromsock == nullptr || link->tosock == nullptr) {
330  continue;
331  }
332  if (link->fromnode->type != NODE_REROUTE && link->tonode->type != NODE_REROUTE) {
333  continue;
334  }
335  if (link->fromnode->type != NODE_REROUTE) {
336  nodes_linked_with_reroutes.add(link->fromnode);
337  }
338  if (link->tonode->type != NODE_REROUTE) {
339  nodes_linked_with_reroutes.add(link->tonode);
340  }
341  links_map.add(link->fromsock, link);
342  links_map.add(link->tosock, link);
343  }
344 
345  /* Will contain the socket type for every linked reroute node. */
347 
348  /* Propagate socket types from left to right. */
349  for (bNode *start_node : nodes_linked_with_reroutes) {
350  LISTBASE_FOREACH (bNodeSocket *, output_socket, &start_node->outputs) {
351  propagate_reroute_type_from_start_socket(output_socket, links_map, reroute_types);
352  }
353  }
354 
355  /* Propagate socket types from right to left. This affects reroute nodes that haven't been
356  * changed in the loop above. */
357  for (bNode *start_node : nodes_linked_with_reroutes) {
358  LISTBASE_FOREACH (bNodeSocket *, input_socket, &start_node->inputs) {
359  propagate_reroute_type_from_start_socket(input_socket, links_map, reroute_types);
360  }
361  }
362 
363  /* Actually update reroute nodes with changed types. */
364  for (const auto item : reroute_types.items()) {
365  bNode *reroute_node = item.key;
366  const bNodeSocketType *socket_type = item.value;
367  bNodeSocket *input_socket = (bNodeSocket *)reroute_node->inputs.first;
368  bNodeSocket *output_socket = (bNodeSocket *)reroute_node->outputs.first;
369 
370  if (input_socket->typeinfo != socket_type) {
371  nodeModifySocketType(ntree, reroute_node, input_socket, socket_type->idname);
372  }
373  if (output_socket->typeinfo != socket_type) {
374  nodeModifySocketType(ntree, reroute_node, output_socket, socket_type->idname);
375  }
376  }
377 }
378 
380 {
381  bNodeLink *link;
382 
383  /* avoid redundant checks, and infinite loops in case of cyclic node links */
384  if (node->done) {
385  return false;
386  }
387  node->done = 1;
388 
389  /* main test, done before child loop so it catches output nodes themselves as well */
390  if (node->typeinfo->nclass == NODE_CLASS_OUTPUT && node->flag & NODE_DO_OUTPUT) {
391  return true;
392  }
393 
394  /* test all connected nodes, first positive find is sufficient to return true */
395  for (link = (bNodeLink *)ntree->links.first; link; link = link->next) {
396  if (link->fromnode == node) {
398  return true;
399  }
400  }
401  }
402  return false;
403 }
404 
406 {
407  bNode *tnode;
408 
409  /* clear flags */
410  for (tnode = (bNode *)ntree->nodes.first; tnode; tnode = tnode->next) {
411  tnode->done = 0;
412  }
413 
415 }
416 
418 {
419  bNode *node;
420 
421  for (node = (bNode *)ntree->nodes.first; node; node = node->next) {
422  if (node->id == id) {
423  node->id = nullptr;
424  }
425  }
426 }
427 
430 /* -------------------------------------------------------------------- */
434 static bool is_group_extension_socket(const bNode *node, const bNodeSocket *socket)
435 {
436  return socket->type == SOCK_CUSTOM && ELEM(node->type, NODE_GROUP_OUTPUT, NODE_GROUP_INPUT);
437 }
438 
440 {
442 }
443 
445 {
446  bNodeSocket *sock;
447  for (sock = (bNodeSocket *)node->outputs.first; sock; sock = sock->next) {
448  if (STREQ(sock->identifier, identifier)) {
449  return sock;
450  }
451  }
452  return nullptr;
453 }
454 
456 {
457  bNodeSocket *extsock = (bNodeSocket *)node->outputs.last;
458  bNodeLink *link, *linknext, *exposelink;
459  /* Adding a tree socket and verifying will remove the extension socket!
460  * This list caches the existing links from the extension socket
461  * so they can be recreated after verification.
462  */
463  ListBase tmplinks;
464 
465  /* find links from the extension socket and store them */
466  BLI_listbase_clear(&tmplinks);
467  for (link = (bNodeLink *)ntree->links.first; link; link = linknext) {
468  linknext = link->next;
469  if (nodeLinkIsHidden(link)) {
470  continue;
471  }
472 
473  if (link->fromsock == extsock) {
474  bNodeLink *tlink = MEM_cnew<bNodeLink>("temporary link");
475  *tlink = *link;
476  BLI_addtail(&tmplinks, tlink);
477 
478  nodeRemLink(ntree, link);
479  }
480  }
481 
482  /* find valid link to expose */
483  exposelink = nullptr;
484  for (link = (bNodeLink *)tmplinks.first; link; link = link->next) {
485  /* XXX Multiple sockets can be connected to the extension socket at once,
486  * in that case the arbitrary first link determines name and type.
487  * This could be improved by choosing the "best" type among all links,
488  * whatever that means.
489  */
490  if (!is_group_extension_socket(link->tonode, link->tosock)) {
491  exposelink = link;
492  break;
493  }
494  }
495 
496  if (exposelink) {
497  bNodeSocket *gsock, *newsock;
498 
499  gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->tonode, exposelink->tosock);
500 
502  newsock = node_group_input_find_socket(node, gsock->identifier);
503 
504  /* redirect links from the extension socket */
505  for (link = (bNodeLink *)tmplinks.first; link; link = link->next) {
506  bNodeLink *newlink = nodeAddLink(ntree, node, newsock, link->tonode, link->tosock);
507  if (newlink->tosock->flag & SOCK_MULTI_INPUT) {
509  }
510  }
511  }
512 
513  BLI_freelistN(&tmplinks);
515 }
516 
518 {
519  /* used for all tree types, needs dynamic allocation */
520  bNodeType *ntype = MEM_cnew<bNodeType>("node type");
521  ntype->free_self = (void (*)(bNodeType *))MEM_freeN;
522 
523  node_type_base(ntype, NODE_GROUP_INPUT, "Group Input", NODE_CLASS_INTERFACE);
524  node_type_size(ntype, 140, 80, 400);
527 
528  nodeRegisterType(ntype);
529 }
530 
532 {
534 }
535 
537 {
538  bNodeSocket *sock;
539  for (sock = (bNodeSocket *)node->inputs.first; sock; sock = sock->next) {
540  if (STREQ(sock->identifier, identifier)) {
541  return sock;
542  }
543  }
544  return nullptr;
545 }
546 
548 {
549  bNodeSocket *extsock = (bNodeSocket *)node->inputs.last;
550  bNodeLink *link, *linknext, *exposelink;
551  /* Adding a tree socket and verifying will remove the extension socket!
552  * This list caches the existing links to the extension socket
553  * so they can be recreated after verification.
554  */
555  ListBase tmplinks;
556 
557  /* find links to the extension socket and store them */
558  BLI_listbase_clear(&tmplinks);
559  for (link = (bNodeLink *)ntree->links.first; link; link = linknext) {
560  linknext = link->next;
561  if (nodeLinkIsHidden(link)) {
562  continue;
563  }
564 
565  if (link->tosock == extsock) {
566  bNodeLink *tlink = MEM_cnew<bNodeLink>("temporary link");
567  *tlink = *link;
568  BLI_addtail(&tmplinks, tlink);
569 
570  nodeRemLink(ntree, link);
571  }
572  }
573 
574  /* find valid link to expose */
575  exposelink = nullptr;
576  for (link = (bNodeLink *)tmplinks.first; link; link = link->next) {
577  /* XXX Multiple sockets can be connected to the extension socket at once,
578  * in that case the arbitrary first link determines name and type.
579  * This could be improved by choosing the "best" type among all links,
580  * whatever that means.
581  */
582  if (!is_group_extension_socket(link->fromnode, link->fromsock)) {
583  exposelink = link;
584  break;
585  }
586  }
587 
588  if (exposelink) {
589  bNodeSocket *gsock, *newsock;
590 
591  /* XXX what if connecting virtual to virtual socket?? */
592  gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->fromnode, exposelink->fromsock);
593 
595  newsock = node_group_output_find_socket(node, gsock->identifier);
596 
597  /* redirect links to the extension socket */
598  for (link = (bNodeLink *)tmplinks.first; link; link = link->next) {
599  nodeAddLink(ntree, link->fromnode, link->fromsock, node, newsock);
600  }
601  }
602 
603  BLI_freelistN(&tmplinks);
605 }
606 
608 {
609  /* used for all tree types, needs dynamic allocation */
610  bNodeType *ntype = MEM_cnew<bNodeType>("node type");
611  ntype->free_self = (void (*)(bNodeType *))MEM_freeN;
612 
613  node_type_base(ntype, NODE_GROUP_OUTPUT, "Group Output", NODE_CLASS_INTERFACE);
614  node_type_size(ntype, 140, 80, 400);
617 
618  ntype->no_muting = true;
619 
620  nodeRegisterType(ntype);
621 }
622 
#define NODE_CLASS_OUTPUT
Definition: BKE_node.h:346
#define NODE_REROUTE
Definition: BKE_node.h:986
void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwidth)
Definition: node.cc:4396
bool nodeLinkIsHidden(const struct bNodeLink *link)
#define NODE_CLASS_INTERFACE
Definition: BKE_node.h:357
struct bNodeSocket * nodeAddSocket(struct bNodeTree *ntree, struct bNode *node, eNodeSocketInOut in_out, const char *idname, const char *identifier, const char *name)
Definition: node.cc:1679
void node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass)
Definition: node.cc:4277
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4443
void nodeModifySocketType(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock, const char *idname)
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4390
void nodeRemoveAllSockets(struct bNodeTree *ntree, struct bNode *node)
Definition: node.cc:1967
void nodeRemLink(struct bNodeTree *ntree, struct bNodeLink *link)
Definition: node.cc:2338
struct bNodeSocket * nodeAddStaticSocket(struct bNodeTree *ntree, struct bNode *node, eNodeSocketInOut in_out, int type, int subtype, const char *identifier, const char *name)
Definition: node.cc:1897
struct bNodeSocket * ntreeAddSocketInterfaceFromSocket(struct bNodeTree *ntree, struct bNode *from_node, struct bNodeSocket *from_sock)
Definition: node.cc:3382
void node_type_storage(struct bNodeType *ntype, const char *storagename, void(*freefunc)(struct bNode *node), void(*copyfunc)(struct bNodeTree *dest_ntree, struct bNode *dest_node, const struct bNode *src_node))
Definition: node.cc:4426
struct bNodeLink * nodeAddLink(struct bNodeTree *ntree, struct bNode *fromnode, struct bNodeSocket *fromsock, struct bNode *tonode, struct bNodeSocket *tosock)
Definition: node.cc:2296
void nodeRemoveSocket(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock)
Definition: node.cc:1933
#define NODE_CLASS_LAYOUT
Definition: BKE_node.h:361
#define NODE_FRAME
Definition: BKE_node.h:985
#define NODE_GROUP_INPUT
Definition: BKE_node.h:987
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
void BKE_ntree_update_tag_interface(struct bNodeTree *ntree)
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
Definition: BLI_listbase.h:354
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
Definition: BLI_listbase.h:344
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
#define TIP_(msgid)
#define IFACE_(msgid)
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:566
@ LIB_TAG_MISSING
Definition: DNA_ID.h:690
#define NODE_BACKGROUND
#define NODE_DO_OUTPUT
eNodeSocketInOut
@ SOCK_OUT
@ SOCK_IN
@ SOCK_HIDE_VALUE
@ SOCK_MULTI_INPUT
#define NODE_FRAME_SHRINK
@ SOCK_CUSTOM
@ SOCK_RGBA
Read Guarded memory(de)allocation.
NODE_GROUP_OUTPUT
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Map
@ PROP_NONE
Definition: RNA_types.h:126
bool add(const Key &key, const Value &value)
Definition: BLI_map.hh:250
ItemIterator items() const
Definition: BLI_map.hh:859
Span< Value > lookup(const Key &key) const
void add(const Key &key, const Value &value)
bool add(const Key &key)
Definition: BLI_set.hh:253
bool is_empty() const
Definition: BLI_stack.hh:308
void push(const T &value)
Definition: BLI_stack.hh:213
int64_t size() const
Definition: BLI_vector.hh:694
OperationNode * node
const char * label
SyclQueue void void size_t num_bytes void
bNodeTree * ntree
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
bNodeSocket * node_group_output_find_socket(bNode *node, const char *identifier)
Definition: node_common.cc:536
void BKE_node_tree_unlink_id(ID *id, struct bNodeTree *ntree)
Definition: node_common.cc:417
static void node_reroute_init(bNodeTree *ntree, bNode *node)
Definition: node_common.cc:267
void node_group_update(struct bNodeTree *ntree, struct bNode *node)
Definition: node_common.cc:213
bool node_group_poll_instance(bNode *node, bNodeTree *nodetree, const char **disabled_hint)
Definition: node_common.cc:71
static bool node_is_connected_to_output_recursive(bNodeTree *ntree, bNode *node)
Definition: node_common.cc:379
void register_node_type_group_output()
Definition: node_common.cc:607
static void propagate_reroute_type_from_start_socket(bNodeSocket *start_socket, const MultiValueMap< bNodeSocket *, bNodeLink * > &links_map, Map< bNode *, const bNodeSocketType * > &r_reroute_types)
Definition: node_common.cc:288
void register_node_type_group_input()
Definition: node_common.cc:517
static void group_verify_socket_list(bNodeTree &node_tree, bNode &node, const ListBase &interface_sockets, ListBase &verify_lb, const eNodeSocketInOut in_out, const bool ensure_extend_socket_exists)
Definition: node_common.cc:156
void ntree_update_reroute_nodes(bNodeTree *ntree)
Definition: node_common.cc:321
void register_node_type_frame()
Definition: node_common.cc:246
static bNodeSocket * find_matching_socket(ListBase &sockets, StringRef identifier)
Definition: node_common.cc:46
void node_group_label(const bNodeTree *UNUSED(ntree), const bNode *node, char *label, int maxlen)
Definition: node_common.cc:66
void node_group_input_update(bNodeTree *ntree, bNode *node)
Definition: node_common.cc:455
static void node_group_output_init(bNodeTree *ntree, bNode *node)
Definition: node_common.cc:531
bool BKE_node_is_connected_to_output(bNodeTree *ntree, bNode *node)
Definition: node_common.cc:405
bNodeSocket * node_group_find_output_socket(bNode *groupnode, const char *identifier)
Definition: node_common.cc:61
static void node_frame_init(bNodeTree *UNUSED(ntree), bNode *node)
Definition: node_common.cc:236
static void update_socket_to_match_interface(bNodeTree &node_tree, bNode &node, bNodeSocket &socket_to_update, const bNodeSocket &interface_socket)
Definition: node_common.cc:129
bNodeSocket * node_group_input_find_socket(bNode *node, const char *identifier)
Definition: node_common.cc:444
static void node_group_input_init(bNodeTree *ntree, bNode *node)
Definition: node_common.cc:439
bool nodeGroupPoll(bNodeTree *nodetree, bNodeTree *grouptree, const char **r_disabled_hint)
Definition: node_common.cc:85
static void add_new_socket_from_interface(bNodeTree &node_tree, bNode &node, const bNodeSocket &interface_socket, const eNodeSocketInOut in_out)
Definition: node_common.cc:111
bNodeSocket * node_group_find_input_socket(bNode *groupnode, const char *identifier)
Definition: node_common.cc:56
void node_group_output_update(bNodeTree *ntree, bNode *node)
Definition: node_common.cc:547
static bool is_group_extension_socket(const bNode *node, const bNodeSocket *socket)
Definition: node_common.cc:434
void register_node_type_reroute()
Definition: node_common.cc:276
void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
Definition: node_util.c:55
void node_free_standard_storage(bNode *node)
Definition: node_util.c:43
Definition: DNA_ID.h:368
void * last
Definition: DNA_listBase.h:31
void * first
Definition: DNA_listBase.h:31
Defines a socket type.
Definition: BKE_node.h:143
void(* interface_init_socket)(struct bNodeTree *ntree, const struct bNodeSocket *interface_socket, struct bNode *node, struct bNodeSocket *sock, const char *data_path)
Definition: BKE_node.h:164
void(* interface_verify_socket)(struct bNodeTree *ntree, const struct bNodeSocket *interface_socket, struct bNode *node, struct bNodeSocket *sock, const char *data_path)
Definition: BKE_node.h:169
char idname[64]
Definition: BKE_node.h:145
char name[64]
struct bNodeSocket * next
struct bNodeSocketType * typeinfo
char identifier[64]
char idname[64]
ListBase nodes
ListBase inputs
ListBase links
ListBase outputs
Defines a node type.
Definition: BKE_node.h:226
short flag
Definition: BKE_node.h:236
void(* free_self)(struct bNodeType *ntype)
Definition: BKE_node.h:303
bool no_muting
Definition: BKE_node.h:338
ListBase inputs
short done
short type
struct bNode * next
ListBase outputs