Blender  V3.3
node.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2005 Blender Foundation. All rights reserved. */
3 
8 #include "CLG_log.h"
9 
10 #include "MEM_guardedalloc.h"
11 
12 #include <climits>
13 #include <cstddef>
14 #include <cstdlib>
15 #include <cstring>
16 
17 /* Allow using deprecated functionality for .blend file I/O. */
18 #define DNA_DEPRECATED_ALLOW
19 
20 #include "DNA_action_types.h"
21 #include "DNA_anim_types.h"
22 #include "DNA_collection_types.h"
23 #include "DNA_gpencil_types.h"
24 #include "DNA_light_types.h"
25 #include "DNA_linestyle_types.h"
26 #include "DNA_material_types.h"
27 #include "DNA_modifier_types.h"
28 #include "DNA_node_types.h"
29 #include "DNA_scene_types.h"
30 #include "DNA_simulation_types.h"
31 #include "DNA_texture_types.h"
32 #include "DNA_world_types.h"
33 
34 #include "BLI_color.hh"
35 #include "BLI_ghash.h"
36 #include "BLI_listbase.h"
37 #include "BLI_map.hh"
38 #include "BLI_path_util.h"
39 #include "BLI_set.hh"
40 #include "BLI_stack.hh"
41 #include "BLI_string.h"
42 #include "BLI_string_utils.h"
43 #include "BLI_threads.h"
44 #include "BLI_utildefines.h"
45 #include "BLI_vector_set.hh"
46 #include "BLT_translation.h"
47 
48 #include "BKE_anim_data.h"
49 #include "BKE_animsys.h"
50 #include "BKE_bpath.h"
51 #include "BKE_colortools.h"
52 #include "BKE_context.h"
53 #include "BKE_cryptomatte.h"
54 #include "BKE_global.h"
55 #include "BKE_icons.h"
56 #include "BKE_idprop.h"
57 #include "BKE_idtype.h"
58 #include "BKE_image_format.h"
59 #include "BKE_lib_id.h"
60 #include "BKE_lib_query.h"
61 #include "BKE_main.h"
62 #include "BKE_node.h"
63 #include "BKE_node_runtime.hh"
64 #include "BKE_node_tree_update.h"
65 
66 #include "RNA_access.h"
67 #include "RNA_define.h"
68 #include "RNA_prototypes.h"
69 
70 #include "NOD_common.h"
71 #include "NOD_composite.h"
72 #include "NOD_function.h"
73 #include "NOD_geometry.h"
74 #include "NOD_node_declaration.hh"
75 #include "NOD_node_tree_ref.hh"
76 #include "NOD_shader.h"
77 #include "NOD_socket.h"
78 #include "NOD_texture.h"
79 
80 #include "DEG_depsgraph.h"
81 #include "DEG_depsgraph_build.h"
82 
83 #include "BLO_read_write.h"
84 
85 #include "MOD_nodes.h"
86 
87 #define NODE_DEFAULT_MAX_WIDTH 700
88 
89 using blender::Array;
90 using blender::Map;
92 using blender::Set;
93 using blender::Span;
94 using blender::Stack;
95 using blender::StringRef;
96 using blender::Vector;
97 using blender::VectorSet;
108 
109 /* Fallback types for undefined tree, nodes, sockets */
113 
114 static CLG_LogRef LOG = {"bke.node"};
115 
116 static void ntree_set_typeinfo(bNodeTree *ntree, bNodeTreeType *typeinfo);
117 static void node_socket_copy(bNodeSocket *sock_dst, const bNodeSocket *sock_src, const int flag);
119 static void node_free_node(bNodeTree *ntree, bNode *node);
121  bNodeSocket *sock,
122  const bool do_id_user);
123 static void nodeMuteRerouteOutputLinks(struct bNodeTree *ntree,
124  struct bNode *node,
125  const bool mute);
126 
127 static void ntree_init_data(ID *id)
128 {
129  bNodeTree *ntree = (bNodeTree *)id;
130  ntree->runtime = MEM_new<bNodeTreeRuntime>(__func__);
131  ntree_set_typeinfo(ntree, nullptr);
132 }
133 
134 static void ntree_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
135 {
136  bNodeTree *ntree_dst = (bNodeTree *)id_dst;
137  const bNodeTree *ntree_src = (const bNodeTree *)id_src;
138 
139  /* We never handle usercount here for own data. */
140  const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
141 
142  ntree_dst->runtime = MEM_new<bNodeTreeRuntime>(__func__);
143 
144  /* in case a running nodetree is copied */
145  ntree_dst->execdata = nullptr;
146 
147  BLI_listbase_clear(&ntree_dst->nodes);
148  BLI_listbase_clear(&ntree_dst->links);
149 
152 
153  BLI_listbase_clear(&ntree_dst->nodes);
154  LISTBASE_FOREACH (const bNode *, src_node, &ntree_src->nodes) {
155  /* Don't find a unique name for every node, since they should have valid names already. */
157  ntree_dst, *src_node, flag_subdata, false, socket_map);
158  node_map.add(src_node, new_node);
159  }
160 
161  /* copy links */
162  BLI_listbase_clear(&ntree_dst->links);
163  LISTBASE_FOREACH (const bNodeLink *, src_link, &ntree_src->links) {
164  bNodeLink *dst_link = (bNodeLink *)MEM_dupallocN(src_link);
165  dst_link->fromnode = node_map.lookup(src_link->fromnode);
166  dst_link->fromsock = socket_map.lookup(src_link->fromsock);
167  dst_link->tonode = node_map.lookup(src_link->tonode);
168  dst_link->tosock = socket_map.lookup(src_link->tosock);
169  BLI_assert(dst_link->tosock);
170  dst_link->tosock->link = dst_link;
171  BLI_addtail(&ntree_dst->links, dst_link);
172  }
173 
174  /* copy interface sockets */
175  BLI_listbase_clear(&ntree_dst->inputs);
176  LISTBASE_FOREACH (const bNodeSocket *, src_socket, &ntree_src->inputs) {
177  bNodeSocket *dst_socket = (bNodeSocket *)MEM_dupallocN(src_socket);
178  node_socket_copy(dst_socket, src_socket, flag_subdata);
179  BLI_addtail(&ntree_dst->inputs, dst_socket);
180  }
181  BLI_listbase_clear(&ntree_dst->outputs);
182  LISTBASE_FOREACH (const bNodeSocket *, src_socket, &ntree_src->outputs) {
183  bNodeSocket *dst_socket = (bNodeSocket *)MEM_dupallocN(src_socket);
184  node_socket_copy(dst_socket, src_socket, flag_subdata);
185  BLI_addtail(&ntree_dst->outputs, dst_socket);
186  }
187 
188  /* copy preview hash */
189  if (ntree_src->previews && (flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
191 
192  ntree_dst->previews = BKE_node_instance_hash_new("node previews");
193 
194  NODE_INSTANCE_HASH_ITER (iter, ntree_src->previews) {
198  }
199  }
200  else {
201  ntree_dst->previews = nullptr;
202  }
203 
204  /* update node->parent pointers */
205  LISTBASE_FOREACH (bNode *, new_node, &ntree_dst->nodes) {
206  if (new_node->parent) {
207  new_node->parent = node_map.lookup(new_node->parent);
208  }
209  }
210  /* node tree will generate its own interface type */
211  ntree_dst->interface_type = nullptr;
212 
213  if (ntree_src->runtime->field_inferencing_interface) {
214  ntree_dst->runtime->field_inferencing_interface = std::make_unique<FieldInferencingInterface>(
215  *ntree_src->runtime->field_inferencing_interface);
216  }
217 
218  if (flag & LIB_ID_COPY_NO_PREVIEW) {
219  ntree_dst->preview = nullptr;
220  }
221  else {
222  BKE_previewimg_id_copy(&ntree_dst->id, &ntree_src->id);
223  }
224 }
225 
226 static void ntree_free_data(ID *id)
227 {
228  bNodeTree *ntree = (bNodeTree *)id;
229 
230  /* XXX hack! node trees should not store execution graphs at all.
231  * This should be removed when old tree types no longer require it.
232  * Currently the execution data for texture nodes remains in the tree
233  * after execution, until the node tree is updated or freed. */
234  if (ntree->execdata) {
235  switch (ntree->type) {
236  case NTREE_SHADER:
238  break;
239  case NTREE_TEXTURE:
241  ntree->execdata = nullptr;
242  break;
243  }
244  }
245 
246  /* XXX not nice, but needed to free localized node groups properly */
248 
249  /* Unregister associated RNA types. */
251 
253 
256  }
257 
258  /* free interface sockets */
260  node_socket_interface_free(ntree, sock, false);
261  MEM_freeN(sock);
262  }
264  node_socket_interface_free(ntree, sock, false);
265  MEM_freeN(sock);
266  }
267 
268  /* free preview hash */
269  if (ntree->previews) {
271  }
272 
273  if (ntree->id.tag & LIB_TAG_LOCALIZED) {
275  }
276 
278  MEM_delete(ntree->runtime);
279 }
280 
282 {
284  data,
287 
288  switch ((eNodeSocketDatatype)sock->type) {
289  case SOCK_OBJECT: {
292  break;
293  }
294  case SOCK_IMAGE: {
297  break;
298  }
299  case SOCK_COLLECTION: {
301  sock->default_value;
303  break;
304  }
305  case SOCK_TEXTURE: {
308  break;
309  }
310  case SOCK_MATERIAL: {
313  break;
314  }
315  case SOCK_FLOAT:
316  case SOCK_VECTOR:
317  case SOCK_RGBA:
318  case SOCK_BOOLEAN:
319  case SOCK_INT:
320  case SOCK_STRING:
321  case __SOCK_MESH:
322  case SOCK_CUSTOM:
323  case SOCK_SHADER:
324  case SOCK_GEOMETRY:
325  break;
326  }
327 }
328 
330 {
331  bNodeTree *ntree = (bNodeTree *)id;
332 
334 
337 
339  data,
343  data));
344  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
346  }
347  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
349  }
350  }
351 
354  }
357  }
358 }
359 
360 static void node_foreach_cache(ID *id,
361  IDTypeForeachCacheFunctionCallback function_callback,
362  void *user_data)
363 {
364  bNodeTree *nodetree = (bNodeTree *)id;
365  IDCacheKey key = {0};
366  key.id_session_uuid = id->session_uuid;
367  key.offset_in_ID = offsetof(bNodeTree, previews);
368 
369  /* TODO: see also `direct_link_nodetree()` in readfile.c. */
370 #if 0
371  function_callback(id, &key, (void **)&nodetree->previews, 0, user_data);
372 #endif
373 
374  if (nodetree->type == NTREE_COMPOSIT) {
375  LISTBASE_FOREACH (bNode *, node, &nodetree->nodes) {
376  if (node->type == CMP_NODE_MOVIEDISTORTION) {
377  key.offset_in_ID = (size_t)BLI_ghashutil_strhash_p(node->name);
378  function_callback(id, &key, (void **)&node->storage, 0, user_data);
379  }
380  }
381  }
382 }
383 
384 static void node_foreach_path(ID *id, BPathForeachPathData *bpath_data)
385 {
386  bNodeTree *ntree = reinterpret_cast<bNodeTree *>(id);
387 
388  switch (ntree->type) {
389  case NTREE_SHADER: {
391  if (node->type == SH_NODE_SCRIPT) {
392  NodeShaderScript *nss = reinterpret_cast<NodeShaderScript *>(node->storage);
394  }
395  else if (node->type == SH_NODE_TEX_IES) {
396  NodeShaderTexIES *ies = reinterpret_cast<NodeShaderTexIES *>(node->storage);
398  }
399  }
400  break;
401  }
402  default:
403  break;
404  }
405 }
406 
407 static ID *node_owner_get(Main *bmain, ID *id, ID *owner_id_hint)
408 {
409  if ((id->flag & LIB_EMBEDDED_DATA) == 0) {
410  return id;
411  }
412  /* TODO: Sort this NO_MAIN or not for embedded node trees. See T86119. */
413  // BLI_assert((id->tag & LIB_TAG_NO_MAIN) == 0);
414 
415  bNodeTree *ntree = reinterpret_cast<bNodeTree *>(id);
416 
417  if (owner_id_hint != nullptr && ntreeFromID(owner_id_hint) == ntree) {
418  return owner_id_hint;
419  }
420 
421  ListBase *lists[] = {&bmain->materials,
422  &bmain->lights,
423  &bmain->worlds,
424  &bmain->textures,
425  &bmain->scenes,
426  &bmain->linestyles,
427  &bmain->simulations,
428  nullptr};
429 
430  for (int i = 0; lists[i] != nullptr; i++) {
431  LISTBASE_FOREACH (ID *, id_iter, lists[i]) {
432  if (ntreeFromID(id_iter) == ntree) {
433  return id_iter;
434  }
435  }
436  }
437 
438  BLI_assert_msg(0, "Embedded node tree with no owner. Critical Main inconsistency.");
439  return nullptr;
440 }
441 
443 {
444  if (sock->default_value == nullptr) {
445  return;
446  }
447 
448  switch ((eNodeSocketDatatype)sock->type) {
449  case SOCK_FLOAT:
451  break;
452  case SOCK_VECTOR:
454  break;
455  case SOCK_RGBA:
457  break;
458  case SOCK_BOOLEAN:
460  break;
461  case SOCK_INT:
463  break;
464  case SOCK_STRING:
466  break;
467  case SOCK_OBJECT:
469  break;
470  case SOCK_IMAGE:
472  break;
473  case SOCK_COLLECTION:
475  break;
476  case SOCK_TEXTURE:
478  break;
479  case SOCK_MATERIAL:
481  break;
482  case SOCK_CUSTOM:
483  /* Custom node sockets where default_value is defined uses custom properties for storage. */
484  break;
485  case __SOCK_MESH:
486  case SOCK_SHADER:
487  case SOCK_GEOMETRY:
489  break;
490  }
491 }
492 
493 static void write_node_socket(BlendWriter *writer, bNodeSocket *sock)
494 {
495  BLO_write_struct(writer, bNodeSocket, sock);
496 
497  if (sock->prop) {
498  IDP_BlendWrite(writer, sock->prop);
499  }
500 
501  /* This property should only be used for group node "interface" sockets. */
502  BLI_assert(sock->default_attribute_name == nullptr);
503 
504  write_node_socket_default_value(writer, sock);
505 }
507 {
508  BLO_write_struct(writer, bNodeSocket, sock);
509 
510  if (sock->prop) {
511  IDP_BlendWrite(writer, sock->prop);
512  }
513 
515 
516  write_node_socket_default_value(writer, sock);
517 }
518 
520 {
521  BKE_id_blend_write(writer, &ntree->id);
522 
523  if (ntree->adt) {
525  }
526 
528  BLO_write_struct(writer, bNode, node);
529 
530  if (node->prop) {
531  IDP_BlendWrite(writer, node->prop);
532  }
533 
534  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
535  write_node_socket(writer, sock);
536  }
537  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
538  write_node_socket(writer, sock);
539  }
540 
541  LISTBASE_FOREACH (bNodeLink *, link, &node->internal_links) {
542  BLO_write_struct(writer, bNodeLink, link);
543  }
544 
545  if (node->storage) {
548  BKE_curvemapping_blend_write(writer, (const CurveMapping *)node->storage);
549  }
550  else if (ntree->type == NTREE_SHADER && (node->type == SH_NODE_SCRIPT)) {
551  NodeShaderScript *nss = (NodeShaderScript *)node->storage;
552  if (nss->bytecode) {
553  BLO_write_string(writer, nss->bytecode);
554  }
555  BLO_write_struct_by_name(writer, node->typeinfo->storagename, node->storage);
556  }
557  else if ((ntree->type == NTREE_COMPOSIT) && ELEM(node->type,
562  BKE_curvemapping_blend_write(writer, (const CurveMapping *)node->storage);
563  }
564  else if ((ntree->type == NTREE_TEXTURE) &&
566  BKE_curvemapping_blend_write(writer, (const CurveMapping *)node->storage);
567  }
568  else if ((ntree->type == NTREE_COMPOSIT) && (node->type == CMP_NODE_MOVIEDISTORTION)) {
569  /* pass */
570  }
571  else if ((ntree->type == NTREE_COMPOSIT) && (node->type == CMP_NODE_GLARE)) {
572  /* Simple forward compatibility for fix for T50736.
573  * Not ideal (there is no ideal solution here), but should do for now. */
574  NodeGlare *ndg = (NodeGlare *)node->storage;
575  /* Not in undo case. */
576  if (!BLO_write_is_undo(writer)) {
577  switch (ndg->type) {
578  case 2: /* Grrrr! magic numbers :( */
579  ndg->angle = ndg->streaks;
580  break;
581  case 0:
582  ndg->angle = ndg->star_45;
583  break;
584  default:
585  break;
586  }
587  }
588  BLO_write_struct_by_name(writer, node->typeinfo->storagename, node->storage);
589  }
590  else if ((ntree->type == NTREE_COMPOSIT) &&
592  NodeCryptomatte *nc = (NodeCryptomatte *)node->storage;
593  BLO_write_string(writer, nc->matte_id);
594  LISTBASE_FOREACH (CryptomatteEntry *, entry, &nc->entries) {
595  BLO_write_struct(writer, CryptomatteEntry, entry);
596  }
597  BLO_write_struct_by_name(writer, node->typeinfo->storagename, node->storage);
598  }
599  else if (node->type == FN_NODE_INPUT_STRING) {
600  NodeInputString *storage = (NodeInputString *)node->storage;
601  if (storage->string) {
602  BLO_write_string(writer, storage->string);
603  }
604  BLO_write_struct_by_name(writer, node->typeinfo->storagename, storage);
605  }
606  else if (node->typeinfo != &NodeTypeUndefined) {
607  BLO_write_struct_by_name(writer, node->typeinfo->storagename, node->storage);
608  }
609  }
610 
611  if (node->type == CMP_NODE_OUTPUT_FILE) {
612  /* Inputs have their own storage data. */
613  NodeImageMultiFile *nimf = (NodeImageMultiFile *)node->storage;
614  BKE_image_format_blend_write(writer, &nimf->format);
615 
616  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
617  NodeImageMultiFileSocket *sockdata = (NodeImageMultiFileSocket *)sock->storage;
618  BLO_write_struct(writer, NodeImageMultiFileSocket, sockdata);
619  BKE_image_format_blend_write(writer, &sockdata->format);
620  }
621  }
622  if (ELEM(node->type, CMP_NODE_IMAGE, CMP_NODE_R_LAYERS)) {
623  /* Write extra socket info. */
624  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
625  BLO_write_struct(writer, NodeImageLayer, sock->storage);
626  }
627  }
628  }
629 
630  LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
631  BLO_write_struct(writer, bNodeLink, link);
632  }
633 
635  write_node_socket_interface(writer, sock);
636  }
638  write_node_socket_interface(writer, sock);
639  }
640 
642 }
643 
644 static void ntree_blend_write(BlendWriter *writer, ID *id, const void *id_address)
645 {
646  bNodeTree *ntree = (bNodeTree *)id;
647 
648  /* Clean up, important in undo case to reduce false detection of changed datablocks. */
649  ntree->is_updating = false;
650  ntree->typeinfo = nullptr;
651  ntree->interface_type = nullptr;
652  ntree->progress = nullptr;
653  ntree->execdata = nullptr;
654 
655  BLO_write_id_struct(writer, bNodeTree, id_address, &ntree->id);
656 
657  ntreeBlendWrite(writer, ntree);
658 }
659 
661 {
662  BLO_read_data_address(reader, &sock->prop);
663  IDP_BlendDataRead(reader, &sock->prop);
664 
665  BLO_read_data_address(reader, &sock->link);
666  sock->typeinfo = nullptr;
667  BLO_read_data_address(reader, &sock->storage);
668  BLO_read_data_address(reader, &sock->default_value);
670  sock->total_inputs = 0; /* Clear runtime data set before drawing. */
671  sock->cache = nullptr;
672  sock->runtime = MEM_new<bNodeSocketRuntime>(__func__);
673 }
674 
676 {
677  /* NOTE: writing and reading goes in sync, for speed. */
678  ntree->is_updating = false;
679  ntree->typeinfo = nullptr;
680  ntree->interface_type = nullptr;
681 
682  ntree->progress = nullptr;
683  ntree->execdata = nullptr;
684  ntree->runtime = MEM_new<bNodeTreeRuntime>(__func__);
686 
687  BLO_read_data_address(reader, &ntree->adt);
689 
690  BLO_read_list(reader, &ntree->nodes);
692  node->runtime = MEM_new<bNodeRuntime>(__func__);
693  node->typeinfo = nullptr;
694 
695  BLO_read_list(reader, &node->inputs);
696  BLO_read_list(reader, &node->outputs);
697 
698  BLO_read_data_address(reader, &node->prop);
699  IDP_BlendDataRead(reader, &node->prop);
700 
701  BLO_read_list(reader, &node->internal_links);
702  LISTBASE_FOREACH (bNodeLink *, link, &node->internal_links) {
703  BLO_read_data_address(reader, &link->fromnode);
704  BLO_read_data_address(reader, &link->fromsock);
705  BLO_read_data_address(reader, &link->tonode);
706  BLO_read_data_address(reader, &link->tosock);
707  }
708 
709  if (node->type == CMP_NODE_MOVIEDISTORTION) {
710  /* Do nothing, this is runtime cache and hence handled by generic code using
711  * `IDTypeInfo.foreach_cache` callback. */
712  }
713  else {
714  BLO_read_data_address(reader, &node->storage);
715  }
716 
717  if (node->storage) {
718  switch (node->type) {
719  case SH_NODE_CURVE_VEC:
720  case SH_NODE_CURVE_RGB:
721  case SH_NODE_CURVE_FLOAT:
722  case CMP_NODE_TIME:
723  case CMP_NODE_CURVE_VEC:
724  case CMP_NODE_CURVE_RGB:
725  case CMP_NODE_HUECORRECT:
726  case TEX_NODE_CURVE_RGB:
727  case TEX_NODE_CURVE_TIME: {
728  BKE_curvemapping_blend_read(reader, (CurveMapping *)node->storage);
729  break;
730  }
731  case SH_NODE_SCRIPT: {
732  NodeShaderScript *nss = (NodeShaderScript *)node->storage;
733  BLO_read_data_address(reader, &nss->bytecode);
734  break;
735  }
738  npd->pd = blender::dna::shallow_zero_initialize();
739  break;
740  }
741  case SH_NODE_TEX_IMAGE: {
742  NodeTexImage *tex = (NodeTexImage *)node->storage;
743  tex->iuser.scene = nullptr;
744  break;
745  }
748  tex->iuser.scene = nullptr;
749  break;
750  }
751  case CMP_NODE_IMAGE:
752  case CMP_NODE_R_LAYERS:
753  case CMP_NODE_VIEWER:
754  case CMP_NODE_SPLITVIEWER: {
755  ImageUser *iuser = (ImageUser *)node->storage;
756  iuser->scene = nullptr;
757  break;
758  }
760  case CMP_NODE_CRYPTOMATTE: {
761  NodeCryptomatte *nc = (NodeCryptomatte *)node->storage;
762  BLO_read_data_address(reader, &nc->matte_id);
763  BLO_read_list(reader, &nc->entries);
765  break;
766  }
767  case TEX_NODE_IMAGE: {
768  ImageUser *iuser = (ImageUser *)node->storage;
769  iuser->scene = nullptr;
770  break;
771  }
772  case CMP_NODE_OUTPUT_FILE: {
773  NodeImageMultiFile *nimf = (NodeImageMultiFile *)node->storage;
775  break;
776  }
777  case FN_NODE_INPUT_STRING: {
778  NodeInputString *storage = (NodeInputString *)node->storage;
779  BLO_read_data_address(reader, &storage->string);
780  break;
781  }
782  default:
783  break;
784  }
785  }
786  }
787  BLO_read_list(reader, &ntree->links);
788 
789  /* and we connect the rest */
791  BLO_read_data_address(reader, &node->parent);
792 
793  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
794  direct_link_node_socket(reader, sock);
795  }
796  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
797  direct_link_node_socket(reader, sock);
798  }
799 
800  /* Socket storage. */
801  if (node->type == CMP_NODE_OUTPUT_FILE) {
802  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
803  NodeImageMultiFileSocket *sockdata = (NodeImageMultiFileSocket *)sock->storage;
804  BKE_image_format_blend_read_data(reader, &sockdata->format);
805  }
806  }
807  }
808 
809  /* interface socket lists */
810  BLO_read_list(reader, &ntree->inputs);
811  BLO_read_list(reader, &ntree->outputs);
813  direct_link_node_socket(reader, sock);
814  }
816  direct_link_node_socket(reader, sock);
817  }
818 
819  LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
820  BLO_read_data_address(reader, &link->fromnode);
821  BLO_read_data_address(reader, &link->tonode);
822  BLO_read_data_address(reader, &link->fromsock);
823  BLO_read_data_address(reader, &link->tosock);
824  }
825 
826  /* TODO: should be dealt by new generic cache handling of IDs... */
827  ntree->previews = nullptr;
828 
831 
832  /* type verification is in lib-link */
833 }
834 
835 static void ntree_blend_read_data(BlendDataReader *reader, ID *id)
836 {
837  bNodeTree *ntree = (bNodeTree *)id;
838  ntreeBlendReadData(reader, ntree);
839 }
840 
842 {
843  IDP_BlendReadLib(reader, lib, sock->prop);
844 
845  /* This can happen for all socket types when a file is saved in an older version of Blender than
846  * it was originally created in (T86298). Some socket types still require a default value. The
847  * default value of those sockets will be created in `ntreeSetTypes`. */
848  if (sock->default_value == nullptr) {
849  return;
850  }
851 
852  switch ((eNodeSocketDatatype)sock->type) {
853  case SOCK_OBJECT: {
855  BLO_read_id_address(reader, lib, &default_value->value);
856  break;
857  }
858  case SOCK_IMAGE: {
860  BLO_read_id_address(reader, lib, &default_value->value);
861  break;
862  }
863  case SOCK_COLLECTION: {
865  sock->default_value;
866  BLO_read_id_address(reader, lib, &default_value->value);
867  break;
868  }
869  case SOCK_TEXTURE: {
871  BLO_read_id_address(reader, lib, &default_value->value);
872  break;
873  }
874  case SOCK_MATERIAL: {
876  BLO_read_id_address(reader, lib, &default_value->value);
877  break;
878  }
879  case SOCK_FLOAT:
880  case SOCK_VECTOR:
881  case SOCK_RGBA:
882  case SOCK_BOOLEAN:
883  case SOCK_INT:
884  case SOCK_STRING:
885  case __SOCK_MESH:
886  case SOCK_CUSTOM:
887  case SOCK_SHADER:
888  case SOCK_GEOMETRY:
889  break;
890  }
891 }
892 
893 static void lib_link_node_sockets(BlendLibReader *reader, Library *lib, ListBase *sockets)
894 {
895  LISTBASE_FOREACH (bNodeSocket *, sock, sockets) {
896  lib_link_node_socket(reader, lib, sock);
897  }
898 }
899 
900 void ntreeBlendReadLib(struct BlendLibReader *reader, struct bNodeTree *ntree)
901 {
902  Library *lib = ntree->id.lib;
903 
904  BLO_read_id_address(reader, lib, &ntree->gpd);
905 
907  /* Link ID Properties -- and copy this comment EXACTLY for easy finding
908  * of library blocks that implement this. */
909  IDP_BlendReadLib(reader, lib, node->prop);
910 
911  BLO_read_id_address(reader, lib, &node->id);
912 
913  lib_link_node_sockets(reader, lib, &node->inputs);
914  lib_link_node_sockets(reader, lib, &node->outputs);
915  }
916 
919 
920  /* Set node->typeinfo pointers. This is done in lib linking, after the
921  * first versioning that can change types still without functions that
922  * update the typeinfo pointers. Versioning after lib linking needs
923  * these top be valid. */
924  ntreeSetTypes(nullptr, ntree);
925 
926  /* For nodes with static socket layout, add/remove sockets as needed
927  * to match the static layout. */
928  if (!BLO_read_lib_is_undo(reader)) {
930  node_verify_sockets(ntree, node, false);
931  }
932  }
933 }
934 
935 static void ntree_blend_read_lib(BlendLibReader *reader, ID *id)
936 {
937  bNodeTree *ntree = (bNodeTree *)id;
938  ntreeBlendReadLib(reader, ntree);
939 }
940 
941 static void expand_node_socket(BlendExpander *expander, bNodeSocket *sock)
942 {
943  IDP_BlendReadExpand(expander, sock->prop);
944 
945  if (sock->default_value != nullptr) {
946 
947  switch ((eNodeSocketDatatype)sock->type) {
948  case SOCK_OBJECT: {
950  BLO_expand(expander, default_value->value);
951  break;
952  }
953  case SOCK_IMAGE: {
955  BLO_expand(expander, default_value->value);
956  break;
957  }
958  case SOCK_COLLECTION: {
960  sock->default_value;
961  BLO_expand(expander, default_value->value);
962  break;
963  }
964  case SOCK_TEXTURE: {
966  BLO_expand(expander, default_value->value);
967  break;
968  }
969  case SOCK_MATERIAL: {
971  BLO_expand(expander, default_value->value);
972  break;
973  }
974  case SOCK_FLOAT:
975  case SOCK_VECTOR:
976  case SOCK_RGBA:
977  case SOCK_BOOLEAN:
978  case SOCK_INT:
979  case SOCK_STRING:
980  case __SOCK_MESH:
981  case SOCK_CUSTOM:
982  case SOCK_SHADER:
983  case SOCK_GEOMETRY:
984  break;
985  }
986  }
987 }
988 
989 static void expand_node_sockets(BlendExpander *expander, ListBase *sockets)
990 {
991  LISTBASE_FOREACH (bNodeSocket *, sock, sockets) {
992  expand_node_socket(expander, sock);
993  }
994 }
995 
997 {
998  if (ntree->gpd) {
999  BLO_expand(expander, ntree->gpd);
1000  }
1001 
1003  if (node->id && !(node->type == CMP_NODE_R_LAYERS) &&
1004  !(node->type == CMP_NODE_CRYPTOMATTE && node->custom1 == CMP_CRYPTOMATTE_SRC_RENDER)) {
1005  BLO_expand(expander, node->id);
1006  }
1007 
1008  IDP_BlendReadExpand(expander, node->prop);
1009 
1010  expand_node_sockets(expander, &node->inputs);
1011  expand_node_sockets(expander, &node->outputs);
1012  }
1013 
1014  expand_node_sockets(expander, &ntree->inputs);
1015  expand_node_sockets(expander, &ntree->outputs);
1016 }
1017 
1018 static void ntree_blend_read_expand(BlendExpander *expander, ID *id)
1019 {
1020  bNodeTree *ntree = (bNodeTree *)id;
1021  ntreeBlendReadExpand(expander, ntree);
1022 }
1023 
1025  /* id_code */ ID_NT,
1026  /* id_filter */ FILTER_ID_NT,
1027  /* main_listbase_index */ INDEX_ID_NT,
1028  /* struct_size */ sizeof(bNodeTree),
1029  /* name */ "NodeTree",
1030  /* name_plural */ "node_groups",
1031  /* translation_context */ BLT_I18NCONTEXT_ID_NODETREE,
1032  /* flags */ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
1033  /* asset_type_info */ nullptr,
1034 
1035  /* init_data */ ntree_init_data,
1036  /* copy_data */ ntree_copy_data,
1037  /* free_data */ ntree_free_data,
1038  /* make_local */ nullptr,
1039  /* foreach_id */ node_foreach_id,
1040  /* foreach_cache */ node_foreach_cache,
1041  /* foreach_path */ node_foreach_path,
1042  /* owner_get */ node_owner_get,
1043 
1044  /* blend_write */ ntree_blend_write,
1045  /* blend_read_data */ ntree_blend_read_data,
1046  /* blend_read_lib */ ntree_blend_read_lib,
1047  /* blend_read_expand */ ntree_blend_read_expand,
1048 
1049  /* blend_read_undo_preserve */ nullptr,
1050 
1051  /* lib_override_apply_post */ nullptr,
1052 };
1053 
1055 {
1056  if (ntype->declare != nullptr) {
1057  node_verify_sockets(ntree, node, true);
1058  return;
1059  }
1060  bNodeSocketTemplate *sockdef;
1061 
1062  if (ntype->inputs) {
1063  sockdef = ntype->inputs;
1064  while (sockdef->type != -1) {
1066  sockdef++;
1067  }
1068  }
1069  if (ntype->outputs) {
1070  sockdef = ntype->outputs;
1071  while (sockdef->type != -1) {
1073  sockdef++;
1074  }
1075  }
1076 }
1077 
1078 /* NOTE: This function is called to initialize node data based on the type.
1079  * The bNodeType may not be registered at creation time of the node,
1080  * so this can be delayed until the node type gets registered.
1081  */
1082 static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
1083 {
1084  bNodeType *ntype = node->typeinfo;
1085  if (ntype == &NodeTypeUndefined) {
1086  return;
1087  }
1088 
1089  /* only do this once */
1090  if (node->flag & NODE_INIT) {
1091  return;
1092  }
1093 
1094  node->flag = NODE_SELECT | NODE_OPTIONS | ntype->flag;
1095  node->width = ntype->width;
1096  node->miniwidth = 42.0f;
1097  node->height = ntype->height;
1098  node->color[0] = node->color[1] = node->color[2] = 0.608; /* default theme color */
1099  /* initialize the node name with the node label.
1100  * NOTE: do this after the initfunc so nodes get their data set which may be used in naming
1101  * (node groups for example) */
1102  /* XXX Do not use nodeLabel() here, it returns translated content for UI,
1103  * which should *only* be used in UI, *never* in data...
1104  * Data have their own translation option!
1105  * This solution may be a bit rougher than nodeLabel()'s returned string, but it's simpler
1106  * than adding "do_translate" flags to this func (and labelfunc() as well). */
1107  BLI_strncpy(node->name, DATA_(ntype->ui_name), NODE_MAXSTR);
1109 
1111 
1112  if (ntype->initfunc != nullptr) {
1113  ntype->initfunc(ntree, node);
1114  }
1115 
1116  if (ntree->typeinfo->node_add_init != nullptr) {
1118  }
1119 
1120  if (node->id) {
1121  id_us_plus(node->id);
1122  }
1123 
1124  /* extra init callback */
1125  if (ntype->initfunc_api) {
1126  PointerRNA ptr;
1127  RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr);
1128 
1129  /* XXX WARNING: context can be nullptr in case nodes are added in do_versions.
1130  * Delayed init is not supported for nodes with context-based `initfunc_api` at the moment. */
1131  BLI_assert(C != nullptr);
1132  ntype->initfunc_api(C, &ptr);
1133  }
1134 
1135  node->flag |= NODE_INIT;
1136 }
1137 
1139 {
1140  if (typeinfo) {
1141  ntree->typeinfo = typeinfo;
1142  }
1143  else {
1145  }
1146 
1147  /* Deprecated integer type. */
1148  ntree->type = ntree->typeinfo->type;
1150 }
1151 
1152 static void node_set_typeinfo(const struct bContext *C,
1153  bNodeTree *ntree,
1154  bNode *node,
1155  bNodeType *typeinfo)
1156 {
1157  /* for nodes saved in older versions storage can get lost, make undefined then */
1158  if (node->flag & NODE_INIT) {
1159  if (typeinfo && typeinfo->storagename[0] && !node->storage) {
1160  typeinfo = nullptr;
1161  }
1162  }
1163 
1164  if (typeinfo) {
1165  node->typeinfo = typeinfo;
1166 
1167  /* deprecated integer type */
1168  node->type = typeinfo->type;
1169 
1170  /* initialize the node if necessary */
1171  node_init(C, ntree, node);
1172  }
1173  else {
1174  node->typeinfo = &NodeTypeUndefined;
1175  }
1176 }
1177 
1178 /* WARNING: default_value must either be null or match the typeinfo at this point.
1179  * This function is called both for initializing new sockets and after loading files.
1180  */
1182  bNodeSocket *sock,
1183  bNodeSocketType *typeinfo)
1184 {
1185  if (typeinfo) {
1186  sock->typeinfo = typeinfo;
1187 
1188  /* deprecated integer type */
1189  sock->type = typeinfo->type;
1190 
1191  if (sock->default_value == nullptr) {
1192  /* initialize the default_value pointer used by standard socket types */
1194  }
1195  }
1196  else {
1198  }
1200 }
1201 
1202 /* Set specific typeinfo pointers in all node trees on register/unregister */
1203 static void update_typeinfo(Main *bmain,
1204  const struct bContext *C,
1205  bNodeTreeType *treetype,
1206  bNodeType *nodetype,
1207  bNodeSocketType *socktype,
1208  bool unregister)
1209 {
1210  if (!bmain) {
1211  return;
1212  }
1213 
1214  FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
1215  if (treetype && STREQ(ntree->idname, treetype->idname)) {
1216  ntree_set_typeinfo(ntree, unregister ? nullptr : treetype);
1217  }
1218 
1219  /* initialize nodes */
1221  if (nodetype && STREQ(node->idname, nodetype->idname)) {
1222  node_set_typeinfo(C, ntree, node, unregister ? nullptr : nodetype);
1223  }
1224 
1225  /* initialize node sockets */
1226  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
1227  if (socktype && STREQ(sock->idname, socktype->idname)) {
1228  node_socket_set_typeinfo(ntree, sock, unregister ? nullptr : socktype);
1229  }
1230  }
1231  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
1232  if (socktype && STREQ(sock->idname, socktype->idname)) {
1233  node_socket_set_typeinfo(ntree, sock, unregister ? nullptr : socktype);
1234  }
1235  }
1236  }
1237 
1238  /* initialize tree sockets */
1239  LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->inputs) {
1240  if (socktype && STREQ(sock->idname, socktype->idname)) {
1241  node_socket_set_typeinfo(ntree, sock, unregister ? nullptr : socktype);
1242  }
1243  }
1244  LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->outputs) {
1245  if (socktype && STREQ(sock->idname, socktype->idname)) {
1246  node_socket_set_typeinfo(ntree, sock, unregister ? nullptr : socktype);
1247  }
1248  }
1249  }
1251 }
1252 
1253 void ntreeSetTypes(const struct bContext *C, bNodeTree *ntree)
1254 {
1256 
1259 
1260  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
1261  node_socket_set_typeinfo(ntree, sock, nodeSocketTypeFind(sock->idname));
1262  }
1263  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
1264  node_socket_set_typeinfo(ntree, sock, nodeSocketTypeFind(sock->idname));
1265  }
1266  }
1267 
1268  LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->inputs) {
1269  node_socket_set_typeinfo(ntree, sock, nodeSocketTypeFind(sock->idname));
1270  }
1271  LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->outputs) {
1272  node_socket_set_typeinfo(ntree, sock, nodeSocketTypeFind(sock->idname));
1273  }
1274 }
1275 
1276 static GHash *nodetreetypes_hash = nullptr;
1277 static GHash *nodetypes_hash = nullptr;
1278 static GHash *nodesockettypes_hash = nullptr;
1279 
1280 bNodeTreeType *ntreeTypeFind(const char *idname)
1281 {
1282  if (idname[0]) {
1284  if (nt) {
1285  return nt;
1286  }
1287  }
1288 
1289  return nullptr;
1290 }
1291 
1293 {
1295  /* XXX pass Main to register function? */
1296  /* Probably not. It is pretty much expected we want to update G_MAIN here I think -
1297  * or we'd want to update *all* active Mains, which we cannot do anyway currently. */
1298  update_typeinfo(G_MAIN, nullptr, nt, nullptr, nullptr, false);
1299 }
1300 
1301 /* callback for hash value free function */
1302 static void ntree_free_type(void *treetype_v)
1303 {
1304  bNodeTreeType *treetype = (bNodeTreeType *)treetype_v;
1305  /* XXX pass Main to unregister 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, treetype, nullptr, nullptr, true);
1309  MEM_freeN(treetype);
1310 }
1311 
1313 {
1315 }
1316 
1318 {
1319  return (ntree->typeinfo != &NodeTreeTypeUndefined);
1320 }
1321 
1323 {
1325 }
1326 
1327 bNodeType *nodeTypeFind(const char *idname)
1328 {
1329  if (idname[0]) {
1331  if (nt) {
1332  return nt;
1333  }
1334  }
1335 
1336  return nullptr;
1337 }
1338 
1339 /* callback for hash value free function */
1340 static void node_free_type(void *nodetype_v)
1341 {
1342  bNodeType *nodetype = (bNodeType *)nodetype_v;
1343  /* XXX pass Main to unregister function? */
1344  /* Probably not. It is pretty much expected we want to update G_MAIN here I think -
1345  * or we'd want to update *all* active Mains, which we cannot do anyway currently. */
1346  update_typeinfo(G_MAIN, nullptr, nullptr, nodetype, nullptr, true);
1347 
1348  delete nodetype->fixed_declaration;
1349  nodetype->fixed_declaration = nullptr;
1350 
1351  /* Can be null when the type is not dynamically allocated. */
1352  if (nodetype->free_self) {
1353  nodetype->free_self(nodetype);
1354  }
1355 }
1356 
1358 {
1359  /* debug only: basic verification of registered types */
1360  BLI_assert(nt->idname[0] != '\0');
1361  BLI_assert(nt->poll != nullptr);
1362 
1363  if (nt->declare && !nt->declaration_is_dynamic) {
1364  if (nt->fixed_declaration == nullptr) {
1367  nt->declare(builder);
1368  }
1369  }
1370 
1372  /* XXX pass Main to register function? */
1373  /* Probably not. It is pretty much expected we want to update G_MAIN here I think -
1374  * or we'd want to update *all* active Mains, which we cannot do anyway currently. */
1375  update_typeinfo(G_MAIN, nullptr, nullptr, nt, nullptr, false);
1376 }
1377 
1379 {
1381 }
1382 
1384 {
1385  return (node->typeinfo == &NodeTypeUndefined) ||
1386  ((ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) && node->id &&
1387  ID_IS_LINKED(node->id) && (node->id->tag & LIB_TAG_MISSING));
1388 }
1389 
1391 {
1393 }
1394 
1396 {
1397  if (idname[0]) {
1399  if (st) {
1400  return st;
1401  }
1402  }
1403 
1404  return nullptr;
1405 }
1406 
1407 /* callback for hash value free function */
1408 static void node_free_socket_type(void *socktype_v)
1409 {
1410  bNodeSocketType *socktype = (bNodeSocketType *)socktype_v;
1411  /* XXX pass Main to unregister function? */
1412  /* Probably not. It is pretty much expected we want to update G_MAIN here I think -
1413  * or we'd want to update *all* active Mains, which we cannot do anyway currently. */
1414  update_typeinfo(G_MAIN, nullptr, nullptr, nullptr, socktype, true);
1415 
1416  socktype->free_self(socktype);
1417 }
1418 
1420 {
1421  BLI_ghash_insert(nodesockettypes_hash, (void *)st->idname, st);
1422  /* XXX pass Main to register function? */
1423  /* Probably not. It is pretty much expected we want to update G_MAIN here I think -
1424  * or we'd want to update *all* active Mains, which we cannot do anyway currently. */
1425  update_typeinfo(G_MAIN, nullptr, nullptr, nullptr, st, false);
1426 }
1427 
1429 {
1431 }
1432 
1434 {
1435  return (sock->typeinfo != &NodeSocketTypeUndefined);
1436 }
1437 
1439 {
1441 }
1442 
1443 const char *nodeSocketTypeLabel(const bNodeSocketType *stype)
1444 {
1445  /* Use socket type name as a fallback if label is undefined. */
1446  return stype->label[0] != '\0' ? stype->label : RNA_struct_ui_name(stype->ext_socket.srna);
1447 }
1448 
1451  const char *identifier)
1452 {
1453  const ListBase *sockets = (in_out == SOCK_IN) ? &node->inputs : &node->outputs;
1454  LISTBASE_FOREACH (bNodeSocket *, sock, sockets) {
1455  if (STREQ(sock->identifier, identifier)) {
1456  return sock;
1457  }
1458  }
1459  return nullptr;
1460 }
1461 
1462 namespace blender::bke {
1463 
1465  const eNodeSocketInOut in_out,
1466  const StringRef name)
1467 {
1468  ListBase *sockets = (in_out == SOCK_IN) ? &node.inputs : &node.outputs;
1469  LISTBASE_FOREACH (bNodeSocket *, socket, sockets) {
1470  if (!(socket->flag & SOCK_UNAVAIL) && socket->name == name) {
1471  return socket;
1472  }
1473  }
1474  return nullptr;
1475 }
1476 
1478 {
1479  return node_find_enabled_socket(node, SOCK_IN, name);
1480 }
1481 
1483 {
1484  return node_find_enabled_socket(node, SOCK_OUT, name);
1485 }
1486 
1487 } // namespace blender::bke
1488 
1489 /* find unique socket identifier */
1490 static bool unique_identifier_check(void *arg, const char *identifier)
1491 {
1492  const ListBase *lb = (const ListBase *)arg;
1493  LISTBASE_FOREACH (bNodeSocket *, sock, lb) {
1494  if (STREQ(sock->identifier, identifier)) {
1495  return true;
1496  }
1497  }
1498  return false;
1499 }
1500 
1502  bNode *UNUSED(node),
1503  int in_out,
1504  ListBase *lb,
1505  const char *idname,
1506  const char *identifier,
1507  const char *name)
1508 {
1509  char auto_identifier[MAX_NAME];
1510 
1511  if (identifier && identifier[0] != '\0') {
1512  /* use explicit identifier */
1513  BLI_strncpy(auto_identifier, identifier, sizeof(auto_identifier));
1514  }
1515  else {
1516  /* if no explicit identifier is given, assign a unique identifier based on the name */
1517  BLI_strncpy(auto_identifier, name, sizeof(auto_identifier));
1518  }
1519  /* Make the identifier unique. */
1521  unique_identifier_check, lb, "socket", '_', auto_identifier, sizeof(auto_identifier));
1522 
1523  bNodeSocket *sock = MEM_cnew<bNodeSocket>("sock");
1524  sock->runtime = MEM_new<bNodeSocketRuntime>(__func__);
1525  sock->in_out = in_out;
1526 
1527  BLI_strncpy(sock->identifier, auto_identifier, NODE_MAXSTR);
1528  sock->limit = (in_out == SOCK_IN ? 1 : 0xFFF);
1529 
1530  BLI_strncpy(sock->name, name, NODE_MAXSTR);
1531  sock->storage = nullptr;
1532  sock->flag |= SOCK_COLLAPSED;
1533  sock->type = SOCK_CUSTOM; /* int type undefined by default */
1534 
1535  BLI_strncpy(sock->idname, idname, sizeof(sock->idname));
1537 
1538  return sock;
1539 }
1540 
1542 {
1543  switch ((eNodeSocketDatatype)sock->type) {
1544  case SOCK_OBJECT: {
1546  id_us_plus((ID *)default_value->value);
1547  break;
1548  }
1549  case SOCK_IMAGE: {
1550  bNodeSocketValueImage *default_value = (bNodeSocketValueImage *)sock->default_value;
1551  id_us_plus((ID *)default_value->value);
1552  break;
1553  }
1554  case SOCK_COLLECTION: {
1556  sock->default_value;
1557  id_us_plus((ID *)default_value->value);
1558  break;
1559  }
1560  case SOCK_TEXTURE: {
1562  id_us_plus((ID *)default_value->value);
1563  break;
1564  }
1565  case SOCK_MATERIAL: {
1567  id_us_plus((ID *)default_value->value);
1568  break;
1569  }
1570  case SOCK_FLOAT:
1571  case SOCK_VECTOR:
1572  case SOCK_RGBA:
1573  case SOCK_BOOLEAN:
1574  case SOCK_INT:
1575  case SOCK_STRING:
1576  case __SOCK_MESH:
1577  case SOCK_CUSTOM:
1578  case SOCK_SHADER:
1579  case SOCK_GEOMETRY:
1580  break;
1581  }
1582 }
1583 
1586 {
1587  switch ((eNodeSocketDatatype)sock->type) {
1588  case SOCK_OBJECT: {
1590  if (default_value->value != nullptr) {
1591  id_us_min(&default_value->value->id);
1592  return true;
1593  }
1594  break;
1595  }
1596  case SOCK_IMAGE: {
1597  bNodeSocketValueImage *default_value = (bNodeSocketValueImage *)sock->default_value;
1598  if (default_value->value != nullptr) {
1599  id_us_min(&default_value->value->id);
1600  return true;
1601  }
1602  break;
1603  }
1604  case SOCK_COLLECTION: {
1606  sock->default_value;
1607  if (default_value->value != nullptr) {
1608  id_us_min(&default_value->value->id);
1609  return true;
1610  }
1611  break;
1612  }
1613  case SOCK_TEXTURE: {
1615  if (default_value->value != nullptr) {
1616  id_us_min(&default_value->value->id);
1617  return true;
1618  }
1619  break;
1620  }
1621  case SOCK_MATERIAL: {
1623  if (default_value->value != nullptr) {
1624  id_us_min(&default_value->value->id);
1625  return true;
1626  }
1627  break;
1628  }
1629  case SOCK_FLOAT:
1630  case SOCK_VECTOR:
1631  case SOCK_RGBA:
1632  case SOCK_BOOLEAN:
1633  case SOCK_INT:
1634  case SOCK_STRING:
1635  case __SOCK_MESH:
1636  case SOCK_CUSTOM:
1637  case SOCK_SHADER:
1638  case SOCK_GEOMETRY:
1639  break;
1640  }
1641  return false;
1642 }
1643 
1645  bNode *UNUSED(node),
1646  bNodeSocket *sock,
1647  const char *idname)
1648 {
1649  bNodeSocketType *socktype = nodeSocketTypeFind(idname);
1650 
1651  if (!socktype) {
1652  CLOG_ERROR(&LOG, "node socket type %s undefined", idname);
1653  return;
1654  }
1655 
1656  if (sock->default_value) {
1658  MEM_freeN(sock->default_value);
1659  sock->default_value = nullptr;
1660  }
1661 
1662  BLI_strncpy(sock->idname, idname, sizeof(sock->idname));
1663  node_socket_set_typeinfo(ntree, sock, socktype);
1664 }
1665 
1667  bNodeTree *ntree, bNode *node, bNodeSocket *sock, int type, int subtype)
1668 {
1669  const char *idname = nodeStaticSocketType(type, subtype);
1670 
1671  if (!idname) {
1672  CLOG_ERROR(&LOG, "static node socket type %d undefined", type);
1673  return;
1674  }
1675 
1676  nodeModifySocketType(ntree, node, sock, idname);
1677 }
1678 
1680  bNode *node,
1681  eNodeSocketInOut in_out,
1682  const char *idname,
1683  const char *identifier,
1684  const char *name)
1685 {
1686  BLI_assert(node->type != NODE_FRAME);
1687  BLI_assert(!(in_out == SOCK_IN && node->type == NODE_GROUP_INPUT));
1688  BLI_assert(!(in_out == SOCK_OUT && node->type == NODE_GROUP_OUTPUT));
1689 
1690  ListBase *lb = (in_out == SOCK_IN ? &node->inputs : &node->outputs);
1691  bNodeSocket *sock = make_socket(ntree, node, in_out, lb, idname, identifier, name);
1692 
1693  BLI_remlink(lb, sock); /* does nothing for new socket */
1694  BLI_addtail(lb, sock);
1695 
1697 
1698  return sock;
1699 }
1700 
1701 bool nodeIsStaticSocketType(const struct bNodeSocketType *stype)
1702 {
1703  /*
1704  * Cannot rely on type==SOCK_CUSTOM here, because type is 0 by default
1705  * and can be changed on custom sockets.
1706  */
1707  return RNA_struct_is_a(stype->ext_socket.srna, &RNA_NodeSocketStandard);
1708 }
1709 
1710 const char *nodeStaticSocketType(int type, int subtype)
1711 {
1712  switch (type) {
1713  case SOCK_FLOAT:
1714  switch (subtype) {
1715  case PROP_UNSIGNED:
1716  return "NodeSocketFloatUnsigned";
1717  case PROP_PERCENTAGE:
1718  return "NodeSocketFloatPercentage";
1719  case PROP_FACTOR:
1720  return "NodeSocketFloatFactor";
1721  case PROP_ANGLE:
1722  return "NodeSocketFloatAngle";
1723  case PROP_TIME:
1724  return "NodeSocketFloatTime";
1725  case PROP_TIME_ABSOLUTE:
1726  return "NodeSocketFloatTimeAbsolute";
1727  case PROP_DISTANCE:
1728  return "NodeSocketFloatDistance";
1729  case PROP_NONE:
1730  default:
1731  return "NodeSocketFloat";
1732  }
1733  case SOCK_INT:
1734  switch (subtype) {
1735  case PROP_UNSIGNED:
1736  return "NodeSocketIntUnsigned";
1737  case PROP_PERCENTAGE:
1738  return "NodeSocketIntPercentage";
1739  case PROP_FACTOR:
1740  return "NodeSocketIntFactor";
1741  case PROP_NONE:
1742  default:
1743  return "NodeSocketInt";
1744  }
1745  case SOCK_BOOLEAN:
1746  return "NodeSocketBool";
1747  case SOCK_VECTOR:
1748  switch (subtype) {
1749  case PROP_TRANSLATION:
1750  return "NodeSocketVectorTranslation";
1751  case PROP_DIRECTION:
1752  return "NodeSocketVectorDirection";
1753  case PROP_VELOCITY:
1754  return "NodeSocketVectorVelocity";
1755  case PROP_ACCELERATION:
1756  return "NodeSocketVectorAcceleration";
1757  case PROP_EULER:
1758  return "NodeSocketVectorEuler";
1759  case PROP_XYZ:
1760  return "NodeSocketVectorXYZ";
1761  case PROP_NONE:
1762  default:
1763  return "NodeSocketVector";
1764  }
1765  case SOCK_RGBA:
1766  return "NodeSocketColor";
1767  case SOCK_STRING:
1768  return "NodeSocketString";
1769  case SOCK_SHADER:
1770  return "NodeSocketShader";
1771  case SOCK_OBJECT:
1772  return "NodeSocketObject";
1773  case SOCK_IMAGE:
1774  return "NodeSocketImage";
1775  case SOCK_GEOMETRY:
1776  return "NodeSocketGeometry";
1777  case SOCK_COLLECTION:
1778  return "NodeSocketCollection";
1779  case SOCK_TEXTURE:
1780  return "NodeSocketTexture";
1781  case SOCK_MATERIAL:
1782  return "NodeSocketMaterial";
1783  }
1784  return nullptr;
1785 }
1786 
1787 const char *nodeStaticSocketInterfaceType(int type, int subtype)
1788 {
1789  switch (type) {
1790  case SOCK_FLOAT:
1791  switch (subtype) {
1792  case PROP_UNSIGNED:
1793  return "NodeSocketInterfaceFloatUnsigned";
1794  case PROP_PERCENTAGE:
1795  return "NodeSocketInterfaceFloatPercentage";
1796  case PROP_FACTOR:
1797  return "NodeSocketInterfaceFloatFactor";
1798  case PROP_ANGLE:
1799  return "NodeSocketInterfaceFloatAngle";
1800  case PROP_TIME:
1801  return "NodeSocketInterfaceFloatTime";
1802  case PROP_TIME_ABSOLUTE:
1803  return "NodeSocketInterfaceFloatTimeAbsolute";
1804  case PROP_DISTANCE:
1805  return "NodeSocketInterfaceFloatDistance";
1806  case PROP_NONE:
1807  default:
1808  return "NodeSocketInterfaceFloat";
1809  }
1810  case SOCK_INT:
1811  switch (subtype) {
1812  case PROP_UNSIGNED:
1813  return "NodeSocketInterfaceIntUnsigned";
1814  case PROP_PERCENTAGE:
1815  return "NodeSocketInterfaceIntPercentage";
1816  case PROP_FACTOR:
1817  return "NodeSocketInterfaceIntFactor";
1818  case PROP_NONE:
1819  default:
1820  return "NodeSocketInterfaceInt";
1821  }
1822  case SOCK_BOOLEAN:
1823  return "NodeSocketInterfaceBool";
1824  case SOCK_VECTOR:
1825  switch (subtype) {
1826  case PROP_TRANSLATION:
1827  return "NodeSocketInterfaceVectorTranslation";
1828  case PROP_DIRECTION:
1829  return "NodeSocketInterfaceVectorDirection";
1830  case PROP_VELOCITY:
1831  return "NodeSocketInterfaceVectorVelocity";
1832  case PROP_ACCELERATION:
1833  return "NodeSocketInterfaceVectorAcceleration";
1834  case PROP_EULER:
1835  return "NodeSocketInterfaceVectorEuler";
1836  case PROP_XYZ:
1837  return "NodeSocketInterfaceVectorXYZ";
1838  case PROP_NONE:
1839  default:
1840  return "NodeSocketInterfaceVector";
1841  }
1842  case SOCK_RGBA:
1843  return "NodeSocketInterfaceColor";
1844  case SOCK_STRING:
1845  return "NodeSocketInterfaceString";
1846  case SOCK_SHADER:
1847  return "NodeSocketInterfaceShader";
1848  case SOCK_OBJECT:
1849  return "NodeSocketInterfaceObject";
1850  case SOCK_IMAGE:
1851  return "NodeSocketInterfaceImage";
1852  case SOCK_GEOMETRY:
1853  return "NodeSocketInterfaceGeometry";
1854  case SOCK_COLLECTION:
1855  return "NodeSocketInterfaceCollection";
1856  case SOCK_TEXTURE:
1857  return "NodeSocketInterfaceTexture";
1858  case SOCK_MATERIAL:
1859  return "NodeSocketInterfaceMaterial";
1860  }
1861  return nullptr;
1862 }
1863 
1864 const char *nodeStaticSocketLabel(int type, int UNUSED(subtype))
1865 {
1866  switch (type) {
1867  case SOCK_FLOAT:
1868  return "Float";
1869  case SOCK_INT:
1870  return "Integer";
1871  case SOCK_BOOLEAN:
1872  return "Boolean";
1873  case SOCK_VECTOR:
1874  return "Vector";
1875  case SOCK_RGBA:
1876  return "Color";
1877  case SOCK_STRING:
1878  return "String";
1879  case SOCK_SHADER:
1880  return "Shader";
1881  case SOCK_OBJECT:
1882  return "Object";
1883  case SOCK_IMAGE:
1884  return "Image";
1885  case SOCK_GEOMETRY:
1886  return "Geometry";
1887  case SOCK_COLLECTION:
1888  return "Collection";
1889  case SOCK_TEXTURE:
1890  return "Texture";
1891  case SOCK_MATERIAL:
1892  return "Material";
1893  }
1894  return nullptr;
1895 }
1896 
1898  bNode *node,
1899  eNodeSocketInOut in_out,
1900  int type,
1901  int subtype,
1902  const char *identifier,
1903  const char *name)
1904 {
1905  const char *idname = nodeStaticSocketType(type, subtype);
1906 
1907  if (!idname) {
1908  CLOG_ERROR(&LOG, "static node socket type %d undefined", type);
1909  return nullptr;
1910  }
1911 
1912  bNodeSocket *sock = nodeAddSocket(ntree, node, in_out, idname, identifier, name);
1913  sock->type = type;
1914  return sock;
1915 }
1916 
1917 static void node_socket_free(bNodeSocket *sock, const bool do_id_user)
1918 {
1919  if (sock->prop) {
1920  IDP_FreePropertyContent_ex(sock->prop, do_id_user);
1921  MEM_freeN(sock->prop);
1922  }
1923 
1924  if (sock->default_value) {
1925  if (do_id_user) {
1927  }
1928  MEM_freeN(sock->default_value);
1929  }
1930  MEM_delete(sock->runtime);
1931 }
1932 
1934 {
1935  nodeRemoveSocketEx(ntree, node, sock, true);
1936 }
1937 
1939  struct bNode *node,
1940  struct bNodeSocket *sock,
1941  bool do_id_user)
1942 {
1944  if (link->fromsock == sock || link->tosock == sock) {
1945  nodeRemLink(ntree, link);
1946  }
1947  }
1948 
1949  LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &node->internal_links) {
1950  if (link->fromsock == sock || link->tosock == sock) {
1951  BLI_remlink(&node->internal_links, link);
1952  MEM_freeN(link);
1954  }
1955  }
1956 
1957  /* this is fast, this way we don't need an in_out argument */
1958  BLI_remlink(&node->inputs, sock);
1959  BLI_remlink(&node->outputs, sock);
1960 
1961  node_socket_free(sock, do_id_user);
1962  MEM_freeN(sock);
1963 
1965 }
1966 
1968 {
1970  if (link->fromnode == node || link->tonode == node) {
1971  nodeRemLink(ntree, link);
1972  }
1973  }
1974 
1975  BLI_freelistN(&node->internal_links);
1976 
1977  LISTBASE_FOREACH_MUTABLE (bNodeSocket *, sock, &node->inputs) {
1978  node_socket_free(sock, true);
1979  MEM_freeN(sock);
1980  }
1981  BLI_listbase_clear(&node->inputs);
1982 
1983  LISTBASE_FOREACH_MUTABLE (bNodeSocket *, sock, &node->outputs) {
1984  node_socket_free(sock, true);
1985  MEM_freeN(sock);
1986  }
1987  BLI_listbase_clear(&node->outputs);
1988 
1990 }
1991 
1993 {
1994  return (bNode *)BLI_findstring(&ntree->nodes, name, offsetof(bNode, name));
1995 }
1996 
1997 bool nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **r_node, int *r_sockindex)
1998 {
1999  *r_node = nullptr;
2000 
2002  ListBase *sockets = (sock->in_out == SOCK_IN) ? &node->inputs : &node->outputs;
2003  int index = 0;
2004  LISTBASE_FOREACH (bNodeSocket *, tsock, sockets) {
2005  if (sock == tsock) {
2006  if (r_node != nullptr) {
2007  *r_node = node;
2008  }
2009  if (r_sockindex != nullptr) {
2010  *r_sockindex = index;
2011  }
2012  return true;
2013  }
2014  index++;
2015  }
2016  }
2017  return false;
2018 }
2019 
2021 {
2022  if (node->parent) {
2023  return nodeFindRootParent(node->parent);
2024  }
2025  return node->type == NODE_FRAME ? node : nullptr;
2026 }
2027 
2028 bool nodeIsChildOf(const bNode *parent, const bNode *child)
2029 {
2030  if (parent == child) {
2031  return true;
2032  }
2033  if (child->parent) {
2034  return nodeIsChildOf(parent, child->parent);
2035  }
2036  return false;
2037 }
2038 
2040  const bNode *node_start,
2041  bool (*callback)(bNode *, bNode *, void *, const bool),
2042  void *userdata,
2043  const bool reversed)
2044 {
2045  LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
2046  if ((link->flag & NODE_LINK_VALID) == 0) {
2047  /* Skip links marked as cyclic. */
2048  continue;
2049  }
2050  if (link->tonode && link->fromnode) {
2051  /* Is the link part of the chain meaning node_start == fromnode
2052  * (or tonode for reversed case)? */
2053  if ((reversed && (link->tonode == node_start)) ||
2054  (!reversed && link->fromnode == node_start)) {
2055  if (!callback(link->fromnode, link->tonode, userdata, reversed)) {
2056  return;
2057  }
2058  nodeChainIter(
2059  ntree, reversed ? link->fromnode : link->tonode, callback, userdata, reversed);
2060  }
2061  }
2062  }
2063 }
2064 
2065 static void iter_backwards_ex(const bNodeTree *ntree,
2066  const bNode *node_start,
2067  bool (*callback)(bNode *, bNode *, void *),
2068  void *userdata,
2069  char recursion_mask)
2070 {
2071  LISTBASE_FOREACH (bNodeSocket *, sock, &node_start->inputs) {
2072  bNodeLink *link = sock->link;
2073  if (link == nullptr) {
2074  continue;
2075  }
2076  if ((link->flag & NODE_LINK_VALID) == 0) {
2077  /* Skip links marked as cyclic. */
2078  continue;
2079  }
2080  if (link->fromnode->iter_flag & recursion_mask) {
2081  continue;
2082  }
2083 
2084  link->fromnode->iter_flag |= recursion_mask;
2085 
2086  if (!callback(link->fromnode, link->tonode, userdata)) {
2087  return;
2088  }
2089  iter_backwards_ex(ntree, link->fromnode, callback, userdata, recursion_mask);
2090  }
2091 }
2092 
2094  const bNode *node_start,
2095  bool (*callback)(bNode *, bNode *, void *),
2096  void *userdata,
2097  int recursion_lvl)
2098 {
2099  if (!node_start) {
2100  return;
2101  }
2102 
2103  /* Limited by iter_flag type. */
2104  BLI_assert(recursion_lvl < 8);
2105  char recursion_mask = (1 << recursion_lvl);
2106 
2107  /* Reset flag. */
2109  node->iter_flag &= ~recursion_mask;
2110  }
2111 
2112  iter_backwards_ex(ntree, node_start, callback, userdata, recursion_mask);
2113 }
2114 
2115 void nodeParentsIter(bNode *node, bool (*callback)(bNode *, void *), void *userdata)
2116 {
2117  if (node->parent) {
2118  if (!callback(node->parent, userdata)) {
2119  return;
2120  }
2121  nodeParentsIter(node->parent, callback, userdata);
2122  }
2123 }
2124 
2125 /* ************** Add stuff ********** */
2126 
2128 {
2130  &ntree->nodes, node, DATA_("Node"), '.', offsetof(bNode, name), sizeof(node->name));
2131 }
2132 
2133 bNode *nodeAddNode(const struct bContext *C, bNodeTree *ntree, const char *idname)
2134 {
2135  bNode *node = MEM_cnew<bNode>("new node");
2136  node->runtime = MEM_new<bNodeRuntime>(__func__);
2138 
2139  BLI_strncpy(node->idname, idname, sizeof(node->idname));
2141 
2143 
2144  if (node->type == GEO_NODE_INPUT_SCENE_TIME) {
2146  }
2147 
2148  return node;
2149 }
2150 
2152 {
2153  const char *idname = nullptr;
2154 
2155  NODE_TYPES_BEGIN (ntype) {
2156  /* Do an extra poll here, because some int types are used
2157  * for multiple node types, this helps find the desired type. */
2158  const char *disabled_hint;
2159  if (ntype->type == type && (!ntype->poll || ntype->poll(ntype, ntree, &disabled_hint))) {
2160  idname = ntype->idname;
2161  break;
2162  }
2163  }
2165  if (!idname) {
2166  CLOG_ERROR(&LOG, "static node type %d undefined", type);
2167  return nullptr;
2168  }
2169  return nodeAddNode(C, ntree, idname);
2170 }
2171 
2172 static void node_socket_copy(bNodeSocket *sock_dst, const bNodeSocket *sock_src, const int flag)
2173 {
2174  sock_dst->runtime = MEM_new<bNodeSocketRuntime>(__func__);
2175  if (sock_src->prop) {
2176  sock_dst->prop = IDP_CopyProperty_ex(sock_src->prop, flag);
2177  }
2178 
2179  if (sock_src->default_value) {
2180  sock_dst->default_value = MEM_dupallocN(sock_src->default_value);
2181 
2182  if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
2183  socket_id_user_increment(sock_dst);
2184  }
2185  }
2186 
2187  sock_dst->default_attribute_name = static_cast<char *>(
2189 
2190  sock_dst->stack_index = 0;
2191  /* XXX some compositor nodes (e.g. image, render layers) still store
2192  * some persistent buffer data here, need to clear this to avoid dangling pointers. */
2193  sock_dst->cache = nullptr;
2194 }
2195 
2196 namespace blender::bke {
2197 
2199  const bNode &node_src,
2200  const int flag,
2201  const bool unique_name,
2203 {
2204  bNode *node_dst = (bNode *)MEM_mallocN(sizeof(bNode), __func__);
2205  *node_dst = node_src;
2206 
2207  node_dst->runtime = MEM_new<bNodeRuntime>(__func__);
2208 
2209  /* Can be called for nodes outside a node tree (e.g. clipboard). */
2210  if (dst_tree) {
2211  if (unique_name) {
2212  nodeUniqueName(dst_tree, node_dst);
2213  }
2214  BLI_addtail(&dst_tree->nodes, node_dst);
2215  }
2216 
2217  BLI_listbase_clear(&node_dst->inputs);
2218  LISTBASE_FOREACH (const bNodeSocket *, src_socket, &node_src.inputs) {
2219  bNodeSocket *dst_socket = (bNodeSocket *)MEM_dupallocN(src_socket);
2220  node_socket_copy(dst_socket, src_socket, flag);
2221  BLI_addtail(&node_dst->inputs, dst_socket);
2222  socket_map.add_new(src_socket, dst_socket);
2223  }
2224 
2225  BLI_listbase_clear(&node_dst->outputs);
2226  LISTBASE_FOREACH (const bNodeSocket *, src_socket, &node_src.outputs) {
2227  bNodeSocket *dst_socket = (bNodeSocket *)MEM_dupallocN(src_socket);
2228  node_socket_copy(dst_socket, src_socket, flag);
2229  BLI_addtail(&node_dst->outputs, dst_socket);
2230  socket_map.add_new(src_socket, dst_socket);
2231  }
2232 
2233  if (node_src.prop) {
2234  node_dst->prop = IDP_CopyProperty_ex(node_src.prop, flag);
2235  }
2236 
2237  BLI_listbase_clear(&node_dst->internal_links);
2238  LISTBASE_FOREACH (const bNodeLink *, src_link, &node_src.internal_links) {
2239  bNodeLink *dst_link = (bNodeLink *)MEM_dupallocN(src_link);
2240  dst_link->fromnode = node_dst;
2241  dst_link->tonode = node_dst;
2242  dst_link->fromsock = socket_map.lookup(src_link->fromsock);
2243  dst_link->tosock = socket_map.lookup(src_link->tosock);
2244  BLI_addtail(&node_dst->internal_links, dst_link);
2245  }
2246 
2247  if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
2248  id_us_plus(node_dst->id);
2249  }
2250 
2251  if (node_src.typeinfo->copyfunc) {
2252  node_src.typeinfo->copyfunc(dst_tree, node_dst, &node_src);
2253  }
2254 
2255  /* Only call copy function when a copy is made for the main database, not
2256  * for cases like the dependency graph and localization. */
2257  if (node_dst->typeinfo->copyfunc_api && !(flag & LIB_ID_CREATE_NO_MAIN)) {
2258  PointerRNA ptr;
2259  RNA_pointer_create((ID *)dst_tree, &RNA_Node, node_dst, &ptr);
2260 
2261  node_dst->typeinfo->copyfunc_api(&ptr, &node_src);
2262  }
2263 
2264  if (dst_tree) {
2265  BKE_ntree_update_tag_node_new(dst_tree, node_dst);
2266  }
2267 
2268  /* Reset the declaration of the new node. */
2269  nodeDeclarationEnsure(dst_tree, node_dst);
2270 
2271  return node_dst;
2272 }
2273 
2275  const bNode &src_node,
2276  const int flag,
2277  const bool unique_name)
2278 {
2280  return node_copy_with_mapping(dst_tree, src_node, flag, unique_name, socket_map);
2281 }
2282 
2283 } // namespace blender::bke
2284 
2285 static int node_count_links(const bNodeTree *ntree, const bNodeSocket *socket)
2286 {
2287  int count = 0;
2288  LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
2289  if (ELEM(socket, link->fromsock, link->tosock)) {
2290  count++;
2291  }
2292  }
2293  return count;
2294 }
2295 
2297  bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock)
2298 {
2299  bNodeLink *link = nullptr;
2300 
2301  /* Test valid input. */
2302  BLI_assert(fromnode);
2303  BLI_assert(tonode);
2304 
2305  if (fromsock->in_out == SOCK_OUT && tosock->in_out == SOCK_IN) {
2306  link = MEM_cnew<bNodeLink>("link");
2307  if (ntree) {
2308  BLI_addtail(&ntree->links, link);
2309  }
2310  link->fromnode = fromnode;
2311  link->fromsock = fromsock;
2312  link->tonode = tonode;
2313  link->tosock = tosock;
2314  }
2315  else if (fromsock->in_out == SOCK_IN && tosock->in_out == SOCK_OUT) {
2316  /* OK but flip */
2317  link = MEM_cnew<bNodeLink>("link");
2318  if (ntree) {
2319  BLI_addtail(&ntree->links, link);
2320  }
2321  link->fromnode = tonode;
2322  link->fromsock = tosock;
2323  link->tonode = fromnode;
2324  link->tosock = fromsock;
2325  }
2326 
2327  if (ntree) {
2329  }
2330 
2331  if (link != nullptr && link->tosock->flag & SOCK_MULTI_INPUT) {
2333  }
2334 
2335  return link;
2336 }
2337 
2339 {
2340  /* Can be called for links outside a node tree (e.g. clipboard). */
2341  if (ntree) {
2342  BLI_remlink(&ntree->links, link);
2343  }
2344 
2345  if (link->tosock) {
2346  link->tosock->link = nullptr;
2347  }
2348  MEM_freeN(link);
2349 
2350  if (ntree) {
2352  }
2353 }
2354 
2355 /* Check if all output links are muted or not. */
2356 static bool nodeMuteFromSocketLinks(const bNodeTree *ntree, const bNodeSocket *sock)
2357 {
2358  int tot = 0;
2359  int muted = 0;
2360  LISTBASE_FOREACH (const bNodeLink *, link, &ntree->links) {
2361  if (link->fromsock == sock) {
2362  tot++;
2363  if (link->flag & NODE_LINK_MUTED) {
2364  muted++;
2365  }
2366  }
2367  }
2368  return tot == muted;
2369 }
2370 
2371 static void nodeMuteLink(bNodeLink *link)
2372 {
2373  link->flag |= NODE_LINK_MUTED;
2374  link->flag |= NODE_LINK_TEST;
2375  if (!(link->tosock->flag & SOCK_MULTI_INPUT)) {
2376  link->tosock->flag &= ~SOCK_IN_USE;
2377  }
2378 }
2379 
2380 static void nodeUnMuteLink(bNodeLink *link)
2381 {
2382  link->flag &= ~NODE_LINK_MUTED;
2383  link->flag |= NODE_LINK_TEST;
2384  link->tosock->flag |= SOCK_IN_USE;
2385 }
2386 
2387 /* Upstream muting. Always happens when unmuting but checks when muting. O(n^2) algorithm. */
2388 static void nodeMuteRerouteInputLinks(bNodeTree *ntree, bNode *node, const bool mute)
2389 {
2390  if (node->type != NODE_REROUTE) {
2391  return;
2392  }
2393  if (!mute || nodeMuteFromSocketLinks(ntree, (bNodeSocket *)node->outputs.first)) {
2394  bNodeSocket *sock = (bNodeSocket *)node->inputs.first;
2395  LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
2396  if (!(link->flag & NODE_LINK_VALID) || (link->tosock != sock)) {
2397  continue;
2398  }
2399  if (mute) {
2400  nodeMuteLink(link);
2401  }
2402  else {
2403  nodeUnMuteLink(link);
2404  }
2405  nodeMuteRerouteInputLinks(ntree, link->fromnode, mute);
2406  }
2407  }
2408 }
2409 
2410 /* Downstream muting propagates when reaching reroute nodes. O(n^2) algorithm. */
2411 static void nodeMuteRerouteOutputLinks(bNodeTree *ntree, bNode *node, const bool mute)
2412 {
2413  if (node->type != NODE_REROUTE) {
2414  return;
2415  }
2416  bNodeSocket *sock;
2417  sock = (bNodeSocket *)node->outputs.first;
2418  LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
2419  if (!(link->flag & NODE_LINK_VALID) || (link->fromsock != sock)) {
2420  continue;
2421  }
2422  if (mute) {
2423  nodeMuteLink(link);
2424  }
2425  else {
2426  nodeUnMuteLink(link);
2427  }
2428  nodeMuteRerouteOutputLinks(ntree, link->tonode, mute);
2429  }
2430 }
2431 
2433 {
2434  if (link->tosock) {
2435  bool mute = !(link->flag & NODE_LINK_MUTED);
2436  if (mute) {
2437  nodeMuteLink(link);
2438  }
2439  else {
2440  nodeUnMuteLink(link);
2441  }
2442  if (link->tonode->type == NODE_REROUTE) {
2443  nodeMuteRerouteOutputLinks(ntree, link->tonode, mute);
2444  }
2445  if (link->fromnode->type == NODE_REROUTE) {
2447  }
2448  }
2449 
2450  if (ntree) {
2452  }
2453 }
2454 
2456 {
2458  if (link->fromsock == sock || link->tosock == sock) {
2459  nodeRemLink(ntree, link);
2460  }
2461  }
2462 }
2463 
2464 bool nodeLinkIsHidden(const bNodeLink *link)
2465 {
2466  return nodeSocketIsHidden(link->fromsock) || nodeSocketIsHidden(link->tosock);
2467 }
2468 
2470 {
2471  return (link->fromnode->flag & NODE_SELECT) || (link->tonode->flag & NODE_SELECT);
2472 }
2473 
2474 /* Adjust the indices of links connected to the given multi input socket after deleting the link at
2475  * `deleted_index`. This function also works if the link has not yet been deleted. */
2477  bNodeSocket *sock,
2478  int deleted_index)
2479 {
2480  LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
2481  /* We only need to adjust those with a greater index, because the others will have the same
2482  * index. */
2483  if (link->tosock != sock || link->multi_input_socket_index <= deleted_index) {
2484  continue;
2485  }
2486  link->multi_input_socket_index -= 1;
2487  }
2488 }
2489 
2491 {
2492  /* store link pointers in output sockets, for efficient lookup */
2493  LISTBASE_FOREACH (bNodeLink *, link, &node->internal_links) {
2494  link->tosock->link = link;
2495  }
2496 
2497  /* redirect downstream links */
2499  /* do we have internal link? */
2500  if (link->fromnode == node) {
2501  if (link->fromsock->link) {
2502  /* get the upstream input link */
2503  bNodeLink *fromlink = link->fromsock->link->fromsock->link;
2504  /* skip the node */
2505  if (fromlink) {
2506  if (link->tosock->flag & SOCK_MULTI_INPUT) {
2507  /* remove the link that would be the same as the relinked one */
2508  LISTBASE_FOREACH_MUTABLE (bNodeLink *, link_to_compare, &ntree->links) {
2509  if (link_to_compare->fromsock == fromlink->fromsock &&
2510  link_to_compare->tosock == link->tosock) {
2512  ntree, link_to_compare->tosock, link_to_compare->multi_input_socket_index);
2513  nodeRemLink(ntree, link_to_compare);
2514  }
2515  }
2516  }
2517  link->fromnode = fromlink->fromnode;
2518  link->fromsock = fromlink->fromsock;
2519 
2520  /* if the up- or downstream link is invalid,
2521  * the replacement link will be invalid too.
2522  */
2523  if (!(fromlink->flag & NODE_LINK_VALID)) {
2524  link->flag &= ~NODE_LINK_VALID;
2525  }
2526 
2527  if (fromlink->flag & NODE_LINK_MUTED) {
2528  link->flag |= NODE_LINK_MUTED;
2529  }
2530 
2532  }
2533  else {
2534  if (link->tosock->flag & SOCK_MULTI_INPUT) {
2536  ntree, link->tosock, link->multi_input_socket_index);
2537  }
2538  nodeRemLink(ntree, link);
2539  }
2540  }
2541  else {
2542  if (link->tosock->flag & SOCK_MULTI_INPUT) {
2544  ntree, link->tosock, link->multi_input_socket_index);
2545  };
2546  nodeRemLink(ntree, link);
2547  }
2548  }
2549  }
2550 
2551  /* remove remaining upstream links */
2553  if (link->tonode == node) {
2554  nodeRemLink(ntree, link);
2555  }
2556  }
2557 }
2558 
2559 void nodeToView(const bNode *node, float x, float y, float *rx, float *ry)
2560 {
2561  if (node->parent) {
2562  nodeToView(node->parent, x + node->locx, y + node->locy, rx, ry);
2563  }
2564  else {
2565  *rx = x + node->locx;
2566  *ry = y + node->locy;
2567  }
2568 }
2569 
2570 void nodeFromView(const bNode *node, float x, float y, float *rx, float *ry)
2571 {
2572  if (node->parent) {
2573  nodeFromView(node->parent, x, y, rx, ry);
2574  *rx -= node->locx;
2575  *ry -= node->locy;
2576  }
2577  else {
2578  *rx = x - node->locx;
2579  *ry = y - node->locy;
2580  }
2581 }
2582 
2583 bool nodeAttachNodeCheck(const bNode *node, const bNode *parent)
2584 {
2585  for (const bNode *parent_iter = node; parent_iter; parent_iter = parent_iter->parent) {
2586  if (parent_iter == parent) {
2587  return true;
2588  }
2589  }
2590 
2591  return false;
2592 }
2593 
2595 {
2596  BLI_assert(parent->type == NODE_FRAME);
2597  BLI_assert(nodeAttachNodeCheck(parent, node) == false);
2598 
2599  float locx, locy;
2600  nodeToView(node, 0.0f, 0.0f, &locx, &locy);
2601 
2602  node->parent = parent;
2603  /* transform to parent space */
2604  nodeFromView(parent, locx, locy, &node->locx, &node->locy);
2605 }
2606 
2608 {
2609  if (node->parent) {
2610  BLI_assert(node->parent->type == NODE_FRAME);
2611 
2612  /* transform to view space */
2613  float locx, locy;
2614  nodeToView(node, 0.0f, 0.0f, &locx, &locy);
2615  node->locx = locx;
2616  node->locy = locy;
2617  node->parent = nullptr;
2618  }
2619 }
2620 
2621 void nodePositionRelative(bNode *from_node,
2622  bNode *to_node,
2623  bNodeSocket *from_sock,
2624  bNodeSocket *to_sock)
2625 {
2626  float offset_x;
2627  int tot_sock_idx;
2628 
2629  /* Socket to plug into. */
2630  if (SOCK_IN == to_sock->in_out) {
2631  offset_x = -(from_node->typeinfo->width + 50);
2632  tot_sock_idx = BLI_listbase_count(&to_node->outputs);
2633  tot_sock_idx += BLI_findindex(&to_node->inputs, to_sock);
2634  }
2635  else {
2636  offset_x = to_node->typeinfo->width + 50;
2637  tot_sock_idx = BLI_findindex(&to_node->outputs, to_sock);
2638  }
2639 
2640  BLI_assert(tot_sock_idx != -1);
2641 
2642  float offset_y = U.widget_unit * tot_sock_idx;
2643 
2644  /* Output socket. */
2645  if (from_sock) {
2646  if (SOCK_IN == from_sock->in_out) {
2647  tot_sock_idx = BLI_listbase_count(&from_node->outputs);
2648  tot_sock_idx += BLI_findindex(&from_node->inputs, from_sock);
2649  }
2650  else {
2651  tot_sock_idx = BLI_findindex(&from_node->outputs, from_sock);
2652  }
2653  }
2654 
2655  BLI_assert(tot_sock_idx != -1);
2656 
2657  offset_y -= U.widget_unit * tot_sock_idx;
2658 
2659  from_node->locx = to_node->locx + offset_x;
2660  from_node->locy = to_node->locy - offset_y;
2661 }
2662 
2664 {
2665  LISTBASE_FOREACH (bNodeSocket *, nsock, &node->inputs) {
2666  if (nsock->link != nullptr) {
2667  bNodeLink *link = nsock->link;
2668  nodePositionRelative(link->fromnode, link->tonode, link->fromsock, link->tosock);
2670  }
2671  }
2672 }
2673 
2674 bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname)
2675 {
2676  /* trees are created as local trees for compositor, material or texture nodes,
2677  * node groups and other tree types are created as library data.
2678  */
2679  const bool is_embedded = (bmain == nullptr);
2680  int flag = 0;
2681  if (is_embedded) {
2682  flag |= LIB_ID_CREATE_NO_MAIN;
2683  }
2684  bNodeTree *ntree = (bNodeTree *)BKE_libblock_alloc(bmain, ID_NT, name, flag);
2686  if (is_embedded) {
2688  }
2689 
2690  BLI_strncpy(ntree->idname, idname, sizeof(ntree->idname));
2692 
2693  return ntree;
2694 }
2695 
2696 bNodeTree *ntreeCopyTree_ex(const bNodeTree *ntree, Main *bmain, const bool do_id_user)
2697 {
2698  const int flag = do_id_user ? 0 : LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_CREATE_NO_MAIN;
2699 
2700  bNodeTree *ntree_copy = (bNodeTree *)BKE_id_copy_ex(bmain, (ID *)ntree, nullptr, flag);
2701  return ntree_copy;
2702 }
2704 {
2705  return ntreeCopyTree_ex(ntree, bmain, true);
2706 }
2707 
2708 /* *************** Node Preview *********** */
2709 
2710 /* XXX this should be removed eventually ...
2711  * Currently BKE functions are modeled closely on previous code,
2712  * using BKE_node_preview_init_tree to set up previews for a whole node tree in advance.
2713  * This should be left more to the individual node tree implementations. */
2714 
2716 {
2717  /* XXX check for closed nodes? */
2718  return (node->typeinfo->flag & NODE_PREVIEW) != 0;
2719 }
2720 
2722  bNodeInstanceKey key,
2723  const int xsize,
2724  const int ysize,
2725  const bool create)
2726 {
2728  if (!preview) {
2729  if (create) {
2730  preview = MEM_cnew<bNodePreview>("node preview");
2731  BKE_node_instance_hash_insert(previews, key, preview);
2732  }
2733  else {
2734  return nullptr;
2735  }
2736  }
2737 
2738  /* node previews can get added with variable size this way */
2739  if (xsize == 0 || ysize == 0) {
2740  return preview;
2741  }
2742 
2743  /* sanity checks & initialize */
2744  if (preview->rect) {
2745  if (preview->xsize != xsize || preview->ysize != ysize) {
2746  MEM_freeN(preview->rect);
2747  preview->rect = nullptr;
2748  }
2749  }
2750 
2751  if (preview->rect == nullptr) {
2752  preview->rect = (unsigned char *)MEM_callocN(4 * xsize + xsize * ysize * sizeof(char[4]),
2753  "node preview rect");
2754  preview->xsize = xsize;
2755  preview->ysize = ysize;
2756  }
2757  /* no clear, makes nicer previews */
2758 
2759  return preview;
2760 }
2761 
2763 {
2764  bNodePreview *new_preview = (bNodePreview *)MEM_dupallocN(preview);
2765  if (preview->rect) {
2766  new_preview->rect = (unsigned char *)MEM_dupallocN(preview->rect);
2767  }
2768  return new_preview;
2769 }
2770 
2772 {
2773  if (preview->rect) {
2774  MEM_freeN(preview->rect);
2775  }
2776  MEM_freeN(preview);
2777 }
2778 
2780  bNodeTree *ntree,
2781  bNodeInstanceKey parent_key,
2782  const int xsize,
2783  const int ysize)
2784 {
2786  bNodeInstanceKey key = BKE_node_instance_key(parent_key, ntree, node);
2787 
2788  if (BKE_node_preview_used(node)) {
2789  node->preview_xsize = xsize;
2790  node->preview_ysize = ysize;
2791 
2792  BKE_node_preview_verify(previews, key, xsize, ysize, false);
2793  }
2794 
2795  if (node->type == NODE_GROUP && node->id) {
2796  node_preview_init_tree_recursive(previews, (bNodeTree *)node->id, key, xsize, ysize);
2797  }
2798  }
2799 }
2800 
2801 void BKE_node_preview_init_tree(bNodeTree *ntree, int xsize, int ysize)
2802 {
2803  if (!ntree) {
2804  return;
2805  }
2806 
2807  if (!ntree->previews) {
2808  ntree->previews = BKE_node_instance_hash_new("node previews");
2809  }
2810 
2812 }
2813 
2815  bNodeTree *ntree,
2816  bNodeInstanceKey parent_key)
2817 {
2819  bNodeInstanceKey key = BKE_node_instance_key(parent_key, ntree, node);
2820 
2821  if (BKE_node_preview_used(node)) {
2822  BKE_node_instance_hash_tag_key(previews, key);
2823  }
2824 
2825  if (node->type == NODE_GROUP && node->id) {
2826  node_preview_tag_used_recursive(previews, (bNodeTree *)node->id, key);
2827  }
2828  }
2829 }
2830 
2832 {
2833  if (!ntree || !ntree->previews) {
2834  return;
2835  }
2836 
2837  /* use the instance hash functions for tagging and removing unused previews */
2840 
2843 }
2844 
2846 {
2847  if (preview && preview->rect) {
2848  memset(preview->rect, 0, MEM_allocN_len(preview->rect));
2849  }
2850 }
2851 
2853 {
2854  if (!ntree || !ntree->previews) {
2855  return;
2856  }
2857 
2862  }
2863 }
2864 
2865 void BKE_node_preview_merge_tree(bNodeTree *to_ntree, bNodeTree *from_ntree, bool remove_old)
2866 {
2867  if (remove_old || !to_ntree->previews) {
2868  /* free old previews */
2869  if (to_ntree->previews) {
2871  }
2872 
2873  /* transfer previews */
2874  to_ntree->previews = from_ntree->previews;
2875  from_ntree->previews = nullptr;
2876 
2877  /* clean up, in case any to_ntree nodes have been removed */
2879  }
2880  else {
2881  if (from_ntree->previews) {
2883  NODE_INSTANCE_HASH_ITER (iter, from_ntree->previews) {
2886 
2887  /* replace existing previews */
2891  }
2892 
2893  /* NOTE: null free function here,
2894  * because pointers have already been moved over to to_ntree->previews! */
2895  BKE_node_instance_hash_free(from_ntree->previews, nullptr);
2896  from_ntree->previews = nullptr;
2897  }
2898  }
2899 }
2900 
2901 /* ************** Free stuff ********** */
2902 
2904 {
2906  ListBase *lb;
2907  if (link->fromnode == node) {
2908  lb = &node->outputs;
2909  }
2910  else if (link->tonode == node) {
2911  lb = &node->inputs;
2912  }
2913  else {
2914  lb = nullptr;
2915  }
2916 
2917  if (lb) {
2918  /* Only bother adjusting if the socket is not on the node we're deleting. */
2919  if (link->tonode != node && link->tosock->flag & SOCK_MULTI_INPUT) {
2921  ntree, link->tosock, link->multi_input_socket_index);
2922  }
2923  LISTBASE_FOREACH (bNodeSocket *, sock, lb) {
2924  if (link->fromsock == sock || link->tosock == sock) {
2925  nodeRemLink(ntree, link);
2926  break;
2927  }
2928  }
2929  }
2930  }
2931 }
2932 
2934 {
2936  if (node->parent == parent) {
2938  }
2939  }
2940 }
2941 
2942 /* Free the node itself. ID user refcounting is up the caller,
2943  * that does not happen here. */
2945 {
2946  /* since it is called while free database, node->id is undefined */
2947 
2948  /* can be called for nodes outside a node tree (e.g. clipboard) */
2949  if (ntree) {
2951 
2952  if (ntree->typeinfo->free_node_cache) {
2954  }
2955 
2956  /* texture node has bad habit of keeping exec data around */
2957  if (ntree->type == NTREE_TEXTURE && ntree->execdata) {
2959  ntree->execdata = nullptr;
2960  }
2961  }
2962 
2963  if (node->typeinfo->freefunc) {
2964  node->typeinfo->freefunc(node);
2965  }
2966 
2967  LISTBASE_FOREACH_MUTABLE (bNodeSocket *, sock, &node->inputs) {
2968  /* Remember, no ID user refcount management here! */
2969  node_socket_free(sock, false);
2970  MEM_freeN(sock);
2971  }
2972  LISTBASE_FOREACH_MUTABLE (bNodeSocket *, sock, &node->outputs) {
2973  /* Remember, no ID user refcount management here! */
2974  node_socket_free(sock, false);
2975  MEM_freeN(sock);
2976  }
2977 
2978  BLI_freelistN(&node->internal_links);
2979 
2980  if (node->prop) {
2981  /* Remember, no ID user refcount management here! */
2982  IDP_FreePropertyContent_ex(node->prop, false);
2983  MEM_freeN(node->prop);
2984  }
2985 
2986  if (node->typeinfo->declaration_is_dynamic) {
2987  delete node->runtime->declaration;
2988  }
2989 
2990  MEM_delete(node->runtime);
2991  MEM_freeN(node);
2992 
2993  if (ntree) {
2995  }
2996 }
2997 
2999 {
3000  /* For removing nodes while editing localized node trees. */
3002 
3003  /* These two lines assume the caller might want to free a single node and maintain
3004  * a valid state in the node tree. */
3007 
3009 }
3010 
3011 void nodeRemoveNode(Main *bmain, bNodeTree *ntree, bNode *node, bool do_id_user)
3012 {
3013  /* This function is not for localized node trees, we do not want
3014  * do to ID user refcounting and removal of animdation data then. */
3016 
3017  bool node_has_id = false;
3018 
3019  if (do_id_user) {
3020  /* Free callback for NodeCustomGroup. */
3021  if (node->typeinfo->freefunc_api) {
3022  PointerRNA ptr;
3023  RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr);
3024 
3025  node->typeinfo->freefunc_api(&ptr);
3026  }
3027 
3028  /* Do user counting. */
3029  if (node->id) {
3030  id_us_min(node->id);
3031  node_has_id = true;
3032  }
3033 
3034  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
3035  node_has_id |= socket_id_user_decrement(sock);
3036  }
3037  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
3038  node_has_id |= socket_id_user_decrement(sock);
3039  }
3040  }
3041 
3042  /* Remove animation data. */
3043  char propname_esc[MAX_IDPROP_NAME * 2];
3044  char prefix[MAX_IDPROP_NAME * 2];
3045 
3046  BLI_str_escape(propname_esc, node->name, sizeof(propname_esc));
3047  BLI_snprintf(prefix, sizeof(prefix), "nodes[\"%s\"]", propname_esc);
3048 
3049  if (BKE_animdata_fix_paths_remove((ID *)ntree, prefix)) {
3050  if (bmain != nullptr) {
3051  DEG_relations_tag_update(bmain);
3052  }
3053  }
3054 
3055  /* Also update relations for the scene time node, which causes a dependency
3056  * on time that users expect to be removed when the node is removed. */
3057  if (node_has_id || node->type == GEO_NODE_INPUT_SCENE_TIME) {
3058  if (bmain != nullptr) {
3059  DEG_relations_tag_update(bmain);
3060  }
3061  }
3062 
3065 
3066  /* Free node itself. */
3068 }
3069 
3071  bNodeSocket *sock,
3072  const bool do_id_user)
3073 {
3074  if (sock->prop) {
3075  IDP_FreeProperty_ex(sock->prop, do_id_user);
3076  }
3077 
3078  if (sock->default_value) {
3079  if (do_id_user) {
3081  }
3082  MEM_freeN(sock->default_value);
3083  }
3084  MEM_delete(sock->runtime);
3085 }
3086 
3088 {
3089  /* Only localized node trees store a copy for each node group tree.
3090  * Each node group tree in a localized node tree can be freed,
3091  * since it is a localized copy itself (no risk of accessing free'd
3092  * data in main, see T37939). */
3093  if (!(ntree->id.tag & LIB_TAG_LOCALIZED)) {
3094  return;
3095  }
3096 
3098  if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) {
3099  bNodeTree *ngroup = (bNodeTree *)node->id;
3100  ntreeFreeTree(ngroup);
3101  MEM_freeN(ngroup);
3102  }
3103  }
3104 }
3105 
3107 {
3109  BKE_animdata_free(&ntree->id, false);
3110 }
3111 
3113 {
3115  BKE_libblock_free_data(&ntree->id, true);
3117 }
3118 
3120 {
3121  if (ntree->id.tag & LIB_TAG_LOCALIZED) {
3123  }
3124  else {
3126  BKE_libblock_free_data(&ntree->id, true);
3127  }
3128 }
3129 
3131 {
3132  if (ntree == nullptr) {
3133  return;
3134  }
3135 
3136  if (ntree->typeinfo->free_cache) {
3138  }
3139 }
3140 
3142 {
3143  /* find the active outputs, might become tree type dependent handler */
3145  if (node->typeinfo->nclass == NODE_CLASS_OUTPUT) {
3146  /* we need a check for which output node should be tagged like this, below an exception */
3147  if (node->type == CMP_NODE_OUTPUT_FILE) {
3148  continue;
3149  }
3150 
3151  int output = 0;
3152  /* there is more types having output class, each one is checked */
3153  LISTBASE_FOREACH (bNode *, tnode, &ntree->nodes) {
3154  if (tnode->typeinfo->nclass == NODE_CLASS_OUTPUT) {
3155  if (ntree->type == NTREE_COMPOSIT) {
3156  /* same type, exception for viewer */
3157  if (tnode->type == node->type ||
3160  if (tnode->flag & NODE_DO_OUTPUT) {
3161  output++;
3162  if (output > 1) {
3163  tnode->flag &= ~NODE_DO_OUTPUT;
3164  }
3165  }
3166  }
3167  }
3168  else {
3169  /* same type */
3170  if (tnode->type == node->type) {
3171  if (tnode->flag & NODE_DO_OUTPUT) {
3172  output++;
3173  if (output > 1) {
3174  tnode->flag &= ~NODE_DO_OUTPUT;
3175  }
3176  }
3177  }
3178  }
3179  }
3180  }
3181  if (output == 0) {
3182  node->flag |= NODE_DO_OUTPUT;
3183  }
3184  }
3185 
3186  /* group node outputs use this flag too */
3187  if (node->type == NODE_GROUP_OUTPUT) {
3188  int output = 0;
3189  LISTBASE_FOREACH (bNode *, tnode, &ntree->nodes) {
3190  if (tnode->type == NODE_GROUP_OUTPUT) {
3191  if (tnode->flag & NODE_DO_OUTPUT) {
3192  output++;
3193  if (output > 1) {
3194  tnode->flag &= ~NODE_DO_OUTPUT;
3195  }
3196  }
3197  }
3198  }
3199  if (output == 0) {
3200  node->flag |= NODE_DO_OUTPUT;
3201  }
3202  }
3203  }
3204 
3205  /* here we could recursively set which nodes have to be done,
3206  * might be different for editor or for "real" use... */
3207 }
3208 
3210 {
3211  switch (GS(id->name)) {
3212  case ID_MA:
3213  return &((Material *)id)->nodetree;
3214  case ID_LA:
3215  return &((Light *)id)->nodetree;
3216  case ID_WO:
3217  return &((World *)id)->nodetree;
3218  case ID_TE:
3219  return &((Tex *)id)->nodetree;
3220  case ID_SCE:
3221  return &((Scene *)id)->nodetree;
3222  case ID_LS:
3223  return &((FreestyleLineStyle *)id)->nodetree;
3224  case ID_SIM:
3225  return &((Simulation *)id)->nodetree;
3226  default:
3227  return nullptr;
3228  }
3229 }
3230 
3232 {
3233  bNodeTree **nodetree = BKE_ntree_ptr_from_id(id);
3234  return (nodetree != nullptr) ? *nodetree : nullptr;
3235 }
3236 
3237 void ntreeNodeFlagSet(const bNodeTree *ntree, const int flag, const bool enable)
3238 {
3240  if (enable) {
3241  node->flag |= flag;
3242  }
3243  else {
3244  node->flag &= ~flag;
3245  }
3246  }
3247 }
3248 
3250 {
3251  if (ntree == nullptr) {
3252  return nullptr;
3253  }
3254 
3255  /* Make full copy outside of Main database.
3256  * NOTE: previews are not copied here. */
3257  bNodeTree *ltree = (bNodeTree *)BKE_id_copy_ex(
3258  nullptr, &ntree->id, nullptr, (LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_NO_ANIMDATA));
3259 
3260  ltree->id.tag |= LIB_TAG_LOCALIZED;
3261 
3262  LISTBASE_FOREACH (bNode *, node, &ltree->nodes) {
3263  if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) {
3264  node->id = (ID *)ntreeLocalize((bNodeTree *)node->id);
3265  }
3266  }
3267 
3268  /* Ensures only a single output node is enabled. */
3270 
3271  bNode *node_src = (bNode *)ntree->nodes.first;
3272  bNode *node_local = (bNode *)ltree->nodes.first;
3273  while (node_src != nullptr) {
3274  node_local->original = node_src;
3275  node_src = node_src->next;
3276  node_local = node_local->next;
3277  }
3278 
3279  if (ntree->typeinfo->localize) {
3280  ntree->typeinfo->localize(ltree, ntree);
3281  }
3282 
3283  return ltree;
3284 }
3285 
3286 void ntreeLocalMerge(Main *bmain, bNodeTree *localtree, bNodeTree *ntree)
3287 {
3288  if (ntree && localtree) {
3289  if (ntree->typeinfo->local_merge) {
3290  ntree->typeinfo->local_merge(bmain, localtree, ntree);
3291  }
3292 
3293  ntreeFreeTree(localtree);
3294  MEM_freeN(localtree);
3295  }
3296 }
3297 
3298 /* ************ NODE TREE INTERFACE *************** */
3299 
3301  eNodeSocketInOut in_out,
3302  const char *idname,
3303  const char *name)
3304 {
3305  bNodeSocketType *stype = nodeSocketTypeFind(idname);
3306  if (stype == nullptr) {
3307  return nullptr;
3308  }
3309 
3310  bNodeSocket *sock = MEM_cnew<bNodeSocket>("socket template");
3311  sock->runtime = MEM_new<bNodeSocketRuntime>(__func__);
3312  BLI_strncpy(sock->idname, stype->idname, sizeof(sock->idname));
3313  sock->in_out = in_out;
3314  sock->type = SOCK_CUSTOM; /* int type undefined by default */
3315  node_socket_set_typeinfo(ntree, sock, stype);
3316 
3317  /* assign new unique index */
3318  const int own_index = ntree->cur_index++;
3319  /* use the own_index as socket identifier */
3320  if (in_out == SOCK_IN) {
3321  BLI_snprintf(sock->identifier, MAX_NAME, "Input_%d", own_index);
3322  }
3323  else {
3324  BLI_snprintf(sock->identifier, MAX_NAME, "Output_%d", own_index);
3325  }
3326 
3327  sock->limit = (in_out == SOCK_IN ? 1 : 0xFFF);
3328 
3329  BLI_strncpy(sock->name, name, NODE_MAXSTR);
3330  sock->storage = nullptr;
3331  sock->flag |= SOCK_COLLAPSED;
3332 
3333  return sock;
3334 }
3335 
3337  eNodeSocketInOut in_out,
3338  const char *identifier)
3339 {
3340  ListBase *sockets = (in_out == SOCK_IN) ? &ntree->inputs : &ntree->outputs;
3341  LISTBASE_FOREACH (bNodeSocket *, iosock, sockets) {
3342  if (STREQ(iosock->identifier, identifier)) {
3343  return iosock;
3344  }
3345  }
3346  return nullptr;
3347 }
3348 
3350  eNodeSocketInOut in_out,
3351  const char *idname,
3352  const char *name)
3353 {
3354  bNodeSocket *iosock = make_socket_interface(ntree, in_out, idname, name);
3355  if (in_out == SOCK_IN) {
3356  BLI_addtail(&ntree->inputs, iosock);
3357  }
3358  else if (in_out == SOCK_OUT) {
3359  BLI_addtail(&ntree->outputs, iosock);
3360  }
3362  return iosock;
3363 }
3364 
3366  eNodeSocketInOut in_out,
3367  const char *idname,
3368  bNodeSocket *next_sock,
3369  const char *name)
3370 {
3371  bNodeSocket *iosock = make_socket_interface(ntree, in_out, idname, name);
3372  if (in_out == SOCK_IN) {
3373  BLI_insertlinkbefore(&ntree->inputs, next_sock, iosock);
3374  }
3375  else if (in_out == SOCK_OUT) {
3376  BLI_insertlinkbefore(&ntree->outputs, next_sock, iosock);
3377  }
3379  return iosock;
3380 }
3381 
3383  bNode *from_node,
3384  bNodeSocket *from_sock)
3385 {
3387  ntree, static_cast<eNodeSocketInOut>(from_sock->in_out), from_sock->idname, from_sock->name);
3388  if (iosock) {
3389  if (iosock->typeinfo->interface_from_socket) {
3390  iosock->typeinfo->interface_from_socket(ntree, iosock, from_node, from_sock);
3391  }
3392  }
3393  return iosock;
3394 }
3395 
3397  bNodeSocket *next_sock,
3398  bNode *from_node,
3399  bNodeSocket *from_sock)
3400 {
3402  ntree,
3403  static_cast<eNodeSocketInOut>(from_sock->in_out),
3404  from_sock->idname,
3405  next_sock,
3406  from_sock->name);
3407  if (iosock) {
3408  if (iosock->typeinfo->interface_from_socket) {
3409  iosock->typeinfo->interface_from_socket(ntree, iosock, from_node, from_sock);
3410  }
3411  }
3412  return iosock;
3413 }
3414 
3416 {
3417  /* this is fast, this way we don't need an in_out argument */
3418  BLI_remlink(&ntree->inputs, sock);
3419  BLI_remlink(&ntree->outputs, sock);
3420 
3421  node_socket_interface_free(ntree, sock, true);
3422  MEM_freeN(sock);
3423 
3425 }
3426 
3427 /* generates a valid RNA identifier from the node tree name */
3429 {
3430  /* generate a valid RNA identifier */
3431  sprintf(base, "NodeTreeInterface_%s", ntree->id.name + 2);
3432  RNA_identifier_sanitize(base, false);
3433 }
3434 
3435 /* check if the identifier is already in use */
3437 {
3438  return (RNA_struct_find(identifier) != nullptr);
3439 }
3440 
3441 /* generates the actual unique identifier and ui name and description */
3443  const char *base,
3444  char *identifier,
3445  int maxlen,
3446  char *name,
3447  char *description)
3448 {
3449  /* There is a possibility that different node tree names get mapped to the same identifier
3450  * after sanitation (e.g. "SomeGroup_A", "SomeGroup.A" both get sanitized to "SomeGroup_A").
3451  * On top of the sanitized id string add a number suffix if necessary to avoid duplicates.
3452  */
3453  identifier[0] = '\0';
3455  ntree_interface_unique_identifier_check, nullptr, base, '_', identifier, maxlen);
3456 
3457  sprintf(name, "Node Tree %s Interface", ntree->id.name + 2);
3458  sprintf(description, "Interface properties of node group %s", ntree->id.name + 2);
3459 }
3460 
3462 {
3463  /* strings are generated from base string + ID name, sizes are sufficient */
3464  char base[MAX_ID_NAME + 64], identifier[MAX_ID_NAME + 64], name[MAX_ID_NAME + 64],
3465  description[MAX_ID_NAME + 64];
3466 
3467  /* generate a valid RNA identifier */
3470 
3471  /* register a subtype of PropertyGroup */
3475 
3476  /* associate the RNA type with the node tree */
3477  ntree->interface_type = srna;
3479 
3480  /* add socket properties */
3481  LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->inputs) {
3482  bNodeSocketType *stype = sock->typeinfo;
3483  if (stype && stype->interface_register_properties) {
3484  stype->interface_register_properties(ntree, sock, srna);
3485  }
3486  }
3487  LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->outputs) {
3488  bNodeSocketType *stype = sock->typeinfo;
3489  if (stype && stype->interface_register_properties) {
3490  stype->interface_register_properties(ntree, sock, srna);
3491  }
3492  }
3493 }
3494 
3496 {
3497  if (ntree->interface_type) {
3498  /* strings are generated from base string + ID name, sizes are sufficient */
3499  char base[MAX_ID_NAME + 64], identifier[MAX_ID_NAME + 64], name[MAX_ID_NAME + 64],
3500  description[MAX_ID_NAME + 64];
3501 
3502  /* A bit of a hack: when changing the ID name, update the RNA type identifier too,
3503  * so that the names match. This is not strictly necessary to keep it working,
3504  * but better for identifying associated NodeTree blocks and RNA types.
3505  */
3506  StructRNA *srna = ntree->interface_type;
3507 
3509 
3510  /* RNA identifier may have a number suffix, but should start with the idbase string */
3511  if (!STREQLEN(RNA_struct_identifier(srna), base, sizeof(base))) {
3512  /* generate new unique RNA identifier from the ID name */
3514 
3515  /* rename the RNA type */
3520  }
3521  }
3522  else if (create) {
3524  }
3525 
3526  return ntree->interface_type;
3527 }
3528 
3530 {
3531  if (ntree->interface_type) {
3533  ntree->interface_type = nullptr;
3534  }
3535 }
3536 
3538 {
3539  /* XXX it would be sufficient to just recreate all properties
3540  * instead of re-registering the whole struct type,
3541  * but there is currently no good way to do this in the RNA functions.
3542  * Overhead should be negligible.
3543  */
3546 }
3547 
3548 /* ************ find stuff *************** */
3549 
3551 {
3552  if (ntree) {
3554  if (node->type == type) {
3555  return node;
3556  }
3557  }
3558  }
3559  return nullptr;
3560 }
3561 
3563 {
3564  if (ntree == lookup) {
3565  return true;
3566  }
3568  if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) {
3569  if (ntreeHasTree((bNodeTree *)node->id, lookup)) {
3570  return true;
3571  }
3572  }
3573  }
3574  return false;
3575 }
3576 
3578 {
3580  if (link->fromsock == from && link->tosock == to) {
3581  return link;
3582  }
3583  if (link->fromsock == to && link->tosock == from) { /* hrms? */
3584  return link;
3585  }
3586  }
3587  return nullptr;
3588 }
3589 
3591 {
3592  int tot = 0;
3593  LISTBASE_FOREACH (const bNodeLink *, link, &ntree->links) {
3594  if (link->fromsock == sock || link->tosock == sock) {
3595  tot++;
3596  }
3597  }
3598  return tot;
3599 }
3600 
3602 {
3603  if (ntree == nullptr) {
3604  return nullptr;
3605  }
3606 
3608  if (node->flag & NODE_ACTIVE) {
3609  return node;
3610  }
3611  }
3612  return nullptr;
3613 }
3614 
3616 {
3617  if (select) {
3618  node->flag |= NODE_SELECT;
3619  }
3620  else {
3621  node->flag &= ~NODE_SELECT;
3622 
3623  /* deselect sockets too */
3624  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
3625  sock->flag &= ~NODE_SELECT;
3626  }
3627  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
3628  sock->flag &= ~NODE_SELECT;
3629  }
3630  }
3631 }
3632 
3634 {
3635  if (ntree == nullptr) {
3636  return;
3637  }
3638 
3640  node->flag &= ~NODE_ACTIVE;
3641  }
3642 }
3643 
3645 {
3646  const bool is_paint_canvas = nodeSupportsActiveFlag(node, NODE_ACTIVE_PAINT_CANVAS);
3647  const bool is_texture_class = nodeSupportsActiveFlag(node, NODE_ACTIVE_TEXTURE);
3648  int flags_to_set = NODE_ACTIVE;
3649  SET_FLAG_FROM_TEST(flags_to_set, is_paint_canvas, NODE_ACTIVE_PAINT_CANVAS);
3650  SET_FLAG_FROM_TEST(flags_to_set, is_texture_class, NODE_ACTIVE_TEXTURE);
3651 
3652  /* Make sure only one node is active per node tree. */
3653  LISTBASE_FOREACH (bNode *, tnode, &ntree->nodes) {
3654  tnode->flag &= ~flags_to_set;
3655  }
3656  node->flag |= flags_to_set;
3657 }
3658 
3660 {
3661  return ((sock->flag & (SOCK_HIDDEN | SOCK_UNAVAIL)) != 0);
3662 }
3663 
3664 void nodeSetSocketAvailability(bNodeTree *ntree, bNodeSocket *sock, bool is_available)
3665 {
3666  const bool was_available = (sock->flag & SOCK_UNAVAIL) == 0;
3667  if (is_available != was_available) {
3669  }
3670 
3671  if (is_available) {
3672  sock->flag &= ~SOCK_UNAVAIL;
3673  }
3674  else {
3675  sock->flag |= SOCK_UNAVAIL;
3676  }
3677 }
3678 
3680 {
3681  bNodeSocketType *stype = sock->typeinfo;
3682  if (sock->flag & SOCK_MULTI_INPUT) {
3683  return 4095;
3684  }
3685  if (stype != nullptr && stype->use_link_limits_of_type) {
3686  int limit = (sock->in_out == SOCK_IN) ? stype->input_link_limit : stype->output_link_limit;
3687  return limit;
3688  }
3689 
3690  return sock->limit;
3691 }
3692 
3695 {
3696  int index;
3697  LISTBASE_FOREACH_INDEX (bNodeSocket *, socket, sockets, index) {
3698  const SocketDeclaration &socket_decl = *declarations[index];
3699  socket->runtime->declaration = &socket_decl;
3700  }
3701 }
3702 
3704 {
3705  BLI_assert(node->runtime->declaration != nullptr);
3706  update_socket_declarations(&node->inputs, node->runtime->declaration->inputs());
3707  update_socket_declarations(&node->outputs, node->runtime->declaration->outputs());
3708 }
3709 
3711 {
3712  if (node->runtime->declaration != nullptr) {
3713  return false;
3714  }
3715  if (node->typeinfo->declare == nullptr) {
3716  return false;
3717  }
3718  if (node->typeinfo->declaration_is_dynamic) {
3719  node->runtime->declaration = new blender::nodes::NodeDeclaration();
3720  blender::nodes::NodeDeclarationBuilder builder{*node->runtime->declaration};
3721  node->typeinfo->declare(builder);
3722  }
3723  else {
3724  /* Declaration should have been created in #nodeRegisterType. */
3725  BLI_assert(node->typeinfo->fixed_declaration != nullptr);
3726  node->runtime->declaration = node->typeinfo->fixed_declaration;
3727  }
3728  return true;
3729 }
3730 
3732 {
3735  return true;
3736  }
3737  return false;
3738 }
3739 
3740 /* ************** Node Clipboard *********** */
3741 
3742 #define USE_NODE_CB_VALIDATE
3743 
3744 #ifdef USE_NODE_CB_VALIDATE
3754  ID *id;
3757 };
3758 #endif /* USE_NODE_CB_VALIDATE */
3759 
3762 
3763 #ifdef USE_NODE_CB_VALIDATE
3765 #endif
3766 
3768  int type;
3769 };
3770 
3771 static bNodeClipboard node_clipboard = {{nullptr}};
3772 
3774 {
3776 }
3777 
3779 {
3781  nodeRemLink(nullptr, link);
3782  }
3784 
3786  node_free_node(nullptr, node);
3787  }
3789 
3790 #ifdef USE_NODE_CB_VALIDATE
3792 #endif
3793 }
3794 
3796 {
3797  bool ok = true;
3798 
3799 #ifdef USE_NODE_CB_VALIDATE
3800  bNodeClipboardExtraInfo *node_info;
3801  bNode *node;
3802 
3803  /* lists must be aligned */
3806 
3807  for (node = (bNode *)node_clipboard.nodes.first,
3809  node;
3810  node = (bNode *)node->next, node_info = (bNodeClipboardExtraInfo *)node_info->next) {
3811  /* validate the node against the stored node info */
3812 
3813  /* re-assign each loop since we may clear,
3814  * open a new file where the ID is valid, and paste again */
3815  node->id = node_info->id;
3816 
3817  /* currently only validate the ID */
3818  if (node->id) {
3819  /* We want to search into current blend file, so using G_MAIN is valid here too. */
3820  ListBase *lb = which_libbase(G_MAIN, GS(node_info->id_name));
3821  BLI_assert(lb != nullptr);
3822 
3823  if (BLI_findindex(lb, node_info->id) == -1) {
3824  /* May assign null. */
3825  node->id = (ID *)BLI_findstring(lb, node_info->id_name + 2, offsetof(ID, name) + 2);
3826 
3827  if (node->id == nullptr) {
3828  ok = false;
3829  }
3830  }
3831  }
3832  }
3833 #endif /* USE_NODE_CB_VALIDATE */
3834 
3835  return ok;
3836 }
3837 
3839 {
3840 #ifdef USE_NODE_CB_VALIDATE
3841  /* add extra info */
3843  sizeof(bNodeClipboardExtraInfo), __func__);
3844 
3845  node_info->id = node->id;
3846  if (node->id) {
3847  BLI_strncpy(node_info->id_name, node->id->name, sizeof(node_info->id_name));
3848  if (ID_IS_LINKED(node->id)) {
3849  BLI_strncpy(
3850  node_info->library_name, node->id->lib->filepath_abs, sizeof(node_info->library_name));
3851  }
3852  else {
3853  node_info->library_name[0] = '\0';
3854  }
3855  }
3856  else {
3857  node_info->id_name[0] = '\0';
3858  node_info->library_name[0] = '\0';
3859  }
3861  /* end extra info */
3862 #endif /* USE_NODE_CB_VALIDATE */
3863 
3864  /* add node */
3866 }
3867 
3869 {
3871 }
3872 
3874 {
3875  return &node_clipboard.nodes;
3876 }
3877 
3879 {
3880  return &node_clipboard.links;
3881 }
3882 
3884 {
3885  return node_clipboard.type;
3886 }
3887 
3889 {
3892 }
3893 
3894 /* Node Instance Hash */
3895 
3898 
3899 /* Generate a hash key from ntree and node names
3900  * Uses the djb2 algorithm with xor by Bernstein:
3901  * http://www.cse.yorku.ca/~oz/hash.html
3902  */
3904 {
3905  char c;
3906 
3907  while ((c = *str++)) {
3908  hash.value = ((hash.value << 5) + hash.value) ^ c; /* (hash * 33) ^ c */
3909  }
3910 
3911  /* separator '\0' character, to avoid ambiguity from concatenated strings */
3912  hash.value = (hash.value << 5) + hash.value; /* hash * 33 */
3913 
3914  return hash;
3915 }
3916 
3918  const bNodeTree *ntree,
3919  const bNode *node)
3920 {
3921  bNodeInstanceKey key = node_hash_int_str(parent_key, ntree->id.name + 2);
3922 
3923  if (node) {
3924  key = node_hash_int_str(key, node->name);
3925  }
3926 
3927  return key;
3928 }
3929 
3930 static unsigned int node_instance_hash_key(const void *key)
3931 {
3932  return ((const bNodeInstanceKey *)key)->value;
3933 }
3934 
3935 static bool node_instance_hash_key_cmp(const void *a, const void *b)
3936 {
3937  unsigned int value_a = ((const bNodeInstanceKey *)a)->value;
3938  unsigned int value_b = ((const bNodeInstanceKey *)b)->value;
3939 
3940  return (value_a != value_b);
3941 }
3942 
3944 {
3946  hash->ghash = BLI_ghash_new(
3947  node_instance_hash_key, node_instance_hash_key_cmp, "node instance hash ghash");
3948  return hash;
3949 }
3950 
3952 {
3953  BLI_ghash_free(hash->ghash, nullptr, (GHashValFreeFP)valfreefp);
3954  MEM_freeN(hash);
3955 }
3956 
3958 {
3960  entry->key = key;
3961  entry->tag = 0;
3962  BLI_ghash_insert(hash->ghash, &entry->key, value);
3963 }
3964 
3966 {
3967  return BLI_ghash_lookup(hash->ghash, &key);
3968 }
3969 
3971  bNodeInstanceKey key,
3972  bNodeInstanceValueFP valfreefp)
3973 {
3974  return BLI_ghash_remove(hash->ghash, &key, nullptr, (GHashValFreeFP)valfreefp);
3975 }
3976 
3978 {
3979  BLI_ghash_clear(hash->ghash, nullptr, (GHashValFreeFP)valfreefp);
3980 }
3981 
3983 {
3984  return BLI_ghash_popkey(hash->ghash, &key, nullptr);
3985 }
3986 
3988 {
3989  return BLI_ghash_haskey(hash->ghash, &key);
3990 }
3991 
3993 {
3994  return BLI_ghash_len(hash->ghash);
3995 }
3996 
3998 {
4000 
4001  NODE_INSTANCE_HASH_ITER (iter, hash) {
4004 
4005  value->tag = 0;
4006  }
4007 }
4008 
4010 {
4012  entry->tag = 1;
4013 }
4014 
4016 {
4018  key);
4019 
4020  if (entry) {
4021  entry->tag = 1;
4022  return true;
4023  }
4024 
4025  return false;
4026 }
4027 
4029  bNodeInstanceValueFP valfreefp)
4030 {
4031  /* NOTE: Hash must not be mutated during iterating!
4032  * Store tagged entries in a separate list and remove items afterward.
4033  */
4036  "temporary node instance key list");
4038  int num_untagged = 0;
4039  NODE_INSTANCE_HASH_ITER (iter, hash) {
4042 
4043  if (!value->tag) {
4044  untagged[num_untagged++] = BKE_node_instance_hash_iterator_get_key(&iter);
4045  }
4046  }
4047 
4048  for (int i = 0; i < num_untagged; i++) {
4049  BKE_node_instance_hash_remove(hash, untagged[i], valfreefp);
4050  }
4051 
4052  MEM_freeN(untagged);
4053 }
4054 
4055 /* ************** dependency stuff *********** */
4056 
4057 /* node is guaranteed to be not checked before */
4059 {
4060  int level = 0xFFF;
4061 
4062  node->done = true;
4063 
4064  /* check linked nodes */
4065  LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
4066  if (link->tonode == node) {
4067  bNode *fromnode = link->fromnode;
4068  if (fromnode->done == 0) {
4069  fromnode->level = node_get_deplist_recurs(ntree, fromnode, nsort);
4070  }
4071  if (fromnode->level <= level) {
4072  level = fromnode->level - 1;
4073  }
4074  }
4075  }
4076 
4077  /* check parent node */
4078  if (node->parent) {
4079  if (node->parent->done == 0) {
4080  node->parent->level = node_get_deplist_recurs(ntree, node->parent, nsort);
4081  }
4082  if (node->parent->level <= level) {
4083  level = node->parent->level - 1;
4084  }
4085  }
4086 
4087  if (nsort) {
4088  **nsort = node;
4089  (*nsort)++;
4090  }
4091 
4092  return level;
4093 }
4094 
4095 void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***r_deplist, int *r_deplist_len)
4096 {
4097  *r_deplist_len = 0;
4098 
4099  /* first clear data */
4101  node->done = false;
4102  (*r_deplist_len)++;
4103  }
4104  if (*r_deplist_len == 0) {
4105  *r_deplist = nullptr;
4106  return;
4107  }
4108 
4109  bNode **nsort;
4110  nsort = *r_deplist = (bNode **)MEM_callocN((*r_deplist_len) * sizeof(bNode *),
4111  "sorted node array");
4112 
4113  /* recursive check */
4115  if (node->done == 0) {
4116  node->level = node_get_deplist_recurs(ntree, node, &nsort);
4117  }
4118  }
4119 }
4120 
4121 /* only updates node->level for detecting cycles links */
4123 {
4124  /* first clear tag */
4126  node->done = false;
4127  }
4128 
4129  /* recursive check */
4131  if (node->done == 0) {
4132  node->level = node_get_deplist_recurs(ntree, node, nullptr);
4133  }
4134  }
4135 }
4136 
4137 /* Build a set of built-in node types to check for known types. */
4139 {
4141  NODE_TYPES_BEGIN (ntype) {
4142  result.add(ntype->type);
4143  }
4145  return result;
4146 }
4147 
4148 static bool can_read_node_type(const int type)
4149 {
4150  /* Can always read custom node types. */
4152  return true;
4153  }
4154 
4155  /* Check known built-in types. */
4156  static blender::Set<int> known_types = get_known_node_types_set();
4157  return known_types.contains(type);
4158 }
4159 
4161 {
4162  /* If the integer type is unknown then this node cannot be read. */
4163  if (!can_read_node_type(node->type)) {
4164  node->type = NODE_CUSTOM;
4165  /* This type name is arbitrary, it just has to be unique enough to not match a future node
4166  * idname. Includes the old type identifier for debugging purposes. */
4167  const std::string old_idname = node->idname;
4168  BLI_snprintf(node->idname, sizeof(node->idname), "Undefined[%s]", old_idname.c_str());
4169  node->typeinfo = &NodeTypeUndefined;
4170  }
4171 }
4172 
4174 {
4175  Vector<bNodeTree *> new_ntrees;
4176 
4177  /* Replace unknown node types with "Undefined".
4178  * This happens when loading files from newer Blender versions. Such nodes cannot be read
4179  * reliably so replace the idname with an undefined type. This keeps links and socket names but
4180  * discards storage and other type-specific data.
4181  *
4182  * Replacement has to happen after after-liblink-versioning, since some node types still get
4183  * replaced in those late versioning steps. */
4184  FOREACH_NODETREE_BEGIN (main, ntree, owner_id) {
4187  }
4188  }
4190  /* Update all new node trees on file read or append, to add/remove sockets
4191  * in groups nodes if the group changed, and handle any update flags that
4192  * might have been set in file reading or versioning. */
4193  FOREACH_NODETREE_BEGIN (main, ntree, owner_id) {
4194  if (owner_id->tag & LIB_TAG_NEW) {
4196  }
4197  }
4199  BKE_ntree_update_main(main, nullptr);
4200 }
4201 
4203 {
4204  if (id == nullptr) {
4205  return;
4206  }
4207 
4208  bool need_update = false;
4209 
4210  /* Update all users of ngroup, to add/remove sockets as needed. */
4211  FOREACH_NODETREE_BEGIN (main, ntree, owner_id) {
4213  if (node->id == id) {
4215  need_update = true;
4216  }
4217  }
4218  }
4220  if (need_update) {
4221  BKE_ntree_update_main(main, nullptr);
4222  }
4223 }
4224 
4225 /* ************* node type access ********** */
4226 
4227 void nodeLabel(const bNodeTree *ntree, const bNode *node, char *label, int maxlen)
4228 {
4229  label[0] = '\0';
4230 
4231  if (node->label[0] != '\0') {
4232  BLI_strncpy(label, node->label, maxlen);
4233  }
4234  else if (node->typeinfo->labelfunc) {
4235  node->typeinfo->labelfunc(ntree, node, label, maxlen);
4236  }
4237 
4238  /* The previous methods (labelfunc) could not provide an adequate label for the node. */
4239  if (label[0] == '\0') {
4240  /* Kind of hacky and weak... Ideally would be better to use RNA here. :| */
4241  const char *tmp = CTX_IFACE_(BLT_I18NCONTEXT_ID_NODETREE, node->typeinfo->ui_name);
4242  if (tmp == node->typeinfo->ui_name) {
4243  tmp = IFACE_(node->typeinfo->ui_name);
4244  }
4245  BLI_strncpy(label, tmp, maxlen);
4246  }
4247 }
4248 
4249 const char *nodeSocketLabel(const bNodeSocket *sock)
4250 {
4251  return (sock->label[0] != '\0') ? sock->label : sock->name;
4252 }
4253 
4255 {
4256  /* default size values */
4258  ntype->height = 100;
4259  ntype->minheight = 30;
4260  ntype->maxheight = FLT_MAX;
4261 }
4262 
4263 /* allow this node for any tree type */
4264 static bool node_poll_default(bNodeType *UNUSED(ntype),
4266  const char **UNUSED(disabled_hint))
4267 {
4268  return true;
4269 }
4270 
4271 /* use the basic poll function */
4272 static bool node_poll_instance_default(bNode *node, bNodeTree *ntree, const char **disabled_hint)
4273 {
4274  return node->typeinfo->poll(node->typeinfo, ntree, disabled_hint);
4275 }
4276 
4277 void node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
4278 {
4279  /* Use static type info header to map static int type to identifier string and RNA struct type.
4280  * Associate the RNA struct type with the bNodeType.
4281  * Dynamically registered nodes will create an RNA type at runtime
4282  * and call RNA_struct_blender_type_set, so this only needs to be done for old RNA types
4283  * created in makesrna, which can not be associated to a bNodeType immediately,
4284  * since bNodeTypes are registered afterward ...
4285  */
4286 #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
4287  case ID: \
4288  BLI_strncpy(ntype->idname, #Category #StructName, sizeof(ntype->idname)); \
4289  ntype->rna_ext.srna = RNA_struct_find(#Category #StructName); \
4290  BLI_assert(ntype->rna_ext.srna != nullptr); \
4291  RNA_struct_blender_type_set(ntype->rna_ext.srna, ntype); \
4292  break;
4293 
4294  switch (type) {
4295 #include "NOD_static_types.h"
4296  }
4297 
4298  /* make sure we have a valid type (everything registered) */
4299  BLI_assert(ntype->idname[0] != '\0');
4300 
4301  ntype->type = type;
4302  BLI_strncpy(ntype->ui_name, name, sizeof(ntype->ui_name));
4303  ntype->nclass = nclass;
4304 
4305  node_type_base_defaults(ntype);
4306 
4307  ntype->poll = node_poll_default;
4309 }
4310 
4311 void node_type_base_custom(bNodeType *ntype, const char *idname, const char *name, short nclass)
4312 {
4313  BLI_strncpy(ntype->idname, idname, sizeof(ntype->idname));
4314  ntype->type = NODE_CUSTOM;
4315  BLI_strncpy(ntype->ui_name, name, sizeof(ntype->ui_name));
4316  ntype->nclass = nclass;
4317 
4318  node_type_base_defaults(ntype);
4319 }
4320 
4324 };
4325 
4326 static bool unique_socket_template_identifier_check(void *arg, const char *name)
4327 {
4329 
4330  for (bNodeSocketTemplate *ntemp = data->list; ntemp->type >= 0; ntemp++) {
4331  if (ntemp != data->ntemp) {
4332  if (STREQ(ntemp->identifier, name)) {
4333  return true;
4334  }
4335  }
4336  }
4337 
4338  return false;
4339 }
4340 
4342  bNodeSocketTemplate *ntemp,
4343  const char defname[],
4344  char delim)
4345 {
4347  data.list = list;
4348  data.ntemp = ntemp;
4349 
4351  &data,
4352  defname,
4353  delim,
4354  ntemp->identifier,
4355  sizeof(ntemp->identifier));
4356 }
4357 
4359  struct bNodeSocketTemplate *inputs,
4360  struct bNodeSocketTemplate *outputs)
4361 {
4362  ntype->inputs = inputs;
4363  ntype->outputs = outputs;
4364 
4365  /* automatically generate unique identifiers */
4366  if (inputs) {
4367  /* clear identifier strings (uninitialized memory) */
4368  for (bNodeSocketTemplate *ntemp = inputs; ntemp->type >= 0; ntemp++) {
4369  ntemp->identifier[0] = '\0';
4370  }
4371 
4372  for (bNodeSocketTemplate *ntemp = inputs; ntemp->type >= 0; ntemp++) {
4373  BLI_strncpy(ntemp->identifier, ntemp->name, sizeof(ntemp->identifier));
4375  }
4376  }
4377  if (outputs) {
4378  /* clear identifier strings (uninitialized memory) */
4379  for (bNodeSocketTemplate *ntemp = outputs; ntemp->type >= 0; ntemp++) {
4380  ntemp->identifier[0] = '\0';
4381  }
4382 
4383  for (bNodeSocketTemplate *ntemp = outputs; ntemp->type >= 0; ntemp++) {
4384  BLI_strncpy(ntemp->identifier, ntemp->name, sizeof(ntemp->identifier));
4386  }
4387  }
4388 }
4389 
4390 void node_type_init(struct bNodeType *ntype,
4391  void (*initfunc)(struct bNodeTree *ntree, struct bNode *node))
4392 {
4393  ntype->initfunc = initfunc;
4394 }
4395 
4396 void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwidth)
4397 {
4398  ntype->width = width;
4399  ntype->minwidth = minwidth;
4400  if (maxwidth <= minwidth) {
4401  ntype->maxwidth = FLT_MAX;
4402  }
4403  else {
4404  ntype->maxwidth = maxwidth;
4405  }
4406 }
4407 
4409 {
4410  switch (size) {
4411  case NODE_SIZE_DEFAULT:
4412  node_type_size(ntype, 140, 100, NODE_DEFAULT_MAX_WIDTH);
4413  break;
4414  case NODE_SIZE_SMALL:
4415  node_type_size(ntype, 100, 80, NODE_DEFAULT_MAX_WIDTH);
4416  break;
4417  case NODE_SIZE_MIDDLE:
4418  node_type_size(ntype, 150, 120, NODE_DEFAULT_MAX_WIDTH);
4419  break;
4420  case NODE_SIZE_LARGE:
4421  node_type_size(ntype, 240, 140, NODE_DEFAULT_MAX_WIDTH);
4422  break;
4423  }
4424 }
4425 
4427  const char *storagename,
4428  void (*freefunc)(struct bNode *node),
4429  void (*copyfunc)(struct bNodeTree *dest_ntree,
4430  struct bNode *dest_node,
4431  const struct bNode *src_node))
4432 {
4433  if (storagename) {
4434  BLI_strncpy(ntype->storagename, storagename, sizeof(ntype->storagename));
4435  }
4436  else {
4437  ntype->storagename[0] = '\0';
4438  }
4439  ntype->copyfunc = copyfunc;
4440  ntype->freefunc = freefunc;
4441 }
4442 
4443 void node_type_update(struct bNodeType *ntype,
4444  void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
4445 {
4446  ntype->updatefunc = updatefunc;
4447 }
4448 
4450  void (*group_update_func)(struct bNodeTree *ntree, struct bNode *node))
4451 {
4452  ntype->group_update_func = group_update_func;
4453 }
4454 
4455 void node_type_exec(struct bNodeType *ntype,
4456  NodeInitExecFunction init_exec_fn,
4457  NodeFreeExecFunction free_exec_fn,
4458  NodeExecFunction exec_fn)
4459 {
4460  ntype->init_exec_fn = init_exec_fn;
4461  ntype->free_exec_fn = free_exec_fn;
4462  ntype->exec_fn = exec_fn;
4463 }
4464 
4465 void node_type_gpu(struct bNodeType *ntype, NodeGPUExecFunction gpu_fn)
4466 {
4467  ntype->gpu_fn = gpu_fn;
4468 }
4469 
4470 /* callbacks for undefined types */
4471 
4473  bNodeTree *UNUSED(nodetree),
4474  const char **UNUSED(r_disabled_hint))
4475 {
4476  /* this type can not be added deliberately, it's just a placeholder */
4477  return false;
4478 }
4479 
4480 /* register fallback types used for undefined tree, nodes, sockets */
4482 {
4483  /* NOTE: these types are not registered in the type hashes,
4484  * they are just used as placeholders in case the actual types are not registered.
4485  */
4486 
4488  strcpy(NodeTreeTypeUndefined.idname, "NodeTreeUndefined");
4489  strcpy(NodeTreeTypeUndefined.ui_name, N_("Undefined"));
4490  strcpy(NodeTreeTypeUndefined.ui_description, N_("Undefined Node Tree Type"));
4491 
4492  node_type_base_custom(&NodeTypeUndefined, "NodeUndefined", "Undefined", 0);
4494 
4496  "NodeSocketUndefined",
4498  /* extra type info for standard socket types */
4501 
4505 }
4506 
4508 {
4510 
4519 
4525 
4537 
4543 
4557 
4577 
4590 
4604 
4613 
4618 }
4619 
4620 static void registerShaderNodes()
4621 {
4623 
4658 
4673 
4697 
4703 
4718 }
4719 
4721 {
4723 
4739 
4748 
4755 
4760 
4771 }
4772 
4774 {
4776 
4906 }
4907 
4909 {
4928 }
4929 
4931 {
4932  nodetreetypes_hash = BLI_ghash_str_new("nodetreetypes_hash gh");
4933  nodetypes_hash = BLI_ghash_str_new("nodetypes_hash gh");
4934  nodesockettypes_hash = BLI_ghash_str_new("nodesockettypes_hash gh");
4935 
4937 
4939 
4944 
4949 
4955 }
4956 
4958 {
4959  if (nodetypes_hash) {
4960  NODE_TYPES_BEGIN (nt) {
4961  if (nt->rna_ext.free) {
4962  nt->rna_ext.free(nt->rna_ext.data);
4963  }
4964  }
4966 
4968  nodetypes_hash = nullptr;
4969  }
4970 
4971  if (nodesockettypes_hash) {
4973  if (st->ext_socket.free) {
4974  st->ext_socket.free(st->ext_socket.data);
4975  }
4976  if (st->ext_interface.free) {
4977  st->ext_interface.free(st->ext_interface.data);
4978  }
4979  }
4981 
4983  nodesockettypes_hash = nullptr;
4984  }
4985 
4986  if (nodetreetypes_hash) {
4987  NODE_TREE_TYPES_BEGIN (nt) {
4988  if (nt->rna_ext.free) {
4989  nt->rna_ext.free(nt->rna_ext.data);
4990  }
4991  }
4993 
4995  nodetreetypes_hash = nullptr;
4996  }
4997 }
4998 
4999 /* -------------------------------------------------------------------- */
5000 /* NodeTree Iterator Helpers (FOREACH_NODETREE_BEGIN) */
5001 
5002 void BKE_node_tree_iter_init(struct NodeTreeIterStore *ntreeiter, struct Main *bmain)
5003 {
5004  ntreeiter->ngroup = (bNodeTree *)bmain->nodetrees.first;
5005  ntreeiter->scene = (Scene *)bmain->scenes.first;
5006  ntreeiter->mat = (Material *)bmain->materials.first;
5007  ntreeiter->tex = (Tex *)bmain->textures.first;
5008  ntreeiter->light = (Light *)bmain->lights.first;
5009  ntreeiter->world = (World *)bmain->worlds.first;
5010  ntreeiter->linestyle = (FreestyleLineStyle *)bmain->linestyles.first;
5011  ntreeiter->simulation = (Simulation *)bmain->simulations.first;
5012 }
5014  bNodeTree **r_nodetree,
5015  struct ID **r_id)
5016 {
5017  if (ntreeiter->ngroup) {
5018  *r_nodetree = (bNodeTree *)ntreeiter->ngroup;
5019  *r_id = (ID *)ntreeiter->ngroup;
5020  ntreeiter->ngroup = (bNodeTree *)ntreeiter->ngroup->id.next;
5021  }
5022  else if (ntreeiter->scene) {
5023  *r_nodetree = (bNodeTree *)ntreeiter->scene->nodetree;
5024  *r_id = (ID *)ntreeiter->scene;
5025  ntreeiter->scene = (Scene *)ntreeiter->scene->id.next;
5026  }
5027  else if (ntreeiter->mat) {
5028  *r_nodetree = (bNodeTree *)ntreeiter->mat->nodetree;
5029  *r_id = (ID *)ntreeiter->mat;
5030  ntreeiter->mat = (Material *)ntreeiter->mat->id.next;
5031  }
5032  else if (ntreeiter->tex) {
5033  *r_nodetree = (bNodeTree *)ntreeiter->tex->nodetree;
5034  *r_id = (ID *)ntreeiter->tex;
5035  ntreeiter->tex = (Tex *)ntreeiter->tex->id.next;
5036  }
5037  else if (ntreeiter->light) {
5038  *r_nodetree = (bNodeTree *)ntreeiter->light->nodetree;
5039  *r_id = (ID *)ntreeiter->light;
5040  ntreeiter->light = (Light *)ntreeiter->light->id.next;
5041  }
5042  else if (ntreeiter->world) {
5043  *r_nodetree = (bNodeTree *)ntreeiter->world->nodetree;
5044  *r_id = (ID *)ntreeiter->world;
5045  ntreeiter->world = (World *)ntreeiter->world->id.next;
5046  }
5047  else if (ntreeiter->linestyle) {
5048  *r_nodetree = (bNodeTree *)ntreeiter->linestyle->nodetree;
5049  *r_id = (ID *)ntreeiter->linestyle;
5050  ntreeiter->linestyle = (FreestyleLineStyle *)ntreeiter->linestyle->id.next;
5051  }
5052  else if (ntreeiter->simulation) {
5053  *r_nodetree = (bNodeTree *)ntreeiter->simulation->nodetree;
5054  *r_id = (ID *)ntreeiter->simulation;
5055  ntreeiter->simulation = (Simulation *)ntreeiter->simulation->id.next;
5056  }
5057  else {
5058  return false;
5059  }
5060 
5061  return true;
5062 }
5063 
5064 /* -------------------------------------------------------------------- */
5065 /* NodeTree kernel functions */
5066 
5067 void BKE_nodetree_remove_layer_n(bNodeTree *ntree, Scene *scene, const int layer_index)
5068 {
5069  BLI_assert(layer_index != -1);
5071  if (node->type == CMP_NODE_R_LAYERS && (Scene *)node->id == scene) {
5072  if (node->custom1 == layer_index) {
5073  node->custom1 = 0;
5074  }
5075  else if (node->custom1 > layer_index) {
5076  node->custom1--;
5077  }
5078  }
5079  }
5080 }
void BKE_animdata_free(struct ID *id, bool do_id_user)
Definition: anim_data.c:197
void BKE_animdata_blend_read_data(struct BlendDataReader *reader, struct AnimData *adt)
Definition: anim_data.c:1443
void BKE_animdata_blend_write(struct BlendWriter *writer, struct AnimData *adt)
Definition: anim_data.c:1421
bool BKE_animdata_fix_paths_remove(struct ID *id, const char *path)
Definition: anim_data.c:1067
bool BKE_bpath_foreach_path_fixed_process(struct BPathForeachPathData *bpath_data, char *path)
Definition: bpath.c:121
void BKE_curvemapping_blend_read(struct BlendDataReader *reader, struct CurveMapping *cumap)
Definition: colortools.c:1300
void BKE_curvemapping_blend_write(struct BlendWriter *writer, const struct CurveMapping *cumap)
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
#define G_MAIN
Definition: BKE_global.h:267
void BKE_previewimg_free(struct PreviewImage **prv)
Definition: icons.cc:283
void BKE_previewimg_id_copy(struct ID *new_id, const struct ID *old_id)
void BKE_previewimg_blend_read(struct BlendDataReader *reader, struct PreviewImage *prv)
Definition: icons.cc:615
void BKE_previewimg_blend_write(struct BlendWriter *writer, const struct PreviewImage *prv)
void IDP_BlendReadExpand(struct BlendExpander *expander, struct IDProperty *prop)
Definition: idprop.c:1471
struct IDProperty * IDP_CopyProperty_ex(const struct IDProperty *prop, int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void IDP_BlendWrite(struct BlendWriter *writer, const struct IDProperty *prop)
void IDP_foreach_property(struct IDProperty *id_property_root, int type_filter, IDPForeachPropertyCallback callback, void *user_data)
Definition: idprop.c:1117
#define IDP_BlendDataRead(reader, prop)
Definition: BKE_idprop.h:321
void IDP_FreeProperty_ex(struct IDProperty *prop, bool do_id_user)
Definition: idprop.c:1087
void IDP_FreePropertyContent_ex(struct IDProperty *prop, bool do_id_user)
Definition: idprop.c:1055
void IDP_BlendReadLib(struct BlendLibReader *reader, struct Library *lib, struct IDProperty *prop)
Definition: idprop.c:1435
@ IDTYPE_FLAGS_APPEND_IS_REUSABLE
Definition: BKE_idtype.h:39
void(* IDTypeForeachCacheFunctionCallback)(struct ID *id, const struct IDCacheKey *cache_key, void **cache_p, uint flags, void *user_data)
Definition: BKE_idtype.h:77
void BKE_image_format_blend_read_data(struct BlendDataReader *reader, struct ImageFormatData *imf)
Definition: image_format.cc:57
void BKE_image_format_blend_write(struct BlendWriter *writer, struct ImageFormatData *imf)
Definition: image_format.cc:62
@ LIB_ID_COPY_NO_PREVIEW
Definition: BKE_lib_id.h:150
@ LIB_ID_COPY_LOCALIZE
Definition: BKE_lib_id.h:187
@ LIB_ID_CREATE_NO_USER_REFCOUNT
Definition: BKE_lib_id.h:126
@ LIB_ID_COPY_NO_ANIMDATA
Definition: BKE_lib_id.h:154
@ LIB_ID_CREATE_NO_MAIN
Definition: BKE_lib_id.h:122
void BKE_libblock_free_data(struct ID *id, bool do_id_user) ATTR_NONNULL()
Definition: lib_id_delete.c:44
struct ID * BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, int flag)
void id_us_min(struct ID *id)
Definition: lib_id.c:313
void BKE_libblock_free_data_py(struct ID *id)
void * BKE_libblock_alloc(struct Main *bmain, short type, const char *name, int flag) ATTR_WARN_UNUSED_RESULT
Definition: lib_id.c:1050
void BKE_libblock_init_empty(struct ID *id) ATTR_NONNULL(1)
Definition: lib_id.c:1115
void id_us_plus(struct ID *id)
Definition: lib_id.c:305
void BKE_id_blend_write(struct BlendWriter *writer, struct ID *id)
Definition: lib_id.c:2008
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(_data, _id_super, _cb_flag)
#define BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(_data, _func_call)
void BKE_lib_query_idpropertiesForeachIDLink_callback(struct IDProperty *id_prop, void *user_data)
Definition: lib_query.c:136
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:73
#define BKE_LIB_FOREACHID_PROCESS_ID(_data, _id, _cb_flag)
struct ListBase * which_libbase(struct Main *bmain, short type)
Definition: main.c:567
void *(* NodeInitExecFunction)(struct bNodeExecContext *context, struct bNode *node, bNodeInstanceKey key)
Definition: BKE_node.h:204
#define NODE_TYPES_BEGIN(ntype)
Definition: BKE_node.h:567
#define NODE_CLASS_OUTPUT
Definition: BKE_node.h:346
#define NODE_REROUTE
Definition: BKE_node.h:986
#define CMP_NODE_TIME
Definition: BKE_node.h:1209
#define CMP_NODE_SPLITVIEWER
Definition: BKE_node.h:1235
#define CMP_NODE_VIEWER
Definition: BKE_node.h:1196
#define NODE_CUSTOM_GROUP
Definition: BKE_node.h:989
BLI_INLINE bNodeInstanceKey BKE_node_instance_hash_iterator_get_key(bNodeInstanceHashIterator *iter)
Definition: BKE_node.h:879
#define CMP_NODE_CRYPTOMATTE
Definition: BKE_node.h:1292
#define GEO_NODE_VIEWER
Definition: BKE_node.h:1413
#define CMP_NODE_MOVIEDISTORTION
Definition: BKE_node.h:1260
#define GEO_NODE_INPUT_SCENE_TIME
Definition: BKE_node.h:1486
void(* bNodeInstanceValueFP)(void *value)
Definition: BKE_node.h:833
BLI_INLINE void * BKE_node_instance_hash_iterator_get_value(bNodeInstanceHashIterator *iter)
Definition: BKE_node.h:883
void(* NodeExecFunction)(void *data, int thread, struct bNode *, struct bNodeExecData *execdata, struct bNodeStack **in, struct bNodeStack **out)
Definition: BKE_node.h:208
#define SH_NODE_TEX_ENVIRONMENT
Definition: BKE_node.h:1128
void(* NodeFreeExecFunction)(void *nodedata)
Definition: BKE_node.h:207
#define NODE_CUSTOM
Definition: BKE_node.h:981
#define CMP_NODE_HUECORRECT
Definition: BKE_node.h:1256
#define SH_NODE_TEX_IES
Definition: BKE_node.h:1165
bool nodeSupportsActiveFlag(const struct bNode *node, int sub_active)
Does the given node supports the sub active flag.
#define FN_NODE_INPUT_STRING
Definition: BKE_node.h:1523
#define CMP_NODE_GLARE
Definition: BKE_node.h:1272
#define CMP_NODE_CRYPTOMATTE_LEGACY
Definition: BKE_node.h:1289
#define TEX_NODE_IMAGE
Definition: BKE_node.h:1355
#define CMP_NODE_OUTPUT_FILE
Definition: BKE_node.h:1218
#define FOREACH_NODETREE_END
Definition: BKE_node.h:1058
#define NODE_TREE_TYPES_BEGIN(ntype)
Definition: BKE_node.h:426
int(* NodeGPUExecFunction)(struct GPUMaterial *mat, struct bNode *node, struct bNodeExecData *execdata, struct GPUNodeStack *in, struct GPUNodeStack *out)
Definition: BKE_node.h:214
#define CMP_NODE_CURVE_RGB
Definition: BKE_node.h:1204
#define NODE_SOCKET_TYPES_BEGIN(stype)
Definition: BKE_node.h:593
#define SH_NODE_TEX_POINTDENSITY
Definition: BKE_node.h:1163
#define SH_NODE_CURVE_RGB
Definition: BKE_node.h:1090
#define NODE_INSTANCE_HASH_ITER(iter_, hash_)
Definition: BKE_node.h:896
#define FOREACH_NODETREE_BEGIN(bmain, _nodetree, _id)
Definition: BKE_node.h:1048
#define TEX_NODE_CURVE_TIME
Definition: BKE_node.h:1359
#define CMP_CRYPTOMATTE_SRC_RENDER
Definition: BKE_node.h:1331
#define NODE_TREE_TYPES_END
Definition: BKE_node.h:433
#define NODE_FRAME
Definition: BKE_node.h:985
#define CMP_NODE_R_LAYERS
Definition: BKE_node.h:1216
#define NODE_SOCKET_TYPES_END
Definition: BKE_node.h:601
#define CMP_NODE_CURVE_VEC
Definition: BKE_node.h:1203
#define NODE_GROUP_INPUT
Definition: BKE_node.h:987
#define NODE_TYPES_END
Definition: BKE_node.h:574
#define CMP_NODE_IMAGE
Definition: BKE_node.h:1215
eNodeSizePreset
Definition: BKE_node.h:363
@ NODE_SIZE_DEFAULT
Definition: BKE_node.h:364
@ NODE_SIZE_LARGE
Definition: BKE_node.h:367
@ NODE_SIZE_SMALL
Definition: BKE_node.h:365
@ NODE_SIZE_MIDDLE
Definition: BKE_node.h:366
#define TEX_NODE_CURVE_RGB
Definition: BKE_node.h:1356
void BKE_ntree_update_tag_interface(struct bNodeTree *ntree)
void BKE_ntree_update_tag_socket_removed(struct bNodeTree *ntree)
void BKE_ntree_update_tag_all(struct bNodeTree *ntree)
void BKE_ntree_update_tag_node_property(struct bNodeTree *ntree, struct bNode *node)
void BKE_ntree_update_tag_socket_availability(struct bNodeTree *ntree, struct bNodeSocket *socket)
void BKE_ntree_update_tag_node_new(struct bNodeTree *ntree, struct bNode *node)
void BKE_ntree_update_tag_link_mute(struct bNodeTree *ntree, struct bNodeLink *link)
void BKE_ntree_update_tag_node_removed(struct bNodeTree *ntree)
void BKE_ntree_update_tag_node_internal_link(struct bNodeTree *ntree, struct bNode *node)
void BKE_ntree_update_tag_link_changed(struct bNodeTree *ntree)
void BKE_ntree_update_tag_socket_new(struct bNodeTree *ntree, struct bNodeSocket *socket)
void BKE_ntree_update_tag_socket_type(struct bNodeTree *ntree, struct bNodeSocket *socket)
void BKE_ntree_update_main(struct Main *bmain, struct NodeTreeUpdateExtraParams *params)
void BKE_ntree_update_tag_link_removed(struct bNodeTree *ntree)
void BKE_ntree_update_tag_link_added(struct bNodeTree *ntree, struct bNodeLink *link)
void BKE_ntree_update_tag_missing_runtime_data(struct bNodeTree *ntree)
#define BLI_assert_unreachable()
Definition: BLI_assert.h:93
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
bool BLI_ghash_haskey(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:822
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:858
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:689
void(* GHashValFreeFP)(void *val)
Definition: BLI_ghash.h:38
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:734
unsigned int BLI_ghash_len(const GHash *gh) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:705
GHashIterator * BLI_ghashIterator_new(GHash *gh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:891
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:790
void * BLI_ghash_popkey(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:805
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:710
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:863
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
Definition: BLI_listbase.h:354
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
Definition: BLI_listbase.h:344
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
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:340
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define FILE_MAX
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
size_t size_t char size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL()
Definition: string.c:250
bool BLI_uniquename_cb(UniquenameCheckCallback unique_check, void *arg, const char *defname, char delim, char *name, size_t name_len)
Definition: string_utils.c:233
bool BLI_uniquename(struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t name_len)
Definition: string_utils.c:309
#define STREQLEN(a, b, n)
#define UNUSED(x)
#define SET_FLAG_FROM_TEST(value, test, flag)
#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:1494
#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:5172
bool BLO_read_lib_is_undo(BlendLibReader *reader)
Definition: readfile.c:5308
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
Definition: writefile.c:1601
#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:1608
#define BLT_I18NCONTEXT_ID_NODETREE
#define CTX_IFACE_(context, msgid)
#define IFACE_(msgid)
#define DATA_(msgid)
#define CLOG_ERROR(clg_ref,...)
Definition: CLG_log.h:190
void DEG_relations_tag_update(struct Main *bmain)
@ IDP_TYPE_FILTER_ID
Definition: DNA_ID.h:155
@ INDEX_ID_NT
Definition: DNA_ID.h:996
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:566
#define MAX_ID_NAME
Definition: DNA_ID.h:337
#define MAX_IDPROP_NAME
Definition: DNA_ID.h:131
@ LIB_TAG_NEW
Definition: DNA_ID.h:704
@ LIB_TAG_LOCALIZED
Definition: DNA_ID.h:740
@ LIB_TAG_MISSING
Definition: DNA_ID.h:690
@ LIB_EMBEDDED_DATA
Definition: DNA_ID.h:635
#define FILTER_ID_NT
Definition: DNA_ID.h:915
@ ID_TE
Definition: DNA_ID_enums.h:52
@ ID_NT
Definition: DNA_ID_enums.h:68
@ ID_LA
Definition: DNA_ID_enums.h:55
@ ID_SCE
Definition: DNA_ID_enums.h:45
@ ID_LS
Definition: DNA_ID_enums.h:75
@ ID_WO
Definition: DNA_ID_enums.h:59
@ ID_SIM
Definition: DNA_ID_enums.h:84
@ ID_MA
Definition: DNA_ID_enums.h:51
Object groups, one object can be in many groups at once.
#define MAX_NAME
Definition: DNA_defs.h:48
#define NODE_OPTIONS
#define NODE_LINK_VALID
#define NTREE_TEXTURE
#define NTREE_UNDEFINED
#define NODE_MAXSTR
#define NODE_DO_OUTPUT
#define NTREE_GEOMETRY
#define NTREE_COMPOSIT
#define NODE_ACTIVE_TEXTURE
#define NODE_LINK_TEST
eNodeSocketInOut
@ SOCK_OUT
@ SOCK_IN
#define NODE_ACTIVE_PAINT_CANVAS
#define NODE_PREVIEW
@ SOCK_MULTI_INPUT
@ SOCK_IN_USE
@ SOCK_COLLAPSED
@ SOCK_HIDDEN
@ SOCK_UNAVAIL
eNodeSocketDatatype
@ SOCK_INT
@ SOCK_TEXTURE
@ __SOCK_MESH
@ SOCK_VECTOR
@ SOCK_BOOLEAN
@ SOCK_MATERIAL
@ SOCK_SHADER
@ SOCK_FLOAT
@ SOCK_IMAGE
@ SOCK_COLLECTION
@ SOCK_CUSTOM
@ SOCK_GEOMETRY
@ SOCK_OBJECT
@ SOCK_STRING
@ SOCK_RGBA
struct bNodeTree bNodeTree
#define NODE_SELECT
#define NTREE_SHADER
#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 y
_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 GLsizei width
Read Guarded memory(de)allocation.
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_point_info(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_sepcolor(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_curve_float(void)
void register_node_type_sh_combxyz(void)
void register_node_type_sh_bsdf_hair_principled(void)
void register_node_type_sh_combcolor(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 ntreeShaderEndExecTree(struct bNodeTreeExec *exec)
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)
NODE_GROUP_OUTPUT
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces SH_NODE_SCRIPT
NODE_GROUP
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color SH_NODE_CURVE_VEC
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color or the default fallback if none is specified Separate Split a vector into its and Z components Generates normals with round corners and may slow down renders Vector Displace the surface along an arbitrary direction White Return a random value or color based on an input seed SH_NODE_CURVE_FLOAT
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block SH_NODE_TEX_IMAGE
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Map
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 ntreeTexEndExecTree(struct bNodeTreeExec *exec)
void register_node_type_tex_combine_color(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_separate_color(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)
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:146
@ PROP_DIRECTION
Definition: RNA_types.h:155
@ PROP_XYZ
Definition: RNA_types.h:162
@ PROP_DISTANCE
Definition: RNA_types.h:149
@ PROP_ACCELERATION
Definition: RNA_types.h:157
@ PROP_ANGLE
Definition: RNA_types.h:145
@ PROP_TIME_ABSOLUTE
Definition: RNA_types.h:147
@ PROP_EULER
Definition: RNA_types.h:159
@ PROP_NONE
Definition: RNA_types.h:126
@ PROP_PERCENTAGE
Definition: RNA_types.h:143
@ PROP_FACTOR
Definition: RNA_types.h:144
@ PROP_TRANSLATION
Definition: RNA_types.h:154
@ PROP_UNSIGNED
Definition: RNA_types.h:142
@ PROP_VELOCITY
Definition: RNA_types.h:156
#define C
Definition: RandGen.cpp:25
__forceinline const avxb select(const avxb &m, const avxb &t, const avxb &f)
Definition: avxb.h:154
int main(int argc, char *argv[])
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
unsigned int U
Definition: btGjkEpa3.h:78
bool add(const Key &key, const Value &value)
Definition: BLI_map.hh:250
const Value & lookup(const Key &key) const
Definition: BLI_map.hh:485
void add_new(const Key &key, const Value &value)
Definition: BLI_map.hh:220
bool contains(const Key &key) const
Definition: BLI_set.hh:296
std::string id_name(void *id)
OperationNode * node
StackEntry * from
const char * label
Scene scene
void * user_data
DEGForeachIDComponentCallback callback
bNodeTree * ntree
DRWShaderLibrary * lib
#define str(s)
int count
#define GS(x)
Definition: iris.c:225
ccl_global KernelShaderEvalInput ccl_global float * output
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
size_t(* MEM_allocN_len)(const void *vmemh)
Definition: mallocn.c:26
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static unsigned c
Definition: RandGen.cpp:83
static unsigned a[3]
Definition: RandGen.cpp:78
GAttributeReader lookup(const void *owner, const AttributeIDRef &attribute_id)
std::unique_ptr< IDProperty, IDPropertyDeleter > create(StringRefNull prop_name, int32_t value)
Allocate a new IDProperty of type IDP_INT, set its name and value.
bNodeSocket * node_find_enabled_socket(bNode &node, const eNodeSocketInOut in_out, const StringRef name)
Definition: node.cc:1464
bNode * node_copy_with_mapping(bNodeTree *dst_tree, const bNode &node_src, const int flag, const bool unique_name, Map< const bNodeSocket *, bNodeSocket * > &socket_map)
Definition: node.cc:2198
bNodeSocket * node_find_enabled_output_socket(bNode &node, StringRef name)
Definition: node.cc:1482
bNodeSocket * node_find_enabled_input_socket(bNode &node, StringRef name)
Definition: node.cc:1477
bNode * node_copy(bNodeTree *dst_tree, const bNode &src_node, const int flag, const bool unique_name)
Definition: node.cc:2274
SymEdge< T > * prev(const SymEdge< T > *se)
Definition: delaunay_2d.cc:105
static const pxr::TfToken st("st", pxr::TfToken::Immortal)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static const pxr::TfToken preview("preview", pxr::TfToken::Immortal)
void nodeModifySocketType(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, const char *idname)
Definition: node.cc:1644
void node_type_gpu(struct bNodeType *ntype, NodeGPUExecFunction gpu_fn)
Definition: node.cc:4465
bNodeInstanceKey BKE_node_instance_key(bNodeInstanceKey parent_key, const bNodeTree *ntree, const bNode *node)
Definition: node.cc:3917
void nodeSocketDeclarationsUpdate(bNode *node)
Definition: node.cc:3703
void BKE_node_clipboard_init(const struct bNodeTree *ntree)
Definition: node.cc:3773
static GHash * nodetreetypes_hash
Definition: node.cc:1276
void node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
Definition: node.cc:4277
static void ntree_interface_type_create(bNodeTree *ntree)
Definition: node.cc:3461
void nodeSetSocketAvailability(bNodeTree *ntree, bNodeSocket *sock, bool is_available)
Definition: node.cc:3664
void ntreeTypeFreeLink(const bNodeTreeType *nt)
Definition: node.cc:1312
bool BKE_node_preview_used(const bNode *node)
Definition: node.cc:2715
static void nodeUnMuteLink(bNodeLink *link)
Definition: node.cc:2380
void nodeRemoveSocketEx(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock, bool do_id_user)
Definition: node.cc:1938
static bNodeInstanceKey node_hash_int_str(bNodeInstanceKey hash, const char *str)
Definition: node.cc:3903
static void library_foreach_node_socket(LibraryForeachIDData *data, bNodeSocket *sock)
Definition: node.cc:281
void ntreeNodeFlagSet(const bNodeTree *ntree, const int flag, const bool enable)
Definition: node.cc:3237
const char * nodeSocketTypeLabel(const bNodeSocketType *stype)
Definition: node.cc:1443
int nodeSocketLinkLimit(const bNodeSocket *sock)
Definition: node.cc:3679
static void ntree_blend_read_lib(BlendLibReader *reader, ID *id)
Definition: node.cc:935
static void node_preview_init_tree_recursive(bNodeInstanceHash *previews, bNodeTree *ntree, bNodeInstanceKey parent_key, const int xsize, const int ysize)
Definition: node.cc:2779
StructRNA * ntreeInterfaceTypeGet(bNodeTree *ntree, bool create)
Definition: node.cc:3495
void BKE_node_preview_init_tree(bNodeTree *ntree, int xsize, int ysize)
Definition: node.cc:2801
void nodeSetSelected(bNode *node, bool select)
Definition: node.cc:3615
bNodeSocket * nodeAddSocket(bNodeTree *ntree, bNode *node, eNodeSocketInOut in_out, const char *idname, const char *identifier, const char *name)
Definition: node.cc:1679
static void node_socket_copy(bNodeSocket *sock_dst, const bNodeSocket *sock_src, const int flag)
Definition: node.cc:2172
void ntreeBlendReadExpand(BlendExpander *expander, bNodeTree *ntree)
Definition: node.cc:996
static void ntree_blend_read_data(BlendDataReader *reader, ID *id)
Definition: node.cc:835
bNodeSocket * ntreeAddSocketInterface(bNodeTree *ntree, eNodeSocketInOut in_out, const char *idname, const char *name)
Definition: node.cc:3349
bool nodeAttachNodeCheck(const bNode *node, const bNode *parent)
Definition: node.cc:2583
bNode * nodeAddStaticNode(const struct bContext *C, bNodeTree *ntree, int type)
Definition: node.cc:2151
IDTypeInfo IDType_ID_NT
Definition: node.cc:1024
void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwidth)
Definition: node.cc:4396
static void update_socket_declarations(ListBase *sockets, Span< blender::nodes::SocketDeclarationPtr > declarations)
Definition: node.cc:3693
static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype)
Definition: node.cc:1054
bNodeTree * ntreeCopyTree(Main *bmain, const bNodeTree *ntree)
Definition: node.cc:2703
struct bNodeSocket * ntreeAddSocketInterfaceFromSocket(bNodeTree *ntree, bNode *from_node, bNodeSocket *from_sock)
Definition: node.cc:3382
void ntreeFreeEmbeddedTree(bNodeTree *ntree)
Definition: node.cc:3112
static GHash * nodesockettypes_hash
Definition: node.cc:1278
bNodeLink * nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock)
Definition: node.cc:2296
static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
Definition: node.cc:1082
void ntreeSetOutput(bNodeTree *ntree)
Definition: node.cc:3141
bNodeInstanceHash * BKE_node_instance_hash_new(const char *info)
Definition: node.cc:3943
bNodeType * nodeTypeFind(const char *idname)
Definition: node.cc:1327
bNodePreview * BKE_node_preview_verify(bNodeInstanceHash *previews, bNodeInstanceKey key, const int xsize, const int ysize, const bool create)
Definition: node.cc:2721
static void unique_socket_template_identifier(bNodeSocketTemplate *list, bNodeSocketTemplate *ntemp, const char defname[], char delim)
Definition: node.cc:4341
void node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs)
Definition: node.cc:4358
static void expand_node_sockets(BlendExpander *expander, ListBase *sockets)
Definition: node.cc:989
const ListBase * BKE_node_clipboard_get_nodes()
Definition: node.cc:3873
const bNodeInstanceKey NODE_INSTANCE_KEY_BASE
Definition: node.cc:3896
bool nodeDeclarationEnsureOnOutdatedNode(bNodeTree *UNUSED(ntree), bNode *node)
Definition: node.cc:3710
static void ntree_blend_write(BlendWriter *writer, ID *id, const void *id_address)
Definition: node.cc:644
static void node_set_typeinfo(const struct bContext *C, bNodeTree *ntree, bNode *node, bNodeType *typeinfo)
Definition: node.cc:1152
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4443
bNodeTree * ntreeFromID(ID *id)
Definition: node.cc:3231
void BKE_nodetree_remove_layer_n(bNodeTree *ntree, Scene *scene, const int layer_index)
Definition: node.cc:5067
static void nodeMuteRerouteInputLinks(bNodeTree *ntree, bNode *node, const bool mute)
Definition: node.cc:2388
void nodePositionPropagate(bNode *node)
Definition: node.cc:2663
void nodeUnregisterType(bNodeType *nt)
Definition: node.cc:1378
static void ntree_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
Definition: node.cc:134
void BKE_node_clipboard_add_node(bNode *node)
Definition: node.cc:3838
void nodeSetActive(bNodeTree *ntree, bNode *node)
Definition: node.cc:3644
static void registerShaderNodes()
Definition: node.cc:4620
void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree)
Definition: node.cc:519
void ntreeBlendReadLib(struct BlendLibReader *reader, struct bNodeTree *ntree)
Definition: node.cc:900
bool nodeIsChildOf(const bNode *parent, const bNode *child)
Definition: node.cc:2028
void BKE_node_instance_hash_insert(bNodeInstanceHash *hash, bNodeInstanceKey key, void *value)
Definition: node.cc:3957
static bNodeSocket * make_socket_interface(bNodeTree *ntree, eNodeSocketInOut in_out, const char *idname, const char *name)
Definition: node.cc:3300
static void ntree_blend_read_expand(BlendExpander *expander, ID *id)
Definition: node.cc:1018
static void ntree_set_typeinfo(bNodeTree *ntree, bNodeTreeType *typeinfo)
Definition: node.cc:1138
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:4426
void BKE_node_tree_iter_init(struct NodeTreeIterStore *ntreeiter, struct Main *bmain)
Definition: node.cc:5002
void ntreeUpdateAllUsers(Main *main, ID *id)
Definition: node.cc:4202
bNodeTree * ntreeLocalize(bNodeTree *ntree)
Definition: node.cc:3249
void BKE_node_preview_remove_unused(bNodeTree *ntree)
Definition: node.cc:2831
static blender::Set< int > get_known_node_types_set()
Definition: node.cc:4138
const ListBase * BKE_node_clipboard_get_links()
Definition: node.cc:3878
void nodeChainIter(const bNodeTree *ntree, const bNode *node_start, bool(*callback)(bNode *, bNode *, void *, const bool), void *userdata, const bool reversed)
Definition: node.cc:2039
static bool node_poll_instance_default(bNode *node, bNodeTree *ntree, const char **disabled_hint)
Definition: node.cc:4272
static void expand_node_socket(BlendExpander *expander, bNodeSocket *sock)
Definition: node.cc:941
GHashIterator * nodeTypeGetIterator()
Definition: node.cc:1390
static bool ntree_interface_unique_identifier_check(void *UNUSED(data), const char *identifier)
Definition: node.cc:3436
static bool node_instance_hash_key_cmp(const void *a, const void *b)
Definition: node.cc:3935
bool ntreeHasTree(const bNodeTree *ntree, const bNodeTree *lookup)
Definition: node.cc:3562
bool nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **r_node, int *r_sockindex)
Definition: node.cc:1997
int nodeSocketIsHidden(const bNodeSocket *sock)
Definition: node.cc:3659
int nodeCountSocketLinks(const bNodeTree *ntree, const bNodeSocket *sock)
Definition: node.cc:3590
static ID * node_owner_get(Main *bmain, ID *id, ID *owner_id_hint)
Definition: node.cc:407
void ntreeFreeCache(bNodeTree *ntree)
Definition: node.cc:3130
static bool unique_socket_template_identifier_check(void *arg, const char *name)
Definition: node.cc:4326
bool nodeDeclarationEnsure(bNodeTree *ntree, bNode *node)
Definition: node.cc:3731
void nodeFromView(const bNode *node, float x, float y, float *rx, float *ry)
Definition: node.cc:2570
void nodeMuteLinkToggle(bNodeTree *ntree, bNodeLink *link)
Definition: node.cc:2432
struct bNodeSocket * ntreeInsertSocketInterfaceFromSocket(bNodeTree *ntree, bNodeSocket *next_sock, bNode *from_node, bNodeSocket *from_sock)
Definition: node.cc:3396
void ntreeUpdateNodeLevels(bNodeTree *ntree)
Definition: node.cc:4122
void BKE_node_preview_free(bNodePreview *preview)
Definition: node.cc:2771
const char * nodeStaticSocketLabel(int type, int UNUSED(subtype))
Definition: node.cc:1864
static int node_count_links(const bNodeTree *ntree, const bNodeSocket *socket)
Definition: node.cc:2285
void BKE_node_preview_clear(bNodePreview *preview)
Definition: node.cc:2845
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4390
int BKE_node_instance_hash_remove(bNodeInstanceHash *hash, bNodeInstanceKey key, bNodeInstanceValueFP valfreefp)
Definition: node.cc:3970
void ntreeUpdateAllNew(Main *main)
Definition: node.cc:4173
static void registerFunctionNodes()
Definition: node.cc:4908
bool nodeSocketIsRegistered(bNodeSocket *sock)
Definition: node.cc:1433
static void node_socket_interface_free(bNodeTree *UNUSED(ntree), bNodeSocket *sock, const bool do_id_user)
Definition: node.cc:3070
static void direct_link_node_socket(BlendDataReader *reader, bNodeSocket *sock)
Definition: node.cc:660
void nodeModifySocketTypeStatic(bNodeTree *ntree, bNode *node, bNodeSocket *sock, int type, int subtype)
Definition: node.cc:1666
bNodeType NodeTypeUndefined
Definition: node.cc:111
bNodeTreeType * ntreeTypeFind(const char *idname)
Definition: node.cc:1280
#define NODE_DEFAULT_MAX_WIDTH
Definition: node.cc:87
void node_type_size_preset(struct bNodeType *ntype, eNodeSizePreset size)
Definition: node.cc:4408
const char * nodeSocketLabel(const bNodeSocket *sock)
Definition: node.cc:4249
static void node_unlink_attached(bNodeTree *ntree, bNode *parent)
Definition: node.cc:2933
bNode * nodeFindNodebyName(bNodeTree *ntree, const char *name)
Definition: node.cc:1992
void BKE_node_preview_merge_tree(bNodeTree *to_ntree, bNodeTree *from_ntree, bool remove_old)
Definition: node.cc:2865
static void update_typeinfo(Main *bmain, const struct bContext *C, bNodeTreeType *treetype, bNodeType *nodetype, bNodeSocketType *socktype, bool unregister)
Definition: node.cc:1203
bool nodeLinkIsSelected(const bNodeLink *link)
Definition: node.cc:2469
GHashIterator * ntreeTypeGetIterator()
Definition: node.cc:1322
static void node_preview_tag_used_recursive(bNodeInstanceHash *previews, bNodeTree *ntree, bNodeInstanceKey parent_key)
Definition: node.cc:2814
void * BKE_node_instance_hash_pop(bNodeInstanceHash *hash, bNodeInstanceKey key)
Definition: node.cc:3982
int BKE_node_instance_hash_haskey(bNodeInstanceHash *hash, bNodeInstanceKey key)
Definition: node.cc:3987
bool ntreeIsRegistered(bNodeTree *ntree)
Definition: node.cc:1317
bool BKE_node_clipboard_validate()
Definition: node.cc:3795
static bool node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *UNUSED(ntree), const char **UNUSED(disabled_hint))
Definition: node.cc:4264
static bool node_undefined_poll(bNodeType *UNUSED(ntype), bNodeTree *UNUSED(nodetree), const char **UNUSED(r_disabled_hint))
Definition: node.cc:4472
void nodeRegisterType(bNodeType *nt)
Definition: node.cc:1357
bNode * nodeGetActive(bNodeTree *ntree)
Definition: node.cc:3601
static GHash * nodetypes_hash
Definition: node.cc:1277
bNodeTree * ntreeAddTree(Main *bmain, const char *name, const char *idname)
Definition: node.cc:2674
GHashIterator * nodeSocketTypeGetIterator()
Definition: node.cc:1438
static void node_free_node(bNodeTree *ntree, bNode *node)
Definition: node.cc:2944
bNodeSocketType * nodeSocketTypeFind(const char *idname)
Definition: node.cc:1395
void ntreeTypeAdd(bNodeTreeType *nt)
Definition: node.cc:1292
void nodeClearActive(bNodeTree *ntree)
Definition: node.cc:3633
void ntreeFreeTree(bNodeTree *ntree)
Definition: node.cc:3106
static void registerTextureNodes()
Definition: node.cc:4720
static void node_foreach_id(ID *id, LibraryForeachIDData *data)
Definition: node.cc:329
bool BKE_node_instance_hash_tag_key(bNodeInstanceHash *hash, bNodeInstanceKey key)
Definition: node.cc:4015
bNodeSocket * ntreeInsertSocketInterface(bNodeTree *ntree, eNodeSocketInOut in_out, const char *idname, bNodeSocket *next_sock, const char *name)
Definition: node.cc:3365
void ntreeFreeLocalNode(bNodeTree *ntree, bNode *node)
Definition: node.cc:2998
void BKE_node_instance_hash_clear(bNodeInstanceHash *hash, bNodeInstanceValueFP valfreefp)
Definition: node.cc:3977
static bNodeClipboard node_clipboard
Definition: node.cc:3771
void node_type_group_update(struct bNodeType *ntype, void(*group_update_func)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4449
static bool unique_identifier_check(void *arg, const char *identifier)
Definition: node.cc:1490
static void ntree_interface_identifier(bNodeTree *ntree, const char *base, char *identifier, int maxlen, char *name, char *description)
Definition: node.cc:3442
const char * nodeStaticSocketType(int type, int subtype)
Definition: node.cc:1710
void BKE_node_preview_clear_tree(bNodeTree *ntree)
Definition: node.cc:2852
static void node_replace_undefined_types(bNode *node)
Definition: node.cc:4160
bNodeSocket * ntreeFindSocketInterface(bNodeTree *ntree, eNodeSocketInOut in_out, const char *identifier)
Definition: node.cc:3336
void BKE_node_clipboard_free()
Definition: node.cc:3888
static unsigned int node_instance_hash_key(const void *key)
Definition: node.cc:3930
bNodeLink * nodeFindLink(bNodeTree *ntree, const bNodeSocket *from, const bNodeSocket *to)
Definition: node.cc:3577
void nodeInternalRelink(bNodeTree *ntree, bNode *node)
Definition: node.cc:2490
bool nodeIsStaticSocketType(const struct bNodeSocketType *stype)
Definition: node.cc:1701
bool BKE_node_tree_iter_step(struct NodeTreeIterStore *ntreeiter, bNodeTree **r_nodetree, struct ID **r_id)
Definition: node.cc:5013
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:1501
static int node_get_deplist_recurs(bNodeTree *ntree, bNode *node, bNode ***nsort)
Definition: node.cc:4058
void BKE_node_instance_hash_tag(bNodeInstanceHash *UNUSED(hash), void *value)
Definition: node.cc:4009
const char * nodeStaticSocketInterfaceType(int type, int subtype)
Definition: node.cc:1787
static void ntree_interface_identifier_base(bNodeTree *ntree, char *base)
Definition: node.cc:3428
bNodeSocket * nodeAddStaticSocket(bNodeTree *ntree, bNode *node, eNodeSocketInOut in_out, int type, int subtype, const char *identifier, const char *name)
Definition: node.cc:1897
static void free_localized_node_groups(bNodeTree *ntree)
Definition: node.cc:3087
void nodeParentsIter(bNode *node, bool(*callback)(bNode *, void *), void *userdata)
Definition: node.cc:2115
void BKE_node_clipboard_add_link(bNodeLink *link)
Definition: node.cc:3868
static void registerGeometryNodes()
Definition: node.cc:4773
static void socket_id_user_increment(bNodeSocket *sock)
Definition: node.cc:1541
int BKE_node_instance_hash_size(bNodeInstanceHash *hash)
Definition: node.cc:3992
void nodeRemLink(bNodeTree *ntree, bNodeLink *link)
Definition: node.cc:2338
void nodeRemoveSocket(bNodeTree *ntree, bNode *node, bNodeSocket *sock)
Definition: node.cc:1933
void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
Definition: node.cc:2455
bool nodeLinkIsHidden(const bNodeLink *link)
Definition: node.cc:2464
void nodeUniqueName(bNodeTree *ntree, bNode *node)
Definition: node.cc:2127
static bool socket_id_user_decrement(bNodeSocket *sock)
Definition: node.cc:1585
void ntreeSetTypes(const struct bContext *C, bNodeTree *ntree)
Definition: node.cc:1253
void nodePositionRelative(bNode *from_node, bNode *to_node, bNodeSocket *from_sock, bNodeSocket *to_sock)
Definition: node.cc:2621
static void nodeMuteLink(bNodeLink *link)
Definition: node.cc:2371
bool nodeTypeUndefined(const bNode *node)
Definition: node.cc:1383
void BKE_node_instance_hash_remove_untagged(bNodeInstanceHash *hash, bNodeInstanceValueFP valfreefp)
Definition: node.cc:4028
static void node_free_socket_type(void *socktype_v)
Definition: node.cc:1408
void ntreeLocalMerge(Main *bmain, bNodeTree *localtree, bNodeTree *ntree)
Definition: node.cc:3286
void nodeToView(const bNode *node, float x, float y, float *rx, float *ry)
Definition: node.cc:2559
static void node_foreach_path(ID *id, BPathForeachPathData *bpath_data)
Definition: node.cc:384
void nodeRemoveNode(Main *bmain, bNodeTree *ntree, bNode *node, bool do_id_user)
Definition: node.cc:3011
static void ntree_free_type(void *treetype_v)
Definition: node.cc:1302
static void register_undefined_types()
Definition: node.cc:4481
static void adjust_multi_input_indices_after_removed_link(bNodeTree *ntree, bNodeSocket *sock, int deleted_index)
Definition: node.cc:2476
static void write_node_socket_default_value(BlendWriter *writer, bNodeSocket *sock)
Definition: node.cc:442
static bool nodeMuteFromSocketLinks(const bNodeTree *ntree, const bNodeSocket *sock)
Definition: node.cc:2356
static void node_socket_free(bNodeSocket *sock, const bool do_id_user)
Definition: node.cc:1917
bNodeTree ** BKE_ntree_ptr_from_id(ID *id)
Definition: node.cc:3209
void BKE_node_clipboard_clear()
Definition: node.cc:3778
void ntreeRemoveSocketInterface(bNodeTree *ntree, bNodeSocket *sock)
Definition: node.cc:3415
static CLG_LogRef LOG
Definition: node.cc:114
static void node_socket_set_typeinfo(bNodeTree *ntree, bNodeSocket *sock, bNodeSocketType *typeinfo)
Definition: node.cc:1181
static void nodeMuteRerouteOutputLinks(struct bNodeTree *ntree, struct bNode *node, const bool mute)
Definition: node.cc:2411
static bool can_read_node_type(const int type)
Definition: node.cc:4148
bNode * nodeFindRootParent(bNode *node)
Definition: node.cc:2020
static void lib_link_node_socket(BlendLibReader *reader, Library *lib, bNodeSocket *sock)
Definition: node.cc:841
void nodeChainIterBackwards(const bNodeTree *ntree, const bNode *node_start, bool(*callback)(bNode *, bNode *, void *), void *userdata, int recursion_lvl)
Definition: node.cc:2093
const bNodeInstanceKey NODE_INSTANCE_KEY_NONE
Definition: node.cc:3897
static void node_type_base_defaults(bNodeType *ntype)
Definition: node.cc:4254
int BKE_node_clipboard_get_type()
Definition: node.cc:3883
void nodeUnlinkNode(bNodeTree *ntree, bNode *node)
Definition: node.cc:2903
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:2065
bNode * ntreeFindType(const bNodeTree *ntree, int type)
Definition: node.cc:3550
void nodeRemoveAllSockets(bNodeTree *ntree, bNode *node)
Definition: node.cc:1967
bNode * nodeAddNode(const struct bContext *C, bNodeTree *ntree, const char *idname)
Definition: node.cc:2133
void BKE_node_instance_hash_clear_tags(bNodeInstanceHash *hash)
Definition: node.cc:3997
static void write_node_socket_interface(BlendWriter *writer, bNodeSocket *sock)
Definition: node.cc:506
void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
Definition: node.cc:675
void node_type_base_custom(bNodeType *ntype, const char *idname, const char *name, short nclass)
Definition: node.cc:4311
void ntreeInterfaceTypeFree(bNodeTree *ntree)
Definition: node.cc:3529
void node_type_exec(struct bNodeType *ntype, NodeInitExecFunction init_exec_fn, NodeFreeExecFunction free_exec_fn, NodeExecFunction exec_fn)
Definition: node.cc:4455
void nodeUnregisterSocketType(bNodeSocketType *st)
Definition: node.cc:1428
static bNodeTreeType NodeTreeTypeUndefined
Definition: node.cc:110
void ntreeFreeLocalTree(bNodeTree *ntree)
Definition: node.cc:3119
void nodeDetachNode(struct bNode *node)
Definition: node.cc:2607
void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***r_deplist, int *r_deplist_len)
Definition: node.cc:4095
void nodeLabel(const bNodeTree *ntree, const bNode *node, char *label, int maxlen)
Definition: node.cc:4227
struct bNodeSocket * nodeFindSocket(const bNode *node, eNodeSocketInOut in_out, const char *identifier)
Definition: node.cc:1449
bNodePreview * BKE_node_preview_copy(bNodePreview *preview)
Definition: node.cc:2762
void * BKE_node_instance_hash_lookup(bNodeInstanceHash *hash, bNodeInstanceKey key)
Definition: node.cc:3965
static void node_foreach_cache(ID *id, IDTypeForeachCacheFunctionCallback function_callback, void *user_data)
Definition: node.cc:360
bNodeTree * ntreeCopyTree_ex(const bNodeTree *ntree, Main *bmain, const bool do_id_user)
Definition: node.cc:2696
void BKE_node_instance_hash_free(bNodeInstanceHash *hash, bNodeInstanceValueFP valfreefp)
Definition: node.cc:3951
void ntreeInterfaceTypeUpdate(bNodeTree *ntree)
Definition: node.cc:3537
void BKE_node_system_init()
Definition: node.cc:4930
void BKE_node_system_exit()
Definition: node.cc:4957
static void registerCompositNodes()
Definition: node.cc:4507
static void ntree_init_data(ID *id)
Definition: node.cc:127
void nodeAttachNode(bNode *node, bNode *parent)
Definition: node.cc:2594
static void ntree_free_data(ID *id)
Definition: node.cc:226
static void lib_link_node_sockets(BlendLibReader *reader, Library *lib, ListBase *sockets)
Definition: node.cc:893
static void write_node_socket(BlendWriter *writer, bNodeSocket *sock)
Definition: node.cc:493
void nodeRegisterSocketType(bNodeSocketType *st)
Definition: node.cc:1419
bNodeSocketType NodeSocketTypeUndefined
Definition: node.cc:112
static void node_free_type(void *nodetype_v)
Definition: node.cc:1340
void register_node_type_group_output()
Definition: node_common.cc:607
void register_node_type_group_input()
Definition: node_common.cc:517
void register_node_type_frame()
Definition: node_common.cc:246
void register_node_type_reroute()
Definition: node_common.cc:276
void register_node_type_cmp_alphaover()
void register_node_type_cmp_antialiasing()
void register_node_type_cmp_bilateralblur()
void register_node_type_cmp_blur()
void register_node_type_cmp_bokehblur()
void register_node_type_cmp_bokehimage()
void register_node_type_cmp_boxmask()
void register_node_type_cmp_brightcontrast()
void register_node_type_cmp_channel_matte()
void register_node_type_cmp_chroma_matte()
void register_node_type_cmp_color_matte()
void register_node_type_cmp_color_spill()
void register_node_type_cmp_colorbalance()
void register_node_type_cmp_colorcorrection()
void register_node_type_cmp_group()
void register_node_type_cmp_composite()
void register_node_type_cmp_convert_color_space(void)
void register_node_type_cmp_cornerpin()
void register_node_type_cmp_crop()
void register_node_type_cmp_cryptomatte_legacy()
void register_node_type_cmp_cryptomatte()
void register_node_type_cmp_curve_rgb()
void register_node_type_cmp_curve_time()
void register_node_type_cmp_curve_vec()
void register_node_type_cmp_defocus()
void register_node_type_cmp_denoise()
void register_node_type_cmp_despeckle()
void register_node_type_cmp_diff_matte()
void register_node_type_cmp_dilateerode()
void register_node_type_cmp_dblur()
void register_node_type_cmp_displace()
void register_node_type_cmp_distance_matte()
void register_node_type_cmp_doubleedgemask()
void register_node_type_cmp_ellipsemask()
void register_node_type_cmp_exposure()
void register_node_type_cmp_filter()
void register_node_type_cmp_flip()
void register_node_type_cmp_gamma()
void register_node_type_cmp_glare()
void register_node_type_cmp_hue_sat()
void register_node_type_cmp_huecorrect()
void register_node_type_cmp_idmask()
void register_node_type_cmp_image()
void register_node_type_cmp_rlayers()
void register_node_type_cmp_inpaint()
void register_node_type_cmp_invert()
void register_node_type_cmp_keying()
void register_node_type_cmp_keyingscreen()
void register_node_type_cmp_lensdist()
void register_node_type_cmp_view_levels()
void register_node_type_cmp_luma_matte()
void register_node_type_cmp_map_range()
void register_node_type_cmp_mapuv()
void register_node_type_cmp_map_value()
void register_node_type_cmp_mask()
void register_node_type_cmp_math()
void register_node_type_cmp_mix_rgb()
void register_node_type_cmp_movieclip()
void register_node_type_cmp_moviedistortion()
void register_node_type_cmp_normal()
void register_node_type_cmp_normalize()
void register_node_type_cmp_output_file()
void register_node_type_cmp_pixelate()
void register_node_type_cmp_planetrackdeform()
void register_node_type_cmp_posterize()
void register_node_type_cmp_premulkey()
void register_node_type_cmp_rgb()
void register_node_type_cmp_rotate()
void register_node_type_cmp_scale()
void register_node_type_cmp_scene_time()
void register_node_type_cmp_combine_color()
void register_node_type_cmp_separate_color()
void register_node_type_cmp_combhsva()
void register_node_type_cmp_sephsva()
void register_node_type_cmp_combrgba()
void register_node_type_cmp_seprgba()
void register_node_type_cmp_separate_xyz()
void register_node_type_cmp_combine_xyz()
void register_node_type_cmp_sepycca()
void register_node_type_cmp_combycca()
void register_node_type_cmp_sepyuva()
void register_node_type_cmp_combyuva()
void register_node_type_cmp_setalpha()
void register_node_type_cmp_splitviewer()
void register_node_type_cmp_stabilize2d()
void register_node_type_cmp_sunbeams()
void register_node_type_cmp_switch()
void register_node_type_cmp_switch_view()
void register_node_type_cmp_texture()
void register_node_type_cmp_tonemap()
void register_node_type_cmp_trackpos()
void register_node_type_cmp_transform()
void register_node_type_cmp_translate()
void register_node_tree_type_cmp()
void register_node_type_cmp_valtorgb()
void register_node_type_cmp_rgbtobw()
void register_node_type_cmp_value()
void register_node_type_cmp_vecblur()
void register_node_type_cmp_viewer()
void register_node_type_cmp_zcombine()
void register_node_type_fn_align_euler_to_vector()
void register_node_type_fn_boolean_math()
void register_node_type_fn_combine_color(void)
void register_node_type_fn_compare()
void register_node_type_fn_float_to_int()
void register_node_type_fn_input_bool()
void register_node_type_fn_input_color()
void register_node_type_fn_input_int()
void register_node_type_fn_input_special_characters()
void register_node_type_fn_input_string()
void register_node_type_fn_input_vector()
void register_node_type_fn_random_value()
void register_node_type_fn_replace_string()
void register_node_type_fn_rotate_euler()
void register_node_type_fn_separate_color(void)
void register_node_type_fn_slice_string()
void register_node_type_fn_string_length()
void register_node_type_fn_value_to_string()
void register_node_type_geo_accumulate_field()
void register_node_type_geo_attribute_capture()
void register_node_type_geo_attribute_domain_size()
void register_node_type_geo_attribute_statistic()
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 register_node_type_geo_convex_hull()
void register_node_type_geo_curve_endpoint_selection()
void register_node_type_geo_curve_fill()
void register_node_type_geo_curve_fillet()
void register_node_type_geo_curve_handle_type_selection()
void register_node_type_geo_curve_length()
void register_node_type_geo_curve_primitive_arc()
void register_node_type_geo_curve_primitive_bezier_segment()
void register_node_type_geo_curve_primitive_circle()
void register_node_type_geo_curve_primitive_line()
void register_node_type_geo_curve_primitive_quadratic_bezier()
void register_node_type_geo_curve_primitive_quadrilateral()
void register_node_type_geo_curve_primitive_spiral()
void register_node_type_geo_curve_primitive_star()
void register_node_type_geo_curve_resample()
void register_node_type_geo_curve_reverse()
void register_node_type_geo_curve_sample()
void register_node_type_geo_curve_set_handle_type()
void register_node_type_geo_curve_spline_parameter()
void register_node_type_geo_curve_spline_type()
void register_node_type_geo_curve_subdivide()
void register_node_type_geo_curve_to_mesh()
void register_node_type_geo_curve_to_points()
void register_node_type_geo_curve_trim()
void register_node_type_geo_deform_curves_on_surface()
void register_node_type_geo_delete_geometry()
void register_node_type_geo_distribute_points_on_faces()
void register_node_type_geo_dual_mesh()
void register_node_type_geo_duplicate_elements()
void register_node_type_geo_edge_paths_to_curves()
void register_node_type_geo_edge_paths_to_selection()
void register_node_type_geo_edge_split()
void register_node_type_geo_extrude_mesh()
void register_node_type_geo_field_at_index()
void register_node_type_geo_flip_faces()
void register_node_type_geo_geometry_to_instance()
void register_node_type_geo_image_texture()
void register_node_type_geo_input_curve_handles()
void register_node_type_geo_input_curve_tilt()
void register_node_type_geo_input_id()
void register_node_type_geo_input_index()
void register_node_type_geo_input_instance_rotation()
void register_node_type_geo_input_instance_scale()
void register_node_type_geo_input_material()
void register_node_type_geo_input_material_index()
void register_node_type_geo_input_mesh_edge_angle()
void register_node_type_geo_input_mesh_edge_neighbors()
void register_node_type_geo_input_mesh_edge_vertices()
void register_node_type_geo_input_mesh_face_area()
void register_node_type_geo_input_mesh_face_is_planar()
void register_node_type_geo_input_mesh_face_neighbors()
void register_node_type_geo_input_mesh_island()
void register_node_type_geo_input_mesh_vertex_neighbors()
void register_node_type_geo_input_named_attribute()
void register_node_type_geo_input_normal()
void register_node_type_geo_input_position()
void register_node_type_geo_input_radius()
void register_node_type_geo_input_scene_time()
void register_node_type_geo_input_shade_smooth()
void register_node_type_geo_input_shortest_edge_paths()
void register_node_type_geo_input_spline_cyclic()
void register_node_type_geo_input_spline_length()
void register_node_type_geo_input_spline_resolution()
void register_node_type_geo_input_tangent()
void register_node_type_geo_instance_on_points()
void register_node_type_geo_instances_to_points()
void register_node_type_geo_interpolate_domain()
void register_node_type_geo_is_viewport()
void register_node_type_geo_join_geometry()
void register_node_type_geo_material_replace()
void register_node_type_geo_material_selection()
void register_node_type_geo_merge_by_distance()
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_mesh_subdivide()
void register_node_type_geo_mesh_to_curve()
void register_node_type_geo_mesh_to_points()
void register_node_type_geo_mesh_to_volume()
void register_node_type_geo_object_info()
void register_node_type_geo_points()
void register_node_type_geo_points_to_vertices()
void register_node_type_geo_points_to_volume()
void register_node_type_geo_proximity()
void register_node_type_geo_raycast()
void register_node_type_geo_realize_instances()
void register_node_type_geo_remove_attribute()
void register_node_type_geo_rotate_instances()
void register_node_type_geo_scale_elements()
void register_node_type_geo_scale_instances()
void register_node_type_geo_separate_components()
void register_node_type_geo_separate_geometry()
void register_node_type_geo_set_curve_handles()
void register_node_type_geo_set_curve_radius()
void register_node_type_geo_set_curve_tilt()
void register_node_type_geo_set_id()
void register_node_type_geo_set_material()
void register_node_type_geo_set_material_index()
void register_node_type_geo_set_point_radius()
void register_node_type_geo_set_position()
void register_node_type_geo_set_shade_smooth()
void register_node_type_geo_set_spline_cyclic()
void register_node_type_geo_set_spline_resolution()
void register_node_type_geo_store_named_attribute()
void register_node_type_geo_string_join()
void register_node_type_geo_string_to_curves()
void register_node_type_geo_subdivision_surface()
void register_node_type_geo_switch()
void register_node_type_geo_transfer_attribute()
void register_node_type_geo_transform()
void register_node_type_geo_translate_instances()
void register_node_type_geo_triangulate()
void register_node_type_geo_uv_pack_islands()
void register_node_type_geo_uv_unwrap()
void register_node_type_geo_viewer()
void register_node_type_geo_volume_cube()
void register_node_type_geo_volume_to_mesh()
void register_node_tree_type_geo()
void node_socket_init_default_value(bNodeSocket *sock)
Definition: node_socket.cc:286
struct bNodeSocket * node_add_socket_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp, eNodeSocketInOut in_out)
Definition: node_socket.cc:41
void node_verify_sockets(bNodeTree *ntree, bNode *node, bool do_id_user)
Definition: node_socket.cc:257
void register_standard_node_socket_types()
Definition: node_socket.cc:860
static bNodeSocketTemplate outputs[]
static bNodeSocketTemplate inputs[]
static void unique_name(bNode *node)
#define hash
Definition: noise.c:153
const char * RNA_struct_identifier(const StructRNA *type)
Definition: rna_access.c:586
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
Definition: rna_access.c:695
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:136
void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
Definition: rna_access.c:902
const char * RNA_struct_ui_name(const StructRNA *type)
Definition: rna_access.c:591
StructRNA * RNA_struct_find(const char *identifier)
Definition: rna_access.c:581
void RNA_def_struct_ui_text(StructRNA *srna, const char *name, const char *description)
Definition: rna_define.c:1237
void RNA_identifier_sanitize(char *identifier, int property)
Definition: rna_define.c:603
void RNA_def_struct_identifier(BlenderRNA *brna, StructRNA *srna, const char *identifier)
Definition: rna_define.c:1205
StructRNA * RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRNA *srnafrom)
Definition: rna_define.c:900
void RNA_struct_free(BlenderRNA *brna, StructRNA *srna)
Definition: rna_define.c:777
BlenderRNA BLENDER_RNA
StructRNA RNA_PropertyGroup
StructRNA * srna
Definition: RNA_types.h:766
struct bNodeTree * nodetree
unsigned int id_session_uuid
Definition: BKE_idtype.h:46
size_t offset_in_ID
Definition: BKE_idtype.h:49
Definition: DNA_ID.h:368
int tag
Definition: DNA_ID.h:387
struct Library * lib
Definition: DNA_ID.h:372
short flag
Definition: DNA_ID.h:383
void * next
Definition: DNA_ID.h:369
char name[66]
Definition: DNA_ID.h:378
struct Scene * scene
struct bNodeTree * nodetree
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
ListBase scenes
Definition: BKE_main.h:168
ListBase textures
Definition: BKE_main.h:175
ListBase lights
Definition: BKE_main.h:178
ListBase nodetrees
Definition: BKE_main.h:192
ListBase materials
Definition: BKE_main.h:174
ListBase linestyles
Definition: BKE_main.h:201
ListBase worlds
Definition: BKE_main.h:182
ListBase simulations
Definition: BKE_main.h:211
struct bNodeTree * nodetree
NodeCryptomatte_Runtime runtime
char angle streaks
char angle star_45
ImageFormatData format
struct Simulation * simulation
Definition: BKE_node.h:1040
struct Light * light
Definition: BKE_node.h:1037
struct World * world
Definition: BKE_node.h:1038
struct FreestyleLineStyle * linestyle
Definition: BKE_node.h:1039
struct Material * mat
Definition: BKE_node.h:1035
bNodeTree * ngroup
Definition: BKE_node.h:1033
struct bNodeTree * nodetree
struct bNodeTree * nodetree
bNodeSocketTemplate * list
Definition: node.cc:4322
bNodeSocketTemplate * ntemp
Definition: node.cc:4323
struct ImageUser iuser
struct bNodeTree * nodetree
struct bNodeTree * nodetree
struct bNodeClipboardExtraInfo * next
Definition: node.cc:3753
char library_name[FILE_MAX]
Definition: node.cc:3756
char id_name[MAX_ID_NAME]
Definition: node.cc:3755
ListBase nodes
Definition: node.cc:3761
ListBase links
Definition: node.cc:3767
ListBase nodes_extra_info
Definition: node.cc:3764
bNodeInstanceKey key
unsigned char * rect
Compact definition of a node socket.
Definition: BKE_node.h:84
char identifier[64]
Definition: BKE_node.h:94
Defines a socket type.
Definition: BKE_node.h:143
char label[64]
Definition: BKE_node.h:147
void(* interface_from_socket)(struct bNodeTree *ntree, struct bNodeSocket *interface_socket, struct bNode *node, struct bNodeSocket *sock)
Definition: BKE_node.h:174
int input_link_limit
Definition: BKE_node.h:188
ExtensionRNA ext_socket
Definition: BKE_node.h:180
int output_link_limit
Definition: BKE_node.h:189
bool use_link_limits_of_type
Definition: BKE_node.h:187
void(* free_self)(struct bNodeSocketType *stype)
Definition: BKE_node.h:192
void(* interface_register_properties)(struct bNodeTree *ntree, struct bNodeSocket *interface_socket, struct StructRNA *data_srna)
Definition: BKE_node.h:161
char idname[64]
Definition: BKE_node.h:145
struct Collection * value
struct Image * value
struct Material * value
struct Object * value
char name[64]
IDProperty * prop
bNodeSocketRuntimeHandle * runtime
struct bNodeLink * link
char description[64]
char * default_attribute_name
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:375
void(* free_node_cache)(struct bNodeTree *ntree, struct bNode *node)
Definition: BKE_node.h:383
void(* local_merge)(struct Main *bmain, struct bNodeTree *localtree, struct bNodeTree *ntree)
Definition: BKE_node.h:397
void(* free_cache)(struct bNodeTree *ntree)
Definition: BKE_node.h:382
char ui_name[64]
Definition: BKE_node.h:377
void(* localize)(struct bNodeTree *localtree, struct bNodeTree *ntree)
Definition: BKE_node.h:396
char ui_description[256]
Definition: BKE_node.h:378
void(* node_add_init)(struct bNodeTree *ntree, struct bNode *bnode)
Definition: BKE_node.h:404
void(* progress)(void *, float progress)
bNodeTreeRuntimeHandle * runtime
char idname[64]
short is_updating
struct bNodeInstanceHash * previews
struct PreviewImage * preview
struct bNodeTreeType * typeinfo
struct bGPdata * gpd
struct StructRNA * interface_type
ListBase nodes
ListBase inputs
ListBase links
ListBase outputs
struct bNodeTreeExec * execdata
struct AnimData * adt
Defines a node type.
Definition: BKE_node.h:226
void(* copyfunc)(struct bNodeTree *dest_ntree, struct bNode *dest_node, const struct bNode *src_node)
Definition: BKE_node.h:274
float minwidth
Definition: BKE_node.h:234
void(* group_update_func)(struct bNodeTree *ntree, struct bNode *node)
Definition: BKE_node.h:267
float width
Definition: BKE_node.h:234
short flag
Definition: BKE_node.h:236
char ui_name[64]
Definition: BKE_node.h:230
bool(* poll)(struct bNodeType *ntype, struct bNodeTree *nodetree, const char **r_disabled_hint)
Definition: BKE_node.h:292
float maxwidth
Definition: BKE_node.h:234
int type
Definition: BKE_node.h:228
NodeInitExecFunction init_exec_fn
Definition: BKE_node.h:306
void(* updatefunc)(struct bNodeTree *ntree, struct bNode *node)
Definition: BKE_node.h:265
bNodeSocketTemplate * outputs
Definition: BKE_node.h:239
void(* initfunc_api)(const struct bContext *C, struct PointerRNA *ptr)
Definition: BKE_node.h:279
void(* free_self)(struct bNodeType *ntype)
Definition: BKE_node.h:303
bool declaration_is_dynamic
Definition: BKE_node.h:326
short nclass
Definition: BKE_node.h:236
void(* freefunc)(struct bNode *node)
Definition: BKE_node.h:272
NodeGPUExecFunction gpu_fn
Definition: BKE_node.h:310
float minheight
Definition: BKE_node.h:235
NodeDeclareFunction declare
Definition: BKE_node.h:324
float height
Definition: BKE_node.h:235
bNodeSocketTemplate * inputs
Definition: BKE_node.h:239
char storagename[64]
Definition: BKE_node.h:241
float maxheight
Definition: BKE_node.h:235
NodeExecFunction exec_fn
Definition: BKE_node.h:308
bool(* poll_instance)(struct bNode *node, struct bNodeTree *nodetree, const char **r_disabled_hint)
Definition: BKE_node.h:296
void(* initfunc)(struct bNodeTree *ntree, struct bNode *node)
Definition: BKE_node.h:270
char idname[64]
Definition: BKE_node.h:227
void(* copyfunc_api)(struct PointerRNA *ptr, const struct bNode *src_node)
Definition: BKE_node.h:281
NodeFreeExecFunction free_exec_fn
Definition: BKE_node.h:307
NodeDeclarationHandle * fixed_declaration
Definition: BKE_node.h:328
short level
float locy
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
bNodeRuntimeHandle * runtime
ListBase outputs
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480