Blender  V2.93
node_common.c
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  * The Original Code is Copyright (C) 2007 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include <stddef.h>
25 #include <string.h>
26 
27 #include "DNA_node_types.h"
28 
29 #include "BLI_listbase.h"
30 #include "BLI_string.h"
31 #include "BLI_utildefines.h"
32 
33 #include "BLT_translation.h"
34 
35 #include "BKE_node.h"
36 
37 #include "RNA_types.h"
38 
39 #include "MEM_guardedalloc.h"
40 
41 #include "NOD_common.h"
42 #include "node_common.h"
43 #include "node_util.h"
44 
45 enum {
46  REFINE_FORWARD = 1 << 0,
47  REFINE_BACKWARD = 1 << 1,
48 };
49 
50 /* -------------------------------------------------------------------- */
54 bNodeSocket *node_group_find_input_socket(bNode *groupnode, const char *identifier)
55 {
56  bNodeSocket *sock;
57  for (sock = groupnode->inputs.first; sock; sock = sock->next) {
58  if (STREQ(sock->identifier, identifier)) {
59  return sock;
60  }
61  }
62  return NULL;
63 }
64 
65 bNodeSocket *node_group_find_output_socket(bNode *groupnode, const char *identifier)
66 {
67  bNodeSocket *sock;
68  for (sock = groupnode->outputs.first; sock; sock = sock->next) {
69  if (STREQ(sock->identifier, identifier)) {
70  return sock;
71  }
72  }
73  return NULL;
74 }
75 
76 /* groups display their internal tree name as label */
77 void node_group_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen)
78 {
79  BLI_strncpy(label, (node->id) ? node->id->name + 2 : IFACE_("Missing Data-Block"), maxlen);
80 }
81 
82 bool node_group_poll_instance(bNode *node, bNodeTree *nodetree, const char **disabled_hint)
83 {
84  if (node->typeinfo->poll(node->typeinfo, nodetree, disabled_hint)) {
85  bNodeTree *grouptree = (bNodeTree *)node->id;
86  if (grouptree) {
87  return nodeGroupPoll(nodetree, grouptree, disabled_hint);
88  }
89 
90  return true; /* without a linked node tree, group node is always ok */
91  }
92 
93  return false;
94 }
95 
96 bool nodeGroupPoll(bNodeTree *nodetree, bNodeTree *grouptree, const char **r_disabled_hint)
97 {
98  bNode *node;
99  bool valid = true;
100 
101  /* unspecified node group, generally allowed
102  * (if anything, should be avoided on operator level)
103  */
104  if (grouptree == NULL) {
105  return true;
106  }
107 
108  if (nodetree == grouptree) {
109  *r_disabled_hint = "Nesting a node group inside of itself is not allowed";
110  return false;
111  }
112 
113  for (node = grouptree->nodes.first; node; node = node->next) {
114  if (node->typeinfo->poll_instance &&
115  !node->typeinfo->poll_instance(node, nodetree, r_disabled_hint)) {
116  valid = false;
117  break;
118  }
119  }
120  return valid;
121 }
122 
123 /* used for both group nodes and interface nodes */
125  bNodeTree *ntree, bNode *gnode, bNodeSocket *iosock, ListBase *verify_lb, int in_out)
126 {
127  bNodeSocket *sock;
128 
129  for (sock = verify_lb->first; sock; sock = sock->next) {
130  if (sock->typeinfo == iosock->typeinfo && STREQ(sock->identifier, iosock->identifier)) {
131  break;
132  }
133  }
134  if (sock) {
135  strcpy(sock->name, iosock->name);
136 
137  const int mask = SOCK_HIDE_VALUE;
138  sock->flag = (sock->flag & ~mask) | (iosock->flag & mask);
139 
140  if (iosock->typeinfo->interface_verify_socket) {
141  iosock->typeinfo->interface_verify_socket(ntree, iosock, gnode, sock, "interface");
142  }
143  }
144  else {
145  sock = nodeAddSocket(ntree, gnode, in_out, iosock->idname, iosock->identifier, iosock->name);
146 
147  if (iosock->typeinfo->interface_init_socket) {
148  iosock->typeinfo->interface_init_socket(ntree, iosock, gnode, sock, "interface");
149  }
150  }
151 
152  /* remove from list temporarily, to distinguish from orphaned sockets */
153  BLI_remlink(verify_lb, sock);
154 
155  return sock;
156 }
157 
158 /* used for both group nodes and interface nodes */
160  bNodeTree *ntree, bNode *gnode, ListBase *iosock_lb, ListBase *verify_lb, int in_out)
161 {
162  bNodeSocket *iosock, *sock, *nextsock;
163 
164  /* step by step compare */
165 
166  iosock = iosock_lb->first;
167  for (; iosock; iosock = iosock->next) {
168  /* abusing new_sock pointer for verification here! only used inside this function */
169  iosock->new_sock = group_verify_socket(ntree, gnode, iosock, verify_lb, in_out);
170  }
171  /* leftovers are removed */
172  for (sock = verify_lb->first; sock; sock = nextsock) {
173  nextsock = sock->next;
174  nodeRemoveSocket(ntree, gnode, sock);
175  }
176  /* and we put back the verified sockets */
177  iosock = iosock_lb->first;
178  for (; iosock; iosock = iosock->next) {
179  if (iosock->new_sock) {
180  BLI_addtail(verify_lb, iosock->new_sock);
181  iosock->new_sock = NULL;
182  }
183  }
184 }
185 
186 /* make sure all group node in ntree, which use ngroup, are sync'd */
188 {
189  /* check inputs and outputs, and remove or insert them */
190  if (node->id == NULL) {
192  }
193  else if ((ID_IS_LINKED(node->id) && (node->id->tag & LIB_TAG_MISSING))) {
194  /* Missing datablock, leave sockets unchanged so that when it comes back
195  * the links remain valid. */
196  }
197  else {
198  bNodeTree *ngroup = (bNodeTree *)node->id;
199  group_verify_socket_list(ntree, node, &ngroup->inputs, &node->inputs, SOCK_IN);
200  group_verify_socket_list(ntree, node, &ngroup->outputs, &node->outputs, SOCK_OUT);
201  }
202 }
203 
206 /* -------------------------------------------------------------------- */
211 {
212  NodeFrame *data = (NodeFrame *)MEM_callocN(sizeof(NodeFrame), "frame node storage");
213  node->storage = data;
214 
215  data->flag |= NODE_FRAME_SHRINK;
216 
217  data->label_size = 20;
218 }
219 
221 {
222  /* frame type is used for all tree types, needs dynamic allocation */
223  bNodeType *ntype = MEM_callocN(sizeof(bNodeType), "frame node type");
224  ntype->free_self = (void (*)(bNodeType *))MEM_freeN;
225 
229  node_type_size(ntype, 150, 100, 0);
230 
231  nodeRegisterType(ntype);
232 }
233 
236 /* -------------------------------------------------------------------- */
240 /* simple, only a single input and output here */
242 {
243  bNodeLink *link;
244 
245  /* Security check! */
246  if (!ntree) {
247  return;
248  }
249 
250  link = MEM_callocN(sizeof(bNodeLink), "internal node link");
251  link->fromnode = node;
252  link->fromsock = node->inputs.first;
253  link->tonode = node;
254  link->tosock = node->outputs.first;
255  /* internal link is always valid */
256  link->flag |= NODE_LINK_VALID;
257  BLI_addtail(&node->internal_links, link);
258 }
259 
261 {
262  /* Note: Cannot use socket templates for this, since it would reset the socket type
263  * on each file read via the template verification procedure.
264  */
265  nodeAddStaticSocket(ntree, node, SOCK_IN, SOCK_RGBA, PROP_NONE, "Input", "Input");
266  nodeAddStaticSocket(ntree, node, SOCK_OUT, SOCK_RGBA, PROP_NONE, "Output", "Output");
267 }
268 
270 {
271  /* frame type is used for all tree types, needs dynamic allocation */
272  bNodeType *ntype = MEM_callocN(sizeof(bNodeType), "frame node type");
273  ntype->free_self = (void (*)(bNodeType *))MEM_freeN;
274 
275  node_type_base(ntype, NODE_REROUTE, "Reroute", NODE_CLASS_LAYOUT, 0);
278 
279  nodeRegisterType(ntype);
280 }
281 
283 {
284  bNodeSocket *input = node->inputs.first;
285  bNodeSocket *output = node->outputs.first;
286  bNodeLink *link;
287  int type = SOCK_FLOAT;
288  const char *type_idname = nodeStaticSocketType(type, PROP_NONE);
289 
290  /* XXX it would be a little bit more efficient to restrict actual updates
291  * to reroute nodes connected to an updated node, but there's no reliable flag
292  * to indicate updated nodes (node->update is not set on linking).
293  */
294 
295  node->done = 1;
296 
297  /* recursive update */
298  for (link = ntree->links.first; link; link = link->next) {
299  bNode *fromnode = link->fromnode;
300  bNode *tonode = link->tonode;
301  if (!tonode || !fromnode) {
302  continue;
303  }
304  if (nodeLinkIsHidden(link)) {
305  continue;
306  }
307 
308  if (flag & REFINE_FORWARD) {
309  if (tonode == node && fromnode->type == NODE_REROUTE && !fromnode->done) {
311  }
312  }
313  if (flag & REFINE_BACKWARD) {
314  if (fromnode == node && tonode->type == NODE_REROUTE && !tonode->done) {
316  }
317  }
318  }
319 
320  /* determine socket type from unambiguous input/output connection if possible */
321  if (nodeSocketLinkLimit(input) == 1 && input->link) {
322  type = input->link->fromsock->type;
323  type_idname = nodeStaticSocketType(type, PROP_NONE);
324  }
325  else if (nodeSocketLinkLimit(output) == 1 && output->link) {
326  type = output->link->tosock->type;
327  type_idname = nodeStaticSocketType(type, PROP_NONE);
328  }
329 
330  if (input->type != type) {
331  bNodeSocket *ninput = nodeAddSocket(ntree, node, SOCK_IN, type_idname, "input", "Input");
332  for (link = ntree->links.first; link; link = link->next) {
333  if (link->tosock == input) {
334  link->tosock = ninput;
335  ninput->link = link;
336  }
337  }
338  nodeRemoveSocket(ntree, node, input);
339  }
340 
341  if (output->type != type) {
342  bNodeSocket *noutput = nodeAddSocket(ntree, node, SOCK_OUT, type_idname, "output", "Output");
343  for (link = ntree->links.first; link; link = link->next) {
344  if (link->fromsock == output) {
345  link->fromsock = noutput;
346  }
347  }
349  }
350 
352 }
353 
354 /* Global update function for Reroute node types.
355  * This depends on connected nodes, so must be done as a tree-wide update.
356  */
358 {
359  bNode *node;
360 
361  /* clear tags */
362  for (node = ntree->nodes.first; node; node = node->next) {
363  node->done = 0;
364  }
365 
366  for (node = ntree->nodes.first; node; node = node->next) {
367  if (node->type == NODE_REROUTE && !node->done) {
369  }
370  }
371 }
372 
374 {
375  bNodeLink *link;
376 
377  /* avoid redundant checks, and infinite loops in case of cyclic node links */
378  if (node->done) {
379  return false;
380  }
381  node->done = 1;
382 
383  /* main test, done before child loop so it catches output nodes themselves as well */
384  if (node->typeinfo->nclass == NODE_CLASS_OUTPUT && node->flag & NODE_DO_OUTPUT) {
385  return true;
386  }
387 
388  /* test all connected nodes, first positive find is sufficient to return true */
389  for (link = ntree->links.first; link; link = link->next) {
390  if (link->fromnode == node) {
392  return true;
393  }
394  }
395  }
396  return false;
397 }
398 
400 {
401  bNode *tnode;
402 
403  /* clear flags */
404  for (tnode = ntree->nodes.first; tnode; tnode = tnode->next) {
405  tnode->done = 0;
406  }
407 
409 }
410 
412 {
413  bNode *node;
414 
415  for (node = ntree->nodes.first; node; node = node->next) {
416  if (node->id == id) {
417  node->id = NULL;
418  }
419  }
420 }
421 
424 /* -------------------------------------------------------------------- */
429 {
431 }
432 
434 {
435  bNodeSocket *sock;
436  for (sock = node->outputs.first; sock; sock = sock->next) {
437  if (STREQ(sock->identifier, identifier)) {
438  return sock;
439  }
440  }
441  return NULL;
442 }
443 
445 {
446  bNodeSocket *extsock = node->outputs.last;
447  bNodeLink *link, *linknext, *exposelink;
448  /* Adding a tree socket and verifying will remove the extension socket!
449  * This list caches the existing links from the extension socket
450  * so they can be recreated after verification.
451  */
452  ListBase tmplinks;
453 
454  /* find links from the extension socket and store them */
455  BLI_listbase_clear(&tmplinks);
456  for (link = ntree->links.first; link; link = linknext) {
457  linknext = link->next;
458  if (nodeLinkIsHidden(link)) {
459  continue;
460  }
461 
462  if (link->fromsock == extsock) {
463  bNodeLink *tlink = MEM_callocN(sizeof(bNodeLink), "temporary link");
464  *tlink = *link;
465  BLI_addtail(&tmplinks, tlink);
466 
467  nodeRemLink(ntree, link);
468  }
469  }
470 
471  /* find valid link to expose */
472  exposelink = NULL;
473  for (link = tmplinks.first; link; link = link->next) {
474  /* XXX Multiple sockets can be connected to the extension socket at once,
475  * in that case the arbitrary first link determines name and type.
476  * This could be improved by choosing the "best" type among all links,
477  * whatever that means.
478  */
479  if (link->tosock->type != SOCK_CUSTOM) {
480  exposelink = link;
481  break;
482  }
483  }
484 
485  if (exposelink) {
486  bNodeSocket *gsock, *newsock;
487 
488  gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->tonode, exposelink->tosock);
489 
491  newsock = node_group_input_find_socket(node, gsock->identifier);
492 
493  /* redirect links from the extension socket */
494  for (link = tmplinks.first; link; link = link->next) {
495  nodeAddLink(ntree, node, newsock, link->tonode, link->tosock);
496  }
497  }
498 
499  BLI_freelistN(&tmplinks);
500 
501  /* check inputs and outputs, and remove or insert them */
502  {
503  /* value_in_out inverted for interface nodes to get correct socket value_property */
505 
506  /* add virtual extension socket */
507  nodeAddSocket(ntree, node, SOCK_OUT, "NodeSocketVirtual", "__extend__", "");
508  }
509 }
510 
512 {
513  /* used for all tree types, needs dynamic allocation */
514  bNodeType *ntype = MEM_callocN(sizeof(bNodeType), "node type");
515  ntype->free_self = (void (*)(bNodeType *))MEM_freeN;
516 
517  node_type_base(ntype, NODE_GROUP_INPUT, "Group Input", NODE_CLASS_INTERFACE, 0);
518  node_type_size(ntype, 140, 80, 400);
521 
522  nodeRegisterType(ntype);
523 }
524 
526 {
528 }
529 
531 {
532  bNodeSocket *sock;
533  for (sock = node->inputs.first; sock; sock = sock->next) {
534  if (STREQ(sock->identifier, identifier)) {
535  return sock;
536  }
537  }
538  return NULL;
539 }
540 
542 {
543  bNodeSocket *extsock = node->inputs.last;
544  bNodeLink *link, *linknext, *exposelink;
545  /* Adding a tree socket and verifying will remove the extension socket!
546  * This list caches the existing links to the extension socket
547  * so they can be recreated after verification.
548  */
549  ListBase tmplinks;
550 
551  /* find links to the extension socket and store them */
552  BLI_listbase_clear(&tmplinks);
553  for (link = ntree->links.first; link; link = linknext) {
554  linknext = link->next;
555  if (nodeLinkIsHidden(link)) {
556  continue;
557  }
558 
559  if (link->tosock == extsock) {
560  bNodeLink *tlink = MEM_callocN(sizeof(bNodeLink), "temporary link");
561  *tlink = *link;
562  BLI_addtail(&tmplinks, tlink);
563 
564  nodeRemLink(ntree, link);
565  }
566  }
567 
568  /* find valid link to expose */
569  exposelink = NULL;
570  for (link = tmplinks.first; link; link = link->next) {
571  /* XXX Multiple sockets can be connected to the extension socket at once,
572  * in that case the arbitrary first link determines name and type.
573  * This could be improved by choosing the "best" type among all links,
574  * whatever that means.
575  */
576  if (link->fromsock->type != SOCK_CUSTOM) {
577  exposelink = link;
578  break;
579  }
580  }
581 
582  if (exposelink) {
583  bNodeSocket *gsock, *newsock;
584 
585  /* XXX what if connecting virtual to virtual socket?? */
586  gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->fromnode, exposelink->fromsock);
587 
589  newsock = node_group_output_find_socket(node, gsock->identifier);
590 
591  /* redirect links to the extension socket */
592  for (link = tmplinks.first; link; link = link->next) {
593  nodeAddLink(ntree, link->fromnode, link->fromsock, node, newsock);
594  }
595  }
596 
597  BLI_freelistN(&tmplinks);
598 
599  /* check inputs and outputs, and remove or insert them */
600  {
601  /* value_in_out inverted for interface nodes to get correct socket value_property */
603 
604  /* add virtual extension socket */
605  nodeAddSocket(ntree, node, SOCK_IN, "NodeSocketVirtual", "__extend__", "");
606  }
607 }
608 
610 {
611  /* used for all tree types, needs dynamic allocation */
612  bNodeType *ntype = MEM_callocN(sizeof(bNodeType), "node type");
613  ntype->free_self = (void (*)(bNodeType *))MEM_freeN;
614 
615  node_type_base(ntype, NODE_GROUP_OUTPUT, "Group Output", NODE_CLASS_INTERFACE, 0);
616  node_type_size(ntype, 140, 80, 400);
619 
620  nodeRegisterType(ntype);
621 }
622 
#define NODE_CLASS_OUTPUT
Definition: BKE_node.h:335
void node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass, short flag)
Definition: node.cc:4443
#define NODE_REROUTE
Definition: BKE_node.h:873
void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwidth)
Definition: node.cc:4565
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:1533
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4623
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4559
void nodeRemoveAllSockets(struct bNodeTree *ntree, struct bNode *node)
Definition: node.cc:1793
void nodeRemLink(struct bNodeTree *ntree, struct bNodeLink *link)
Definition: node.cc:2231
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:1716
struct bNodeSocket * ntreeAddSocketInterfaceFromSocket(struct bNodeTree *ntree, struct bNode *from_node, struct bNodeSocket *from_sock)
Definition: node.cc:3337
int nodeSocketLinkLimit(const struct bNodeSocket *sock)
void node_type_internal_links(struct bNodeType *ntype, void(*update_internal_links)(struct bNodeTree *, struct bNode *))
const char * nodeStaticSocketType(int type, int subtype)
Definition: node.cc:1574
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:4599
struct bNodeLink * nodeAddLink(struct bNodeTree *ntree, struct bNode *fromnode, struct bNodeSocket *fromsock, struct bNode *tonode, struct bNodeSocket *tosock)
Definition: node.cc:2189
void nodeRemoveSocket(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock)
Definition: node.cc:1775
#define NODE_CLASS_LAYOUT
Definition: BKE_node.h:361
void nodeUpdateInternalLinks(struct bNodeTree *ntree, struct bNode *node)
Definition: node.cc:4380
#define NODE_FRAME
Definition: BKE_node.h:872
#define NODE_GROUP_INPUT
Definition: BKE_node.h:874
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1298
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:133
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
#define UNUSED(x)
#define STREQ(a, b)
#define IFACE_(msgid)
@ LIB_TAG_MISSING
Definition: DNA_ID.h:537
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:426
#define NODE_LINK_VALID
#define NODE_BACKGROUND
#define NODE_DO_OUTPUT
@ SOCK_OUT
@ SOCK_IN
@ SOCK_HIDE_VALUE
#define NODE_FRAME_SHRINK
@ SOCK_FLOAT
@ SOCK_CUSTOM
@ SOCK_RGBA
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
NODE_GROUP_OUTPUT
@ PROP_NONE
Definition: RNA_types.h:113
#define output
OperationNode * node
const char * label
bNodeTree * ntree
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static void node_reroute_update_internal_links(bNodeTree *ntree, bNode *node)
Definition: node_common.c:241
static void node_reroute_inherit_type_recursive(bNodeTree *ntree, bNode *node, int flag)
Definition: node_common.c:282
static void group_verify_socket_list(bNodeTree *ntree, bNode *gnode, ListBase *iosock_lb, ListBase *verify_lb, int in_out)
Definition: node_common.c:159
bNodeSocket * node_group_output_find_socket(bNode *node, const char *identifier)
Definition: node_common.c:530
void BKE_node_tree_unlink_id(ID *id, struct bNodeTree *ntree)
Definition: node_common.c:411
static void node_reroute_init(bNodeTree *ntree, bNode *node)
Definition: node_common.c:260
void node_group_update(struct bNodeTree *ntree, struct bNode *node)
Definition: node_common.c:187
bool node_group_poll_instance(bNode *node, bNodeTree *nodetree, const char **disabled_hint)
Definition: node_common.c:82
static bool node_is_connected_to_output_recursive(bNodeTree *ntree, bNode *node)
Definition: node_common.c:373
void register_node_type_frame(void)
Definition: node_common.c:220
void ntree_update_reroute_nodes(bNodeTree *ntree)
Definition: node_common.c:357
@ REFINE_FORWARD
Definition: node_common.c:46
@ REFINE_BACKWARD
Definition: node_common.c:47
void register_node_type_group_input(void)
Definition: node_common.c:511
void node_group_input_update(bNodeTree *ntree, bNode *node)
Definition: node_common.c:444
static void node_group_output_init(bNodeTree *ntree, bNode *node)
Definition: node_common.c:525
bool BKE_node_is_connected_to_output(bNodeTree *ntree, bNode *node)
Definition: node_common.c:399
bNodeSocket * node_group_find_output_socket(bNode *groupnode, const char *identifier)
Definition: node_common.c:65
static void node_frame_init(bNodeTree *UNUSED(ntree), bNode *node)
Definition: node_common.c:210
bNodeSocket * node_group_input_find_socket(bNode *node, const char *identifier)
Definition: node_common.c:433
void register_node_type_reroute(void)
Definition: node_common.c:269
void node_group_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen)
Definition: node_common.c:77
static void node_group_input_init(bNodeTree *ntree, bNode *node)
Definition: node_common.c:428
bool nodeGroupPoll(bNodeTree *nodetree, bNodeTree *grouptree, const char **r_disabled_hint)
Definition: node_common.c:96
bNodeSocket * node_group_find_input_socket(bNode *groupnode, const char *identifier)
Definition: node_common.c:54
void node_group_output_update(bNodeTree *ntree, bNode *node)
Definition: node_common.c:541
static bNodeSocket * group_verify_socket(bNodeTree *ntree, bNode *gnode, bNodeSocket *iosock, ListBase *verify_lb, int in_out)
Definition: node_common.c:124
void register_node_type_group_output(void)
Definition: node_common.c:609
void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
Definition: node_util.c:67
void node_free_standard_storage(bNode *node)
Definition: node_util.c:55
Definition: DNA_ID.h:273
void * first
Definition: DNA_listBase.h:47
void(* interface_init_socket)(struct bNodeTree *ntree, struct bNodeSocket *stemp, struct bNode *node, struct bNodeSocket *sock, const char *data_path)
Definition: BKE_node.h:161
void(* interface_verify_socket)(struct bNodeTree *ntree, struct bNodeSocket *stemp, struct bNode *node, struct bNodeSocket *sock, const char *data_path)
Definition: BKE_node.h:166
char name[64]
struct bNodeLink * link
struct bNodeSocket * new_sock
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:221
void(* free_self)(struct bNodeType *ntype)
Definition: BKE_node.h:314
ListBase inputs
short done
short type
struct bNode * next
ListBase outputs
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)