Blender  V3.3
node_composite_tree.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2007 Blender Foundation. All rights reserved. */
3 
8 #include <cstdio>
9 
10 #include "DNA_color_types.h"
11 #include "DNA_node_types.h"
12 #include "DNA_scene_types.h"
13 
14 #include "BLT_translation.h"
15 
16 #include "BKE_context.h"
17 #include "BKE_global.h"
18 #include "BKE_image.h"
19 #include "BKE_main.h"
20 #include "BKE_node.h"
21 #include "BKE_node_tree_update.h"
22 #include "BKE_tracking.h"
23 
24 #include "UI_resources.h"
25 
26 #include "node_common.h"
27 #include "node_util.h"
28 
29 #include "RNA_access.h"
30 #include "RNA_prototypes.h"
31 
32 #include "NOD_composite.h"
33 #include "node_composite_util.hh"
34 
35 #ifdef WITH_COMPOSITOR
36 # include "COM_compositor.h"
37 #endif
38 
40  bNodeTreeType *UNUSED(treetype),
41  bNodeTree **r_ntree,
42  ID **r_id,
43  ID **r_from)
44 {
46 
47  *r_from = nullptr;
48  *r_id = &scene->id;
49  *r_ntree = scene->nodetree;
50 }
51 
52 static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func)
53 {
54  func(calldata, NODE_CLASS_INPUT, N_("Input"));
55  func(calldata, NODE_CLASS_OUTPUT, N_("Output"));
56  func(calldata, NODE_CLASS_OP_COLOR, N_("Color"));
57  func(calldata, NODE_CLASS_OP_VECTOR, N_("Vector"));
58  func(calldata, NODE_CLASS_OP_FILTER, N_("Filter"));
59  func(calldata, NODE_CLASS_CONVERTER, N_("Converter"));
60  func(calldata, NODE_CLASS_MATTE, N_("Matte"));
61  func(calldata, NODE_CLASS_DISTORT, N_("Distort"));
62  func(calldata, NODE_CLASS_GROUP, N_("Group"));
63  func(calldata, NODE_CLASS_INTERFACE, N_("Interface"));
64  func(calldata, NODE_CLASS_LAYOUT, N_("Layout"));
65 }
66 
68 {
69  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
70  if (sock->cache) {
71  sock->cache = nullptr;
72  }
73  }
74 }
75 
76 static void free_cache(bNodeTree *ntree)
77 {
80  }
81 }
82 
83 /* local tree then owns all compbufs */
84 static void localize(bNodeTree *localtree, bNodeTree *ntree)
85 {
86 
88  bNode *local_node = (bNode *)localtree->nodes.first;
89  while (node != nullptr) {
90 
91  /* Ensure new user input gets handled ok. */
92  node->need_exec = 0;
93  local_node->original = node;
94 
95  /* move over the compbufs */
96  /* right after #ntreeCopyTree() `oldsock` pointers are valid */
97 
99  if (node->id) {
100  if (node->flag & NODE_DO_OUTPUT) {
101  local_node->id = (ID *)node->id;
102  }
103  else {
104  local_node->id = nullptr;
105  }
106  }
107  }
108 
109  node = node->next;
110  local_node = local_node->next;
111  }
112 }
113 
114 static void local_merge(Main *bmain, bNodeTree *localtree, bNodeTree *ntree)
115 {
116  bNode *lnode;
117  bNodeSocket *lsock;
118 
119  /* move over the compbufs and previews */
120  BKE_node_preview_merge_tree(ntree, localtree, true);
121 
122  for (lnode = (bNode *)localtree->nodes.first; lnode; lnode = lnode->next) {
123  if (bNode *orig_node = nodeFindNodebyName(ntree, lnode->name)) {
125  if (lnode->id && (lnode->flag & NODE_DO_OUTPUT)) {
126  /* image_merge does sanity check for pointers */
127  BKE_image_merge(bmain, (Image *)orig_node->id, (Image *)lnode->id);
128  }
129  }
130  else if (lnode->type == CMP_NODE_MOVIEDISTORTION) {
131  /* special case for distortion node: distortion context is allocating in exec function
132  * and to achieve much better performance on further calls this context should be
133  * copied back to original node */
134  if (lnode->storage) {
135  if (orig_node->storage) {
136  BKE_tracking_distortion_free((MovieDistortion *)orig_node->storage);
137  }
138 
139  orig_node->storage = BKE_tracking_distortion_copy((MovieDistortion *)lnode->storage);
140  }
141  }
142 
143  for (lsock = (bNodeSocket *)lnode->outputs.first; lsock; lsock = lsock->next) {
144  if (bNodeSocket *orig_socket = nodeFindSocket(orig_node, SOCK_OUT, lsock->identifier)) {
145  orig_socket->cache = lsock->cache;
146  lsock->cache = nullptr;
147  orig_socket = nullptr;
148  }
149  }
150  }
151  }
152 }
153 
154 static void update(bNodeTree *ntree)
155 {
157 
159 }
160 
161 static void composite_node_add_init(bNodeTree *UNUSED(bnodetree), bNode *bnode)
162 {
163  /* Composite node will only show previews for input classes
164  * by default, other will be hidden
165  * but can be made visible with the show_preview option */
166  if (bnode->typeinfo->nclass != NODE_CLASS_INPUT) {
167  bnode->flag &= ~NODE_PREVIEW;
168  }
169 }
170 
172  bNodeSocketType *socket_type)
173 {
174  return nodeIsStaticSocketType(socket_type) &&
175  ELEM(socket_type->type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA);
176 }
177 
179 
181 {
182  bNodeTreeType *tt = ntreeType_Composite = MEM_cnew<bNodeTreeType>(__func__);
183 
184  tt->type = NTREE_COMPOSIT;
185  strcpy(tt->idname, "CompositorNodeTree");
186  strcpy(tt->ui_name, N_("Compositor"));
187  tt->ui_icon = ICON_NODE_COMPOSITING;
188  strcpy(tt->ui_description, N_("Compositing nodes"));
189 
190  tt->free_cache = free_cache;
193  tt->localize = localize;
194  tt->local_merge = local_merge;
195  tt->update = update;
199 
200  tt->rna_ext.srna = &RNA_CompositorNodeTree;
201 
202  ntreeTypeAdd(tt);
203 }
204 
206  bNodeTree *ntree,
207  RenderData *rd,
208  int rendering,
209  int do_preview,
210  const char *view_name)
211 {
212 #ifdef WITH_COMPOSITOR
213  COM_execute(rd, scene, ntree, rendering, view_name);
214 #else
215  UNUSED_VARS(scene, ntree, rd, rendering, view_name);
216 #endif
217 
218  UNUSED_VARS(do_preview);
219 }
220 
221 /* *********************************************** */
222 
224 {
225  if (ntree == nullptr) {
226  return;
227  }
228 
230  if (node->type == CMP_NODE_R_LAYERS) {
232  }
233  }
234 }
235 
237 {
238  /* XXX Think using G_MAIN here is valid, since you want to update current file's scene nodes,
239  * not the ones in temp main generated for rendering?
240  * This is still rather weak though,
241  * ideally render struct would store own main AND original G_MAIN. */
242 
243  for (Scene *sce_iter = (Scene *)G_MAIN->scenes.first; sce_iter;
244  sce_iter = (Scene *)sce_iter->id.next) {
245  if (sce_iter->nodetree) {
246  LISTBASE_FOREACH (bNode *, node, &sce_iter->nodetree->nodes) {
247  if (node->id == (ID *)scene || node->type == CMP_NODE_COMPOSITE) {
248  BKE_ntree_update_tag_node_property(sce_iter->nodetree, node);
249  }
250  else if (node->type == CMP_NODE_TEXTURE) /* uses scene size_x/size_y */ {
251  BKE_ntree_update_tag_node_property(sce_iter->nodetree, node);
252  }
253  }
254  }
255  }
256  BKE_ntree_update_main(G_MAIN, nullptr);
257 }
258 
259 /* XXX after render animation system gets a refresh, this call allows composite to end clean */
261 {
262  if (ntree == nullptr) {
263  return;
264  }
265 
267  node->need_exec = 0;
268  if (node->type == NODE_GROUP) {
270  }
271  }
272 }
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
#define G_MAIN
Definition: BKE_global.h:267
void BKE_image_merge(struct Main *bmain, struct Image *dest, struct Image *source)
void ntreeTypeAdd(struct bNodeTreeType *nt)
Definition: node.cc:1292
#define NODE_CLASS_OUTPUT
Definition: BKE_node.h:346
#define CMP_NODE_COMPOSITE
Definition: BKE_node.h:1217
#define CMP_NODE_SPLITVIEWER
Definition: BKE_node.h:1235
#define NODE_CLASS_INTERFACE
Definition: BKE_node.h:357
#define CMP_NODE_VIEWER
Definition: BKE_node.h:1196
#define NODE_CLASS_MATTE
Definition: BKE_node.h:352
#define NODE_CLASS_CONVERTER
Definition: BKE_node.h:351
#define CMP_NODE_MOVIEDISTORTION
Definition: BKE_node.h:1260
void(* bNodeClassCallback)(void *calldata, int nclass, const char *name)
Definition: BKE_node.h:372
#define CMP_NODE_TEXTURE
Definition: BKE_node.h:1219
struct bNode * nodeFindNodebyName(struct bNodeTree *ntree, const char *name)
Definition: node.cc:1992
#define NODE_CLASS_DISTORT
Definition: BKE_node.h:353
void BKE_node_preview_merge_tree(struct bNodeTree *to_ntree, struct bNodeTree *from_ntree, bool remove_old)
Definition: node.cc:2865
bool nodeIsStaticSocketType(const struct bNodeSocketType *stype)
Definition: node.cc:1701
void ntreeSetOutput(struct bNodeTree *ntree)
Definition: node.cc:3141
struct bNodeSocket * nodeFindSocket(const struct bNode *node, eNodeSocketInOut in_out, const char *identifier)
#define NODE_CLASS_OP_VECTOR
Definition: BKE_node.h:348
#define NODE_CLASS_LAYOUT
Definition: BKE_node.h:361
#define NODE_CLASS_OP_COLOR
Definition: BKE_node.h:347
#define NODE_CLASS_INPUT
Definition: BKE_node.h:345
#define NODE_CLASS_OP_FILTER
Definition: BKE_node.h:349
#define CMP_NODE_R_LAYERS
Definition: BKE_node.h:1216
#define NODE_CLASS_GROUP
Definition: BKE_node.h:350
void BKE_ntree_update_tag_node_property(struct bNodeTree *ntree, struct bNode *node)
void BKE_ntree_update_main(struct Main *bmain, struct NodeTreeUpdateExtraParams *params)
struct MovieDistortion * BKE_tracking_distortion_copy(struct MovieDistortion *distortion)
Definition: tracking.c:2347
void BKE_tracking_distortion_free(struct MovieDistortion *distortion)
Definition: tracking.c:2450
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
#define UNUSED_VARS(...)
#define UNUSED(x)
#define ELEM(...)
void COM_execute(RenderData *render_data, Scene *scene, bNodeTree *node_tree, int rendering, const char *view_name)
The main method that is used to execute the compositor tree. It can be executed during editing (blenk...
#define NODE_DO_OUTPUT
#define NTREE_COMPOSIT
@ SOCK_OUT
#define NODE_PREVIEW
@ SOCK_VECTOR
@ SOCK_FLOAT
@ SOCK_RGBA
NODE_GROUP
#define C
Definition: RandGen.cpp:25
OperationNode * node
Scene scene
bNodeTree * ntree
void ntree_update_reroute_nodes(bNodeTree *ntree)
Definition: node_common.cc:321
void node_cmp_rlayers_outputs(bNodeTree *ntree, bNode *node)
static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func)
static bool composite_node_tree_socket_type_valid(bNodeTreeType *UNUSED(ntreetype), bNodeSocketType *socket_type)
static void composite_node_add_init(bNodeTree *UNUSED(bnodetree), bNode *bnode)
static void free_node_cache(bNodeTree *UNUSED(ntree), bNode *node)
void ntreeCompositTagRender(Scene *scene)
static void local_merge(Main *bmain, bNodeTree *localtree, bNodeTree *ntree)
static void localize(bNodeTree *localtree, bNodeTree *ntree)
static void update(bNodeTree *ntree)
bNodeTreeType * ntreeType_Composite
void ntreeCompositUpdateRLayers(bNodeTree *ntree)
void ntreeCompositClearTags(bNodeTree *ntree)
static void free_cache(bNodeTree *ntree)
static void composite_get_from_context(const bContext *C, bNodeTreeType *UNUSED(treetype), bNodeTree **r_ntree, ID **r_id, ID **r_from)
void register_node_tree_type_cmp()
void ntreeCompositExecTree(Scene *scene, bNodeTree *ntree, RenderData *rd, int rendering, int do_preview, const char *view_name)
StructRNA * srna
Definition: RNA_types.h:766
Definition: DNA_ID.h:368
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
struct bNodeTree * nodetree
Defines a socket type.
Definition: BKE_node.h:143
struct bNodeSocket * next
char identifier[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(* update)(struct bNodeTree *ntree)
Definition: BKE_node.h:400
void(* local_merge)(struct Main *bmain, struct bNodeTree *localtree, struct bNodeTree *ntree)
Definition: BKE_node.h:397
void(* get_from_context)(const struct bContext *C, struct bNodeTreeType *ntreetype, struct bNodeTree **r_ntree, struct ID **r_id, struct ID **r_from)
Definition: BKE_node.h:389
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
bool(* valid_socket_type)(struct bNodeTreeType *ntreetype, struct bNodeSocketType *socket_type)
Definition: BKE_node.h:407
void(* foreach_nodeclass)(struct Scene *scene, void *calldata, bNodeClassCallback func)
Definition: BKE_node.h:385
void(* node_add_init)(struct bNodeTree *ntree, struct bNode *bnode)
Definition: BKE_node.h:404
ExtensionRNA rna_ext
Definition: BKE_node.h:410
ListBase nodes
short nclass
Definition: BKE_node.h:236
struct bNodeType * typeinfo
struct ID * id
char name[64]
short type
struct bNode * next
void * storage
ListBase outputs
#define N_(msgid)