Blender  V2.93
node.cc
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) 2005 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "CLG_log.h"
25 
26 #include "MEM_guardedalloc.h"
27 
28 #include <climits>
29 #include <cstddef>
30 #include <cstdlib>
31 #include <cstring>
32 
33 /* Allow using deprecated functionality for .blend file I/O. */
34 #define DNA_DEPRECATED_ALLOW
35 
36 #include "DNA_action_types.h"
37 #include "DNA_anim_types.h"
38 #include "DNA_collection_types.h"
39 #include "DNA_gpencil_types.h"
40 #include "DNA_light_types.h"
41 #include "DNA_linestyle_types.h"
42 #include "DNA_material_types.h"
43 #include "DNA_modifier_types.h"
44 #include "DNA_node_types.h"
45 #include "DNA_scene_types.h"
46 #include "DNA_simulation_types.h"
47 #include "DNA_texture_types.h"
48 #include "DNA_world_types.h"
49 
50 #include "BLI_ghash.h"
51 #include "BLI_listbase.h"
52 #include "BLI_map.hh"
53 #include "BLI_math.h"
54 #include "BLI_path_util.h"
55 #include "BLI_string.h"
56 #include "BLI_string_utils.h"
57 #include "BLI_utildefines.h"
58 
59 #include "BLT_translation.h"
60 
61 #include "BKE_anim_data.h"
62 #include "BKE_animsys.h"
63 #include "BKE_colortools.h"
64 #include "BKE_cryptomatte.h"
65 #include "BKE_global.h"
66 #include "BKE_idprop.h"
67 #include "BKE_idtype.h"
68 #include "BKE_lib_id.h"
69 #include "BKE_lib_query.h"
70 #include "BKE_main.h"
71 #include "BKE_node.h"
72 #include "BKE_node_ui_storage.hh"
73 
74 #include "BLI_ghash.h"
75 #include "BLI_threads.h"
76 #include "RNA_access.h"
77 #include "RNA_define.h"
78 
79 #include "NOD_common.h"
80 #include "NOD_composite.h"
81 #include "NOD_function.h"
82 #include "NOD_geometry.h"
83 #include "NOD_shader.h"
84 #include "NOD_socket.h"
85 #include "NOD_texture.h"
86 
87 #include "DEG_depsgraph.h"
88 #include "DEG_depsgraph_build.h"
89 
90 #include "BLO_read_write.h"
91 
92 #include "MOD_nodes.h"
93 
94 #define NODE_DEFAULT_MAX_WIDTH 700
95 
96 /* Fallback types for undefined tree, nodes, sockets */
100 
101 static CLG_LogRef LOG = {"bke.node"};
102 
103 static void ntree_set_typeinfo(bNodeTree *ntree, bNodeTreeType *typeinfo);
104 static void node_socket_copy(bNodeSocket *sock_dst, const bNodeSocket *sock_src, const int flag);
106 static void node_free_node(bNodeTree *ntree, bNode *node);
108  bNodeSocket *sock,
109  const bool do_id_user);
110 static void nodeMuteRerouteOutputLinks(struct bNodeTree *ntree,
111  struct bNode *node,
112  const bool mute);
113 
114 static void ntree_init_data(ID *id)
115 {
116  bNodeTree *ntree = (bNodeTree *)id;
117  ntree_set_typeinfo(ntree, nullptr);
118 }
119 
120 static void ntree_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
121 {
122  bNodeTree *ntree_dst = (bNodeTree *)id_dst;
123  const bNodeTree *ntree_src = (const bNodeTree *)id_src;
124 
125  /* We never handle usercount here for own data. */
126  const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
127 
128  /* in case a running nodetree is copied */
129  ntree_dst->execdata = nullptr;
130 
131  BLI_listbase_clear(&ntree_dst->nodes);
132  BLI_listbase_clear(&ntree_dst->links);
133 
134  /* Since source nodes and sockets are unique pointers we can put everything in a single map. */
135  GHash *new_pointers = BLI_ghash_ptr_new(__func__);
136 
137  LISTBASE_FOREACH (const bNode *, node_src, &ntree_src->nodes) {
138  bNode *new_node = BKE_node_copy_ex(ntree_dst, node_src, flag_subdata, true);
139  BLI_ghash_insert(new_pointers, (void *)node_src, new_node);
140  /* Store mapping to inputs. */
141  bNodeSocket *new_input_sock = (bNodeSocket *)new_node->inputs.first;
142  const bNodeSocket *input_sock_src = (const bNodeSocket *)node_src->inputs.first;
143  while (new_input_sock != nullptr) {
144  BLI_ghash_insert(new_pointers, (void *)input_sock_src, new_input_sock);
145  new_input_sock = new_input_sock->next;
146  input_sock_src = input_sock_src->next;
147  }
148  /* Store mapping to outputs. */
149  bNodeSocket *new_output_sock = (bNodeSocket *)new_node->outputs.first;
150  const bNodeSocket *output_sock_src = (const bNodeSocket *)node_src->outputs.first;
151  while (new_output_sock != nullptr) {
152  BLI_ghash_insert(new_pointers, (void *)output_sock_src, new_output_sock);
153  new_output_sock = new_output_sock->next;
154  output_sock_src = output_sock_src->next;
155  }
156  }
157 
158  /* copy links */
159  BLI_duplicatelist(&ntree_dst->links, &ntree_src->links);
160  LISTBASE_FOREACH (bNodeLink *, link_dst, &ntree_dst->links) {
161  link_dst->fromnode = (bNode *)BLI_ghash_lookup_default(
162  new_pointers, link_dst->fromnode, nullptr);
163  link_dst->fromsock = (bNodeSocket *)BLI_ghash_lookup_default(
164  new_pointers, link_dst->fromsock, nullptr);
165  link_dst->tonode = (bNode *)BLI_ghash_lookup_default(new_pointers, link_dst->tonode, nullptr);
166  link_dst->tosock = (bNodeSocket *)BLI_ghash_lookup_default(
167  new_pointers, link_dst->tosock, nullptr);
168  /* update the link socket's pointer */
169  if (link_dst->tosock) {
170  link_dst->tosock->link = link_dst;
171  }
172  }
173 
174  /* copy interface sockets */
175  BLI_duplicatelist(&ntree_dst->inputs, &ntree_src->inputs);
176  bNodeSocket *sock_dst, *sock_src;
177  for (sock_dst = (bNodeSocket *)ntree_dst->inputs.first,
178  sock_src = (bNodeSocket *)ntree_src->inputs.first;
179  sock_dst != nullptr;
180  sock_dst = (bNodeSocket *)sock_dst->next, sock_src = (bNodeSocket *)sock_src->next) {
181  node_socket_copy(sock_dst, sock_src, flag_subdata);
182  }
183 
184  BLI_duplicatelist(&ntree_dst->outputs, &ntree_src->outputs);
185  for (sock_dst = (bNodeSocket *)ntree_dst->outputs.first,
186  sock_src = (bNodeSocket *)ntree_src->outputs.first;
187  sock_dst != nullptr;
188  sock_dst = (bNodeSocket *)sock_dst->next, sock_src = (bNodeSocket *)sock_src->next) {
189  node_socket_copy(sock_dst, sock_src, flag_subdata);
190  }
191 
192  /* copy preview hash */
193  if (ntree_src->previews && (flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
195 
196  ntree_dst->previews = BKE_node_instance_hash_new("node previews");
197 
198  NODE_INSTANCE_HASH_ITER (iter, ntree_src->previews) {
202  }
203  }
204  else {
205  ntree_dst->previews = nullptr;
206  }
207 
208  /* update node->parent pointers */
209  for (bNode *node_dst = (bNode *)ntree_dst->nodes.first,
210  *node_src = (bNode *)ntree_src->nodes.first;
211  node_dst;
212  node_dst = (bNode *)node_dst->next, node_src = (bNode *)node_src->next) {
213  if (node_dst->parent) {
214  node_dst->parent = (bNode *)BLI_ghash_lookup_default(
215  new_pointers, node_dst->parent, nullptr);
216  }
217  }
218 
219  BLI_ghash_free(new_pointers, nullptr, nullptr);
220 
221  /* node tree will generate its own interface type */
222  ntree_dst->interface_type = nullptr;
223 
224  /* Don't copy error messages in the runtime struct.
225  * They should be filled during execution anyway. */
226  ntree_dst->ui_storage = nullptr;
227 }
228 
229 static void ntree_free_data(ID *id)
230 {
231  bNodeTree *ntree = (bNodeTree *)id;
232 
233  /* XXX hack! node trees should not store execution graphs at all.
234  * This should be removed when old tree types no longer require it.
235  * Currently the execution data for texture nodes remains in the tree
236  * after execution, until the node tree is updated or freed.
237  */
238  if (ntree->execdata) {
239  switch (ntree->type) {
240  case NTREE_SHADER:
242  break;
243  case NTREE_TEXTURE:
245  ntree->execdata = nullptr;
246  break;
247  }
248  }
249 
250  /* XXX not nice, but needed to free localized node groups properly */
252 
253  /* unregister associated RNA types */
255 
256  BLI_freelistN(&ntree->links); /* do first, then unlink_node goes fast */
257 
260  }
261 
262  /* free interface sockets */
264  node_socket_interface_free(ntree, sock, false);
265  MEM_freeN(sock);
266  }
268  node_socket_interface_free(ntree, sock, false);
269  MEM_freeN(sock);
270  }
271 
272  /* free preview hash */
273  if (ntree->previews) {
275  }
276 
277  if (ntree->id.tag & LIB_TAG_LOCALIZED) {
279  }
280 
281  delete ntree->ui_storage;
282 }
283 
285 {
288 
289  switch ((eNodeSocketDatatype)sock->type) {
290  case SOCK_OBJECT: {
293  break;
294  }
295  case SOCK_IMAGE: {
298  break;
299  }
300  case SOCK_COLLECTION: {
302  sock->default_value;
304  break;
305  }
306  case SOCK_FLOAT:
307  case SOCK_VECTOR:
308  case SOCK_RGBA:
309  case SOCK_BOOLEAN:
310  case SOCK_INT:
311  case SOCK_STRING:
312  case __SOCK_MESH:
313  case SOCK_CUSTOM:
314  case SOCK_SHADER:
315  case SOCK_GEOMETRY:
316  break;
317  }
318 }
319 
321 {
322  bNodeTree *ntree = (bNodeTree *)id;
323 
325 
328 
331  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
333  }
334  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
336  }
337  }
338 
341  }
344  }
345 }
346 
347 static void node_foreach_cache(ID *id,
348  IDTypeForeachCacheFunctionCallback function_callback,
349  void *user_data)
350 {
351  bNodeTree *nodetree = (bNodeTree *)id;
352  IDCacheKey key = {0};
353  key.id_session_uuid = id->session_uuid;
354  key.offset_in_ID = offsetof(bNodeTree, previews);
355  key.cache_v = nodetree->previews;
356 
357  /* TODO, see also `direct_link_nodetree()` in readfile.c. */
358 #if 0
359  function_callback(id, &key, (void **)&nodetree->previews, 0, user_data);
360 #endif
361 
362  if (nodetree->type == NTREE_COMPOSIT) {
363  LISTBASE_FOREACH (bNode *, node, &nodetree->nodes) {
364  if (node->type == CMP_NODE_MOVIEDISTORTION) {
365  key.offset_in_ID = (size_t)BLI_ghashutil_strhash_p(node->name);
366  key.cache_v = node->storage;
367  function_callback(id, &key, (void **)&node->storage, 0, user_data);
368  }
369  }
370  }
371 }
372 
373 static ID *node_owner_get(Main *bmain, ID *id)
374 {
375  if ((id->flag & LIB_EMBEDDED_DATA) == 0) {
376  return id;
377  }
378  /* TODO: Sort this NO_MAIN or not for embedded node trees. See T86119. */
379  // BLI_assert((id->tag & LIB_TAG_NO_MAIN) == 0);
380 
381  ListBase *lists[] = {&bmain->materials,
382  &bmain->lights,
383  &bmain->worlds,
384  &bmain->textures,
385  &bmain->scenes,
386  &bmain->linestyles,
387  &bmain->simulations,
388  nullptr};
389 
390  bNodeTree *ntree = (bNodeTree *)id;
391  for (int i = 0; lists[i] != nullptr; i++) {
392  LISTBASE_FOREACH (ID *, id_iter, lists[i]) {
393  if (ntreeFromID(id_iter) == ntree) {
394  return id_iter;
395  }
396  }
397  }
398 
399  BLI_assert(!"Embedded node tree with no owner. Critical Main inconsistency.");
400  return nullptr;
401 }
402 
404 {
405  if (sock->default_value == nullptr) {
406  return;
407  }
408 
409  switch ((eNodeSocketDatatype)sock->type) {
410  case SOCK_FLOAT:
412  break;
413  case SOCK_VECTOR:
415  break;
416  case SOCK_RGBA:
418  break;
419  case SOCK_BOOLEAN:
421  break;
422  case SOCK_INT:
424  break;
425  case SOCK_STRING:
427  break;
428  case SOCK_OBJECT:
430  break;
431  case SOCK_IMAGE:
433  break;
434  case SOCK_COLLECTION:
436  break;
437  case SOCK_CUSTOM:
438  /* Custom node sockets where default_value is defined uses custom properties for storage. */
439  break;
440  case __SOCK_MESH:
441  case SOCK_SHADER:
442  case SOCK_GEOMETRY:
444  break;
445  }
446 }
447 
448 static void write_node_socket(BlendWriter *writer, bNodeSocket *sock)
449 {
450  /* actual socket writing */
451  BLO_write_struct(writer, bNodeSocket, sock);
452 
453  if (sock->prop) {
454  IDP_BlendWrite(writer, sock->prop);
455  }
456 
457  write_node_socket_default_value(writer, sock);
458 }
460 {
461  /* actual socket writing */
462  BLO_write_struct(writer, bNodeSocket, sock);
463 
464  if (sock->prop) {
465  IDP_BlendWrite(writer, sock->prop);
466  }
467 
468  write_node_socket_default_value(writer, sock);
469 }
470 
471 /* this is only direct data, tree itself should have been written */
473 {
474  BKE_id_blend_write(writer, &ntree->id);
475 
476  /* for link_list() speed, we write per list */
477 
478  if (ntree->adt) {
480  }
481 
483  BLO_write_struct(writer, bNode, node);
484 
485  if (node->prop) {
486  IDP_BlendWrite(writer, node->prop);
487  }
488 
489  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
490  write_node_socket(writer, sock);
491  }
492  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
493  write_node_socket(writer, sock);
494  }
495 
496  LISTBASE_FOREACH (bNodeLink *, link, &node->internal_links) {
497  BLO_write_struct(writer, bNodeLink, link);
498  }
499 
500  if (node->storage) {
501  /* could be handlerized at some point, now only 1 exception still */
502  if ((ntree->type == NTREE_SHADER) &&
504  BKE_curvemapping_blend_write(writer, (const CurveMapping *)node->storage);
505  }
506  else if (ntree->type == NTREE_SHADER && (node->type == SH_NODE_SCRIPT)) {
507  NodeShaderScript *nss = (NodeShaderScript *)node->storage;
508  if (nss->bytecode) {
509  BLO_write_string(writer, nss->bytecode);
510  }
511  BLO_write_struct_by_name(writer, node->typeinfo->storagename, node->storage);
512  }
513  else if ((ntree->type == NTREE_COMPOSIT) && ELEM(node->type,
518  BKE_curvemapping_blend_write(writer, (const CurveMapping *)node->storage);
519  }
520  else if ((ntree->type == NTREE_TEXTURE) &&
521  (node->type == TEX_NODE_CURVE_RGB || node->type == TEX_NODE_CURVE_TIME)) {
522  BKE_curvemapping_blend_write(writer, (const CurveMapping *)node->storage);
523  }
524  else if ((ntree->type == NTREE_COMPOSIT) && (node->type == CMP_NODE_MOVIEDISTORTION)) {
525  /* pass */
526  }
527  else if ((ntree->type == NTREE_COMPOSIT) && (node->type == CMP_NODE_GLARE)) {
528  /* Simple forward compatibility for fix for T50736.
529  * Not ideal (there is no ideal solution here), but should do for now. */
530  NodeGlare *ndg = (NodeGlare *)node->storage;
531  /* Not in undo case. */
532  if (!BLO_write_is_undo(writer)) {
533  switch (ndg->type) {
534  case 2: /* Grrrr! magic numbers :( */
535  ndg->angle = ndg->streaks;
536  break;
537  case 0:
538  ndg->angle = ndg->star_45;
539  break;
540  default:
541  break;
542  }
543  }
544  BLO_write_struct_by_name(writer, node->typeinfo->storagename, node->storage);
545  }
546  else if ((ntree->type == NTREE_COMPOSIT) &&
548  NodeCryptomatte *nc = (NodeCryptomatte *)node->storage;
549  BLO_write_string(writer, nc->matte_id);
550  LISTBASE_FOREACH (CryptomatteEntry *, entry, &nc->entries) {
551  BLO_write_struct(writer, CryptomatteEntry, entry);
552  }
553  BLO_write_struct_by_name(writer, node->typeinfo->storagename, node->storage);
554  }
555  else if (node->type == FN_NODE_INPUT_STRING) {
556  NodeInputString *storage = (NodeInputString *)node->storage;
557  if (storage->string) {
558  BLO_write_string(writer, storage->string);
559  }
560  BLO_write_struct_by_name(writer, node->typeinfo->storagename, storage);
561  }
562  else if (node->typeinfo != &NodeTypeUndefined) {
563  BLO_write_struct_by_name(writer, node->typeinfo->storagename, node->storage);
564  }
565  }
566 
567  if (node->type == CMP_NODE_OUTPUT_FILE) {
568  /* inputs have own storage data */
569  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
570  BLO_write_struct(writer, NodeImageMultiFileSocket, sock->storage);
571  }
572  }
573  if (ELEM(node->type, CMP_NODE_IMAGE, CMP_NODE_R_LAYERS)) {
574  /* write extra socket info */
575  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
576  BLO_write_struct(writer, NodeImageLayer, sock->storage);
577  }
578  }
579  }
580 
581  LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
582  BLO_write_struct(writer, bNodeLink, link);
583  }
584 
586  write_node_socket_interface(writer, sock);
587  }
589  write_node_socket_interface(writer, sock);
590  }
591 }
592 
593 static void ntree_blend_write(BlendWriter *writer, ID *id, const void *id_address)
594 {
595  bNodeTree *ntree = (bNodeTree *)id;
596  if (ntree->id.us > 0 || BLO_write_is_undo(writer)) {
597  /* Clean up, important in undo case to reduce false detection of changed datablocks. */
598  ntree->init = 0; /* to set callbacks and force setting types */
599  ntree->is_updating = false;
600  ntree->typeinfo = nullptr;
601  ntree->interface_type = nullptr;
602  ntree->progress = nullptr;
603  ntree->execdata = nullptr;
604  ntree->ui_storage = nullptr;
605 
606  BLO_write_id_struct(writer, bNodeTree, id_address, &ntree->id);
607 
608  ntreeBlendWrite(writer, ntree);
609  }
610 }
611 
613 {
614  BLO_read_data_address(reader, &sock->prop);
615  IDP_BlendDataRead(reader, &sock->prop);
616 
617  BLO_read_data_address(reader, &sock->link);
618  sock->typeinfo = nullptr;
619  BLO_read_data_address(reader, &sock->storage);
620  BLO_read_data_address(reader, &sock->default_value);
621  sock->total_inputs = 0; /* Clear runtime data set before drawing. */
622  sock->cache = nullptr;
623 }
624 
625 /* ntree itself has been read! */
627 {
628  /* note: writing and reading goes in sync, for speed */
629  ntree->init = 0; /* to set callbacks and force setting types */
630  ntree->is_updating = false;
631  ntree->typeinfo = nullptr;
632  ntree->interface_type = nullptr;
633 
634  ntree->progress = nullptr;
635  ntree->execdata = nullptr;
636  ntree->ui_storage = nullptr;
637 
638  BLO_read_data_address(reader, &ntree->adt);
640 
641  BLO_read_list(reader, &ntree->nodes);
643  node->typeinfo = nullptr;
644 
645  BLO_read_list(reader, &node->inputs);
646  BLO_read_list(reader, &node->outputs);
647 
648  BLO_read_data_address(reader, &node->prop);
649  IDP_BlendDataRead(reader, &node->prop);
650 
651  BLO_read_list(reader, &node->internal_links);
652  LISTBASE_FOREACH (bNodeLink *, link, &node->internal_links) {
653  BLO_read_data_address(reader, &link->fromnode);
654  BLO_read_data_address(reader, &link->fromsock);
655  BLO_read_data_address(reader, &link->tonode);
656  BLO_read_data_address(reader, &link->tosock);
657  }
658 
659  if (node->type == CMP_NODE_MOVIEDISTORTION) {
660  /* Do nothing, this is runtime cache and hence handled by generic code using
661  * `IDTypeInfo.foreach_cache` callback. */
662  }
663  else {
664  BLO_read_data_address(reader, &node->storage);
665  }
666 
667  if (node->storage) {
668  /* could be handlerized at some point */
669  switch (node->type) {
670  case SH_NODE_CURVE_VEC:
671  case SH_NODE_CURVE_RGB:
672  case CMP_NODE_TIME:
673  case CMP_NODE_CURVE_VEC:
674  case CMP_NODE_CURVE_RGB:
675  case CMP_NODE_HUECORRECT:
676  case TEX_NODE_CURVE_RGB:
677  case TEX_NODE_CURVE_TIME: {
678  BKE_curvemapping_blend_read(reader, (CurveMapping *)node->storage);
679  break;
680  }
681  case SH_NODE_SCRIPT: {
682  NodeShaderScript *nss = (NodeShaderScript *)node->storage;
683  BLO_read_data_address(reader, &nss->bytecode);
684  break;
685  }
688  memset(&npd->pd, 0, sizeof(npd->pd));
689  break;
690  }
691  case SH_NODE_TEX_IMAGE: {
692  NodeTexImage *tex = (NodeTexImage *)node->storage;
693  tex->iuser.ok = 1;
694  tex->iuser.scene = nullptr;
695  break;
696  }
699  tex->iuser.ok = 1;
700  tex->iuser.scene = nullptr;
701  break;
702  }
703  case CMP_NODE_IMAGE:
704  case CMP_NODE_R_LAYERS:
705  case CMP_NODE_VIEWER:
706  case CMP_NODE_SPLITVIEWER: {
707  ImageUser *iuser = (ImageUser *)node->storage;
708  iuser->ok = 1;
709  iuser->scene = nullptr;
710  break;
711  }
713  case CMP_NODE_CRYPTOMATTE: {
714  NodeCryptomatte *nc = (NodeCryptomatte *)node->storage;
715  BLO_read_data_address(reader, &nc->matte_id);
716  BLO_read_list(reader, &nc->entries);
718  break;
719  }
720  case TEX_NODE_IMAGE: {
721  ImageUser *iuser = (ImageUser *)node->storage;
722  iuser->ok = 1;
723  iuser->scene = nullptr;
724  break;
725  }
726  case FN_NODE_INPUT_STRING: {
727  NodeInputString *storage = (NodeInputString *)node->storage;
728  BLO_read_data_address(reader, &storage->string);
729  break;
730  }
731  default:
732  break;
733  }
734  }
735  }
736  BLO_read_list(reader, &ntree->links);
737 
738  /* and we connect the rest */
740  BLO_read_data_address(reader, &node->parent);
741 
742  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
743  direct_link_node_socket(reader, sock);
744  }
745  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
746  direct_link_node_socket(reader, sock);
747  }
748  }
749 
750  /* interface socket lists */
751  BLO_read_list(reader, &ntree->inputs);
752  BLO_read_list(reader, &ntree->outputs);
754  direct_link_node_socket(reader, sock);
755  }
757  direct_link_node_socket(reader, sock);
758  }
759 
760  LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
761  BLO_read_data_address(reader, &link->fromnode);
762  BLO_read_data_address(reader, &link->tonode);
763  BLO_read_data_address(reader, &link->fromsock);
764  BLO_read_data_address(reader, &link->tosock);
765  }
766 
767  /* TODO, should be dealt by new generic cache handling of IDs... */
768  ntree->previews = nullptr;
769 
770  /* type verification is in lib-link */
771 }
772 
773 static void ntree_blend_read_data(BlendDataReader *reader, ID *id)
774 {
775  bNodeTree *ntree = (bNodeTree *)id;
776  ntreeBlendReadData(reader, ntree);
777 }
778 
780 {
781  IDP_BlendReadLib(reader, sock->prop);
782 
783  /* This can happen for all socket types when a file is saved in an older version of Blender than
784  * it was originally created in (T86298). Some socket types still require a default value. The
785  * default value of those sockets will be created in `ntreeSetTypes`. */
786  if (sock->default_value == nullptr) {
787  return;
788  }
789 
790  switch ((eNodeSocketDatatype)sock->type) {
791  case SOCK_OBJECT: {
793  BLO_read_id_address(reader, lib, &default_value->value);
794  break;
795  }
796  case SOCK_IMAGE: {
798  BLO_read_id_address(reader, lib, &default_value->value);
799  break;
800  }
801  case SOCK_COLLECTION: {
803  sock->default_value;
804  BLO_read_id_address(reader, lib, &default_value->value);
805  break;
806  }
807  case SOCK_FLOAT:
808  case SOCK_VECTOR:
809  case SOCK_RGBA:
810  case SOCK_BOOLEAN:
811  case SOCK_INT:
812  case SOCK_STRING:
813  case __SOCK_MESH:
814  case SOCK_CUSTOM:
815  case SOCK_SHADER:
816  case SOCK_GEOMETRY:
817  break;
818  }
819 }
820 
821 static void lib_link_node_sockets(BlendLibReader *reader, Library *lib, ListBase *sockets)
822 {
823  LISTBASE_FOREACH (bNodeSocket *, sock, sockets) {
824  lib_link_node_socket(reader, lib, sock);
825  }
826 }
827 
828 void ntreeBlendReadLib(struct BlendLibReader *reader, struct bNodeTree *ntree)
829 {
830  Library *lib = ntree->id.lib;
831 
832  BLO_read_id_address(reader, lib, &ntree->gpd);
833 
835  /* Link ID Properties -- and copy this comment EXACTLY for easy finding
836  * of library blocks that implement this.*/
837  IDP_BlendReadLib(reader, node->prop);
838 
839  BLO_read_id_address(reader, lib, &node->id);
840 
841  lib_link_node_sockets(reader, lib, &node->inputs);
842  lib_link_node_sockets(reader, lib, &node->outputs);
843  }
844 
847 
848  /* Set node->typeinfo pointers. This is done in lib linking, after the
849  * first versioning that can change types still without functions that
850  * update the typeinfo pointers. Versioning after lib linking needs
851  * these top be valid. */
852  ntreeSetTypes(nullptr, ntree);
853 
854  /* For nodes with static socket layout, add/remove sockets as needed
855  * to match the static layout. */
856  if (!BLO_read_lib_is_undo(reader)) {
859  }
860  }
861 }
862 
863 static void ntree_blend_read_lib(BlendLibReader *reader, ID *id)
864 {
865  bNodeTree *ntree = (bNodeTree *)id;
866  ntreeBlendReadLib(reader, ntree);
867 }
868 
869 static void expand_node_socket(BlendExpander *expander, bNodeSocket *sock)
870 {
871  IDP_BlendReadExpand(expander, sock->prop);
872 
873  if (sock->default_value != nullptr) {
874 
875  switch ((eNodeSocketDatatype)sock->type) {
876  case SOCK_OBJECT: {
878  BLO_expand(expander, default_value->value);
879  break;
880  }
881  case SOCK_IMAGE: {
883  BLO_expand(expander, default_value->value);
884  break;
885  }
886  case SOCK_COLLECTION: {
888  sock->default_value;
889  BLO_expand(expander, default_value->value);
890  break;
891  }
892  case SOCK_FLOAT:
893  case SOCK_VECTOR:
894  case SOCK_RGBA:
895  case SOCK_BOOLEAN:
896  case SOCK_INT:
897  case SOCK_STRING:
898  case __SOCK_MESH:
899  case SOCK_CUSTOM:
900  case SOCK_SHADER:
901  case SOCK_GEOMETRY:
902  break;
903  }
904  }
905 }
906 
907 static void expand_node_sockets(BlendExpander *expander, ListBase *sockets)
908 {
909  LISTBASE_FOREACH (bNodeSocket *, sock, sockets) {
910  expand_node_socket(expander, sock);
911  }
912 }
913 
915 {
916  if (ntree->gpd) {
917  BLO_expand(expander, ntree->gpd);
918  }
919 
921  if (node->id && !(node->type == CMP_NODE_R_LAYERS) &&
922  !(node->type == CMP_NODE_CRYPTOMATTE && node->custom1 == CMP_CRYPTOMATTE_SRC_RENDER)) {
923  BLO_expand(expander, node->id);
924  }
925 
926  IDP_BlendReadExpand(expander, node->prop);
927 
928  expand_node_sockets(expander, &node->inputs);
929  expand_node_sockets(expander, &node->outputs);
930  }
931 
932  expand_node_sockets(expander, &ntree->inputs);
933  expand_node_sockets(expander, &ntree->outputs);
934 }
935 
936 static void ntree_blend_read_expand(BlendExpander *expander, ID *id)
937 {
938  bNodeTree *ntree = (bNodeTree *)id;
939  ntreeBlendReadExpand(expander, ntree);
940 }
941 
943  /* id_code */ ID_NT,
944  /* id_filter */ FILTER_ID_NT,
945  /* main_listbase_index */ INDEX_ID_NT,
946  /* struct_size */ sizeof(bNodeTree),
947  /* name */ "NodeTree",
948  /* name_plural */ "node_groups",
949  /* translation_context */ BLT_I18NCONTEXT_ID_NODETREE,
950  /* flags */ 0,
951 
952  /* init_data */ ntree_init_data,
953  /* copy_data */ ntree_copy_data,
954  /* free_data */ ntree_free_data,
955  /* make_local */ nullptr,
956  /* foreach_id */ node_foreach_id,
957  /* foreach_cache */ node_foreach_cache,
958  /* owner_get */ node_owner_get,
959 
960  /* blend_write */ ntree_blend_write,
961  /* blend_read_data */ ntree_blend_read_data,
962  /* blend_read_lib */ ntree_blend_read_lib,
963  /* blend_read_expand */ ntree_blend_read_expand,
964 
965  /* blend_read_undo_preserve */ nullptr,
966 
967  /* lib_override_apply_post */ nullptr,
968 };
969 
971 {
972  bNodeSocketTemplate *sockdef;
973  /* bNodeSocket *sock; */ /* UNUSED */
974 
975  if (ntype->inputs) {
976  sockdef = ntype->inputs;
977  while (sockdef->type != -1) {
978  /* sock = */ node_add_socket_from_template(ntree, node, sockdef, SOCK_IN);
979 
980  sockdef++;
981  }
982  }
983  if (ntype->outputs) {
984  sockdef = ntype->outputs;
985  while (sockdef->type != -1) {
986  /* sock = */ node_add_socket_from_template(ntree, node, sockdef, SOCK_OUT);
987 
988  sockdef++;
989  }
990  }
991 }
992 
993 /* Note: This function is called to initialize node data based on the type.
994  * The bNodeType may not be registered at creation time of the node,
995  * so this can be delayed until the node type gets registered.
996  */
997 static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
998 {
999  bNodeType *ntype = node->typeinfo;
1000  if (ntype == &NodeTypeUndefined) {
1001  return;
1002  }
1003 
1004  /* only do this once */
1005  if (node->flag & NODE_INIT) {
1006  return;
1007  }
1008 
1009  node->flag = NODE_SELECT | NODE_OPTIONS | ntype->flag;
1010  node->width = ntype->width;
1011  node->miniwidth = 42.0f;
1012  node->height = ntype->height;
1013  node->color[0] = node->color[1] = node->color[2] = 0.608; /* default theme color */
1014  /* initialize the node name with the node label.
1015  * note: do this after the initfunc so nodes get their data set which may be used in naming
1016  * (node groups for example) */
1017  /* XXX Do not use nodeLabel() here, it returns translated content for UI,
1018  * which should *only* be used in UI, *never* in data...
1019  * Data have their own translation option!
1020  * This solution may be a bit rougher than nodeLabel()'s returned string, but it's simpler
1021  * than adding "do_translate" flags to this func (and labelfunc() as well). */
1022  BLI_strncpy(node->name, DATA_(ntype->ui_name), NODE_MAXSTR);
1024 
1026 
1027  if (ntype->initfunc != nullptr) {
1028  ntype->initfunc(ntree, node);
1029  }
1030 
1031  if (ntree->typeinfo->node_add_init != nullptr) {
1033  }
1034 
1035  if (node->id) {
1036  id_us_plus(node->id);
1037  }
1038 
1039  /* extra init callback */
1040  if (ntype->initfunc_api) {
1041  PointerRNA ptr;
1043 
1044  /* XXX Warning: context can be nullptr in case nodes are added in do_versions.
1045  * Delayed init is not supported for nodes with context-based initfunc_api atm.
1046  */
1047  BLI_assert(C != nullptr);
1048  ntype->initfunc_api(C, &ptr);
1049  }
1050 
1051  node->flag |= NODE_INIT;
1052 }
1053 
1055 {
1056  if (typeinfo) {
1057  ntree->typeinfo = typeinfo;
1058 
1059  /* deprecated integer type */
1060  ntree->type = typeinfo->type;
1061  }
1062  else {
1064 
1065  ntree->init &= ~NTREE_TYPE_INIT;
1066  }
1067 }
1068 
1069 static void node_set_typeinfo(const struct bContext *C,
1070  bNodeTree *ntree,
1071  bNode *node,
1072  bNodeType *typeinfo)
1073 {
1074  /* for nodes saved in older versions storage can get lost, make undefined then */
1075  if (node->flag & NODE_INIT) {
1076  if (typeinfo && typeinfo->storagename[0] && !node->storage) {
1077  typeinfo = nullptr;
1078  }
1079  }
1080 
1081  if (typeinfo) {
1082  node->typeinfo = typeinfo;
1083 
1084  /* deprecated integer type */
1085  node->type = typeinfo->type;
1086 
1087  /* initialize the node if necessary */
1088  node_init(C, ntree, node);
1089  }
1090  else {
1091  node->typeinfo = &NodeTypeUndefined;
1092 
1093  ntree->init &= ~NTREE_TYPE_INIT;
1094  }
1095 }
1096 
1098  bNodeSocket *sock,
1099  bNodeSocketType *typeinfo)
1100 {
1101  if (typeinfo) {
1102  sock->typeinfo = typeinfo;
1103 
1104  /* deprecated integer type */
1105  sock->type = typeinfo->type;
1106 
1107  if (sock->default_value == nullptr) {
1108  /* initialize the default_value pointer used by standard socket types */
1110  }
1111  }
1112  else {
1114 
1115  ntree->init &= ~NTREE_TYPE_INIT;
1116  }
1117 }
1118 
1119 /* Set specific typeinfo pointers in all node trees on register/unregister */
1120 static void update_typeinfo(Main *bmain,
1121  const struct bContext *C,
1122  bNodeTreeType *treetype,
1123  bNodeType *nodetype,
1124  bNodeSocketType *socktype,
1125  bool unregister)
1126 {
1127  if (!bmain) {
1128  return;
1129  }
1130 
1131  FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1133 
1134  if (treetype && STREQ(ntree->idname, treetype->idname)) {
1135  ntree_set_typeinfo(ntree, unregister ? nullptr : treetype);
1136  }
1137 
1138  /* initialize nodes */
1140  if (nodetype && STREQ(node->idname, nodetype->idname)) {
1141  node_set_typeinfo(C, ntree, node, unregister ? nullptr : nodetype);
1142  }
1143 
1144  /* initialize node sockets */
1145  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
1146  if (socktype && STREQ(sock->idname, socktype->idname)) {
1147  node_socket_set_typeinfo(ntree, sock, unregister ? nullptr : socktype);
1148  }
1149  }
1150  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
1151  if (socktype && STREQ(sock->idname, socktype->idname)) {
1152  node_socket_set_typeinfo(ntree, sock, unregister ? nullptr : socktype);
1153  }
1154  }
1155  }
1156 
1157  /* initialize tree sockets */
1158  LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->inputs) {
1159  if (socktype && STREQ(sock->idname, socktype->idname)) {
1160  node_socket_set_typeinfo(ntree, sock, unregister ? nullptr : socktype);
1161  }
1162  }
1163  LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->outputs) {
1164  if (socktype && STREQ(sock->idname, socktype->idname)) {
1165  node_socket_set_typeinfo(ntree, sock, unregister ? nullptr : socktype);
1166  }
1167  }
1168  }
1170 }
1171 
1172 /* Try to initialize all typeinfo in a node tree.
1173  * NB: In general undefined typeinfo is a perfectly valid case,
1174  * the type may just be registered later.
1175  * In that case the update_typeinfo function will set typeinfo on registration
1176  * and do necessary updates.
1177  */
1178 void ntreeSetTypes(const struct bContext *C, bNodeTree *ntree)
1179 {
1181 
1183 
1186 
1187  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
1188  node_socket_set_typeinfo(ntree, sock, nodeSocketTypeFind(sock->idname));
1189  }
1190  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
1191  node_socket_set_typeinfo(ntree, sock, nodeSocketTypeFind(sock->idname));
1192  }
1193  }
1194 
1195  LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->inputs) {
1196  node_socket_set_typeinfo(ntree, sock, nodeSocketTypeFind(sock->idname));
1197  }
1198  LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->outputs) {
1199  node_socket_set_typeinfo(ntree, sock, nodeSocketTypeFind(sock->idname));
1200  }
1201 }
1202 
1203 static GHash *nodetreetypes_hash = nullptr;
1204 static GHash *nodetypes_hash = nullptr;
1205 static GHash *nodesockettypes_hash = nullptr;
1206 
1207 bNodeTreeType *ntreeTypeFind(const char *idname)
1208 {
1209  if (idname[0]) {
1211  if (nt) {
1212  return nt;
1213  }
1214  }
1215 
1216  return nullptr;
1217 }
1218 
1220 {
1222  /* XXX pass Main to register function? */
1223  /* Probably not. It is pretty much expected we want to update G_MAIN here I think -
1224  * or we'd want to update *all* active Mains, which we cannot do anyway currently. */
1225  update_typeinfo(G_MAIN, nullptr, nt, nullptr, nullptr, false);
1226 }
1227 
1228 /* callback for hash value free function */
1229 static void ntree_free_type(void *treetype_v)
1230 {
1231  bNodeTreeType *treetype = (bNodeTreeType *)treetype_v;
1232  /* XXX pass Main to unregister function? */
1233  /* Probably not. It is pretty much expected we want to update G_MAIN here I think -
1234  * or we'd want to update *all* active Mains, which we cannot do anyway currently. */
1235  update_typeinfo(G_MAIN, nullptr, treetype, nullptr, nullptr, true);
1236  MEM_freeN(treetype);
1237 }
1238 
1240 {
1242 }
1243 
1245 {
1246  return (ntree->typeinfo != &NodeTreeTypeUndefined);
1247 }
1248 
1250 {
1252 }
1253 
1254 bNodeType *nodeTypeFind(const char *idname)
1255 {
1256  if (idname[0]) {
1258  if (nt) {
1259  return nt;
1260  }
1261  }
1262 
1263  return nullptr;
1264 }
1265 
1267 {
1268  if (ntype->type == NODE_DYNAMIC) {
1269  if (ntype->inputs) {
1270  MEM_freeN(ntype->inputs);
1271  }
1272  if (ntype->outputs) {
1273  MEM_freeN(ntype->outputs);
1274  }
1275  }
1276 }
1277 
1278 /* callback for hash value free function */
1279 static void node_free_type(void *nodetype_v)
1280 {
1281  bNodeType *nodetype = (bNodeType *)nodetype_v;
1282  /* XXX pass Main to unregister function? */
1283  /* Probably not. It is pretty much expected we want to update G_MAIN here I think -
1284  * or we'd want to update *all* active Mains, which we cannot do anyway currently. */
1285  update_typeinfo(G_MAIN, nullptr, nullptr, nodetype, nullptr, true);
1286 
1287  /* XXX deprecated */
1288  if (nodetype->type == NODE_DYNAMIC) {
1289  free_dynamic_typeinfo(nodetype);
1290  }
1291 
1292  /* Can be null when the type is not dynamically allocated. */
1293  if (nodetype->free_self) {
1294  nodetype->free_self(nodetype);
1295  }
1296 }
1297 
1299 {
1300  /* debug only: basic verification of registered types */
1301  BLI_assert(nt->idname[0] != '\0');
1302  BLI_assert(nt->poll != nullptr);
1303 
1305  /* XXX pass Main to register function? */
1306  /* Probably not. It is pretty much expected we want to update G_MAIN here I think -
1307  * or we'd want to update *all* active Mains, which we cannot do anyway currently. */
1308  update_typeinfo(G_MAIN, nullptr, nullptr, nt, nullptr, false);
1309 }
1310 
1312 {
1314 }
1315 
1317 {
1318  return (node->typeinfo == &NodeTypeUndefined) ||
1319  ((node->type == NODE_GROUP || node->type == NODE_CUSTOM_GROUP) && node->id &&
1320  ID_IS_LINKED(node->id) && (node->id->tag & LIB_TAG_MISSING));
1321 }
1322 
1324 {
1326 }
1327 
1329 {
1330  if (idname[0]) {
1332  if (st) {
1333  return st;
1334  }
1335  }
1336 
1337  return nullptr;
1338 }
1339 
1340 /* callback for hash value free function */
1341 static void node_free_socket_type(void *socktype_v)
1342 {
1343  bNodeSocketType *socktype = (bNodeSocketType *)socktype_v;
1344  /* XXX pass Main to unregister function? */
1345  /* Probably not. It is pretty much expected we want to update G_MAIN here I think -
1346  * or we'd want to update *all* active Mains, which we cannot do anyway currently. */
1347  update_typeinfo(G_MAIN, nullptr, nullptr, nullptr, socktype, true);
1348 
1349  socktype->free_self(socktype);
1350 }
1351 
1353 {
1354  BLI_ghash_insert(nodesockettypes_hash, (void *)st->idname, st);
1355  /* XXX pass Main to register function? */
1356  /* Probably not. It is pretty much expected we want to update G_MAIN here I think -
1357  * or we'd want to update *all* active Mains, which we cannot do anyway currently. */
1358  update_typeinfo(G_MAIN, nullptr, nullptr, nullptr, st, false);
1359 }
1360 
1362 {
1364 }
1365 
1367 {
1368  return (sock->typeinfo != &NodeSocketTypeUndefined);
1369 }
1370 
1372 {
1374 }
1375 
1378  const char *identifier)
1379 {
1380  const ListBase *sockets = (in_out == SOCK_IN) ? &node->inputs : &node->outputs;
1381  LISTBASE_FOREACH (bNodeSocket *, sock, sockets) {
1382  if (STREQ(sock->identifier, identifier)) {
1383  return sock;
1384  }
1385  }
1386  return nullptr;
1387 }
1388 
1389 /* find unique socket identifier */
1390 static bool unique_identifier_check(void *arg, const char *identifier)
1391 {
1392  const ListBase *lb = (const ListBase *)arg;
1393  LISTBASE_FOREACH (bNodeSocket *, sock, lb) {
1394  if (STREQ(sock->identifier, identifier)) {
1395  return true;
1396  }
1397  }
1398  return false;
1399 }
1400 
1402  bNode *UNUSED(node),
1403  int in_out,
1404  ListBase *lb,
1405  const char *idname,
1406  const char *identifier,
1407  const char *name)
1408 {
1409  char auto_identifier[MAX_NAME];
1410 
1411  if (identifier && identifier[0] != '\0') {
1412  /* use explicit identifier */
1413  BLI_strncpy(auto_identifier, identifier, sizeof(auto_identifier));
1414  }
1415  else {
1416  /* if no explicit identifier is given, assign a unique identifier based on the name */
1417  BLI_strncpy(auto_identifier, name, sizeof(auto_identifier));
1418  }
1419  /* make the identifier unique */
1421  unique_identifier_check, lb, "socket", '.', auto_identifier, sizeof(auto_identifier));
1422 
1423  bNodeSocket *sock = (bNodeSocket *)MEM_callocN(sizeof(bNodeSocket), "sock");
1424  sock->in_out = in_out;
1425 
1426  BLI_strncpy(sock->identifier, auto_identifier, NODE_MAXSTR);
1427  sock->limit = (in_out == SOCK_IN ? 1 : 0xFFF);
1428 
1429  BLI_strncpy(sock->name, name, NODE_MAXSTR);
1430  sock->storage = nullptr;
1431  sock->flag |= SOCK_COLLAPSED;
1432  sock->type = SOCK_CUSTOM; /* int type undefined by default */
1433 
1434  BLI_strncpy(sock->idname, idname, sizeof(sock->idname));
1436 
1437  return sock;
1438 }
1439 
1441 {
1442  switch ((eNodeSocketDatatype)sock->type) {
1443  case SOCK_OBJECT: {
1445  id_us_plus((ID *)default_value->value);
1446  break;
1447  }
1448  case SOCK_IMAGE: {
1450  id_us_plus((ID *)default_value->value);
1451  break;
1452  }
1453  case SOCK_COLLECTION: {
1455  sock->default_value;
1456  id_us_plus((ID *)default_value->value);
1457  break;
1458  }
1459  case SOCK_FLOAT:
1460  case SOCK_VECTOR:
1461  case SOCK_RGBA:
1462  case SOCK_BOOLEAN:
1463  case SOCK_INT:
1464  case SOCK_STRING:
1465  case __SOCK_MESH:
1466  case SOCK_CUSTOM:
1467  case SOCK_SHADER:
1468  case SOCK_GEOMETRY:
1469  break;
1470  }
1471 }
1472 
1474 {
1475  switch ((eNodeSocketDatatype)sock->type) {
1476  case SOCK_OBJECT: {
1478  if (default_value->value != nullptr) {
1479  id_us_min(&default_value->value->id);
1480  }
1481  break;
1482  }
1483  case SOCK_IMAGE: {
1485  if (default_value->value != nullptr) {
1486  id_us_min(&default_value->value->id);
1487  }
1488  break;
1489  }
1490  case SOCK_COLLECTION: {
1492  sock->default_value;
1493  if (default_value->value != nullptr) {
1494  id_us_min(&default_value->value->id);
1495  }
1496  break;
1497  }
1498  case SOCK_FLOAT:
1499  case SOCK_VECTOR:
1500  case SOCK_RGBA:
1501  case SOCK_BOOLEAN:
1502  case SOCK_INT:
1503  case SOCK_STRING:
1504  case __SOCK_MESH:
1505  case SOCK_CUSTOM:
1506  case SOCK_SHADER:
1507  case SOCK_GEOMETRY:
1508  break;
1509  }
1510 }
1511 
1513  bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, int type, int subtype)
1514 {
1515  const char *idname = nodeStaticSocketType(type, subtype);
1516 
1517  if (!idname) {
1518  CLOG_ERROR(&LOG, "static node socket type %d undefined", type);
1519  return;
1520  }
1521 
1522  if (sock->default_value) {
1524  MEM_freeN(sock->default_value);
1525  sock->default_value = nullptr;
1526  }
1527 
1528  sock->type = type;
1529  BLI_strncpy(sock->idname, idname, sizeof(sock->idname));
1531 }
1532 
1534  bNode *node,
1536  const char *idname,
1537  const char *identifier,
1538  const char *name)
1539 {
1540  BLI_assert(node->type != NODE_FRAME);
1541  BLI_assert(!(in_out == SOCK_IN && node->type == NODE_GROUP_INPUT));
1542  BLI_assert(!(in_out == SOCK_OUT && node->type == NODE_GROUP_OUTPUT));
1543 
1544  ListBase *lb = (in_out == SOCK_IN ? &node->inputs : &node->outputs);
1546 
1547  BLI_remlink(lb, sock); /* does nothing for new socket */
1548  BLI_addtail(lb, sock);
1549 
1550  node->update |= NODE_UPDATE;
1551 
1552  return sock;
1553 }
1554 
1556  bNode *node,
1558  const char *idname,
1559  bNodeSocket *next_sock,
1560  const char *identifier,
1561  const char *name)
1562 {
1563  ListBase *lb = (in_out == SOCK_IN ? &node->inputs : &node->outputs);
1565 
1566  BLI_remlink(lb, sock); /* does nothing for new socket */
1567  BLI_insertlinkbefore(lb, next_sock, sock);
1568 
1569  node->update |= NODE_UPDATE;
1570 
1571  return sock;
1572 }
1573 
1574 const char *nodeStaticSocketType(int type, int subtype)
1575 {
1576  switch (type) {
1577  case SOCK_FLOAT:
1578  switch (subtype) {
1579  case PROP_UNSIGNED:
1580  return "NodeSocketFloatUnsigned";
1581  case PROP_PERCENTAGE:
1582  return "NodeSocketFloatPercentage";
1583  case PROP_FACTOR:
1584  return "NodeSocketFloatFactor";
1585  case PROP_ANGLE:
1586  return "NodeSocketFloatAngle";
1587  case PROP_TIME:
1588  return "NodeSocketFloatTime";
1589  case PROP_DISTANCE:
1590  return "NodeSocketFloatDistance";
1591  case PROP_NONE:
1592  default:
1593  return "NodeSocketFloat";
1594  }
1595  case SOCK_INT:
1596  switch (subtype) {
1597  case PROP_UNSIGNED:
1598  return "NodeSocketIntUnsigned";
1599  case PROP_PERCENTAGE:
1600  return "NodeSocketIntPercentage";
1601  case PROP_FACTOR:
1602  return "NodeSocketIntFactor";
1603  case PROP_NONE:
1604  default:
1605  return "NodeSocketInt";
1606  }
1607  case SOCK_BOOLEAN:
1608  return "NodeSocketBool";
1609  case SOCK_VECTOR:
1610  switch (subtype) {
1611  case PROP_TRANSLATION:
1612  return "NodeSocketVectorTranslation";
1613  case PROP_DIRECTION:
1614  return "NodeSocketVectorDirection";
1615  case PROP_VELOCITY:
1616  return "NodeSocketVectorVelocity";
1617  case PROP_ACCELERATION:
1618  return "NodeSocketVectorAcceleration";
1619  case PROP_EULER:
1620  return "NodeSocketVectorEuler";
1621  case PROP_XYZ:
1622  return "NodeSocketVectorXYZ";
1623  case PROP_NONE:
1624  default:
1625  return "NodeSocketVector";
1626  }
1627  case SOCK_RGBA:
1628  return "NodeSocketColor";
1629  case SOCK_STRING:
1630  return "NodeSocketString";
1631  case SOCK_SHADER:
1632  return "NodeSocketShader";
1633  case SOCK_OBJECT:
1634  return "NodeSocketObject";
1635  case SOCK_IMAGE:
1636  return "NodeSocketImage";
1637  case SOCK_GEOMETRY:
1638  return "NodeSocketGeometry";
1639  case SOCK_COLLECTION:
1640  return "NodeSocketCollection";
1641  }
1642  return nullptr;
1643 }
1644 
1645 const char *nodeStaticSocketInterfaceType(int type, int subtype)
1646 {
1647  switch (type) {
1648  case SOCK_FLOAT:
1649  switch (subtype) {
1650  case PROP_UNSIGNED:
1651  return "NodeSocketInterfaceFloatUnsigned";
1652  case PROP_PERCENTAGE:
1653  return "NodeSocketInterfaceFloatPercentage";
1654  case PROP_FACTOR:
1655  return "NodeSocketInterfaceFloatFactor";
1656  case PROP_ANGLE:
1657  return "NodeSocketInterfaceFloatAngle";
1658  case PROP_TIME:
1659  return "NodeSocketInterfaceFloatTime";
1660  case PROP_DISTANCE:
1661  return "NodeSocketInterfaceFloatDistance";
1662  case PROP_NONE:
1663  default:
1664  return "NodeSocketInterfaceFloat";
1665  }
1666  case SOCK_INT:
1667  switch (subtype) {
1668  case PROP_UNSIGNED:
1669  return "NodeSocketInterfaceIntUnsigned";
1670  case PROP_PERCENTAGE:
1671  return "NodeSocketInterfaceIntPercentage";
1672  case PROP_FACTOR:
1673  return "NodeSocketInterfaceIntFactor";
1674  case PROP_NONE:
1675  default:
1676  return "NodeSocketInterfaceInt";
1677  }
1678  case SOCK_BOOLEAN:
1679  return "NodeSocketInterfaceBool";
1680  case SOCK_VECTOR:
1681  switch (subtype) {
1682  case PROP_TRANSLATION:
1683  return "NodeSocketInterfaceVectorTranslation";
1684  case PROP_DIRECTION:
1685  return "NodeSocketInterfaceVectorDirection";
1686  case PROP_VELOCITY:
1687  return "NodeSocketInterfaceVectorVelocity";
1688  case PROP_ACCELERATION:
1689  return "NodeSocketInterfaceVectorAcceleration";
1690  case PROP_EULER:
1691  return "NodeSocketInterfaceVectorEuler";
1692  case PROP_XYZ:
1693  return "NodeSocketInterfaceVectorXYZ";
1694  case PROP_NONE:
1695  default:
1696  return "NodeSocketInterfaceVector";
1697  }
1698  case SOCK_RGBA:
1699  return "NodeSocketInterfaceColor";
1700  case SOCK_STRING:
1701  return "NodeSocketInterfaceString";
1702  case SOCK_SHADER:
1703  return "NodeSocketInterfaceShader";
1704  case SOCK_OBJECT:
1705  return "NodeSocketInterfaceObject";
1706  case SOCK_IMAGE:
1707  return "NodeSocketInterfaceImage";
1708  case SOCK_GEOMETRY:
1709  return "NodeSocketInterfaceGeometry";
1710  case SOCK_COLLECTION:
1711  return "NodeSocketInterfaceCollection";
1712  }
1713  return nullptr;
1714 }
1715 
1717  bNode *node,
1719  int type,
1720  int subtype,
1721  const char *identifier,
1722  const char *name)
1723 {
1724  const char *idname = nodeStaticSocketType(type, subtype);
1725 
1726  if (!idname) {
1727  CLOG_ERROR(&LOG, "static node socket type %d undefined", type);
1728  return nullptr;
1729  }
1730 
1732  sock->type = type;
1733  return sock;
1734 }
1735 
1737  bNode *node,
1739  int type,
1740  int subtype,
1741  bNodeSocket *next_sock,
1742  const char *identifier,
1743  const char *name)
1744 {
1745  const char *idname = nodeStaticSocketType(type, subtype);
1746 
1747  if (!idname) {
1748  CLOG_ERROR(&LOG, "static node socket type %d undefined", type);
1749  return nullptr;
1750  }
1751 
1753  sock->type = type;
1754  return sock;
1755 }
1756 
1758  bNodeSocket *sock,
1759  bNode *UNUSED(node),
1760  const bool do_id_user)
1761 {
1762  if (sock->prop) {
1763  IDP_FreePropertyContent_ex(sock->prop, do_id_user);
1764  MEM_freeN(sock->prop);
1765  }
1766 
1767  if (sock->default_value) {
1768  if (do_id_user) {
1770  }
1771  MEM_freeN(sock->default_value);
1772  }
1773 }
1774 
1776 {
1778  if (link->fromsock == sock || link->tosock == sock) {
1780  }
1781  }
1782 
1783  /* this is fast, this way we don't need an in_out argument */
1784  BLI_remlink(&node->inputs, sock);
1785  BLI_remlink(&node->outputs, sock);
1786 
1787  node_socket_free(ntree, sock, node, true);
1788  MEM_freeN(sock);
1789 
1790  node->update |= NODE_UPDATE;
1791 }
1792 
1794 {
1796  if (link->fromnode == node || link->tonode == node) {
1798  }
1799  }
1800 
1801  LISTBASE_FOREACH_MUTABLE (bNodeSocket *, sock, &node->inputs) {
1802  node_socket_free(ntree, sock, node, true);
1803  MEM_freeN(sock);
1804  }
1805  BLI_listbase_clear(&node->inputs);
1806 
1807  LISTBASE_FOREACH_MUTABLE (bNodeSocket *, sock, &node->outputs) {
1808  node_socket_free(ntree, sock, node, true);
1809  MEM_freeN(sock);
1810  }
1811  BLI_listbase_clear(&node->outputs);
1812 
1813  node->update |= NODE_UPDATE;
1814 }
1815 
1816 /* finds a node based on its name */
1818 {
1819  return (bNode *)BLI_findstring(&ntree->nodes, name, offsetof(bNode, name));
1820 }
1821 
1822 /* Finds a node based on given socket and returns true on success. */
1823 bool nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **r_node, int *r_sockindex)
1824 {
1825  *r_node = nullptr;
1826 
1828  ListBase *sockets = (sock->in_out == SOCK_IN) ? &node->inputs : &node->outputs;
1829  int index = 0;
1830  LISTBASE_FOREACH (bNodeSocket *, tsock, sockets) {
1831  if (sock == tsock) {
1832  if (r_node != nullptr) {
1833  *r_node = node;
1834  }
1835  if (r_sockindex != nullptr) {
1836  *r_sockindex = index;
1837  }
1838  return true;
1839  }
1840  index++;
1841  }
1842  }
1843  return false;
1844 }
1845 
1850 {
1851  if (node->parent) {
1852  return nodeFindRootParent(node->parent);
1853  }
1854  return node->type == NODE_FRAME ? node : nullptr;
1855 }
1856 
1861 bool nodeIsChildOf(const bNode *parent, const bNode *child)
1862 {
1863  if (parent == child) {
1864  return true;
1865  }
1866  if (child->parent) {
1867  return nodeIsChildOf(parent, child->parent);
1868  }
1869  return false;
1870 }
1871 
1880  const bNode *node_start,
1881  bool (*callback)(bNode *, bNode *, void *, const bool),
1882  void *userdata,
1883  const bool reversed)
1884 {
1886  if ((link->flag & NODE_LINK_VALID) == 0) {
1887  /* Skip links marked as cyclic. */
1888  continue;
1889  }
1890  if (link->tonode && link->fromnode) {
1891  /* Is the link part of the chain meaning node_start == fromnode
1892  * (or tonode for reversed case)? */
1893  if ((reversed && (link->tonode == node_start)) ||
1894  (!reversed && link->fromnode == node_start)) {
1895  if (!callback(link->fromnode, link->tonode, userdata, reversed)) {
1896  return;
1897  }
1898  nodeChainIter(
1899  ntree, reversed ? link->fromnode : link->tonode, callback, userdata, reversed);
1900  }
1901  }
1902  }
1903 }
1904 
1905 static void iter_backwards_ex(const bNodeTree *ntree,
1906  const bNode *node_start,
1907  bool (*callback)(bNode *, bNode *, void *),
1908  void *userdata,
1909  char recursion_mask)
1910 {
1911  LISTBASE_FOREACH (bNodeSocket *, sock, &node_start->inputs) {
1912  bNodeLink *link = sock->link;
1913  if (link == nullptr) {
1914  continue;
1915  }
1916  if ((link->flag & NODE_LINK_VALID) == 0) {
1917  /* Skip links marked as cyclic. */
1918  continue;
1919  }
1920  if (link->fromnode->iter_flag & recursion_mask) {
1921  continue;
1922  }
1923 
1924  link->fromnode->iter_flag |= recursion_mask;
1925 
1926  if (!callback(link->fromnode, link->tonode, userdata)) {
1927  return;
1928  }
1929  iter_backwards_ex(ntree, link->fromnode, callback, userdata, recursion_mask);
1930  }
1931 }
1932 
1945  const bNode *node_start,
1946  bool (*callback)(bNode *, bNode *, void *),
1947  void *userdata,
1948  int recursion_lvl)
1949 {
1950  if (!node_start) {
1951  return;
1952  }
1953 
1954  /* Limited by iter_flag type. */
1955  BLI_assert(recursion_lvl < 8);
1956  char recursion_mask = (1 << recursion_lvl);
1957 
1958  /* Reset flag. */
1960  node->iter_flag &= ~recursion_mask;
1961  }
1962 
1963  iter_backwards_ex(ntree, node_start, callback, userdata, recursion_mask);
1964 }
1965 
1972 void nodeParentsIter(bNode *node, bool (*callback)(bNode *, void *), void *userdata)
1973 {
1974  if (node->parent) {
1975  if (!callback(node->parent, userdata)) {
1976  return;
1977  }
1978  nodeParentsIter(node->parent, callback, userdata);
1979  }
1980 }
1981 
1982 /* ************** Add stuff ********** */
1983 
1984 /* Find the first available, non-duplicate name for a given node */
1986 {
1988  &ntree->nodes, node, DATA_("Node"), '.', offsetof(bNode, name), sizeof(node->name));
1989 }
1990 
1991 bNode *nodeAddNode(const struct bContext *C, bNodeTree *ntree, const char *idname)
1992 {
1993  bNode *node = (bNode *)MEM_callocN(sizeof(bNode), "new node");
1995 
1996  BLI_strncpy(node->idname, idname, sizeof(node->idname));
1998 
2000 
2001  return node;
2002 }
2003 
2005 {
2006  const char *idname = nullptr;
2007 
2008  NODE_TYPES_BEGIN (ntype) {
2009  /* do an extra poll here, because some int types are used
2010  * for multiple node types, this helps find the desired type
2011  */
2012  const char *disabled_hint;
2013  if (ntype->type == type && (!ntype->poll || ntype->poll(ntype, ntree, &disabled_hint))) {
2014  idname = ntype->idname;
2015  break;
2016  }
2017  }
2019  if (!idname) {
2020  CLOG_ERROR(&LOG, "static node type %d undefined", type);
2021  return nullptr;
2022  }
2023  return nodeAddNode(C, ntree, idname);
2024 }
2025 
2026 static void node_socket_copy(bNodeSocket *sock_dst, const bNodeSocket *sock_src, const int flag)
2027 {
2028  if (sock_src->prop) {
2029  sock_dst->prop = IDP_CopyProperty_ex(sock_src->prop, flag);
2030  }
2031 
2032  if (sock_src->default_value) {
2033  sock_dst->default_value = MEM_dupallocN(sock_src->default_value);
2034 
2035  if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
2036  socket_id_user_increment(sock_dst);
2037  }
2038  }
2039 
2040  sock_dst->stack_index = 0;
2041  /* XXX some compositor node (e.g. image, render layers) still store
2042  * some persistent buffer data here, need to clear this to avoid dangling pointers.
2043  */
2044  sock_dst->cache = nullptr;
2045 }
2046 
2047 /* keep socket listorder identical, for copying links */
2048 /* ntree is the target tree */
2049 /* unique_name needs to be true. It's only disabled for speed when doing GPUnodetrees. */
2051  const bNode *node_src,
2052  const int flag,
2053  const bool unique_name)
2054 {
2055  bNode *node_dst = (bNode *)MEM_callocN(sizeof(bNode), "dupli node");
2056  bNodeSocket *sock_dst, *sock_src;
2057  bNodeLink *link_dst, *link_src;
2058 
2059  *node_dst = *node_src;
2060  /* can be called for nodes outside a node tree (e.g. clipboard) */
2061  if (ntree) {
2062  if (unique_name) {
2063  nodeUniqueName(ntree, node_dst);
2064  }
2065 
2066  BLI_addtail(&ntree->nodes, node_dst);
2067  }
2068 
2069  BLI_duplicatelist(&node_dst->inputs, &node_src->inputs);
2070  for (sock_dst = (bNodeSocket *)node_dst->inputs.first,
2071  sock_src = (bNodeSocket *)node_src->inputs.first;
2072  sock_dst != nullptr;
2073  sock_dst = (bNodeSocket *)sock_dst->next, sock_src = (bNodeSocket *)sock_src->next) {
2074  node_socket_copy(sock_dst, sock_src, flag);
2075  }
2076 
2077  BLI_duplicatelist(&node_dst->outputs, &node_src->outputs);
2078  for (sock_dst = (bNodeSocket *)node_dst->outputs.first,
2079  sock_src = (bNodeSocket *)node_src->outputs.first;
2080  sock_dst != nullptr;
2081  sock_dst = (bNodeSocket *)sock_dst->next, sock_src = (bNodeSocket *)sock_src->next) {
2082  node_socket_copy(sock_dst, sock_src, flag);
2083  }
2084 
2085  if (node_src->prop) {
2086  node_dst->prop = IDP_CopyProperty_ex(node_src->prop, flag);
2087  }
2088 
2089  BLI_duplicatelist(&node_dst->internal_links, &node_src->internal_links);
2090  for (link_dst = (bNodeLink *)node_dst->internal_links.first,
2091  link_src = (bNodeLink *)node_src->internal_links.first;
2092  link_dst != nullptr;
2093  link_dst = (bNodeLink *)link_dst->next, link_src = (bNodeLink *)link_src->next) {
2094  /* This is a bit annoying to do index lookups in a list, but is likely to be faster than
2095  * trying to create a hash-map. At least for usual nodes, which only have so much sockets
2096  * and internal links. */
2097  const int from_sock_index = BLI_findindex(&node_src->inputs, link_src->fromsock);
2098  const int to_sock_index = BLI_findindex(&node_src->outputs, link_src->tosock);
2099  BLI_assert(from_sock_index != -1);
2100  BLI_assert(to_sock_index != -1);
2101  link_dst->fromnode = node_dst;
2102  link_dst->tonode = node_dst;
2103  link_dst->fromsock = (bNodeSocket *)BLI_findlink(&node_dst->inputs, from_sock_index);
2104  link_dst->tosock = (bNodeSocket *)BLI_findlink(&node_dst->outputs, to_sock_index);
2105  }
2106 
2107  if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
2108  id_us_plus(node_dst->id);
2109  }
2110 
2111  if (node_src->typeinfo->copyfunc) {
2112  node_src->typeinfo->copyfunc(ntree, node_dst, node_src);
2113  }
2114 
2115  node_dst->new_node = nullptr;
2116 
2117  /* Only call copy function when a copy is made for the main database, not
2118  * for cases like the dependency graph and localization. */
2119  if (node_dst->typeinfo->copyfunc_api && !(flag & LIB_ID_CREATE_NO_MAIN)) {
2120  PointerRNA ptr;
2121  RNA_pointer_create((ID *)ntree, &RNA_Node, node_dst, &ptr);
2122 
2123  node_dst->typeinfo->copyfunc_api(&ptr, node_src);
2124  }
2125 
2126  if (ntree) {
2128  }
2129 
2130  return node_dst;
2131 }
2132 
2133 static void node_set_new_pointers(bNode *node_src, bNode *new_node)
2134 {
2135  /* Store mapping to the node itself. */
2136  node_src->new_node = new_node;
2137  /* Store mapping to inputs. */
2138  bNodeSocket *new_input_sock = (bNodeSocket *)new_node->inputs.first;
2139  bNodeSocket *input_sock_src = (bNodeSocket *)node_src->inputs.first;
2140  while (new_input_sock != nullptr) {
2141  input_sock_src->new_sock = new_input_sock;
2142  new_input_sock = new_input_sock->next;
2143  input_sock_src = input_sock_src->next;
2144  }
2145  /* Store mapping to outputs. */
2146  bNodeSocket *new_output_sock = (bNodeSocket *)new_node->outputs.first;
2147  bNodeSocket *output_sock_src = (bNodeSocket *)node_src->outputs.first;
2148  while (new_output_sock != nullptr) {
2149  output_sock_src->new_sock = new_output_sock;
2150  new_output_sock = new_output_sock->next;
2151  output_sock_src = output_sock_src->next;
2152  }
2153 }
2154 
2156 {
2157  bNode *new_node = BKE_node_copy_ex(ntree, node_src, flag, true);
2158  node_set_new_pointers(node_src, new_node);
2159  return new_node;
2160 }
2161 
2163  Main *bmain,
2164  const bool do_id_user)
2165 {
2166  bNodeTree *new_ntree = ntreeCopyTree_ex(ntree, bmain, do_id_user);
2167  bNode *new_node = (bNode *)new_ntree->nodes.first;
2168  bNode *node_src = (bNode *)ntree->nodes.first;
2169  while (new_node != nullptr) {
2170  node_set_new_pointers(node_src, new_node);
2171  new_node = new_node->next;
2172  node_src = node_src->next;
2173  }
2174  return new_ntree;
2175 }
2176 
2177 static int node_count_links(const bNodeTree *ntree, const bNodeSocket *socket)
2178 {
2179  int count = 0;
2181  if (ELEM(socket, link->fromsock, link->tosock)) {
2182  count++;
2183  }
2184  }
2185  return count;
2186 }
2187 
2188 /* also used via rna api, so we check for proper input output direction */
2190  bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock)
2191 {
2192  bNodeLink *link = nullptr;
2193 
2194  /* test valid input */
2195  BLI_assert(fromnode);
2196  BLI_assert(tonode);
2197 
2198  if (fromsock->in_out == SOCK_OUT && tosock->in_out == SOCK_IN) {
2199  link = (bNodeLink *)MEM_callocN(sizeof(bNodeLink), "link");
2200  if (ntree) {
2202  }
2203  link->fromnode = fromnode;
2204  link->fromsock = fromsock;
2205  link->tonode = tonode;
2206  link->tosock = tosock;
2207  }
2208  else if (fromsock->in_out == SOCK_IN && tosock->in_out == SOCK_OUT) {
2209  /* OK but flip */
2210  link = (bNodeLink *)MEM_callocN(sizeof(bNodeLink), "link");
2211  if (ntree) {
2213  }
2214  link->fromnode = tonode;
2215  link->fromsock = tosock;
2216  link->tonode = fromnode;
2217  link->tosock = fromsock;
2218  }
2219 
2220  if (ntree) {
2222  }
2223 
2224  if (link->tosock->flag & SOCK_MULTI_INPUT) {
2226  }
2227 
2228  return link;
2229 }
2230 
2232 {
2233  /* can be called for links outside a node tree (e.g. clipboard) */
2234  if (ntree) {
2236  }
2237 
2238  if (link->tosock) {
2239  link->tosock->link = nullptr;
2240  }
2241  MEM_freeN(link);
2242 
2243  if (ntree) {
2245  }
2246 }
2247 
2248 /* Check if all output links are muted or not. */
2249 static bool nodeMuteFromSocketLinks(const bNodeTree *ntree, const bNodeSocket *sock)
2250 {
2251  int tot = 0;
2252  int muted = 0;
2253  LISTBASE_FOREACH (const bNodeLink *, link, &ntree->links) {
2254  if (link->fromsock == sock) {
2255  tot++;
2256  if (link->flag & NODE_LINK_MUTED) {
2257  muted++;
2258  }
2259  }
2260  }
2261  return tot == muted;
2262 }
2263 
2265 {
2267  link->flag |= NODE_LINK_TEST;
2268  if (!(link->tosock->flag & SOCK_MULTI_INPUT)) {
2269  link->tosock->flag &= ~SOCK_IN_USE;
2270  }
2271 }
2272 
2274 {
2275  link->flag &= ~NODE_LINK_MUTED;
2276  link->flag |= NODE_LINK_TEST;
2277  link->tosock->flag |= SOCK_IN_USE;
2278 }
2279 
2280 /* Upstream muting. Always happens when unmuting but checks when muting. O(n^2) algorithm.*/
2281 static void nodeMuteRerouteInputLinks(bNodeTree *ntree, bNode *node, const bool mute)
2282 {
2283  if (node->type != NODE_REROUTE) {
2284  return;
2285  }
2286  if (!mute || nodeMuteFromSocketLinks(ntree, (bNodeSocket *)node->outputs.first)) {
2287  bNodeSocket *sock = (bNodeSocket *)node->inputs.first;
2289  if (!(link->flag & NODE_LINK_VALID) || (link->tosock != sock)) {
2290  continue;
2291  }
2292  if (mute) {
2293  nodeMuteLink(link);
2294  }
2295  else {
2297  }
2299  }
2300  }
2301 }
2302 
2303 /* Downstream muting propagates when reaching reroute nodes. O(n^2) algorithm.*/
2304 static void nodeMuteRerouteOutputLinks(bNodeTree *ntree, bNode *node, const bool mute)
2305 {
2306  if (node->type != NODE_REROUTE) {
2307  return;
2308  }
2309  bNodeSocket *sock;
2310  sock = (bNodeSocket *)node->outputs.first;
2312  if (!(link->flag & NODE_LINK_VALID) || (link->fromsock != sock)) {
2313  continue;
2314  }
2315  if (mute) {
2316  nodeMuteLink(link);
2317  }
2318  else {
2320  }
2322  }
2323 }
2324 
2326 {
2327  if (link->tosock) {
2328  bool mute = !(link->flag & NODE_LINK_MUTED);
2329  if (mute) {
2330  nodeMuteLink(link);
2331  }
2332  else {
2334  }
2335  if (link->tonode->type == NODE_REROUTE) {
2337  }
2338  if (link->fromnode->type == NODE_REROUTE) {
2340  }
2341  }
2342 
2343  if (ntree) {
2345  }
2346 }
2347 
2349 {
2351  if (link->fromsock == sock || link->tosock == sock) {
2353  }
2354  }
2355 
2357 }
2358 
2360 {
2362 }
2363 
2365 {
2366  /* store link pointers in output sockets, for efficient lookup */
2367  LISTBASE_FOREACH (bNodeLink *, link, &node->internal_links) {
2368  link->tosock->link = link;
2369  }
2370 
2371  /* redirect downstream links */
2373  /* do we have internal link? */
2374  if (link->fromnode == node) {
2375  if (link->fromsock->link) {
2376  /* get the upstream input link */
2377  bNodeLink *fromlink = link->fromsock->link->fromsock->link;
2378  /* skip the node */
2379  if (fromlink) {
2380  link->fromnode = fromlink->fromnode;
2381  link->fromsock = fromlink->fromsock;
2382 
2383  /* if the up- or downstream link is invalid,
2384  * the replacement link will be invalid too.
2385  */
2386  if (!(fromlink->flag & NODE_LINK_VALID)) {
2387  link->flag &= ~NODE_LINK_VALID;
2388  }
2389 
2390  if (fromlink->flag & NODE_LINK_MUTED) {
2392  }
2393 
2395  }
2396  else {
2398  }
2399  }
2400  else {
2402  }
2403  }
2404  }
2405 
2406  /* remove remaining upstream links */
2408  if (link->tonode == node) {
2410  }
2411  }
2412 }
2413 
2414 void nodeToView(const bNode *node, float x, float y, float *rx, float *ry)
2415 {
2416  if (node->parent) {
2417  nodeToView(node->parent, x + node->locx, y + node->locy, rx, ry);
2418  }
2419  else {
2420  *rx = x + node->locx;
2421  *ry = y + node->locy;
2422  }
2423 }
2424 
2425 void nodeFromView(const bNode *node, float x, float y, float *rx, float *ry)
2426 {
2427  if (node->parent) {
2428  nodeFromView(node->parent, x, y, rx, ry);
2429  *rx -= node->locx;
2430  *ry -= node->locy;
2431  }
2432  else {
2433  *rx = x - node->locx;
2434  *ry = y - node->locy;
2435  }
2436 }
2437 
2438 bool nodeAttachNodeCheck(const bNode *node, const bNode *parent)
2439 {
2440  for (const bNode *parent_iter = node; parent_iter; parent_iter = parent_iter->parent) {
2441  if (parent_iter == parent) {
2442  return true;
2443  }
2444  }
2445 
2446  return false;
2447 }
2448 
2450 {
2451  BLI_assert(parent->type == NODE_FRAME);
2452  BLI_assert(nodeAttachNodeCheck(parent, node) == false);
2453 
2454  float locx, locy;
2455  nodeToView(node, 0.0f, 0.0f, &locx, &locy);
2456 
2457  node->parent = parent;
2458  /* transform to parent space */
2459  nodeFromView(parent, locx, locy, &node->locx, &node->locy);
2460 }
2461 
2463 {
2464  if (node->parent) {
2465  BLI_assert(node->parent->type == NODE_FRAME);
2466 
2467  /* transform to view space */
2468  float locx, locy;
2469  nodeToView(node, 0.0f, 0.0f, &locx, &locy);
2470  node->locx = locx;
2471  node->locy = locy;
2472  node->parent = nullptr;
2473  }
2474 }
2475 
2476 void nodePositionRelative(bNode *from_node,
2477  bNode *to_node,
2478  bNodeSocket *from_sock,
2479  bNodeSocket *to_sock)
2480 {
2481  float offset_x;
2482  int tot_sock_idx;
2483 
2484  /* Socket to plug into. */
2485  if (SOCK_IN == to_sock->in_out) {
2486  offset_x = -(from_node->typeinfo->width + 50);
2487  tot_sock_idx = BLI_listbase_count(&to_node->outputs);
2488  tot_sock_idx += BLI_findindex(&to_node->inputs, to_sock);
2489  }
2490  else {
2491  offset_x = to_node->typeinfo->width + 50;
2492  tot_sock_idx = BLI_findindex(&to_node->outputs, to_sock);
2493  }
2494 
2495  BLI_assert(tot_sock_idx != -1);
2496 
2497  float offset_y = U.widget_unit * tot_sock_idx;
2498 
2499  /* Output socket. */
2500  if (from_sock) {
2501  if (SOCK_IN == from_sock->in_out) {
2502  tot_sock_idx = BLI_listbase_count(&from_node->outputs);
2503  tot_sock_idx += BLI_findindex(&from_node->inputs, from_sock);
2504  }
2505  else {
2506  tot_sock_idx = BLI_findindex(&from_node->outputs, from_sock);
2507  }
2508  }
2509 
2510  BLI_assert(tot_sock_idx != -1);
2511 
2512  offset_y -= U.widget_unit * tot_sock_idx;
2513 
2514  from_node->locx = to_node->locx + offset_x;
2515  from_node->locy = to_node->locy - offset_y;
2516 }
2517 
2519 {
2520  LISTBASE_FOREACH (bNodeSocket *, nsock, &node->inputs) {
2521  if (nsock->link != nullptr) {
2522  bNodeLink *link = nsock->link;
2525  }
2526  }
2527 }
2528 
2529 bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname)
2530 {
2531  /* trees are created as local trees for compositor, material or texture nodes,
2532  * node groups and other tree types are created as library data.
2533  */
2534  const bool is_embedded = (bmain == nullptr);
2535  int flag = 0;
2536  if (is_embedded) {
2538  }
2540  if (is_embedded) {
2542  }
2543 
2544  /* Types are fully initialized at this point,
2545  * if an undefined node is added later this will be reset.
2546  */
2548 
2549  BLI_strncpy(ntree->idname, idname, sizeof(ntree->idname));
2551 
2552  return ntree;
2553 }
2554 
2555 bNodeTree *ntreeCopyTree_ex(const bNodeTree *ntree, Main *bmain, const bool do_id_user)
2556 {
2557  const int flag = do_id_user ? 0 : LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_CREATE_NO_MAIN;
2558 
2559  bNodeTree *ntree_copy = (bNodeTree *)BKE_id_copy_ex(bmain, (ID *)ntree, nullptr, flag);
2560  return ntree_copy;
2561 }
2563 {
2564  return ntreeCopyTree_ex(ntree, bmain, true);
2565 }
2566 
2567 /* *************** Node Preview *********** */
2568 
2569 /* XXX this should be removed eventually ...
2570  * Currently BKE functions are modeled closely on previous code,
2571  * using BKE_node_preview_init_tree to set up previews for a whole node tree in advance.
2572  * This should be left more to the individual node tree implementations.
2573  */
2575 {
2576  /* XXX check for closed nodes? */
2577  return (node->typeinfo->flag & NODE_PREVIEW) != 0;
2578 }
2579 
2581  bNodeInstanceHash *previews, bNodeInstanceKey key, int xsize, int ysize, bool create)
2582 {
2583  bNodePreview *preview = (bNodePreview *)BKE_node_instance_hash_lookup(previews, key);
2584  if (!preview) {
2585  if (create) {
2586  preview = (bNodePreview *)MEM_callocN(sizeof(bNodePreview), "node preview");
2587  BKE_node_instance_hash_insert(previews, key, preview);
2588  }
2589  else {
2590  return nullptr;
2591  }
2592  }
2593 
2594  /* node previews can get added with variable size this way */
2595  if (xsize == 0 || ysize == 0) {
2596  return preview;
2597  }
2598 
2599  /* sanity checks & initialize */
2600  if (preview->rect) {
2601  if (preview->xsize != xsize || preview->ysize != ysize) {
2602  MEM_freeN(preview->rect);
2603  preview->rect = nullptr;
2604  }
2605  }
2606 
2607  if (preview->rect == nullptr) {
2608  preview->rect = (unsigned char *)MEM_callocN(4 * xsize + xsize * ysize * sizeof(char[4]),
2609  "node preview rect");
2610  preview->xsize = xsize;
2611  preview->ysize = ysize;
2612  }
2613  /* no clear, makes nicer previews */
2614 
2615  return preview;
2616 }
2617 
2619 {
2620  bNodePreview *new_preview = (bNodePreview *)MEM_dupallocN(preview);
2621  if (preview->rect) {
2622  new_preview->rect = (unsigned char *)MEM_dupallocN(preview->rect);
2623  }
2624  return new_preview;
2625 }
2626 
2628 {
2629  if (preview->rect) {
2630  MEM_freeN(preview->rect);
2631  }
2632  MEM_freeN(preview);
2633 }
2634 
2636  bNodeTree *ntree,
2637  bNodeInstanceKey parent_key,
2638  int xsize,
2639  int ysize,
2640  bool create_previews)
2641 {
2643  bNodeInstanceKey key = BKE_node_instance_key(parent_key, ntree, node);
2644 
2645  if (BKE_node_preview_used(node)) {
2646  node->preview_xsize = xsize;
2647  node->preview_ysize = ysize;
2648 
2649  BKE_node_preview_verify(previews, key, xsize, ysize, create_previews);
2650  }
2651 
2652  if (node->type == NODE_GROUP && node->id) {
2654  previews, (bNodeTree *)node->id, key, xsize, ysize, create_previews);
2655  }
2656  }
2657 }
2658 
2659 void BKE_node_preview_init_tree(bNodeTree *ntree, int xsize, int ysize, bool create_previews)
2660 {
2661  if (!ntree) {
2662  return;
2663  }
2664 
2665  if (!ntree->previews) {
2666  ntree->previews = BKE_node_instance_hash_new("node previews");
2667  }
2668 
2670  ntree->previews, ntree, NODE_INSTANCE_KEY_BASE, xsize, ysize, create_previews);
2671 }
2672 
2674  bNodeTree *ntree,
2675  bNodeInstanceKey parent_key)
2676 {
2678  bNodeInstanceKey key = BKE_node_instance_key(parent_key, ntree, node);
2679 
2680  if (BKE_node_preview_used(node)) {
2681  BKE_node_instance_hash_tag_key(previews, key);
2682  }
2683 
2684  if (node->type == NODE_GROUP && node->id) {
2685  node_preview_tag_used_recursive(previews, (bNodeTree *)node->id, key);
2686  }
2687  }
2688 }
2689 
2691 {
2692  if (!ntree || !ntree->previews) {
2693  return;
2694  }
2695 
2696  /* use the instance hash functions for tagging and removing unused previews */
2699 
2702 }
2703 
2705 {
2706  if (!ntree) {
2707  return;
2708  }
2709 
2710  if (ntree->previews) {
2712  ntree->previews = nullptr;
2713  }
2714 }
2715 
2717 {
2718  if (preview && preview->rect) {
2719  memset(preview->rect, 0, MEM_allocN_len(preview->rect));
2720  }
2721 }
2722 
2724 {
2725  if (!ntree || !ntree->previews) {
2726  return;
2727  }
2728 
2732  BKE_node_preview_clear(preview);
2733  }
2734 }
2735 
2737 {
2738  /* sizes should have been initialized by BKE_node_preview_init_tree */
2739  BLI_assert(to->xsize == from->xsize && to->ysize == from->ysize);
2740 
2741  /* copy over contents of previews */
2742  if (to->rect && from->rect) {
2743  int xsize = to->xsize;
2744  int ysize = to->ysize;
2745  memcpy(to->rect, from->rect, xsize * ysize * sizeof(char[4]));
2746  }
2747 }
2748 
2749 void BKE_node_preview_sync_tree(bNodeTree *to_ntree, bNodeTree *from_ntree)
2750 {
2751  bNodeInstanceHash *from_previews = from_ntree->previews;
2752  bNodeInstanceHash *to_previews = to_ntree->previews;
2753 
2754  if (!from_previews || !to_previews) {
2755  return;
2756  }
2757 
2759  NODE_INSTANCE_HASH_ITER (iter, from_previews) {
2762  bNodePreview *to = (bNodePreview *)BKE_node_instance_hash_lookup(to_previews, key);
2763 
2764  if (from && to) {
2765  node_preview_sync(to, from);
2766  }
2767  }
2768 }
2769 
2770 void BKE_node_preview_merge_tree(bNodeTree *to_ntree, bNodeTree *from_ntree, bool remove_old)
2771 {
2772  if (remove_old || !to_ntree->previews) {
2773  /* free old previews */
2774  if (to_ntree->previews) {
2776  }
2777 
2778  /* transfer previews */
2779  to_ntree->previews = from_ntree->previews;
2780  from_ntree->previews = nullptr;
2781 
2782  /* clean up, in case any to_ntree nodes have been removed */
2784  }
2785  else {
2786  if (from_ntree->previews) {
2788  NODE_INSTANCE_HASH_ITER (iter, from_ntree->previews) {
2791 
2792  /* replace existing previews */
2795  BKE_node_instance_hash_insert(to_ntree->previews, key, preview);
2796  }
2797 
2798  /* Note: null free function here,
2799  * because pointers have already been moved over to to_ntree->previews! */
2800  BKE_node_instance_hash_free(from_ntree->previews, nullptr);
2801  from_ntree->previews = nullptr;
2802  }
2803  }
2804 }
2805 
2806 /* hack warning! this function is only used for shader previews, and
2807  * since it gets called multiple times per pixel for Ztransp we only
2808  * add the color once. Preview gets cleared before it starts render though */
2810  bNodePreview *preview, const float col[4], int x, int y, bool do_manage)
2811 {
2812  if (preview) {
2813  if (x >= 0 && y >= 0) {
2814  if (x < preview->xsize && y < preview->ysize) {
2815  unsigned char *tar = preview->rect + 4 * ((preview->xsize * y) + x);
2816 
2817  if (do_manage) {
2819  }
2820  else {
2821  rgba_float_to_uchar(tar, col);
2822  }
2823  }
2824  // else printf("prv out bound x y %d %d\n", x, y);
2825  }
2826  // else printf("prv out bound x y %d %d\n", x, y);
2827  }
2828 }
2829 
2830 /* ************** Free stuff ********** */
2831 
2832 /* goes over entire tree */
2834 {
2836  ListBase *lb;
2837  if (link->fromnode == node) {
2838  lb = &node->outputs;
2839  if (link->tonode) {
2841  }
2842  }
2843  else if (link->tonode == node) {
2844  lb = &node->inputs;
2845  }
2846  else {
2847  lb = nullptr;
2848  }
2849 
2850  if (lb) {
2851  LISTBASE_FOREACH (bNodeSocket *, sock, lb) {
2852  if (link->fromsock == sock || link->tosock == sock) {
2854  break;
2855  }
2856  }
2857  }
2858  }
2859 }
2860 
2862 {
2864  if (node->parent == parent) {
2866  }
2867  }
2868 }
2869 
2870 /* Free the node itself. ID user refcounting is up the caller,
2871  * that does not happen here. */
2873 {
2874  /* since it is called while free database, node->id is undefined */
2875 
2876  /* can be called for nodes outside a node tree (e.g. clipboard) */
2877  if (ntree) {
2878  /* remove all references to this node */
2881 
2883 
2884  if (ntree->typeinfo->free_node_cache) {
2886  }
2887 
2888  /* texture node has bad habit of keeping exec data around */
2889  if (ntree->type == NTREE_TEXTURE && ntree->execdata) {
2891  ntree->execdata = nullptr;
2892  }
2893  }
2894 
2895  if (node->typeinfo->freefunc) {
2896  node->typeinfo->freefunc(node);
2897  }
2898 
2899  LISTBASE_FOREACH_MUTABLE (bNodeSocket *, sock, &node->inputs) {
2900  /* Remember, no ID user refcount management here! */
2901  node_socket_free(ntree, sock, node, false);
2902  MEM_freeN(sock);
2903  }
2904  LISTBASE_FOREACH_MUTABLE (bNodeSocket *, sock, &node->outputs) {
2905  /* Remember, no ID user refcount management here! */
2906  node_socket_free(ntree, sock, node, false);
2907  MEM_freeN(sock);
2908  }
2909 
2910  BLI_freelistN(&node->internal_links);
2911 
2912  if (node->prop) {
2913  /* Remember, no ID user refcount management here! */
2914  IDP_FreePropertyContent_ex(node->prop, false);
2915  MEM_freeN(node->prop);
2916  }
2917 
2918  MEM_freeN(node);
2919 
2920  if (ntree) {
2922  }
2923 }
2924 
2926 {
2927  /* For removing nodes while editing localized node trees. */
2930 }
2931 
2932 void nodeRemoveNode(Main *bmain, bNodeTree *ntree, bNode *node, bool do_id_user)
2933 {
2934  /* This function is not for localized node trees, we do not want
2935  * do to ID user refcounting and removal of animdation data then. */
2937 
2938  if (do_id_user) {
2939  /* Free callback for NodeCustomGroup. */
2940  if (node->typeinfo->freefunc_api) {
2941  PointerRNA ptr;
2943 
2944  node->typeinfo->freefunc_api(&ptr);
2945  }
2946 
2947  /* Do user counting. */
2948  if (node->id) {
2949  id_us_min(node->id);
2950  }
2951 
2952  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
2954  }
2955  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
2957  }
2958  }
2959 
2960  /* Remove animation data. */
2961  char propname_esc[MAX_IDPROP_NAME * 2];
2962  char prefix[MAX_IDPROP_NAME * 2];
2963 
2964  BLI_str_escape(propname_esc, node->name, sizeof(propname_esc));
2965  BLI_snprintf(prefix, sizeof(prefix), "nodes[\"%s\"]", propname_esc);
2966 
2967  if (BKE_animdata_fix_paths_remove((ID *)ntree, prefix)) {
2968  if (bmain != nullptr) {
2969  DEG_relations_tag_update(bmain);
2970  }
2971  }
2972 
2973  /* Free node itself. */
2975 }
2976 
2978  bNodeSocket *sock,
2979  const bool do_id_user)
2980 {
2981  if (sock->prop) {
2982  IDP_FreeProperty_ex(sock->prop, do_id_user);
2983  }
2984 
2985  if (sock->default_value) {
2986  if (do_id_user) {
2988  }
2989  MEM_freeN(sock->default_value);
2990  }
2991 }
2992 
2994 {
2995  /* Only localized node trees store a copy for each node group tree.
2996  * Each node group tree in a localized node tree can be freed,
2997  * since it is a localized copy itself (no risk of accessing free'd
2998  * data in main, see T37939).
2999  */
3000  if (!(ntree->id.tag & LIB_TAG_LOCALIZED)) {
3001  return;
3002  }
3003 
3005  if ((ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) && node->id) {
3006  bNodeTree *ngroup = (bNodeTree *)node->id;
3007  ntreeFreeTree(ngroup);
3008  MEM_freeN(ngroup);
3009  }
3010  }
3011 }
3012 
3013 /* Free (or release) any data used by this nodetree. Does not free the
3014  * nodetree itself and does no ID user counting. */
3016 {
3018  BKE_animdata_free(&ntree->id, false);
3019 }
3020 
3022 {
3024  BKE_libblock_free_data(&ntree->id, true);
3026 }
3027 
3029 {
3030  if (ntree->id.tag & LIB_TAG_LOCALIZED) {
3032  }
3033  else {
3035  BKE_libblock_free_data(&ntree->id, true);
3036  }
3037 }
3038 
3040 {
3041  if (ntree == nullptr) {
3042  return;
3043  }
3044 
3045  if (ntree->typeinfo->free_cache) {
3047  }
3048 }
3049 
3051 {
3052  /* find the active outputs, might become tree type dependent handler */
3054  if (node->typeinfo->nclass == NODE_CLASS_OUTPUT) {
3055  /* we need a check for which output node should be tagged like this, below an exception */
3056  if (node->type == CMP_NODE_OUTPUT_FILE) {
3057  continue;
3058  }
3059 
3060  int output = 0;
3061  /* there is more types having output class, each one is checked */
3062  LISTBASE_FOREACH (bNode *, tnode, &ntree->nodes) {
3063  if (tnode->typeinfo->nclass == NODE_CLASS_OUTPUT) {
3064  if (ntree->type == NTREE_COMPOSIT) {
3065  /* same type, exception for viewer */
3066  if (tnode->type == node->type ||
3067  (ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) &&
3069  if (tnode->flag & NODE_DO_OUTPUT) {
3070  output++;
3071  if (output > 1) {
3072  tnode->flag &= ~NODE_DO_OUTPUT;
3073  }
3074  }
3075  }
3076  }
3077  else {
3078  /* same type */
3079  if (tnode->type == node->type) {
3080  if (tnode->flag & NODE_DO_OUTPUT) {
3081  output++;
3082  if (output > 1) {
3083  tnode->flag &= ~NODE_DO_OUTPUT;
3084  }
3085  }
3086  }
3087  }
3088  }
3089  }
3090  if (output == 0) {
3091  node->flag |= NODE_DO_OUTPUT;
3092  }
3093  }
3094 
3095  /* group node outputs use this flag too */
3096  if (node->type == NODE_GROUP_OUTPUT) {
3097  int output = 0;
3098  LISTBASE_FOREACH (bNode *, tnode, &ntree->nodes) {
3099  if (tnode->type == NODE_GROUP_OUTPUT) {
3100  if (tnode->flag & NODE_DO_OUTPUT) {
3101  output++;
3102  if (output > 1) {
3103  tnode->flag &= ~NODE_DO_OUTPUT;
3104  }
3105  }
3106  }
3107  }
3108  if (output == 0) {
3109  node->flag |= NODE_DO_OUTPUT;
3110  }
3111  }
3112  }
3113 
3114  /* here we could recursively set which nodes have to be done,
3115  * might be different for editor or for "real" use... */
3116 }
3117 
3125 {
3126  switch (GS(id->name)) {
3127  case ID_MA:
3128  return &((Material *)id)->nodetree;
3129  case ID_LA:
3130  return &((Light *)id)->nodetree;
3131  case ID_WO:
3132  return &((World *)id)->nodetree;
3133  case ID_TE:
3134  return &((Tex *)id)->nodetree;
3135  case ID_SCE:
3136  return &((Scene *)id)->nodetree;
3137  case ID_LS:
3138  return &((FreestyleLineStyle *)id)->nodetree;
3139  case ID_SIM:
3140  return &((Simulation *)id)->nodetree;
3141  default:
3142  return nullptr;
3143  }
3144 }
3145 
3146 /* Returns the private NodeTree object of the datablock, if it has one. */
3148 {
3149  bNodeTree **nodetree = BKE_ntree_ptr_from_id(id);
3150  return (nodetree != nullptr) ? *nodetree : nullptr;
3151 }
3152 
3153 bool ntreeNodeExists(const bNodeTree *ntree, const bNode *testnode)
3154 {
3155  LISTBASE_FOREACH (const bNode *, node, &ntree->nodes) {
3156  if (node == testnode) {
3157  return true;
3158  }
3159  }
3160  return false;
3161 }
3162 
3163 bool ntreeOutputExists(const bNode *node, const bNodeSocket *testsock)
3164 {
3165  LISTBASE_FOREACH (const bNodeSocket *, sock, &node->outputs) {
3166  if (sock == testsock) {
3167  return true;
3168  }
3169  }
3170  return false;
3171 }
3172 
3173 void ntreeNodeFlagSet(const bNodeTree *ntree, const int flag, const bool enable)
3174 {
3176  if (enable) {
3177  node->flag |= flag;
3178  }
3179  else {
3180  node->flag &= ~flag;
3181  }
3182  }
3183 }
3184 
3185 /* returns localized tree for execution in threads */
3187 {
3188  if (ntree) {
3189  /* Make full copy outside of Main database.
3190  * Note: previews are not copied here.
3191  */
3192  bNodeTree *ltree = (bNodeTree *)BKE_id_copy_ex(
3193  nullptr, &ntree->id, nullptr, (LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_NO_ANIMDATA));
3194 
3195  ltree->id.tag |= LIB_TAG_LOCALIZED;
3196 
3197  LISTBASE_FOREACH (bNode *, node, &ltree->nodes) {
3198  if ((ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) && node->id) {
3199  node->id = (ID *)ntreeLocalize((bNodeTree *)node->id);
3200  }
3201  }
3202 
3203  /* ensures only a single output node is enabled */
3205 
3206  bNode *node_src = (bNode *)ntree->nodes.first;
3207  bNode *node_local = (bNode *)ltree->nodes.first;
3208  while (node_src != nullptr) {
3209  node_local->original = node_src;
3210  node_src = node_src->next;
3211  node_local = node_local->next;
3212  }
3213 
3214  if (ntree->typeinfo->localize) {
3215  ntree->typeinfo->localize(ltree, ntree);
3216  }
3217 
3218  return ltree;
3219  }
3220 
3221  return nullptr;
3222 }
3223 
3224 /* sync local composite with real tree */
3225 /* local tree is supposed to be running, be careful moving previews! */
3226 /* is called by jobs manager, outside threads, so it doesn't happen during draw */
3228 {
3229  if (localtree && ntree) {
3230  if (ntree->typeinfo->local_sync) {
3231  ntree->typeinfo->local_sync(localtree, ntree);
3232  }
3233  }
3234 }
3235 
3236 /* merge local tree results back, and free local tree */
3237 /* we have to assume the editor already changed completely */
3238 void ntreeLocalMerge(Main *bmain, bNodeTree *localtree, bNodeTree *ntree)
3239 {
3240  if (ntree && localtree) {
3241  if (ntree->typeinfo->local_merge) {
3242  ntree->typeinfo->local_merge(bmain, localtree, ntree);
3243  }
3244 
3245  ntreeFreeTree(localtree);
3246  MEM_freeN(localtree);
3247  }
3248 }
3249 
3250 /* ************ NODE TREE INTERFACE *************** */
3251 
3254  const char *idname,
3255  const char *name)
3256 {
3258  int own_index = ntree->cur_index++;
3259 
3260  if (stype == nullptr) {
3261  return nullptr;
3262  }
3263 
3264  bNodeSocket *sock = (bNodeSocket *)MEM_callocN(sizeof(bNodeSocket), "socket template");
3265  BLI_strncpy(sock->idname, stype->idname, sizeof(sock->idname));
3266  node_socket_set_typeinfo(ntree, sock, stype);
3267  sock->in_out = in_out;
3268  sock->type = SOCK_CUSTOM; /* int type undefined by default */
3269 
3270  /* assign new unique index */
3271  own_index = ntree->cur_index++;
3272  /* use the own_index as socket identifier */
3273  if (in_out == SOCK_IN) {
3274  BLI_snprintf(sock->identifier, MAX_NAME, "Input_%d", own_index);
3275  }
3276  else {
3277  BLI_snprintf(sock->identifier, MAX_NAME, "Output_%d", own_index);
3278  }
3279 
3280  sock->limit = (in_out == SOCK_IN ? 1 : 0xFFF);
3281 
3282  BLI_strncpy(sock->name, name, NODE_MAXSTR);
3283  sock->storage = nullptr;
3284  sock->flag |= SOCK_COLLAPSED;
3285 
3286  return sock;
3287 }
3288 
3291  const char *identifier)
3292 {
3293  ListBase *sockets = (in_out == SOCK_IN) ? &ntree->inputs : &ntree->outputs;
3294  LISTBASE_FOREACH (bNodeSocket *, iosock, sockets) {
3295  if (STREQ(iosock->identifier, identifier)) {
3296  return iosock;
3297  }
3298  }
3299  return nullptr;
3300 }
3301 
3304  const char *idname,
3305  const char *name)
3306 {
3308  if (in_out == SOCK_IN) {
3309  BLI_addtail(&ntree->inputs, iosock);
3311  }
3312  else if (in_out == SOCK_OUT) {
3313  BLI_addtail(&ntree->outputs, iosock);
3315  }
3316  return iosock;
3317 }
3318 
3321  const char *idname,
3322  bNodeSocket *next_sock,
3323  const char *name)
3324 {
3326  if (in_out == SOCK_IN) {
3327  BLI_insertlinkbefore(&ntree->inputs, next_sock, iosock);
3329  }
3330  else if (in_out == SOCK_OUT) {
3331  BLI_insertlinkbefore(&ntree->outputs, next_sock, iosock);
3333  }
3334  return iosock;
3335 }
3336 
3338  bNode *from_node,
3339  bNodeSocket *from_sock)
3340 {
3342  ntree, static_cast<eNodeSocketInOut>(from_sock->in_out), from_sock->idname, from_sock->name);
3343  if (iosock) {
3344  if (iosock->typeinfo->interface_from_socket) {
3345  iosock->typeinfo->interface_from_socket(ntree, iosock, from_node, from_sock);
3346  }
3347  }
3348  return iosock;
3349 }
3350 
3352  bNodeSocket *next_sock,
3353  bNode *from_node,
3354  bNodeSocket *from_sock)
3355 {
3357  ntree,
3358  static_cast<eNodeSocketInOut>(from_sock->in_out),
3359  from_sock->idname,
3360  next_sock,
3361  from_sock->name);
3362  if (iosock) {
3363  if (iosock->typeinfo->interface_from_socket) {
3364  iosock->typeinfo->interface_from_socket(ntree, iosock, from_node, from_sock);
3365  }
3366  }
3367  return iosock;
3368 }
3369 
3371 {
3372  /* this is fast, this way we don't need an in_out argument */
3373  BLI_remlink(&ntree->inputs, sock);
3374  BLI_remlink(&ntree->outputs, sock);
3375 
3376  node_socket_interface_free(ntree, sock, true);
3377  MEM_freeN(sock);
3378 
3380 }
3381 
3382 /* generates a valid RNA identifier from the node tree name */
3384 {
3385  /* generate a valid RNA identifier */
3386  sprintf(base, "NodeTreeInterface_%s", ntree->id.name + 2);
3387  RNA_identifier_sanitize(base, false);
3388 }
3389 
3390 /* check if the identifier is already in use */
3392 {
3393  return (RNA_struct_find(identifier) != nullptr);
3394 }
3395 
3396 /* generates the actual unique identifier and ui name and description */
3398  const char *base,
3399  char *identifier,
3400  int maxlen,
3401  char *name,
3402  char *description)
3403 {
3404  /* There is a possibility that different node tree names get mapped to the same identifier
3405  * after sanitation (e.g. "SomeGroup_A", "SomeGroup.A" both get sanitized to "SomeGroup_A").
3406  * On top of the sanitized id string add a number suffix if necessary to avoid duplicates.
3407  */
3408  identifier[0] = '\0';
3410  ntree_interface_unique_identifier_check, nullptr, base, '_', identifier, maxlen);
3411 
3412  sprintf(name, "Node Tree %s Interface", ntree->id.name + 2);
3413  sprintf(description, "Interface properties of node group %s", ntree->id.name + 2);
3414 }
3415 
3417 {
3418  /* strings are generated from base string + ID name, sizes are sufficient */
3419  char base[MAX_ID_NAME + 64], identifier[MAX_ID_NAME + 64], name[MAX_ID_NAME + 64],
3420  description[MAX_ID_NAME + 64];
3421 
3422  /* generate a valid RNA identifier */
3425 
3426  /* register a subtype of PropertyGroup */
3430 
3431  /* associate the RNA type with the node tree */
3432  ntree->interface_type = srna;
3434 
3435  /* add socket properties */
3436  LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->inputs) {
3437  bNodeSocketType *stype = sock->typeinfo;
3438  if (stype && stype->interface_register_properties) {
3439  stype->interface_register_properties(ntree, sock, srna);
3440  }
3441  }
3442  LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->outputs) {
3443  bNodeSocketType *stype = sock->typeinfo;
3444  if (stype && stype->interface_register_properties) {
3445  stype->interface_register_properties(ntree, sock, srna);
3446  }
3447  }
3448 }
3449 
3451 {
3452  if (ntree->interface_type) {
3453  /* strings are generated from base string + ID name, sizes are sufficient */
3454  char base[MAX_ID_NAME + 64], identifier[MAX_ID_NAME + 64], name[MAX_ID_NAME + 64],
3455  description[MAX_ID_NAME + 64];
3456 
3457  /* A bit of a hack: when changing the ID name, update the RNA type identifier too,
3458  * so that the names match. This is not strictly necessary to keep it working,
3459  * but better for identifying associated NodeTree blocks and RNA types.
3460  */
3461  StructRNA *srna = ntree->interface_type;
3462 
3464 
3465  /* RNA identifier may have a number suffix, but should start with the idbase string */
3466  if (!STREQLEN(RNA_struct_identifier(srna), base, sizeof(base))) {
3467  /* generate new unique RNA identifier from the ID name */
3469 
3470  /* rename the RNA type */
3475  }
3476  }
3477  else if (create) {
3479  }
3480 
3481  return ntree->interface_type;
3482 }
3483 
3485 {
3486  if (ntree->interface_type) {
3488  ntree->interface_type = nullptr;
3489  }
3490 }
3491 
3493 {
3494  /* XXX it would be sufficient to just recreate all properties
3495  * instead of re-registering the whole struct type,
3496  * but there is currently no good way to do this in the RNA functions.
3497  * Overhead should be negligible.
3498  */
3501 }
3502 
3503 /* ************ find stuff *************** */
3504 
3506 {
3507  if (ntree) {
3509  if (node->type == type) {
3510  return node;
3511  }
3512  }
3513  }
3514  return nullptr;
3515 }
3516 
3518 {
3519  return ntreeFindType(ntree, type) != nullptr;
3520 }
3521 
3522 bool ntreeHasTree(const bNodeTree *ntree, const bNodeTree *lookup)
3523 {
3524  if (ntree == lookup) {
3525  return true;
3526  }
3528  if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) {
3529  if (ntreeHasTree((bNodeTree *)node->id, lookup)) {
3530  return true;
3531  }
3532  }
3533  }
3534  return false;
3535 }
3536 
3538 {
3540  if (link->fromsock == from && link->tosock == to) {
3541  return link;
3542  }
3543  if (link->fromsock == to && link->tosock == from) { /* hrms? */
3544  return link;
3545  }
3546  }
3547  return nullptr;
3548 }
3549 
3551 {
3552  int tot = 0;
3553  LISTBASE_FOREACH (const bNodeLink *, link, &ntree->links) {
3554  if (link->fromsock == sock || link->tosock == sock) {
3555  tot++;
3556  }
3557  }
3558  return tot;
3559 }
3560 
3562 {
3563  if (ntree == nullptr) {
3564  return nullptr;
3565  }
3566 
3568  if (node->flag & NODE_ACTIVE) {
3569  return node;
3570  }
3571  }
3572  return nullptr;
3573 }
3574 
3576  bNodeInstanceKey parent_key,
3577  bNodeTree *ntree,
3578  short idtype)
3579 {
3580  if (parent_key.value == active_key.value || active_key.value == 0) {
3582  if (node->id && GS(node->id->name) == idtype) {
3583  if (node->flag & NODE_ACTIVE_ID) {
3584  return node;
3585  }
3586  }
3587  }
3588  }
3589  else {
3590  /* no node with active ID in this tree, look inside groups */
3592  if (node->type == NODE_GROUP) {
3593  bNodeTree *group = (bNodeTree *)node->id;
3594  if (group) {
3595  bNodeInstanceKey group_key = BKE_node_instance_key(parent_key, ntree, node);
3596  bNode *tnode = node_get_active_id_recursive(active_key, group_key, group, idtype);
3597  if (tnode) {
3598  return tnode;
3599  }
3600  }
3601  }
3602  }
3603  }
3604  return nullptr;
3605 }
3606 
3607 /* two active flags, ID nodes have special flag for buttons display */
3609 {
3610  if (ntree) {
3613  }
3614  return nullptr;
3615 }
3616 
3617 bool nodeSetActiveID(bNodeTree *ntree, short idtype, ID *id)
3618 {
3619  bool ok = false;
3620 
3621  if (ntree == nullptr) {
3622  return ok;
3623  }
3624 
3626  if (node->id && GS(node->id->name) == idtype) {
3627  if (id && ok == false && node->id == id) {
3628  node->flag |= NODE_ACTIVE_ID;
3629  ok = true;
3630  }
3631  else {
3632  node->flag &= ~NODE_ACTIVE_ID;
3633  }
3634  }
3635  }
3636 
3637  /* update all groups linked from here
3638  * if active ID node has been found already,
3639  * just pass null so other matching nodes are deactivated.
3640  */
3642  if (node->type == NODE_GROUP) {
3643  ok |= nodeSetActiveID((bNodeTree *)node->id, idtype, (ok == false ? id : nullptr));
3644  }
3645  }
3646 
3647  return ok;
3648 }
3649 
3650 /* two active flags, ID nodes have special flag for buttons display */
3651 void nodeClearActiveID(bNodeTree *ntree, short idtype)
3652 {
3653  if (ntree == nullptr) {
3654  return;
3655  }
3656 
3658  if (node->id && GS(node->id->name) == idtype) {
3659  node->flag &= ~NODE_ACTIVE_ID;
3660  }
3661  }
3662 }
3663 
3665 {
3666  if (select) {
3667  node->flag |= NODE_SELECT;
3668  }
3669  else {
3670  node->flag &= ~NODE_SELECT;
3671 
3672  /* deselect sockets too */
3673  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
3674  sock->flag &= ~NODE_SELECT;
3675  }
3676  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
3677  sock->flag &= ~NODE_SELECT;
3678  }
3679  }
3680 }
3681 
3683 {
3684  if (ntree == nullptr) {
3685  return;
3686  }
3687 
3689  node->flag &= ~(NODE_ACTIVE | NODE_ACTIVE_ID);
3690  }
3691 }
3692 
3693 /* two active flags, ID nodes have special flag for buttons display */
3695 {
3696  /* make sure only one node is active, and only one per ID type */
3697  LISTBASE_FOREACH (bNode *, tnode, &ntree->nodes) {
3698  tnode->flag &= ~NODE_ACTIVE;
3699 
3700  if (node->id && tnode->id) {
3701  if (GS(node->id->name) == GS(tnode->id->name)) {
3702  tnode->flag &= ~NODE_ACTIVE_ID;
3703  }
3704  }
3705  if ((node->typeinfo->nclass == NODE_CLASS_TEXTURE) ||
3706  (node->typeinfo->type == GEO_NODE_ATTRIBUTE_SAMPLE_TEXTURE)) {
3707  tnode->flag &= ~NODE_ACTIVE_TEXTURE;
3708  }
3709  }
3710 
3711  node->flag |= NODE_ACTIVE;
3712  if (node->id) {
3713  node->flag |= NODE_ACTIVE_ID;
3714  }
3715  if ((node->typeinfo->nclass == NODE_CLASS_TEXTURE) ||
3716  (node->typeinfo->type == GEO_NODE_ATTRIBUTE_SAMPLE_TEXTURE)) {
3717  node->flag |= NODE_ACTIVE_TEXTURE;
3718  }
3719 }
3720 
3722 {
3723  return ((sock->flag & (SOCK_HIDDEN | SOCK_UNAVAIL)) != 0);
3724 }
3725 
3726 void nodeSetSocketAvailability(bNodeSocket *sock, bool is_available)
3727 {
3728  if (is_available) {
3729  sock->flag &= ~SOCK_UNAVAIL;
3730  }
3731  else {
3732  sock->flag |= SOCK_UNAVAIL;
3733  }
3734 }
3735 
3737 {
3738  bNodeSocketType *stype = sock->typeinfo;
3739  if (sock->flag & SOCK_MULTI_INPUT) {
3740  return 4095;
3741  }
3742  if (stype != nullptr && stype->use_link_limits_of_type) {
3743  int limit = (sock->in_out == SOCK_IN) ? stype->input_link_limit : stype->output_link_limit;
3744  return limit;
3745  }
3746 
3747  return sock->limit;
3748 }
3749 
3750 /* ************** Node Clipboard *********** */
3751 
3752 #define USE_NODE_CB_VALIDATE
3753 
3754 #ifdef USE_NODE_CB_VALIDATE
3764  ID *id;
3767 };
3768 #endif /* USE_NODE_CB_VALIDATE */
3769 
3772 
3773 #ifdef USE_NODE_CB_VALIDATE
3775 #endif
3776 
3778  int type;
3779 };
3780 
3781 static bNodeClipboard node_clipboard = {{nullptr}};
3782 
3784 {
3786 }
3787 
3789 {
3791  nodeRemLink(nullptr, link);
3792  }
3794 
3796  node_free_node(nullptr, node);
3797  }
3799 
3800 #ifdef USE_NODE_CB_VALIDATE
3802 #endif
3803 }
3804 
3805 /* return false when one or more ID's are lost */
3807 {
3808  bool ok = true;
3809 
3810 #ifdef USE_NODE_CB_VALIDATE
3811  bNodeClipboardExtraInfo *node_info;
3812  bNode *node;
3813 
3814  /* lists must be aligned */
3817 
3818  for (node = (bNode *)node_clipboard.nodes.first,
3820  node;
3821  node = (bNode *)node->next, node_info = (bNodeClipboardExtraInfo *)node_info->next) {
3822  /* validate the node against the stored node info */
3823 
3824  /* re-assign each loop since we may clear,
3825  * open a new file where the ID is valid, and paste again */
3826  node->id = node_info->id;
3827 
3828  /* currently only validate the ID */
3829  if (node->id) {
3830  /* We want to search into current blend file, so using G_MAIN is valid here too. */
3831  ListBase *lb = which_libbase(G_MAIN, GS(node_info->id_name));
3832  BLI_assert(lb != nullptr);
3833 
3834  if (BLI_findindex(lb, node_info->id) == -1) {
3835  /* May assign null. */
3836  node->id = (ID *)BLI_findstring(lb, node_info->id_name + 2, offsetof(ID, name) + 2);
3837 
3838  if (node->id == nullptr) {
3839  ok = false;
3840  }
3841  }
3842  }
3843  }
3844 #endif /* USE_NODE_CB_VALIDATE */
3845 
3846  return ok;
3847 }
3848 
3850 {
3851 #ifdef USE_NODE_CB_VALIDATE
3852  /* add extra info */
3854  sizeof(bNodeClipboardExtraInfo), __func__);
3855 
3856  node_info->id = node->id;
3857  if (node->id) {
3858  BLI_strncpy(node_info->id_name, node->id->name, sizeof(node_info->id_name));
3859  if (ID_IS_LINKED(node->id)) {
3860  BLI_strncpy(
3861  node_info->library_name, node->id->lib->filepath_abs, sizeof(node_info->library_name));
3862  }
3863  else {
3864  node_info->library_name[0] = '\0';
3865  }
3866  }
3867  else {
3868  node_info->id_name[0] = '\0';
3869  node_info->library_name[0] = '\0';
3870  }
3872  /* end extra info */
3873 #endif /* USE_NODE_CB_VALIDATE */
3874 
3875  /* add node */
3877 }
3878 
3880 {
3882 }
3883 
3885 {
3886  return &node_clipboard.nodes;
3887 }
3888 
3890 {
3891  return &node_clipboard.links;
3892 }
3893 
3895 {
3896  return node_clipboard.type;
3897 }
3898 
3900 {
3903 }
3904 
3905 /* Node Instance Hash */
3906 
3907 /* magic number for initial hash key */
3910 
3911 /* Generate a hash key from ntree and node names
3912  * Uses the djb2 algorithm with xor by Bernstein:
3913  * http://www.cse.yorku.ca/~oz/hash.html
3914  */
3916 {
3917  char c;
3918 
3919  while ((c = *str++)) {
3920  hash.value = ((hash.value << 5) + hash.value) ^ c; /* (hash * 33) ^ c */
3921  }
3922 
3923  /* separator '\0' character, to avoid ambiguity from concatenated strings */
3924  hash.value = (hash.value << 5) + hash.value; /* hash * 33 */
3925 
3926  return hash;
3927 }
3928 
3930  const bNodeTree *ntree,
3931  const bNode *node)
3932 {
3933  bNodeInstanceKey key = node_hash_int_str(parent_key, ntree->id.name + 2);
3934 
3935  if (node) {
3936  key = node_hash_int_str(key, node->name);
3937  }
3938 
3939  return key;
3940 }
3941 
3942 static unsigned int node_instance_hash_key(const void *key)
3943 {
3944  return ((const bNodeInstanceKey *)key)->value;
3945 }
3946 
3947 static bool node_instance_hash_key_cmp(const void *a, const void *b)
3948 {
3949  unsigned int value_a = ((const bNodeInstanceKey *)a)->value;
3950  unsigned int value_b = ((const bNodeInstanceKey *)b)->value;
3951 
3952  return (value_a != value_b);
3953 }
3954 
3956 {
3958  hash->ghash = BLI_ghash_new(
3959  node_instance_hash_key, node_instance_hash_key_cmp, "node instance hash ghash");
3960  return hash;
3961 }
3962 
3964 {
3965  BLI_ghash_free(hash->ghash, nullptr, (GHashValFreeFP)valfreefp);
3966  MEM_freeN(hash);
3967 }
3968 
3970 {
3972  entry->key = key;
3973  entry->tag = 0;
3974  BLI_ghash_insert(hash->ghash, &entry->key, value);
3975 }
3976 
3978 {
3979  return BLI_ghash_lookup(hash->ghash, &key);
3980 }
3981 
3983  bNodeInstanceKey key,
3984  bNodeInstanceValueFP valfreefp)
3985 {
3986  return BLI_ghash_remove(hash->ghash, &key, nullptr, (GHashValFreeFP)valfreefp);
3987 }
3988 
3990 {
3991  BLI_ghash_clear(hash->ghash, nullptr, (GHashValFreeFP)valfreefp);
3992 }
3993 
3995 {
3996  return BLI_ghash_popkey(hash->ghash, &key, nullptr);
3997 }
3998 
4000 {
4001  return BLI_ghash_haskey(hash->ghash, &key);
4002 }
4003 
4005 {
4006  return BLI_ghash_len(hash->ghash);
4007 }
4008 
4010 {
4012 
4013  NODE_INSTANCE_HASH_ITER (iter, hash) {
4016 
4017  value->tag = 0;
4018  }
4019 }
4020 
4022 {
4024  entry->tag = 1;
4025 }
4026 
4028 {
4030  key);
4031 
4032  if (entry) {
4033  entry->tag = 1;
4034  return true;
4035  }
4036 
4037  return false;
4038 }
4039 
4041  bNodeInstanceValueFP valfreefp)
4042 {
4043  /* NOTE: Hash must not be mutated during iterating!
4044  * Store tagged entries in a separate list and remove items afterward.
4045  */
4048  "temporary node instance key list");
4050  int num_untagged = 0;
4051  NODE_INSTANCE_HASH_ITER (iter, hash) {
4054 
4055  if (!value->tag) {
4056  untagged[num_untagged++] = BKE_node_instance_hash_iterator_get_key(&iter);
4057  }
4058  }
4059 
4060  for (int i = 0; i < num_untagged; i++) {
4061  BKE_node_instance_hash_remove(hash, untagged[i], valfreefp);
4062  }
4063 
4064  MEM_freeN(untagged);
4065 }
4066 
4067 /* ************** dependency stuff *********** */
4068 
4069 /* node is guaranteed to be not checked before */
4071 {
4072  int level = 0xFFF;
4073 
4074  node->done = true;
4075 
4076  /* check linked nodes */
4077  LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
4078  if (link->tonode == node) {
4079  bNode *fromnode = link->fromnode;
4080  if (fromnode->done == 0) {
4081  fromnode->level = node_get_deplist_recurs(ntree, fromnode, nsort);
4082  }
4083  if (fromnode->level <= level) {
4084  level = fromnode->level - 1;
4085  }
4086  }
4087  }
4088 
4089  /* check parent node */
4090  if (node->parent) {
4091  if (node->parent->done == 0) {
4092  node->parent->level = node_get_deplist_recurs(ntree, node->parent, nsort);
4093  }
4094  if (node->parent->level <= level) {
4095  level = node->parent->level - 1;
4096  }
4097  }
4098 
4099  if (nsort) {
4100  **nsort = node;
4101  (*nsort)++;
4102  }
4103 
4104  return level;
4105 }
4106 
4107 void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***r_deplist, int *r_deplist_len)
4108 {
4109  *r_deplist_len = 0;
4110 
4111  /* first clear data */
4113  node->done = false;
4114  (*r_deplist_len)++;
4115  }
4116  if (*r_deplist_len == 0) {
4117  *r_deplist = nullptr;
4118  return;
4119  }
4120 
4121  bNode **nsort;
4122  nsort = *r_deplist = (bNode **)MEM_callocN((*r_deplist_len) * sizeof(bNode *),
4123  "sorted node array");
4124 
4125  /* recursive check */
4127  if (node->done == 0) {
4128  node->level = node_get_deplist_recurs(ntree, node, &nsort);
4129  }
4130  }
4131 }
4132 
4133 /* only updates node->level for detecting cycles links */
4135 {
4136  /* first clear tag */
4138  node->done = false;
4139  }
4140 
4141  /* recursive check */
4143  if (node->done == 0) {
4144  node->level = node_get_deplist_recurs(ntree, node, nullptr);
4145  }
4146  }
4147 }
4148 
4150 {
4151  /* first clear data */
4153  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
4154  sock->flag &= ~SOCK_IN_USE;
4155  }
4156  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
4157  sock->flag &= ~SOCK_IN_USE;
4158  }
4159  }
4160 
4161  LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
4162  link->fromsock->flag |= SOCK_IN_USE;
4163  if (!(link->flag & NODE_LINK_MUTED)) {
4164  link->tosock->flag |= SOCK_IN_USE;
4165  }
4166  }
4167 }
4168 
4170 {
4171  /* first clear data */
4173  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
4174  sock->link = nullptr;
4175  }
4176  }
4177 
4178  LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
4179  link->tosock->link = link;
4180  }
4181 
4183 }
4184 
4186 {
4187  LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
4188  link->flag |= NODE_LINK_VALID;
4189  if (link->fromnode && link->tonode && link->fromnode->level <= link->tonode->level) {
4190  link->flag &= ~NODE_LINK_VALID;
4191  }
4192  else if (ntree->typeinfo->validate_link) {
4193  if (!ntree->typeinfo->validate_link(ntree, link)) {
4194  link->flag &= ~NODE_LINK_VALID;
4195  }
4196  }
4197  }
4198 }
4199 
4201 {
4202  /* Update all new node trees on file read or append, to add/remove sockets
4203  * in groups nodes if the group changed, and handle any update flags that
4204  * might have been set in file reading or versioning. */
4205  FOREACH_NODETREE_BEGIN (main, ntree, owner_id) {
4206  if (owner_id->tag & LIB_TAG_NEW) {
4208  if (node->typeinfo->group_update_func) {
4209  node->typeinfo->group_update_func(ntree, node);
4210  }
4211  }
4212 
4213  ntreeUpdateTree(nullptr, ntree);
4214  }
4215  }
4217 }
4218 
4220 {
4221  if (id == nullptr) {
4222  return;
4223  }
4224 
4225  /* Update all users of ngroup, to add/remove sockets as needed. */
4226  FOREACH_NODETREE_BEGIN (main, ntree, owner_id) {
4227  bool need_update = false;
4228 
4230  if (node->id == id) {
4231  if (node->typeinfo->group_update_func) {
4232  node->typeinfo->group_update_func(ntree, node);
4233  }
4234 
4235  need_update = true;
4236  }
4237  }
4238 
4239  if (need_update) {
4240  ntreeUpdateTree(nullptr, ntree);
4241  }
4242  }
4244 
4245  if (GS(id->name) == ID_NT) {
4246  bNodeTree *ngroup = (bNodeTree *)id;
4247  if (ngroup->type == NTREE_GEOMETRY) {
4248  LISTBASE_FOREACH (Object *, object, &main->objects) {
4249  LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
4250  if (md->type == eModifierType_Nodes) {
4251  NodesModifierData *nmd = (NodesModifierData *)md;
4252  if (nmd->node_group == ngroup) {
4253  MOD_nodes_update_interface(object, nmd);
4254  }
4255  }
4256  }
4257  }
4258  }
4259  }
4260 }
4261 
4263 {
4264  if (!ntree) {
4265  return;
4266  }
4267 
4268  /* Avoid re-entrant updates, can be caused by RNA update callbacks. */
4269  if (ntree->is_updating) {
4270  return;
4271  }
4272  ntree->is_updating = true;
4273 
4275  /* set the bNodeSocket->link pointers */
4277  }
4278 
4279  /* update individual nodes */
4281  /* node tree update tags override individual node update flags */
4282  if ((node->update & NODE_UPDATE) || (ntree->update & NTREE_UPDATE)) {
4283  if (node->typeinfo->updatefunc) {
4284  node->typeinfo->updatefunc(ntree, node);
4285  }
4286 
4288  }
4289  }
4290 
4291  /* generic tree update callback */
4292  if (ntree->typeinfo->update) {
4294  }
4295  /* XXX this should be moved into the tree type update callback for tree supporting node groups.
4296  * Currently the node tree interface is still a generic feature of the base NodeTree type.
4297  */
4298  if (ntree->update & NTREE_UPDATE_GROUP) {
4300  }
4301 
4302  if (bmain) {
4303  ntreeUpdateAllUsers(bmain, &ntree->id);
4304  }
4305 
4307  /* node updates can change sockets or links, repeat link pointer update afterward */
4309 
4310  /* update the node level from link dependencies */
4312 
4313  /* check link validity */
4315  }
4316 
4317  /* clear update flags */
4319  node->update = 0;
4320  }
4321  ntree->update = 0;
4322 
4323  ntree->is_updating = false;
4324 }
4325 
4327 {
4328  /* Avoid re-entrant updates, can be caused by RNA update callbacks. */
4329  if (ntree->is_updating) {
4330  return;
4331  }
4332  ntree->is_updating = true;
4333 
4334  if (node->typeinfo->updatefunc) {
4335  node->typeinfo->updatefunc(ntree, node);
4336  }
4337 
4339 
4340  /* clear update flag */
4341  node->update = 0;
4342 
4343  ntree->is_updating = false;
4344 }
4345 
4347 {
4348  bool changed = false;
4349 
4350  if (ELEM(nullptr, id, ntree)) {
4351  return changed;
4352  }
4353 
4354  /* Avoid re-entrant updates, can be caused by RNA update callbacks. */
4355  if (ntree->is_updating) {
4356  return changed;
4357  }
4358  ntree->is_updating = true;
4359 
4361  if (node->id == id) {
4362  changed = true;
4363  node->update |= NODE_UPDATE_ID;
4364  if (node->typeinfo->updatefunc) {
4365  node->typeinfo->updatefunc(ntree, node);
4366  }
4367  /* clear update flag */
4368  node->update = 0;
4369  }
4370  }
4371 
4374  }
4375 
4376  ntree->is_updating = false;
4377  return changed;
4378 }
4379 
4381 {
4382  BLI_freelistN(&node->internal_links);
4383 
4384  if (node->typeinfo && node->typeinfo->update_internal_links) {
4385  node->typeinfo->update_internal_links(ntree, node);
4386  }
4387 }
4388 
4389 /* ************* node type access ********** */
4390 
4391 void nodeLabel(bNodeTree *ntree, bNode *node, char *label, int maxlen)
4392 {
4393  label[0] = '\0';
4394 
4395  if (node->label[0] != '\0') {
4396  BLI_strncpy(label, node->label, maxlen);
4397  }
4398  else if (node->typeinfo->labelfunc) {
4399  node->typeinfo->labelfunc(ntree, node, label, maxlen);
4400  }
4401 
4402  /* The previous methods (labelfunc) could not provide an adequate label for the node. */
4403  if (label[0] == '\0') {
4404  /* Kind of hacky and weak... Ideally would be better to use RNA here. :| */
4405  const char *tmp = CTX_IFACE_(BLT_I18NCONTEXT_ID_NODETREE, node->typeinfo->ui_name);
4406  if (tmp == node->typeinfo->ui_name) {
4407  tmp = IFACE_(node->typeinfo->ui_name);
4408  }
4409  BLI_strncpy(label, tmp, maxlen);
4410  }
4411 }
4412 
4413 /* Get node socket label if it is set */
4414 const char *nodeSocketLabel(const bNodeSocket *sock)
4415 {
4416  return (sock->label[0] != '\0') ? sock->label : sock->name;
4417 }
4418 
4420 {
4421  /* default size values */
4423  ntype->height = 100;
4424  ntype->minheight = 30;
4425  ntype->maxheight = FLT_MAX;
4426 }
4427 
4428 /* allow this node for any tree type */
4429 static bool node_poll_default(bNodeType *UNUSED(ntype),
4431  const char **UNUSED(disabled_hint))
4432 {
4433  return true;
4434 }
4435 
4436 /* use the basic poll function */
4437 static bool node_poll_instance_default(bNode *node, bNodeTree *ntree, const char **disabled_hint)
4438 {
4439  return node->typeinfo->poll(node->typeinfo, ntree, disabled_hint);
4440 }
4441 
4442 /* NOLINTNEXTLINE: readability-function-size */
4443 void node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
4444 {
4445  /* Use static type info header to map static int type to identifier string and RNA struct type.
4446  * Associate the RNA struct type with the bNodeType.
4447  * Dynamically registered nodes will create an RNA type at runtime
4448  * and call RNA_struct_blender_type_set, so this only needs to be done for old RNA types
4449  * created in makesrna, which can not be associated to a bNodeType immediately,
4450  * since bNodeTypes are registered afterward ...
4451  */
4452 #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
4453  case ID: \
4454  BLI_strncpy(ntype->idname, #Category #StructName, sizeof(ntype->idname)); \
4455  ntype->rna_ext.srna = RNA_struct_find(#Category #StructName); \
4456  BLI_assert(ntype->rna_ext.srna != nullptr); \
4457  RNA_struct_blender_type_set(ntype->rna_ext.srna, ntype); \
4458  break;
4459 
4460  switch (type) {
4461 #include "NOD_static_types.h"
4462  }
4463 
4464  /* make sure we have a valid type (everything registered) */
4465  BLI_assert(ntype->idname[0] != '\0');
4466 
4467  ntype->type = type;
4468  BLI_strncpy(ntype->ui_name, name, sizeof(ntype->ui_name));
4469  ntype->nclass = nclass;
4470  ntype->flag = flag;
4471 
4472  node_type_base_defaults(ntype);
4473 
4474  ntype->poll = node_poll_default;
4476 }
4477 
4479  bNodeType *ntype, const char *idname, const char *name, short nclass, short flag)
4480 {
4481  BLI_strncpy(ntype->idname, idname, sizeof(ntype->idname));
4482  ntype->type = NODE_CUSTOM;
4483  BLI_strncpy(ntype->ui_name, name, sizeof(ntype->ui_name));
4484  ntype->nclass = nclass;
4485  ntype->flag = flag;
4486 
4487  node_type_base_defaults(ntype);
4488 }
4489 
4493 };
4494 
4495 static bool unique_socket_template_identifier_check(void *arg, const char *name)
4496 {
4498 
4499  for (bNodeSocketTemplate *ntemp = data->list; ntemp->type >= 0; ntemp++) {
4500  if (ntemp != data->ntemp) {
4501  if (STREQ(ntemp->identifier, name)) {
4502  return true;
4503  }
4504  }
4505  }
4506 
4507  return false;
4508 }
4509 
4511  bNodeSocketTemplate *ntemp,
4512  const char defname[],
4513  char delim)
4514 {
4516  data.list = list;
4517  data.ntemp = ntemp;
4518 
4520  &data,
4521  defname,
4522  delim,
4523  ntemp->identifier,
4524  sizeof(ntemp->identifier));
4525 }
4526 
4528  struct bNodeSocketTemplate *inputs,
4529  struct bNodeSocketTemplate *outputs)
4530 {
4531  ntype->inputs = inputs;
4532  ntype->outputs = outputs;
4533 
4534  /* automatically generate unique identifiers */
4535  if (inputs) {
4536  /* clear identifier strings (uninitialized memory) */
4537  for (bNodeSocketTemplate *ntemp = inputs; ntemp->type >= 0; ntemp++) {
4538  ntemp->identifier[0] = '\0';
4539  }
4540 
4541  for (bNodeSocketTemplate *ntemp = inputs; ntemp->type >= 0; ntemp++) {
4542  BLI_strncpy(ntemp->identifier, ntemp->name, sizeof(ntemp->identifier));
4544  }
4545  }
4546  if (outputs) {
4547  /* clear identifier strings (uninitialized memory) */
4548  for (bNodeSocketTemplate *ntemp = outputs; ntemp->type >= 0; ntemp++) {
4549  ntemp->identifier[0] = '\0';
4550  }
4551 
4552  for (bNodeSocketTemplate *ntemp = outputs; ntemp->type >= 0; ntemp++) {
4553  BLI_strncpy(ntemp->identifier, ntemp->name, sizeof(ntemp->identifier));
4555  }
4556  }
4557 }
4558 
4559 void node_type_init(struct bNodeType *ntype,
4560  void (*initfunc)(struct bNodeTree *ntree, struct bNode *node))
4561 {
4562  ntype->initfunc = initfunc;
4563 }
4564 
4565 void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwidth)
4566 {
4567  ntype->width = width;
4568  ntype->minwidth = minwidth;
4569  if (maxwidth <= minwidth) {
4570  ntype->maxwidth = FLT_MAX;
4571  }
4572  else {
4573  ntype->maxwidth = maxwidth;
4574  }
4575 }
4576 
4578 {
4579  switch (size) {
4580  case NODE_SIZE_DEFAULT:
4581  node_type_size(ntype, 140, 100, NODE_DEFAULT_MAX_WIDTH);
4582  break;
4583  case NODE_SIZE_SMALL:
4584  node_type_size(ntype, 100, 80, NODE_DEFAULT_MAX_WIDTH);
4585  break;
4586  case NODE_SIZE_MIDDLE:
4587  node_type_size(ntype, 150, 120, NODE_DEFAULT_MAX_WIDTH);
4588  break;
4589  case NODE_SIZE_LARGE:
4590  node_type_size(ntype, 240, 140, NODE_DEFAULT_MAX_WIDTH);
4591  break;
4592  }
4593 }
4594 
4600  const char *storagename,
4601  void (*freefunc)(struct bNode *node),
4602  void (*copyfunc)(struct bNodeTree *dest_ntree,
4603  struct bNode *dest_node,
4604  const struct bNode *src_node))
4605 {
4606  if (storagename) {
4607  BLI_strncpy(ntype->storagename, storagename, sizeof(ntype->storagename));
4608  }
4609  else {
4610  ntype->storagename[0] = '\0';
4611  }
4612  ntype->copyfunc = copyfunc;
4613  ntype->freefunc = freefunc;
4614 }
4615 
4617  struct bNodeType *ntype,
4618  void (*labelfunc)(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen))
4619 {
4620  ntype->labelfunc = labelfunc;
4621 }
4622 
4623 void node_type_update(struct bNodeType *ntype,
4624  void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
4625 {
4626  ntype->updatefunc = updatefunc;
4627 }
4628 
4630  void (*group_update_func)(struct bNodeTree *ntree, struct bNode *node))
4631 {
4632  ntype->group_update_func = group_update_func;
4633 }
4634 
4635 void node_type_exec(struct bNodeType *ntype,
4636  NodeInitExecFunction init_exec_fn,
4637  NodeFreeExecFunction free_exec_fn,
4638  NodeExecFunction exec_fn)
4639 {
4640  ntype->init_exec_fn = init_exec_fn;
4641  ntype->free_exec_fn = free_exec_fn;
4642  ntype->exec_fn = exec_fn;
4643 }
4644 
4645 void node_type_gpu(struct bNodeType *ntype, NodeGPUExecFunction gpu_fn)
4646 {
4647  ntype->gpu_fn = gpu_fn;
4648 }
4649 
4651  void (*update_internal_links)(bNodeTree *, bNode *))
4652 {
4653  ntype->update_internal_links = update_internal_links;
4654 }
4655 
4656 /* callbacks for undefined types */
4657 
4659  bNodeTree *UNUSED(nodetree),
4660  const char **UNUSED(r_disabled_hint))
4661 {
4662  /* this type can not be added deliberately, it's just a placeholder */
4663  return false;
4664 }
4665 
4666 /* register fallback types used for undefined tree, nodes, sockets */
4668 {
4669  /* Note: these types are not registered in the type hashes,
4670  * they are just used as placeholders in case the actual types are not registered.
4671  */
4672 
4673  strcpy(NodeTreeTypeUndefined.idname, "NodeTreeUndefined");
4674  strcpy(NodeTreeTypeUndefined.ui_name, N_("Undefined"));
4675  strcpy(NodeTreeTypeUndefined.ui_description, N_("Undefined Node Tree Type"));
4676 
4677  node_type_base_custom(&NodeTypeUndefined, "NodeUndefined", "Undefined", 0, 0);
4679 
4681  "NodeSocketUndefined",
4683  /* extra type info for standard socket types */
4686 
4690 }
4691 
4693 {
4695 
4703 
4709 
4721 
4727 
4740 
4755 
4768 
4782 
4791 
4796 }
4797 
4798 static void registerShaderNodes()
4799 {
4801 
4833 
4848 
4872 
4878 
4893 }
4894 
4896 {
4898 
4912 
4920 
4927 
4932 
4943 }
4944 
4946 {
4948 
4992 }
4993 
4995 {
5001 }
5002 
5004 {
5005  nodetreetypes_hash = BLI_ghash_str_new("nodetreetypes_hash gh");
5006  nodetypes_hash = BLI_ghash_str_new("nodetypes_hash gh");
5007  nodesockettypes_hash = BLI_ghash_str_new("nodesockettypes_hash gh");
5008 
5010 
5012 
5017 
5022 
5028 }
5029 
5031 {
5032  if (nodetypes_hash) {
5033  NODE_TYPES_BEGIN (nt) {
5034  if (nt->rna_ext.free) {
5035  nt->rna_ext.free(nt->rna_ext.data);
5036  }
5037  }
5039 
5041  nodetypes_hash = nullptr;
5042  }
5043 
5044  if (nodesockettypes_hash) {
5046  if (st->ext_socket.free) {
5047  st->ext_socket.free(st->ext_socket.data);
5048  }
5049  if (st->ext_interface.free) {
5050  st->ext_interface.free(st->ext_interface.data);
5051  }
5052  }
5054 
5056  nodesockettypes_hash = nullptr;
5057  }
5058 
5059  if (nodetreetypes_hash) {
5060  NODE_TREE_TYPES_BEGIN (nt) {
5061  if (nt->rna_ext.free) {
5062  nt->rna_ext.free(nt->rna_ext.data);
5063  }
5064  }
5066 
5068  nodetreetypes_hash = nullptr;
5069  }
5070 }
5071 
5072 /* -------------------------------------------------------------------- */
5073 /* NodeTree Iterator Helpers (FOREACH_NODETREE_BEGIN) */
5074 
5075 void BKE_node_tree_iter_init(struct NodeTreeIterStore *ntreeiter, struct Main *bmain)
5076 {
5077  ntreeiter->ngroup = (bNodeTree *)bmain->nodetrees.first;
5078  ntreeiter->scene = (Scene *)bmain->scenes.first;
5079  ntreeiter->mat = (Material *)bmain->materials.first;
5080  ntreeiter->tex = (Tex *)bmain->textures.first;
5081  ntreeiter->light = (Light *)bmain->lights.first;
5082  ntreeiter->world = (World *)bmain->worlds.first;
5083  ntreeiter->linestyle = (FreestyleLineStyle *)bmain->linestyles.first;
5084  ntreeiter->simulation = (Simulation *)bmain->simulations.first;
5085 }
5087  bNodeTree **r_nodetree,
5088  struct ID **r_id)
5089 {
5090  if (ntreeiter->ngroup) {
5091  *r_nodetree = (bNodeTree *)ntreeiter->ngroup;
5092  *r_id = (ID *)ntreeiter->ngroup;
5093  ntreeiter->ngroup = (bNodeTree *)ntreeiter->ngroup->id.next;
5094  }
5095  else if (ntreeiter->scene) {
5096  *r_nodetree = (bNodeTree *)ntreeiter->scene->nodetree;
5097  *r_id = (ID *)ntreeiter->scene;
5098  ntreeiter->scene = (Scene *)ntreeiter->scene->id.next;
5099  }
5100  else if (ntreeiter->mat) {
5101  *r_nodetree = (bNodeTree *)ntreeiter->mat->nodetree;
5102  *r_id = (ID *)ntreeiter->mat;
5103  ntreeiter->mat = (Material *)ntreeiter->mat->id.next;
5104  }
5105  else if (ntreeiter->tex) {
5106  *r_nodetree = (bNodeTree *)ntreeiter->tex->nodetree;
5107  *r_id = (ID *)ntreeiter->tex;
5108  ntreeiter->tex = (Tex *)ntreeiter->tex->id.next;
5109  }
5110  else if (ntreeiter->light) {
5111  *r_nodetree = (bNodeTree *)ntreeiter->light->nodetree;
5112  *r_id = (ID *)ntreeiter->light;
5113  ntreeiter->light = (Light *)ntreeiter->light->id.next;
5114  }
5115  else if (ntreeiter->world) {
5116  *r_nodetree = (bNodeTree *)ntreeiter->world->nodetree;
5117  *r_id = (ID *)ntreeiter->world;
5118  ntreeiter->world = (World *)ntreeiter->world->id.next;
5119  }
5120  else if (ntreeiter->linestyle) {
5121  *r_nodetree = (bNodeTree *)ntreeiter->linestyle->nodetree;
5122  *r_id = (ID *)ntreeiter->linestyle;
5123  ntreeiter->linestyle = (FreestyleLineStyle *)ntreeiter->linestyle->id.next;
5124  }
5125  else if (ntreeiter->simulation) {
5126  *r_nodetree = (bNodeTree *)ntreeiter->simulation->nodetree;
5127  *r_id = (ID *)ntreeiter->simulation;
5128  ntreeiter->simulation = (Simulation *)ntreeiter->simulation->id.next;
5129  }
5130  else {
5131  return false;
5132  }
5133 
5134  return true;
5135 }
5136 
5137 /* -------------------------------------------------------------------- */
5138 /* NodeTree kernel functions */
5139 
5140 void BKE_nodetree_remove_layer_n(bNodeTree *ntree, Scene *scene, const int layer_index)
5141 {
5142  BLI_assert(layer_index != -1);
5144  if (node->type == CMP_NODE_R_LAYERS && (Scene *)node->id == scene) {
5145  if (node->custom1 == layer_index) {
5146  node->custom1 = 0;
5147  }
5148  else if (node->custom1 > layer_index) {
5149  node->custom1--;
5150  }
5151  }
5152  }
5153 }
void BKE_animdata_free(struct ID *id, const bool do_id_user)
Definition: anim_data.c:230
void BKE_animdata_blend_read_data(struct BlendDataReader *reader, struct AnimData *adt)
Definition: anim_data.c:1574
void BKE_animdata_blend_write(struct BlendWriter *writer, struct AnimData *adt)
Definition: anim_data.c:1552
bool BKE_animdata_fix_paths_remove(struct ID *id, const char *path)
Definition: anim_data.c:1188
void BKE_curvemapping_blend_read(struct BlendDataReader *reader, struct CurveMapping *cumap)
Definition: colortools.c:1252
void BKE_curvemapping_blend_write(struct BlendWriter *writer, const struct CurveMapping *cumap)
#define G_MAIN
Definition: BKE_global.h:232
void IDP_BlendReadExpand(struct BlendExpander *expander, struct IDProperty *prop)
Definition: idprop.c:1336
void IDP_FreeProperty_ex(struct IDProperty *prop, const bool do_id_user)
Definition: idprop.c:1034
void IDP_BlendWrite(struct BlendWriter *writer, const struct IDProperty *prop)
void IDP_BlendReadLib(struct BlendLibReader *reader, struct IDProperty *prop)
Definition: idprop.c:1300
void IDP_FreePropertyContent_ex(struct IDProperty *prop, const bool do_id_user)
Definition: idprop.c:1006
#define IDP_BlendDataRead(reader, prop)
Definition: BKE_idprop.h:208
void IDP_foreach_property(struct IDProperty *id_property_root, const int type_filter, IDPForeachPropertyCallback callback, void *user_data)
Definition: idprop.c:1072
struct IDProperty * IDP_CopyProperty_ex(const struct IDProperty *prop, const int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void(* IDTypeForeachCacheFunctionCallback)(struct ID *id, const struct IDCacheKey *cache_key, void **cache_p, uint flags, void *user_data)
Definition: BKE_idtype.h:89
void id_us_min(struct ID *id)
Definition: lib_id.c:297
void BKE_libblock_free_data_py(struct ID *id)
void BKE_libblock_free_data(struct ID *id, const bool do_id_user) ATTR_NONNULL()
Definition: lib_id_delete.c:55
@ LIB_ID_COPY_NO_PREVIEW
Definition: BKE_lib_id.h:116
@ LIB_ID_COPY_LOCALIZE
Definition: BKE_lib_id.h:145
@ LIB_ID_CREATE_NO_USER_REFCOUNT
Definition: BKE_lib_id.h:92
@ LIB_ID_COPY_NO_ANIMDATA
Definition: BKE_lib_id.h:120
@ LIB_ID_CREATE_NO_MAIN
Definition: BKE_lib_id.h:88
void * BKE_libblock_alloc(struct Main *bmain, short type, const char *name, const int flag) ATTR_WARN_UNUSED_RESULT
Definition: lib_id.c:1062
struct ID * BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag)
void id_us_plus(struct ID *id)
Definition: lib_id.c:288
void BKE_id_blend_write(struct BlendWriter *writer, struct ID *id)
Definition: lib_id.c:2395
#define BKE_LIB_FOREACHID_PROCESS(_data, _id_super, _cb_flag)
void BKE_lib_query_idpropertiesForeachIDLink_callback(struct IDProperty *id_prop, void *user_data)
Definition: lib_query.c:150
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:87
#define BKE_LIB_FOREACHID_PROCESS_ID(_data, _id, _cb_flag)
struct ListBase * which_libbase(struct Main *bmain, short type)
Definition: main.c:447
void *(* NodeInitExecFunction)(struct bNodeExecContext *context, struct bNode *node, bNodeInstanceKey key)
Definition: BKE_node.h:199
#define NODE_TYPES_BEGIN(ntype)
Definition: BKE_node.h:535
#define NODE_CLASS_OUTPUT
Definition: BKE_node.h:335
#define NODE_REROUTE
Definition: BKE_node.h:873
void ntreeTexEndExecTree(struct bNodeTreeExec *exec)
#define NODE_DYNAMIC
Definition: BKE_node.h:993
#define NODE_CUSTOM_GROUP
Definition: BKE_node.h:876
BLI_INLINE bNodeInstanceKey BKE_node_instance_hash_iterator_get_key(bNodeInstanceHashIterator *iter)
Definition: BKE_node.h:764
void(* bNodeInstanceValueFP)(void *value)
Definition: BKE_node.h:721
BLI_INLINE void * BKE_node_instance_hash_iterator_get_value(bNodeInstanceHashIterator *iter)
Definition: BKE_node.h:768
void(* NodeExecFunction)(void *data, int thread, struct bNode *, struct bNodeExecData *execdata, struct bNodeStack **in, struct bNodeStack **out)
Definition: BKE_node.h:203
#define SH_NODE_TEX_ENVIRONMENT
Definition: BKE_node.h:1022
void(* NodeFreeExecFunction)(void *nodedata)
Definition: BKE_node.h:202
#define NODE_CUSTOM
Definition: BKE_node.h:868
#define CMP_NODE_GLARE
Definition: BKE_node.h:1208
#define CMP_NODE_CRYPTOMATTE_LEGACY
Definition: BKE_node.h:1225
#define TEX_NODE_IMAGE
Definition: BKE_node.h:1333
#define CMP_NODE_OUTPUT_FILE
Definition: BKE_node.h:1154
#define FOREACH_NODETREE_END
Definition: BKE_node.h:945
#define NODE_TREE_TYPES_BEGIN(ntype)
Definition: BKE_node.h:430
int(* NodeGPUExecFunction)(struct GPUMaterial *mat, struct bNode *node, struct bNodeExecData *execdata, struct GPUNodeStack *in, struct GPUNodeStack *out)
Definition: BKE_node.h:209
#define NODE_SOCKET_TYPES_BEGIN(stype)
Definition: BKE_node.h:557
#define SH_NODE_TEX_POINTDENSITY
Definition: BKE_node.h:1057
#define SH_NODE_CURVE_RGB
Definition: BKE_node.h:983
void ntreeShaderEndExecTree(struct bNodeTreeExec *exec)
#define NODE_INSTANCE_HASH_ITER(iter_, hash_)
Definition: BKE_node.h:781
#define FOREACH_NODETREE_BEGIN(bmain, _nodetree, _id)
Definition: BKE_node.h:935
#define TEX_NODE_CURVE_TIME
Definition: BKE_node.h:1337
#define CMP_CRYPTOMATTE_SRC_RENDER
Definition: BKE_node.h:1259
#define NODE_TREE_TYPES_END
Definition: BKE_node.h:437
#define NODE_FRAME
Definition: BKE_node.h:872
#define CMP_NODE_R_LAYERS
Definition: BKE_node.h:1152
#define NODE_SOCKET_TYPES_END
Definition: BKE_node.h:565
#define CMP_NODE_CURVE_VEC
Definition: BKE_node.h:1139
#define NODE_GROUP_INPUT
Definition: BKE_node.h:874
#define NODE_TYPES_END
Definition: BKE_node.h:542
#define NODE_CLASS_TEXTURE
Definition: BKE_node.h:346
#define SH_NODE_SCRIPT
Definition: BKE_node.h:1036
eNodeSizePreset
Definition: BKE_node.h:369
@ NODE_SIZE_DEFAULT
Definition: BKE_node.h:370
@ NODE_SIZE_LARGE
Definition: BKE_node.h:373
@ NODE_SIZE_SMALL
Definition: BKE_node.h:371
@ NODE_SIZE_MIDDLE
Definition: BKE_node.h:372
#define BLI_assert_unreachable()
Definition: BLI_assert.h:96
#define BLI_assert(a)
Definition: BLI_assert.h:58
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:996
unsigned int BLI_ghashutil_strhash_p(const void *ptr)
GHash * BLI_ghash_str_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
GHash * BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:718
unsigned int BLI_ghash_len(GHash *gh) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:744
bool BLI_ghash_haskey(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:941
void(* GHashValFreeFP)(void *val)
Definition: BLI_ghash.h:50
void * BLI_ghash_lookup_default(GHash *gh, const void *key, void *val_default) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:813
GHashIterator * BLI_ghashIterator_new(GHash *gh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:1050
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:900
void * BLI_ghash_popkey(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:924
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:756
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:1008
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:803
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void void void void void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
Definition: BLI_listbase.h:188
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_findstring(const struct ListBase *listbase, const char *id, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
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
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
Definition: listbase.c:395
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4])
Definition: math_color.c:427
MINLINE void linearrgb_to_srgb_uchar4(unsigned char srgb[4], const float linear[4])
#define FILE_MAX
size_t size_t char size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, const size_t dst_maxncpy) ATTR_NONNULL()
Definition: string.c:333
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
bool BLI_uniquename_cb(UniquenameCheckCallback unique_check, void *arg, const char *defname, char delim, char *name, size_t name_len)
Definition: string_utils.c:294
bool BLI_uniquename(struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t len)
Definition: string_utils.c:381
#define STREQLEN(a, b, n)
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
#define BLO_read_data_address(reader, ptr_p)
void BLO_write_struct_by_name(BlendWriter *writer, const char *struct_name, const void *data_ptr)
Definition: writefile.c:1291
#define BLO_write_id_struct(writer, struct_name, id_address, id)
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_read_list(BlendDataReader *reader, struct ListBase *list)
Definition: readfile.c:5654
bool BLO_read_lib_is_undo(BlendLibReader *reader)
Definition: readfile.c:5790
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
Definition: writefile.c:1401
#define BLO_read_id_address(reader, lib, id_ptr_p)
#define BLO_expand(expander, id)
bool BLO_write_is_undo(BlendWriter *writer)
Definition: writefile.c:1412
#define BLT_I18NCONTEXT_ID_NODETREE
#define CTX_IFACE_(context, msgid)
#define IFACE_(msgid)
#define N_(msgid)
#define DATA_(msgid)
#define CLOG_ERROR(clg_ref,...)
Definition: CLG_log.h:204
void DEG_relations_tag_update(struct Main *bmain)
@ LIB_TAG_NEW
Definition: DNA_ID.h:551
@ LIB_TAG_LOCALIZED
Definition: DNA_ID.h:568
@ LIB_TAG_MISSING
Definition: DNA_ID.h:537
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:426
#define MAX_ID_NAME
Definition: DNA_ID.h:269
@ LIB_EMBEDDED_DATA
Definition: DNA_ID.h:482
#define MAX_IDPROP_NAME
Definition: DNA_ID.h:92
@ IDP_TYPE_FILTER_ID
Definition: DNA_ID.h:115
#define FILTER_ID_NT
Definition: DNA_ID.h:721
@ INDEX_ID_NT
Definition: DNA_ID.h:797
@ ID_TE
Definition: DNA_ID_enums.h:64
@ ID_NT
Definition: DNA_ID_enums.h:80
@ ID_LA
Definition: DNA_ID_enums.h:67
@ ID_SCE
Definition: DNA_ID_enums.h:57
@ ID_LS
Definition: DNA_ID_enums.h:87
@ ID_WO
Definition: DNA_ID_enums.h:71
@ ID_SIM
Definition: DNA_ID_enums.h:96
@ ID_MA
Definition: DNA_ID_enums.h:63
Object groups, one object can be in many groups at once.
#define MAX_NAME
Definition: DNA_defs.h:62
@ eModifierType_Nodes
#define NODE_OPTIONS
#define NODE_LINK_VALID
#define NTREE_TEXTURE
#define NODE_MAXSTR
#define NODE_DO_OUTPUT
#define NTREE_GEOMETRY
#define NTREE_COMPOSIT
#define NODE_ACTIVE_TEXTURE
#define NODE_UPDATE_ID
#define NODE_LINK_TEST
eNodeSocketInOut
@ SOCK_OUT
@ SOCK_IN
#define NODE_PREVIEW
@ SOCK_MULTI_INPUT
@ SOCK_IN_USE
@ SOCK_COLLAPSED
@ SOCK_HIDDEN
@ SOCK_UNAVAIL
#define NODE_ACTIVE_ID
eNodeSocketDatatype
@ SOCK_INT
@ __SOCK_MESH
@ SOCK_VECTOR
@ SOCK_BOOLEAN
@ SOCK_SHADER
@ SOCK_FLOAT
@ SOCK_IMAGE
@ SOCK_COLLECTION
@ SOCK_CUSTOM
@ SOCK_GEOMETRY
@ SOCK_OBJECT
@ SOCK_STRING
@ SOCK_RGBA
#define NTREE_TYPE_INIT
struct bNodeTree bNodeTree
#define NODE_SELECT
#define NTREE_SHADER
@ NTREE_UPDATE
@ NTREE_UPDATE_GROUP_OUT
@ NTREE_UPDATE_GROUP
@ NTREE_UPDATE_LINKS
@ NTREE_UPDATE_GROUP_IN
@ NTREE_UPDATE_NODES
#define NODE_UPDATE
#define NODE_LINK_MUTED
#define NODE_INIT
#define NODE_ACTIVE
_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 const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_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
_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 const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
Read Guarded memory(de)allocation.
void MOD_nodes_update_interface(Object *object, NodesModifierData *nmd)
Definition: MOD_nodes.cc:948
void register_node_type_sh_bevel(void)
void register_node_type_sh_curve_rgb(void)
void register_node_type_sh_map_range(void)
void register_node_type_sh_combrgb(void)
void register_node_type_sh_normal_map(void)
void register_node_type_sh_uvalongstroke(void)
void register_node_type_sh_vector_rotate(void)
void register_node_type_sh_tex_coord(void)
void register_node_type_sh_output_world(void)
void register_node_type_sh_mix_shader(void)
void register_node_type_sh_shadertorgb(void)
void register_node_type_sh_bsdf_transparent(void)
void register_node_type_sh_group(void)
void register_node_type_sh_bsdf_refraction(void)
void register_node_type_sh_output_linestyle(void)
void register_node_type_sh_rgb(void)
void register_node_type_sh_clamp(void)
void register_node_type_sh_fresnel(void)
void register_node_type_sh_bsdf_hair(void)
void register_node_type_sh_uvmap(void)
void register_node_type_sh_bsdf_glossy(void)
void register_node_type_sh_blackbody(void)
void register_node_type_sh_background(void)
void register_node_type_sh_gamma(void)
void register_node_type_sh_emission(void)
void register_node_type_sh_script(void)
void register_node_type_sh_tangent(void)
void register_node_type_sh_subsurface_scattering(void)
void register_node_type_sh_object_info(void)
void register_node_type_sh_ambient_occlusion(void)
void register_node_type_sh_value(void)
void register_node_type_sh_tex_environment(void)
void register_node_type_sh_bsdf_glass(void)
void register_node_type_sh_curve_vec(void)
void register_node_type_sh_light_path(void)
void register_node_type_sh_vertex_color(void)
void register_node_type_sh_bsdf_toon(void)
void register_node_type_sh_tex_noise(void)
void register_node_type_sh_tex_musgrave(void)
void register_node_type_sh_sepxyz(void)
void register_node_type_sh_bump(void)
void register_node_type_sh_normal(void)
void register_node_type_sh_combxyz(void)
void register_node_type_sh_bsdf_hair_principled(void)
void register_node_type_sh_tex_voronoi(void)
void register_node_type_sh_output_material(void)
void register_node_type_sh_vector_displacement(void)
void register_node_type_sh_bsdf_translucent(void)
void register_node_type_sh_hair_info(void)
void register_node_type_sh_bsdf_diffuse(void)
void register_node_type_sh_tex_magic(void)
void register_node_type_sh_geometry(void)
void register_node_type_sh_mix_rgb(void)
void register_node_type_sh_wireframe(void)
void register_node_type_sh_math(void)
void register_node_type_sh_attribute(void)
void register_node_type_sh_tex_image(void)
void register_node_type_sh_tex_pointdensity(void)
void register_node_type_sh_hue_sat(void)
void register_node_type_sh_bsdf_principled(void)
void register_node_type_sh_displacement(void)
void register_node_type_sh_tex_brick(void)
void register_node_type_sh_bsdf_velvet(void)
void register_node_type_sh_combhsv(void)
void register_node_type_sh_light_falloff(void)
void register_node_type_sh_squeeze(void)
void register_node_type_sh_volume_info(void)
void register_node_type_sh_volume_absorption(void)
void register_node_type_sh_add_shader(void)
void register_node_type_sh_layer_weight(void)
void register_node_type_sh_camera(void)
void register_node_type_sh_particle_info(void)
void register_node_type_sh_tex_checker(void)
void register_node_type_sh_rgbtobw(void)
void register_node_type_sh_holdout(void)
void register_node_type_sh_wavelength(void)
void register_node_type_sh_seprgb(void)
void register_node_type_sh_mapping(void)
void register_node_type_sh_tex_wave(void)
void register_node_type_sh_volume_scatter(void)
void register_node_type_sh_valtorgb(void)
void register_node_tree_type_sh(void)
void register_node_type_sh_eevee_specular(void)
void register_node_type_sh_vect_math(void)
void register_node_type_sh_output_light(void)
void register_node_type_sh_invert(void)
void register_node_type_sh_vect_transform(void)
void register_node_type_sh_tex_white_noise(void)
void register_node_type_sh_tex_ies(void)
void register_node_type_sh_sephsv(void)
void register_node_type_sh_volume_principled(void)
void register_node_type_sh_tex_gradient(void)
void register_node_type_sh_brightcontrast(void)
void register_node_type_sh_bsdf_anisotropic(void)
void register_node_type_sh_tex_sky(void)
void register_node_type_sh_output_aov(void)
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel CMP_NODE_SPLITVIEWER
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel Split ID Combine Luminance Directional Alpha Distance Hue Movie Ellipse Bokeh View Corner Anti Mix RGB Hue Separate TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC Boolean Random Edge Subdivision Point Object Attribute Attribute Attribute Color Attribute Attribute Vector Point GEO_NODE_ATTRIBUTE_SAMPLE_TEXTURE
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel Split ID Combine Luminance Directional Alpha Distance Hue Movie Ellipse Bokeh View Corner CMP_NODE_CRYPTOMATTE
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White CMP_NODE_CURVE_RGB
NODE_GROUP_OUTPUT
NODE_GROUP
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel Split ID Combine Luminance Directional Alpha Distance Hue Movie Ellipse Bokeh View Corner Anti Mix TEX_NODE_CURVE_RGB
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White CMP_NODE_VIEWER
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel Split ID Combine Luminance Directional Alpha Distance CMP_NODE_HUECORRECT
Group RGB to Bright SH_NODE_CURVE_VEC
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map CMP_NODE_TIME
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel Split ID Combine Luminance Directional Alpha Distance Hue Movie Ellipse Bokeh View Corner Anti Mix RGB Hue Separate TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC Boolean Random FN_NODE_INPUT_STRING
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel Split ID Combine Luminance Directional Alpha Distance Hue CMP_NODE_MOVIEDISTORTION
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume SH_NODE_TEX_IMAGE
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set CMP_NODE_IMAGE
void register_node_type_tex_bricks(void)
void register_node_type_tex_coord(void)
void register_node_type_tex_compose(void)
void register_node_type_tex_valtonor(void)
void register_node_type_tex_rotate(void)
void register_node_type_tex_viewer(void)
void register_node_type_tex_math(void)
void register_node_type_tex_group(void)
void register_node_type_tex_proc_distnoise(void)
void register_node_type_tex_output(void)
void register_node_type_tex_mix_rgb(void)
void register_node_type_tex_curve_rgb(void)
void register_node_type_tex_translate(void)
void register_node_type_tex_image(void)
void register_node_type_tex_proc_noise(void)
void register_node_type_tex_curve_time(void)
void register_node_type_tex_rgbtobw(void)
void register_node_type_tex_proc_marble(void)
void register_node_type_tex_proc_musgrave(void)
void register_node_type_tex_distance(void)
void register_node_type_tex_at(void)
void register_node_type_tex_valtorgb(void)
void register_node_type_tex_proc_voronoi(void)
void register_node_type_tex_proc_wood(void)
void register_node_type_tex_proc_clouds(void)
void register_node_type_tex_texture(void)
void register_node_type_tex_scale(void)
void register_node_type_tex_invert(void)
void register_node_type_tex_proc_magic(void)
void register_node_tree_type_tex(void)
void register_node_type_tex_proc_blend(void)
void register_node_type_tex_hue_sat(void)
void register_node_type_tex_decompose(void)
void register_node_type_tex_checker(void)
void register_node_type_tex_proc_stucci(void)
StructRNA RNA_Node
void RNA_def_struct_free_pointers(BlenderRNA *brna, StructRNA *srna)
void RNA_def_struct_duplicate_pointers(BlenderRNA *brna, StructRNA *srna)
@ PROP_TIME
Definition: RNA_types.h:133
@ PROP_DIRECTION
Definition: RNA_types.h:141
@ PROP_XYZ
Definition: RNA_types.h:148
@ PROP_DISTANCE
Definition: RNA_types.h:135
@ PROP_ACCELERATION
Definition: RNA_types.h:143
@ PROP_ANGLE
Definition: RNA_types.h:132
@ PROP_EULER
Definition: RNA_types.h:145
@ PROP_NONE
Definition: RNA_types.h:113
@ PROP_PERCENTAGE
Definition: RNA_types.h:130
@ PROP_FACTOR
Definition: RNA_types.h:131
@ PROP_TRANSLATION
Definition: RNA_types.h:140
@ PROP_UNSIGNED
Definition: RNA_types.h:129
@ PROP_VELOCITY
Definition: RNA_types.h:142
#define C
Definition: RandGen.cpp:39
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
unsigned int U
Definition: btGjkEpa3.h:78
#define output
OperationNode * node
StackEntry * from
const char * label
Scene scene
void * user_data
DEGForeachIDComponentCallback callback
bNodeTree * ntree
DRWShaderLibrary * lib
#define str(s)
uint col
int count
#define GS(x)
Definition: iris.c:241
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
size_t(* MEM_allocN_len)(const void *vmemh)
Definition: mallocn.c:40
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
int main(int argc, char **argv)
Definition: msgfmt.c:457
static unsigned c
Definition: RandGen.cpp:97
static unsigned a[3]
Definition: RandGen.cpp:92
void node_type_gpu(struct bNodeType *ntype, NodeGPUExecFunction gpu_fn)
Definition: node.cc:4645
bNodeInstanceKey BKE_node_instance_key(bNodeInstanceKey parent_key, const bNodeTree *ntree, const bNode *node)
Definition: node.cc:3929
void BKE_node_clipboard_init(const struct bNodeTree *ntree)
Definition: node.cc:3783
static GHash * nodetreetypes_hash
Definition: node.cc:1203
static void ntree_interface_type_create(bNodeTree *ntree)
Definition: node.cc:3416
void ntreeTypeFreeLink(const bNodeTreeType *nt)
Definition: node.cc:1239
bool BKE_node_preview_used(const bNode *node)
Definition: node.cc:2574
static void socket_id_user_decrement(bNodeSocket *sock)
Definition: node.cc:1473
static void nodeUnMuteLink(bNodeLink *link)
Definition: node.cc:2273
bNodeSocket * nodeInsertSocket(bNodeTree *ntree, bNode *node, eNodeSocketInOut in_out, const char *idname, bNodeSocket *next_sock, const char *identifier, const char *name)
Definition: node.cc:1555
static bNodeInstanceKey node_hash_int_str(bNodeInstanceKey hash, const char *str)
Definition: node.cc:3915
static void library_foreach_node_socket(LibraryForeachIDData *data, bNodeSocket *sock)
Definition: node.cc:284
void ntreeNodeFlagSet(const bNodeTree *ntree, const int flag, const bool enable)
Definition: node.cc:3173
bool nodeTypeUndefined(bNode *node)
Definition: node.cc:1316
int nodeSocketLinkLimit(const bNodeSocket *sock)
Definition: node.cc:3736
static void ntree_blend_read_lib(BlendLibReader *reader, ID *id)
Definition: node.cc:863
StructRNA * ntreeInterfaceTypeGet(bNodeTree *ntree, bool create)
Definition: node.cc:3450
void nodeSetSelected(bNode *node, bool select)
Definition: node.cc:3664
bNodeSocket * nodeAddSocket(bNodeTree *ntree, bNode *node, eNodeSocketInOut in_out, const char *idname, const char *identifier, const char *name)
Definition: node.cc:1533
static void node_socket_copy(bNodeSocket *sock_dst, const bNodeSocket *sock_src, const int flag)
Definition: node.cc:2026
void ntreeBlendReadExpand(BlendExpander *expander, bNodeTree *ntree)
Definition: node.cc:914
static void ntree_blend_read_data(BlendDataReader *reader, ID *id)
Definition: node.cc:773
bNodeSocket * ntreeAddSocketInterface(bNodeTree *ntree, eNodeSocketInOut in_out, const char *idname, const char *name)
Definition: node.cc:3302
bool nodeAttachNodeCheck(const bNode *node, const bNode *parent)
Definition: node.cc:2438
bNode * nodeAddStaticNode(const struct bContext *C, bNodeTree *ntree, int type)
Definition: node.cc:2004
IDTypeInfo IDType_ID_NT
Definition: node.cc:942
void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwidth)
Definition: node.cc:4565
void nodeUpdate(bNodeTree *ntree, bNode *node)
Definition: node.cc:4326
static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype)
Definition: node.cc:970
bNodeTree * ntreeCopyTree(Main *bmain, const bNodeTree *ntree)
Definition: node.cc:2562
struct bNodeSocket * ntreeAddSocketInterfaceFromSocket(bNodeTree *ntree, bNode *from_node, bNodeSocket *from_sock)
Definition: node.cc:3337
void ntreeFreeEmbeddedTree(bNodeTree *ntree)
Definition: node.cc:3021
static GHash * nodesockettypes_hash
Definition: node.cc:1205
bNodeLink * nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock)
Definition: node.cc:2189
static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
Definition: node.cc:997
void ntreeSetOutput(bNodeTree *ntree)
Definition: node.cc:3050
bNodeInstanceHash * BKE_node_instance_hash_new(const char *info)
Definition: node.cc:3955
bNodeType * nodeTypeFind(const char *idname)
Definition: node.cc:1254
static void unique_socket_template_identifier(bNodeSocketTemplate *list, bNodeSocketTemplate *ntemp, const char defname[], char delim)
Definition: node.cc:4510
void node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs)
Definition: node.cc:4527
static void expand_node_sockets(BlendExpander *expander, ListBase *sockets)
Definition: node.cc:907
static void node_socket_free(bNodeTree *UNUSED(ntree), bNodeSocket *sock, bNode *UNUSED(node), const bool do_id_user)
Definition: node.cc:1757
const bNodeInstanceKey NODE_INSTANCE_KEY_BASE
Definition: node.cc:3908
static void ntree_blend_write(BlendWriter *writer, ID *id, const void *id_address)
Definition: node.cc:593
const ListBase * BKE_node_clipboard_get_nodes(void)
Definition: node.cc:3884
static void node_set_typeinfo(const struct bContext *C, bNodeTree *ntree, bNode *node, bNodeType *typeinfo)
Definition: node.cc:1069
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4623
bNodeTree * ntreeFromID(ID *id)
Definition: node.cc:3147
void BKE_nodetree_remove_layer_n(bNodeTree *ntree, Scene *scene, const int layer_index)
Definition: node.cc:5140
static void nodeMuteRerouteInputLinks(bNodeTree *ntree, bNode *node, const bool mute)
Definition: node.cc:2281
static void node_set_new_pointers(bNode *node_src, bNode *new_node)
Definition: node.cc:2133
void nodePositionPropagate(bNode *node)
Definition: node.cc:2518
void nodeUnregisterType(bNodeType *nt)
Definition: node.cc:1311
static void ntree_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
Definition: node.cc:120
void BKE_node_clipboard_add_node(bNode *node)
Definition: node.cc:3849
void nodeSetActive(bNodeTree *ntree, bNode *node)
Definition: node.cc:3694
static void registerShaderNodes()
Definition: node.cc:4798
void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree)
Definition: node.cc:472
void ntreeBlendReadLib(struct BlendLibReader *reader, struct bNodeTree *ntree)
Definition: node.cc:828
bool nodeIsChildOf(const bNode *parent, const bNode *child)
Definition: node.cc:1861
void BKE_node_instance_hash_insert(bNodeInstanceHash *hash, bNodeInstanceKey key, void *value)
Definition: node.cc:3969
static bNodeSocket * make_socket_interface(bNodeTree *ntree, eNodeSocketInOut in_out, const char *idname, const char *name)
Definition: node.cc:3252
static void ntree_blend_read_expand(BlendExpander *expander, ID *id)
Definition: node.cc:936
static void ntree_set_typeinfo(bNodeTree *ntree, bNodeTreeType *typeinfo)
Definition: node.cc:1054
const ListBase * BKE_node_clipboard_get_links(void)
Definition: node.cc:3889
void node_type_storage(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
void BKE_node_tree_iter_init(struct NodeTreeIterStore *ntreeiter, struct Main *bmain)
Definition: node.cc:5075
void ntreeUpdateAllUsers(Main *main, ID *id)
Definition: node.cc:4219
void ntreeUpdateTree(Main *bmain, bNodeTree *ntree)
Definition: node.cc:4262
bNodeTree * ntreeLocalize(bNodeTree *ntree)
Definition: node.cc:3186
void BKE_node_preview_remove_unused(bNodeTree *ntree)
Definition: node.cc:2690
void nodeChainIter(const bNodeTree *ntree, const bNode *node_start, bool(*callback)(bNode *, bNode *, void *, const bool), void *userdata, const bool reversed)
Definition: node.cc:1879
static bool node_poll_instance_default(bNode *node, bNodeTree *ntree, const char **disabled_hint)
Definition: node.cc:4437
static void expand_node_socket(BlendExpander *expander, bNodeSocket *sock)
Definition: node.cc:869
static bool ntree_interface_unique_identifier_check(void *UNUSED(data), const char *identifier)
Definition: node.cc:3391
static bool node_instance_hash_key_cmp(const void *a, const void *b)
Definition: node.cc:3947
bool ntreeHasTree(const bNodeTree *ntree, const bNodeTree *lookup)
Definition: node.cc:3522
bool nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **r_node, int *r_sockindex)
Definition: node.cc:1823
static void ntree_validate_links(bNodeTree *ntree)
Definition: node.cc:4185
bool ntreeHasType(const bNodeTree *ntree, int type)
Definition: node.cc:3517
int nodeSocketIsHidden(const bNodeSocket *sock)
Definition: node.cc:3721
int nodeCountSocketLinks(const bNodeTree *ntree, const bNodeSocket *sock)
Definition: node.cc:3550
void ntreeFreeCache(bNodeTree *ntree)
Definition: node.cc:3039
static bool unique_socket_template_identifier_check(void *arg, const char *name)
Definition: node.cc:4495
bool nodeUpdateID(bNodeTree *ntree, ID *id)
Definition: node.cc:4346
void nodeFromView(const bNode *node, float x, float y, float *rx, float *ry)
Definition: node.cc:2425
void nodeMuteLinkToggle(bNodeTree *ntree, bNodeLink *link)
Definition: node.cc:2325
struct bNodeSocket * ntreeInsertSocketInterfaceFromSocket(bNodeTree *ntree, bNodeSocket *next_sock, bNode *from_node, bNodeSocket *from_sock)
Definition: node.cc:3351
void ntreeTagUsedSockets(bNodeTree *ntree)
Definition: node.cc:4149
void BKE_node_preview_free(bNodePreview *preview)
Definition: node.cc:2627
static bNode * node_get_active_id_recursive(bNodeInstanceKey active_key, bNodeInstanceKey parent_key, bNodeTree *ntree, short idtype)
Definition: node.cc:3575
static int node_count_links(const bNodeTree *ntree, const bNodeSocket *socket)
Definition: node.cc:2177
void BKE_node_preview_clear(bNodePreview *preview)
Definition: node.cc:2716
GHashIterator * nodeSocketTypeGetIterator(void)
Definition: node.cc:1371
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4559
int BKE_node_instance_hash_remove(bNodeInstanceHash *hash, bNodeInstanceKey key, bNodeInstanceValueFP valfreefp)
Definition: node.cc:3982
void ntreeUpdateAllNew(Main *main)
Definition: node.cc:4200
static void registerFunctionNodes()
Definition: node.cc:4994
bool nodeSocketIsRegistered(bNodeSocket *sock)
Definition: node.cc:1366
static void node_socket_interface_free(bNodeTree *UNUSED(ntree), bNodeSocket *sock, const bool do_id_user)
Definition: node.cc:2977
bNode * BKE_node_copy_store_new_pointers(bNodeTree *ntree, bNode *node_src, const int flag)
Definition: node.cc:2155
static void direct_link_node_socket(BlendDataReader *reader, bNodeSocket *sock)
Definition: node.cc:612
bNodeType NodeTypeUndefined
Definition: node.cc:98
bNodeTreeType * ntreeTypeFind(const char *idname)
Definition: node.cc:1207
void BKE_node_system_exit(void)
Definition: node.cc:5030
#define NODE_DEFAULT_MAX_WIDTH
Definition: node.cc:94
void node_type_size_preset(struct bNodeType *ntype, eNodeSizePreset size)
Definition: node.cc:4577
const char * nodeSocketLabel(const bNodeSocket *sock)
Definition: node.cc:4414
static void node_unlink_attached(bNodeTree *ntree, bNode *parent)
Definition: node.cc:2861
bNode * nodeFindNodebyName(bNodeTree *ntree, const char *name)
Definition: node.cc:1817
void BKE_node_preview_merge_tree(bNodeTree *to_ntree, bNodeTree *from_ntree, bool remove_old)
Definition: node.cc:2770
static void update_typeinfo(Main *bmain, const struct bContext *C, bNodeTreeType *treetype, bNodeType *nodetype, bNodeSocketType *socktype, bool unregister)
Definition: node.cc:1120
int BKE_node_clipboard_get_type(void)
Definition: node.cc:3894
GHashIterator * nodeTypeGetIterator(void)
Definition: node.cc:1323
static void node_preview_tag_used_recursive(bNodeInstanceHash *previews, bNodeTree *ntree, bNodeInstanceKey parent_key)
Definition: node.cc:2673
void * BKE_node_instance_hash_pop(bNodeInstanceHash *hash, bNodeInstanceKey key)
Definition: node.cc:3994
int BKE_node_instance_hash_haskey(bNodeInstanceHash *hash, bNodeInstanceKey key)
Definition: node.cc:3999
bNode * nodeGetActiveID(bNodeTree *ntree, short idtype)
Definition: node.cc:3608
bool ntreeIsRegistered(bNodeTree *ntree)
Definition: node.cc:1244
bNodeSocket * nodeInsertStaticSocket(bNodeTree *ntree, bNode *node, eNodeSocketInOut in_out, int type, int subtype, bNodeSocket *next_sock, const char *identifier, const char *name)
Definition: node.cc:1736
static bool node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *UNUSED(ntree), const char **UNUSED(disabled_hint))
Definition: node.cc:4429
static bool node_undefined_poll(bNodeType *UNUSED(ntype), bNodeTree *UNUSED(nodetree), const char **UNUSED(r_disabled_hint))
Definition: node.cc:4658
void nodeRegisterType(bNodeType *nt)
Definition: node.cc:1298
bNode * nodeGetActive(bNodeTree *ntree)
Definition: node.cc:3561
static GHash * nodetypes_hash
Definition: node.cc:1204
bNodeTree * ntreeCopyTree_ex_new_pointers(const bNodeTree *ntree, Main *bmain, const bool do_id_user)
Definition: node.cc:2162
bNodeTree * ntreeAddTree(Main *bmain, const char *name, const char *idname)
Definition: node.cc:2529
static void node_free_node(bNodeTree *ntree, bNode *node)
Definition: node.cc:2872
bNodeSocketType * nodeSocketTypeFind(const char *idname)
Definition: node.cc:1328
void ntreeTypeAdd(bNodeTreeType *nt)
Definition: node.cc:1219
void nodeClearActive(bNodeTree *ntree)
Definition: node.cc:3682
void ntreeFreeTree(bNodeTree *ntree)
Definition: node.cc:3015
static void registerTextureNodes()
Definition: node.cc:4895
static void node_foreach_id(ID *id, LibraryForeachIDData *data)
Definition: node.cc:320
bool BKE_node_instance_hash_tag_key(bNodeInstanceHash *hash, bNodeInstanceKey key)
Definition: node.cc:4027
bNodeSocket * ntreeInsertSocketInterface(bNodeTree *ntree, eNodeSocketInOut in_out, const char *idname, bNodeSocket *next_sock, const char *name)
Definition: node.cc:3319
void ntreeFreeLocalNode(bNodeTree *ntree, bNode *node)
Definition: node.cc:2925
void BKE_node_instance_hash_clear(bNodeInstanceHash *hash, bNodeInstanceValueFP valfreefp)
Definition: node.cc:3989
static bNodeClipboard node_clipboard
Definition: node.cc:3781
void node_type_group_update(struct bNodeType *ntype, void(*group_update_func)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4629
static bool unique_identifier_check(void *arg, const char *identifier)
Definition: node.cc:1390
static void ntree_interface_identifier(bNodeTree *ntree, const char *base, char *identifier, int maxlen, char *name, char *description)
Definition: node.cc:3397
const char * nodeStaticSocketType(int type, int subtype)
Definition: node.cc:1574
void BKE_node_preview_clear_tree(bNodeTree *ntree)
Definition: node.cc:2723
bNodeSocket * ntreeFindSocketInterface(bNodeTree *ntree, eNodeSocketInOut in_out, const char *identifier)
Definition: node.cc:3289
static unsigned int node_instance_hash_key(const void *key)
Definition: node.cc:3942
bNodeLink * nodeFindLink(bNodeTree *ntree, const bNodeSocket *from, const bNodeSocket *to)
Definition: node.cc:3537
void nodeInternalRelink(bNodeTree *ntree, bNode *node)
Definition: node.cc:2364
void node_type_base_custom(bNodeType *ntype, const char *idname, const char *name, short nclass, short flag)
Definition: node.cc:4478
void BKE_node_system_init(void)
Definition: node.cc:5003
bool BKE_node_tree_iter_step(struct NodeTreeIterStore *ntreeiter, bNodeTree **r_nodetree, struct ID **r_id)
Definition: node.cc:5086
static bNodeSocket * make_socket(bNodeTree *ntree, bNode *UNUSED(node), int in_out, ListBase *lb, const char *idname, const char *identifier, const char *name)
Definition: node.cc:1401
void BKE_node_preview_free_tree(bNodeTree *ntree)
Definition: node.cc:2704
static int node_get_deplist_recurs(bNodeTree *ntree, bNode *node, bNode ***nsort)
Definition: node.cc:4070
void BKE_node_instance_hash_tag(bNodeInstanceHash *UNUSED(hash), void *value)
Definition: node.cc:4021
void node_type_label(struct bNodeType *ntype, void(*labelfunc)(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen))
Definition: node.cc:4616
const char * nodeStaticSocketInterfaceType(int type, int subtype)
Definition: node.cc:1645
static void ntree_interface_identifier_base(bNodeTree *ntree, char *base)
Definition: node.cc:3383
bNodeSocket * nodeAddStaticSocket(bNodeTree *ntree, bNode *node, eNodeSocketInOut in_out, int type, int subtype, const char *identifier, const char *name)
Definition: node.cc:1716
static void free_localized_node_groups(bNodeTree *ntree)
Definition: node.cc:2993
static void node_preview_sync(bNodePreview *to, bNodePreview *from)
Definition: node.cc:2736
void nodeParentsIter(bNode *node, bool(*callback)(bNode *, void *), void *userdata)
Definition: node.cc:1972
void BKE_node_clipboard_add_link(bNodeLink *link)
Definition: node.cc:3879
static void registerGeometryNodes()
Definition: node.cc:4945
void nodeLabel(bNodeTree *ntree, bNode *node, char *label, int maxlen)
Definition: node.cc:4391
static void socket_id_user_increment(bNodeSocket *sock)
Definition: node.cc:1440
static ID * node_owner_get(Main *bmain, ID *id)
Definition: node.cc:373
int BKE_node_instance_hash_size(bNodeInstanceHash *hash)
Definition: node.cc:4004
void nodeRemLink(bNodeTree *ntree, bNodeLink *link)
Definition: node.cc:2231
void nodeClearActiveID(bNodeTree *ntree, short idtype)
Definition: node.cc:3651
void nodeRemoveSocket(bNodeTree *ntree, bNode *node, bNodeSocket *sock)
Definition: node.cc:1775
void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
Definition: node.cc:2348
bool nodeLinkIsHidden(const bNodeLink *link)
Definition: node.cc:2359
void nodeUniqueName(bNodeTree *ntree, bNode *node)
Definition: node.cc:1985
bool nodeSetActiveID(bNodeTree *ntree, short idtype, ID *id)
Definition: node.cc:3617
void ntreeSetTypes(const struct bContext *C, bNodeTree *ntree)
Definition: node.cc:1178
void nodePositionRelative(bNode *from_node, bNode *to_node, bNodeSocket *from_sock, bNodeSocket *to_sock)
Definition: node.cc:2476
static void nodeMuteLink(bNodeLink *link)
Definition: node.cc:2264
void BKE_node_instance_hash_remove_untagged(bNodeInstanceHash *hash, bNodeInstanceValueFP valfreefp)
Definition: node.cc:4040
static void node_free_socket_type(void *socktype_v)
Definition: node.cc:1341
void ntreeLocalMerge(Main *bmain, bNodeTree *localtree, bNodeTree *ntree)
Definition: node.cc:3238
void nodeToView(const bNode *node, float x, float y, float *rx, float *ry)
Definition: node.cc:2414
void nodeRemoveNode(Main *bmain, bNodeTree *ntree, bNode *node, bool do_id_user)
Definition: node.cc:2932
static void ntree_free_type(void *treetype_v)
Definition: node.cc:1229
static void register_undefined_types()
Definition: node.cc:4667
GHashIterator * ntreeTypeGetIterator(void)
Definition: node.cc:1249
static void write_node_socket_default_value(BlendWriter *writer, bNodeSocket *sock)
Definition: node.cc:403
static bool nodeMuteFromSocketLinks(const bNodeTree *ntree, const bNodeSocket *sock)
Definition: node.cc:2249
bNodeTree ** BKE_ntree_ptr_from_id(ID *id)
Definition: node.cc:3124
static void node_preview_init_tree_recursive(bNodeInstanceHash *previews, bNodeTree *ntree, bNodeInstanceKey parent_key, int xsize, int ysize, bool create_previews)
Definition: node.cc:2635
void nodeModifySocketType(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, int type, int subtype)
Definition: node.cc:1512
bNode * BKE_node_copy_ex(bNodeTree *ntree, const bNode *node_src, const int flag, const bool unique_name)
Definition: node.cc:2050
void ntreeRemoveSocketInterface(bNodeTree *ntree, bNodeSocket *sock)
Definition: node.cc:3370
bool ntreeNodeExists(const bNodeTree *ntree, const bNode *testnode)
Definition: node.cc:3153
static CLG_LogRef LOG
Definition: node.cc:101
void BKE_node_preview_init_tree(bNodeTree *ntree, int xsize, int ysize, bool create_previews)
Definition: node.cc:2659
static void node_socket_set_typeinfo(bNodeTree *ntree, bNodeSocket *sock, bNodeSocketType *typeinfo)
Definition: node.cc:1097
static void nodeMuteRerouteOutputLinks(struct bNodeTree *ntree, struct bNode *node, const bool mute)
Definition: node.cc:2304
bool ntreeOutputExists(const bNode *node, const bNodeSocket *testsock)
Definition: node.cc:3163
bNode * nodeFindRootParent(bNode *node)
Definition: node.cc:1849
static void lib_link_node_socket(BlendLibReader *reader, Library *lib, bNodeSocket *sock)
Definition: node.cc:779
static void ntree_update_node_level(bNodeTree *ntree)
Definition: node.cc:4134
void nodeChainIterBackwards(const bNodeTree *ntree, const bNode *node_start, bool(*callback)(bNode *, bNode *, void *), void *userdata, int recursion_lvl)
Definition: node.cc:1944
const bNodeInstanceKey NODE_INSTANCE_KEY_NONE
Definition: node.cc:3909
static void node_type_base_defaults(bNodeType *ntype)
Definition: node.cc:4419
static void ntree_update_link_pointers(bNodeTree *ntree)
Definition: node.cc:4169
void nodeUnlinkNode(bNodeTree *ntree, bNode *node)
Definition: node.cc:2833
static void iter_backwards_ex(const bNodeTree *ntree, const bNode *node_start, bool(*callback)(bNode *, bNode *, void *), void *userdata, char recursion_mask)
Definition: node.cc:1905
bNode * ntreeFindType(const bNodeTree *ntree, int type)
Definition: node.cc:3505
void nodeRemoveAllSockets(bNodeTree *ntree, bNode *node)
Definition: node.cc:1793
bNode * nodeAddNode(const struct bContext *C, bNodeTree *ntree, const char *idname)
Definition: node.cc:1991
void BKE_node_instance_hash_clear_tags(bNodeInstanceHash *hash)
Definition: node.cc:4009
bool BKE_node_clipboard_validate(void)
Definition: node.cc:3806
static void write_node_socket_interface(BlendWriter *writer, bNodeSocket *sock)
Definition: node.cc:459
void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
Definition: node.cc:626
void BKE_node_clipboard_clear(void)
Definition: node.cc:3788
void ntreeInterfaceTypeFree(bNodeTree *ntree)
Definition: node.cc:3484
void node_type_exec(struct bNodeType *ntype, NodeInitExecFunction init_exec_fn, NodeFreeExecFunction free_exec_fn, NodeExecFunction exec_fn)
Definition: node.cc:4635
void nodeUnregisterSocketType(bNodeSocketType *st)
Definition: node.cc:1361
static bNodeTreeType NodeTreeTypeUndefined
Definition: node.cc:97
void ntreeFreeLocalTree(bNodeTree *ntree)
Definition: node.cc:3028
void nodeDetachNode(struct bNode *node)
Definition: node.cc:2462
void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***r_deplist, int *r_deplist_len)
Definition: node.cc:4107
struct bNodeSocket * nodeFindSocket(const bNode *node, eNodeSocketInOut in_out, const char *identifier)
Definition: node.cc:1376
bNodePreview * BKE_node_preview_copy(bNodePreview *preview)
Definition: node.cc:2618
void * BKE_node_instance_hash_lookup(bNodeInstanceHash *hash, bNodeInstanceKey key)
Definition: node.cc:3977
void node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
Definition: node.cc:4443
static void node_foreach_cache(ID *id, IDTypeForeachCacheFunctionCallback function_callback, void *user_data)
Definition: node.cc:347
bNodeTree * ntreeCopyTree_ex(const bNodeTree *ntree, Main *bmain, const bool do_id_user)
Definition: node.cc:2555
void node_type_internal_links(bNodeType *ntype, void(*update_internal_links)(bNodeTree *, bNode *))
Definition: node.cc:4650
void BKE_node_instance_hash_free(bNodeInstanceHash *hash, bNodeInstanceValueFP valfreefp)
Definition: node.cc:3963
void ntreeInterfaceTypeUpdate(bNodeTree *ntree)
Definition: node.cc:3492
static void registerCompositNodes()
Definition: node.cc:4692
static void ntree_init_data(ID *id)
Definition: node.cc:114
void BKE_node_clipboard_free(void)
Definition: node.cc:3899
void BKE_node_preview_set_pixel(bNodePreview *preview, const float col[4], int x, int y, bool do_manage)
Definition: node.cc:2809
void nodeAttachNode(bNode *node, bNode *parent)
Definition: node.cc:2449
static void ntree_free_data(ID *id)
Definition: node.cc:229
static void lib_link_node_sockets(BlendLibReader *reader, Library *lib, ListBase *sockets)
Definition: node.cc:821
static void free_dynamic_typeinfo(bNodeType *ntype)
Definition: node.cc:1266
void ntreeLocalSync(bNodeTree *localtree, bNodeTree *ntree)
Definition: node.cc:3227
static void write_node_socket(BlendWriter *writer, bNodeSocket *sock)
Definition: node.cc:448
void nodeRegisterSocketType(bNodeSocketType *st)
Definition: node.cc:1352
bNodeSocketType NodeSocketTypeUndefined
Definition: node.cc:99
void nodeUpdateInternalLinks(bNodeTree *ntree, bNode *node)
Definition: node.cc:4380
void BKE_node_preview_sync_tree(bNodeTree *to_ntree, bNodeTree *from_ntree)
Definition: node.cc:2749
static void node_free_type(void *nodetype_v)
Definition: node.cc:1279
bNodePreview * BKE_node_preview_verify(bNodeInstanceHash *previews, bNodeInstanceKey key, int xsize, int ysize, bool create)
Definition: node.cc:2580
void nodeSetSocketAvailability(bNodeSocket *sock, bool is_available)
Definition: node.cc:3726
void register_node_type_frame(void)
Definition: node_common.c:220
void register_node_type_group_input(void)
Definition: node_common.c:511
void register_node_type_reroute(void)
Definition: node_common.c:269
void register_node_type_group_output(void)
Definition: node_common.c:609
void register_node_type_cmp_alphaover(void)
void register_node_type_cmp_antialiasing(void)
void register_node_type_cmp_bilateralblur(void)
void register_node_type_cmp_blur(void)
void register_node_type_cmp_bokehblur(void)
void register_node_type_cmp_bokehimage(void)
void register_node_type_cmp_boxmask(void)
void register_node_type_cmp_brightcontrast(void)
void register_node_type_cmp_channel_matte(void)
void register_node_type_cmp_chroma_matte(void)
void register_node_type_cmp_color_matte(void)
void register_node_type_cmp_color_spill(void)
void register_node_type_cmp_colorbalance(void)
void register_node_type_cmp_colorcorrection(void)
void register_node_type_cmp_group(void)
void register_node_type_cmp_composite(void)
static bNodeSocketTemplate outputs[]
void register_node_type_cmp_cornerpin(void)
static bNodeSocketTemplate inputs[]
void register_node_type_cmp_crop(void)
void register_node_type_cmp_cryptomatte_legacy(void)
void register_node_type_cmp_cryptomatte(void)
void register_node_type_cmp_curve_rgb(void)
void register_node_type_cmp_curve_time(void)
void register_node_type_cmp_curve_vec(void)
void register_node_type_cmp_defocus(void)
void register_node_type_cmp_denoise(void)
void register_node_type_cmp_despeckle(void)
void register_node_type_cmp_diff_matte(void)
void register_node_type_cmp_dilateerode(void)
void register_node_type_cmp_dblur(void)
void register_node_type_cmp_displace(void)
void register_node_type_cmp_distance_matte(void)
void register_node_type_cmp_doubleedgemask(void)
void register_node_type_cmp_ellipsemask(void)
void register_node_type_cmp_exposure(void)
void register_node_type_cmp_filter(void)
void register_node_type_cmp_flip(void)
void register_node_type_cmp_gamma(void)
void register_node_type_cmp_glare(void)
void register_node_type_cmp_hue_sat(void)
void register_node_type_cmp_huecorrect(void)
void register_node_type_cmp_idmask(void)
void register_node_type_cmp_rlayers(void)
void register_node_type_cmp_image(void)
void register_node_type_cmp_inpaint(void)
void register_node_type_cmp_invert(void)
void register_node_type_cmp_keying(void)
void register_node_type_cmp_keyingscreen(void)
void register_node_type_cmp_lensdist(void)
void register_node_type_cmp_view_levels(void)
void register_node_type_cmp_luma_matte(void)
void register_node_type_cmp_map_range(void)
void register_node_type_cmp_mapuv(void)
void register_node_type_cmp_map_value(void)
void register_node_type_cmp_mask(void)
void register_node_type_cmp_math(void)
void register_node_type_cmp_mix_rgb(void)
void register_node_type_cmp_movieclip(void)
void register_node_type_cmp_moviedistortion(void)
void register_node_type_cmp_normal(void)
void register_node_type_cmp_normalize(void)
void register_node_type_cmp_output_file(void)
void register_node_type_cmp_pixelate(void)
void register_node_type_cmp_planetrackdeform(void)
void register_node_type_cmp_premulkey(void)
void register_node_type_cmp_rgb(void)
void register_node_type_cmp_rotate(void)
void register_node_type_cmp_scale(void)
void register_node_type_cmp_combhsva(void)
void register_node_type_cmp_sephsva(void)
void register_node_type_cmp_combrgba(void)
void register_node_type_cmp_seprgba(void)
void register_node_type_cmp_sepycca(void)
void register_node_type_cmp_combycca(void)
void register_node_type_cmp_sepyuva(void)
void register_node_type_cmp_combyuva(void)
void register_node_type_cmp_setalpha(void)
void register_node_type_cmp_splitviewer(void)
void register_node_type_cmp_stabilize2d(void)
void register_node_type_cmp_sunbeams(void)
void register_node_type_cmp_switch(void)
void register_node_type_cmp_switch_view(void)
void register_node_type_cmp_texture(void)
void register_node_type_cmp_tonemap(void)
void register_node_type_cmp_trackpos(void)
void register_node_type_cmp_transform(void)
void register_node_type_cmp_translate(void)
void register_node_tree_type_cmp(void)
void register_node_type_cmp_rgbtobw(void)
void register_node_type_cmp_valtorgb(void)
void register_node_type_cmp_value(void)
void register_node_type_cmp_vecblur(void)
void register_node_type_cmp_viewer(void)
void register_node_type_cmp_zcombine(void)
void register_node_type_fn_boolean_math()
void register_node_type_fn_float_compare()
void register_node_type_fn_input_string()
void register_node_type_fn_input_vector()
void register_node_type_fn_random_float()
void register_node_type_geo_align_rotation_to_vector()
void register_node_type_geo_attribute_clamp()
void register_node_type_geo_attribute_color_ramp()
void register_node_type_geo_attribute_combine_xyz()
void register_node_type_geo_attribute_compare()
void register_node_type_geo_attribute_convert()
void register_node_type_geo_attribute_fill()
void register_node_type_geo_attribute_map_range()
void register_node_type_geo_attribute_math()
void register_node_type_geo_attribute_mix()
void register_node_type_geo_attribute_proximity()
void register_node_type_geo_attribute_randomize()
void register_node_type_geo_attribute_remove()
void register_node_type_geo_sample_texture()
void register_node_type_geo_attribute_separate_xyz()
void register_node_type_geo_attribute_vector_math()
void register_node_type_geo_boolean()
void register_node_type_geo_bounding_box()
void register_node_type_geo_collection_info()
void register_node_type_geo_group(void)
void register_node_type_geo_edge_split()
void register_node_type_geo_is_viewport()
void register_node_type_geo_join_geometry()
void register_node_type_geo_mesh_primitive_circle()
void register_node_type_geo_mesh_primitive_cone()
void register_node_type_geo_mesh_primitive_cube()
void register_node_type_geo_mesh_primitive_cylinder()
void register_node_type_geo_mesh_primitive_grid()
void register_node_type_geo_mesh_primitive_ico_sphere()
void register_node_type_geo_mesh_primitive_line()
void register_node_type_geo_mesh_primitive_uv_sphere()
void register_node_type_geo_object_info()
void register_node_type_geo_point_distribute()
void register_node_type_geo_point_instance()
void register_node_type_geo_point_rotate()
void register_node_type_geo_point_scale()
void register_node_type_geo_point_separate()
void register_node_type_geo_point_translate()
void register_node_type_geo_points_to_volume()
void register_node_type_geo_subdivide()
void register_node_type_geo_subdivision_surface()
void register_node_type_geo_transform()
void register_node_type_geo_triangulate()
void register_node_type_geo_volume_to_mesh()
void register_node_tree_type_geo(void)
void node_socket_init_default_value(bNodeSocket *sock)
Definition: node_socket.cc:204
void node_verify_socket_templates(bNodeTree *ntree, bNode *node)
Definition: node_socket.cc:186
void register_standard_node_socket_types(void)
Definition: node_socket.cc:717
struct bNodeSocket * node_add_socket_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp, eNodeSocketInOut in_out)
Definition: node_socket.cc:52
static void unique_name(bNode *node)
#define hash
Definition: noise.c:169
const char * RNA_struct_identifier(const StructRNA *type)
Definition: rna_access.c:723
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
Definition: rna_access.c:1044
StructRNA * RNA_struct_find(const char *identifier)
Definition: rna_access.c:718
void RNA_def_struct_ui_text(StructRNA *srna, const char *name, const char *description)
Definition: rna_define.c:1259
void RNA_identifier_sanitize(char *identifier, int property)
Definition: rna_define.c:617
void RNA_def_struct_identifier(BlenderRNA *brna, StructRNA *srna, const char *identifier)
Definition: rna_define.c:1224
StructRNA * RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRNA *srnafrom)
Definition: rna_define.c:919
void RNA_struct_free(BlenderRNA *brna, StructRNA *srna)
Definition: rna_define.c:795
BlenderRNA BLENDER_RNA
StructRNA RNA_PropertyGroup
struct bNodeTree * nodetree
unsigned int id_session_uuid
Definition: BKE_idtype.h:56
size_t offset_in_ID
Definition: BKE_idtype.h:59
void * cache_v
Definition: BKE_idtype.h:61
Definition: DNA_ID.h:273
int tag
Definition: DNA_ID.h:292
struct Library * lib
Definition: DNA_ID.h:277
int us
Definition: DNA_ID.h:293
short flag
Definition: DNA_ID.h:288
void * next
Definition: DNA_ID.h:274
char name[66]
Definition: DNA_ID.h:283
struct Scene * scene
struct bNodeTree * nodetree
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
ListBase scenes
Definition: BKE_main.h:146
ListBase textures
Definition: BKE_main.h:153
ListBase lights
Definition: BKE_main.h:156
ListBase nodetrees
Definition: BKE_main.h:170
ListBase materials
Definition: BKE_main.h:152
ListBase linestyles
Definition: BKE_main.h:179
ListBase worlds
Definition: BKE_main.h:160
ListBase simulations
Definition: BKE_main.h:185
struct bNodeTree * nodetree
NodeCryptomatte_Runtime runtime
char angle streaks
char angle star_45
struct Simulation * simulation
Definition: BKE_node.h:927
struct Light * light
Definition: BKE_node.h:924
struct World * world
Definition: BKE_node.h:925
struct FreestyleLineStyle * linestyle
Definition: BKE_node.h:926
struct Material * mat
Definition: BKE_node.h:922
bNodeTree * ngroup
Definition: BKE_node.h:920
struct bNodeTree * node_group
struct bNodeTree * nodetree
struct bNodeTree * nodetree
bNodeSocketTemplate * list
Definition: node.cc:4491
bNodeSocketTemplate * ntemp
Definition: node.cc:4492
struct ImageUser iuser
struct bNodeTree * nodetree
struct bNodeTree * nodetree
struct bNodeClipboardExtraInfo * next
Definition: node.cc:3763
struct bNodeClipboardExtraInfo * prev
Definition: node.cc:3763
char library_name[FILE_MAX]
Definition: node.cc:3766
char id_name[MAX_ID_NAME]
Definition: node.cc:3765
ListBase nodes
Definition: node.cc:3771
ListBase links
Definition: node.cc:3777
ListBase nodes_extra_info
Definition: node.cc:3774
bNodeInstanceKey key
unsigned int value
unsigned char * rect
Compact definition of a node socket.
Definition: BKE_node.h:95
char identifier[64]
Definition: BKE_node.h:105
Defines a socket type.
Definition: BKE_node.h:143
int input_link_limit
Definition: BKE_node.h:185
void(* interface_register_properties)(struct bNodeTree *ntree, struct bNodeSocket *stemp, struct StructRNA *data_srna)
Definition: BKE_node.h:158
int output_link_limit
Definition: BKE_node.h:186
bool use_link_limits_of_type
Definition: BKE_node.h:184
void(* free_self)(struct bNodeSocketType *stype)
Definition: BKE_node.h:189
char idname[64]
Definition: BKE_node.h:144
void(* interface_from_socket)(struct bNodeTree *ntree, struct bNodeSocket *stemp, struct bNode *node, struct bNodeSocket *sock)
Definition: BKE_node.h:171
struct Collection * value
struct Image * value
struct Object * value
char name[64]
IDProperty * prop
void * storage
struct bNodeLink * link
char description[64]
struct bNodeSocket * next
void * default_value
struct bNodeSocketType * typeinfo
short total_inputs
char identifier[64]
char idname[64]
char label[64]
char idname[64]
Definition: BKE_node.h:381
void(* free_node_cache)(struct bNodeTree *ntree, struct bNode *node)
Definition: BKE_node.h:389
void(* update)(struct bNodeTree *ntree)
Definition: BKE_node.h:407
void(* local_merge)(struct Main *bmain, struct bNodeTree *localtree, struct bNodeTree *ntree)
Definition: BKE_node.h:404
bool(* validate_link)(struct bNodeTree *ntree, struct bNodeLink *link)
Definition: BKE_node.h:409
void(* free_cache)(struct bNodeTree *ntree)
Definition: BKE_node.h:388
char ui_name[64]
Definition: BKE_node.h:383
void(* localize)(struct bNodeTree *localtree, struct bNodeTree *ntree)
Definition: BKE_node.h:402
char ui_description[256]
Definition: BKE_node.h:384
void(* local_sync)(struct bNodeTree *localtree, struct bNodeTree *ntree)
Definition: BKE_node.h:403
void(* node_add_init)(struct bNodeTree *ntree, struct bNode *bnode)
Definition: BKE_node.h:411
void(* progress)(void *, float progress)
char idname[64]
short is_updating
struct NodeTreeUIStorage * ui_storage
struct bNodeInstanceHash * previews
struct bNodeTreeType * typeinfo
struct bGPdata * gpd
struct StructRNA * interface_type
ListBase nodes
ListBase inputs
ListBase links
bNodeInstanceKey active_viewer_key
ListBase outputs
struct bNodeTreeExec * execdata
struct AnimData * adt
Defines a node type.
Definition: BKE_node.h:221
void(* copyfunc)(struct bNodeTree *dest_ntree, struct bNode *dest_node, const struct bNode *src_node)
Definition: BKE_node.h:283
float minwidth
Definition: BKE_node.h:231
void(* group_update_func)(struct bNodeTree *ntree, struct bNode *node)
Definition: BKE_node.h:276
float width
Definition: BKE_node.h:231
short flag
Definition: BKE_node.h:233
char ui_name[64]
Definition: BKE_node.h:227
bool(* poll)(struct bNodeType *ntype, struct bNodeTree *nodetree, const char **r_disabled_hint)
Definition: BKE_node.h:301
float maxwidth
Definition: BKE_node.h:231
void(* update_internal_links)(struct bNodeTree *, struct bNode *node)
Definition: BKE_node.h:312
int type
Definition: BKE_node.h:225
NodeInitExecFunction init_exec_fn
Definition: BKE_node.h:317
void(* updatefunc)(struct bNodeTree *ntree, struct bNode *node)
Definition: BKE_node.h:274
bNodeSocketTemplate * outputs
Definition: BKE_node.h:236
void(* initfunc_api)(const struct bContext *C, struct PointerRNA *ptr)
Definition: BKE_node.h:288
void(* free_self)(struct bNodeType *ntype)
Definition: BKE_node.h:314
short nclass
Definition: BKE_node.h:233
void(* freefunc)(struct bNode *node)
Definition: BKE_node.h:281
NodeGPUExecFunction gpu_fn
Definition: BKE_node.h:321
float minheight
Definition: BKE_node.h:232
float height
Definition: BKE_node.h:232
void(* labelfunc)(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen)
Definition: BKE_node.h:265
bNodeSocketTemplate * inputs
Definition: BKE_node.h:236
char storagename[64]
Definition: BKE_node.h:238
float maxheight
Definition: BKE_node.h:232
NodeExecFunction exec_fn
Definition: BKE_node.h:319
bool(* poll_instance)(struct bNode *node, struct bNodeTree *nodetree, const char **r_disabled_hint)
Definition: BKE_node.h:305
void(* initfunc)(struct bNodeTree *ntree, struct bNode *node)
Definition: BKE_node.h:279
char idname[64]
Definition: BKE_node.h:224
void(* copyfunc_api)(struct PointerRNA *ptr, const struct bNode *src_node)
Definition: BKE_node.h:290
NodeFreeExecFunction free_exec_fn
Definition: BKE_node.h:318
short level
struct bNode * new_node
float locy
int update
IDProperty * prop
ListBase inputs
struct bNodeType * typeinfo
struct ID * id
struct bNode * parent
ListBase internal_links
float locx
char iter_flag
short done
short type
struct bNode * next
ListBase outputs
__forceinline const avxb select(const avxb &m, const avxb &t, const avxb &f)
Definition: util_avxb.h:167
PointerRNA * ptr
Definition: wm_files.c:3157