Blender V4.3
node_composite_tree.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2007 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cstdio>
10
11#include "BLI_string.h"
12
13#include "DNA_color_types.h"
14#include "DNA_node_types.h"
15#include "DNA_scene_types.h"
16
17#include "BKE_context.hh"
18#include "BKE_global.hh"
19#include "BKE_image.hh"
20#include "BKE_main.hh"
21#include "BKE_node.hh"
22#include "BKE_node_runtime.hh"
24#include "BKE_tracking.h"
25
26#include "UI_resources.hh"
27
28#include "node_common.h"
29
30#include "RNA_prototypes.hh"
31
32#include "NOD_composite.hh"
34
35#ifdef WITH_COMPOSITOR_CPU
36# include "COM_compositor.hh"
37#endif
38
40 blender::bke::bNodeTreeType * /*treetype*/,
41 bNodeTree **r_ntree,
42 ID **r_id,
43 ID **r_from)
44{
45 Scene *scene = CTX_data_scene(C);
46
47 *r_from = nullptr;
48 *r_id = &scene->id;
49 *r_ntree = scene->nodetree;
50}
51
52static void foreach_nodeclass(void *calldata, blender::bke::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
67/* local tree then owns all compbufs */
68static void localize(bNodeTree *localtree, bNodeTree *ntree)
69{
70
71 bNode *node = (bNode *)ntree->nodes.first;
72 bNode *local_node = (bNode *)localtree->nodes.first;
73 while (node != nullptr) {
74
75 /* Ensure new user input gets handled ok. */
76 node->runtime->need_exec = 0;
77 local_node->runtime->original = node;
78
79 /* move over the compbufs */
80 /* right after #blender::bke::node_tree_copy_tree() `oldsock` pointers are valid */
81
82 if (node->type == CMP_NODE_VIEWER) {
83 if (node->id) {
84 if (node->flag & NODE_DO_OUTPUT) {
85 local_node->id = (ID *)node->id;
86 }
87 else {
88 local_node->id = nullptr;
89 }
90 }
91 }
92
93 node = node->next;
94 local_node = local_node->next;
95 }
96}
97
98static void local_merge(Main *bmain, bNodeTree *localtree, bNodeTree *ntree)
99{
100 /* move over the compbufs and previews */
101 blender::bke::node_preview_merge_tree(ntree, localtree, true);
102
103 LISTBASE_FOREACH (bNode *, lnode, &localtree->nodes) {
104 if (bNode *orig_node = blender::bke::node_find_node_by_name(ntree, lnode->name)) {
105 if (lnode->type == CMP_NODE_VIEWER) {
106 if (lnode->id && (lnode->flag & NODE_DO_OUTPUT)) {
107 /* image_merge does sanity check for pointers */
108 BKE_image_merge(bmain, (Image *)orig_node->id, (Image *)lnode->id);
109 }
110 }
111 else if (lnode->type == CMP_NODE_MOVIEDISTORTION) {
112 /* special case for distortion node: distortion context is allocating in exec function
113 * and to achieve much better performance on further calls this context should be
114 * copied back to original node */
115 if (lnode->storage) {
116 if (orig_node->storage) {
117 BKE_tracking_distortion_free((MovieDistortion *)orig_node->storage);
118 }
119
120 orig_node->storage = BKE_tracking_distortion_copy((MovieDistortion *)lnode->storage);
121 }
122 }
123 }
124 }
125}
126
127static void update(bNodeTree *ntree)
128{
130
132}
133
134static void composite_node_add_init(bNodeTree * /*bnodetree*/, bNode *bnode)
135{
136 /* Composite node will only show previews for input classes
137 * by default, other will be hidden
138 * but can be made visible with the show_preview option */
139 if (bnode->typeinfo->nclass != NODE_CLASS_INPUT) {
140 bnode->flag &= ~NODE_PREVIEW;
141 }
142}
143
150
152
154{
155 blender::bke::bNodeTreeType *tt = ntreeType_Composite = MEM_cnew<blender::bke::bNodeTreeType>(
156 __func__);
157
158 tt->type = NTREE_COMPOSIT;
159 STRNCPY(tt->idname, "CompositorNodeTree");
160 STRNCPY(tt->group_idname, "CompositorNodeGroup");
161 STRNCPY(tt->ui_name, N_("Compositor"));
162 tt->ui_icon = ICON_NODE_COMPOSITING;
163 STRNCPY(tt->ui_description, N_("Compositing nodes"));
164
166 tt->localize = localize;
168 tt->update = update;
172
173 tt->rna_ext.srna = &RNA_CompositorNodeTree;
174
176}
177
179 Scene *scene,
180 bNodeTree *ntree,
181 RenderData *rd,
182 const char *view_name,
185{
186#ifdef WITH_COMPOSITOR_CPU
187 COM_execute(render, rd, scene, ntree, view_name, render_context, profiler);
188#else
189 UNUSED_VARS(render, scene, ntree, rd, view_name, render_context, profiler);
190#endif
191}
192
193/* *********************************************** */
194
196{
197 if (ntree == nullptr) {
198 return;
199 }
200
201 for (bNode *node : ntree->all_nodes()) {
202 if (node->type == CMP_NODE_R_LAYERS) {
203 node_cmp_rlayers_outputs(ntree, node);
204 }
205 else if (node->type == CMP_NODE_CRYPTOMATTE &&
206 node->custom1 == CMP_NODE_CRYPTOMATTE_SOURCE_RENDER)
207 {
208 node->typeinfo->updatefunc(ntree, node);
209 }
210 }
211}
212
214{
215 /* XXX Think using G_MAIN here is valid, since you want to update current file's scene nodes,
216 * not the ones in temp main generated for rendering?
217 * This is still rather weak though,
218 * ideally render struct would store its own main AND original G_MAIN. */
219
220 for (Scene *sce_iter = (Scene *)G_MAIN->scenes.first; sce_iter;
221 sce_iter = (Scene *)sce_iter->id.next)
222 {
223 if (sce_iter->nodetree) {
224 for (bNode *node : sce_iter->nodetree->all_nodes()) {
225 if (node->id == (ID *)scene || node->type == CMP_NODE_COMPOSITE) {
226 BKE_ntree_update_tag_node_property(sce_iter->nodetree, node);
227 }
228 else if (node->type == CMP_NODE_TEXTURE) /* uses scene size_x/size_y */ {
229 BKE_ntree_update_tag_node_property(sce_iter->nodetree, node);
230 }
231 }
232 }
233 }
235}
236
238{
239 /* XXX: after render animation system gets a refresh, this call allows composite to end clean. */
240
241 if (ntree == nullptr) {
242 return;
243 }
244
245 for (bNode *node : ntree->all_nodes()) {
246 node->runtime->need_exec = 0;
247 if (node->type == NODE_GROUP) {
249 }
250 }
251}
252
254{
255 node->runtime->need_exec = true;
256}
Scene * CTX_data_scene(const bContext *C)
#define G_MAIN
void BKE_image_merge(Main *bmain, Image *dest, Image *source)
#define NODE_CLASS_OUTPUT
Definition BKE_node.hh:405
#define CMP_NODE_COMPOSITE
Definition BKE_node.hh:1033
#define NODE_CLASS_INTERFACE
Definition BKE_node.hh:416
#define NODE_CLASS_MATTE
Definition BKE_node.hh:411
#define NODE_CLASS_CONVERTER
Definition BKE_node.hh:410
#define NODE_CLASS_DISTORT
Definition BKE_node.hh:412
#define NODE_CLASS_OP_VECTOR
Definition BKE_node.hh:407
#define NODE_GROUP
Definition BKE_node.hh:800
#define NODE_CLASS_LAYOUT
Definition BKE_node.hh:420
#define NODE_CLASS_OP_COLOR
Definition BKE_node.hh:406
#define NODE_CLASS_INPUT
Definition BKE_node.hh:404
#define NODE_CLASS_OP_FILTER
Definition BKE_node.hh:408
#define NODE_CLASS_GROUP
Definition BKE_node.hh:409
void BKE_ntree_update_main(Main *bmain, NodeTreeUpdateExtraParams *params)
void BKE_ntree_update_tag_node_property(bNodeTree *ntree, bNode *node)
struct MovieDistortion * BKE_tracking_distortion_copy(struct MovieDistortion *distortion)
Definition tracking.cc:2313
void BKE_tracking_distortion_free(struct MovieDistortion *distortion)
Definition tracking.cc:2414
#define LISTBASE_FOREACH(type, var, list)
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#define UNUSED_VARS(...)
#define ELEM(...)
void COM_execute(Render *render, RenderData *render_data, Scene *scene, bNodeTree *node_tree, const char *view_name, blender::realtime_compositor::RenderContext *render_context, blender::realtime_compositor::Profiler *profiler)
The main method that is used to execute the compositor tree. It can be executed during editing (blenk...
@ NTREE_COMPOSIT
@ NODE_DO_OUTPUT
@ CMP_NODE_CRYPTOMATTE_SOURCE_RENDER
@ SOCK_VECTOR
@ SOCK_FLOAT
@ SOCK_RGBA
OperationNode * node
void node_tree_set_output(bNodeTree *ntree)
Definition node.cc:3650
bool node_is_static_socket_type(const bNodeSocketType *stype)
Definition node.cc:2117
void(*)(void *calldata, int nclass, const char *name) bNodeClassCallback
Definition BKE_node.hh:446
void node_tree_type_add(bNodeTreeType *nt)
Definition node.cc:1633
void node_preview_merge_tree(bNodeTree *to_ntree, bNodeTree *from_ntree, bool remove_old)
Definition node.cc:3390
bNode * node_find_node_by_name(bNodeTree *ntree, const char *name)
Definition node.cc:2437
void ntree_update_reroute_nodes(bNodeTree *ntree)
void node_cmp_rlayers_outputs(bNodeTree *ntree, bNode *node)
void ntreeCompositExecTree(Render *render, Scene *scene, bNodeTree *ntree, RenderData *rd, const char *view_name, blender::realtime_compositor::RenderContext *render_context, blender::realtime_compositor::Profiler *profiler)
static void composite_node_add_init(bNodeTree *, bNode *bnode)
void ntreeCompositTagRender(Scene *scene)
static void local_merge(Main *bmain, bNodeTree *localtree, bNodeTree *ntree)
static void localize(bNodeTree *localtree, bNodeTree *ntree)
void ntreeCompositTagNeedExec(bNode *node)
static void update(bNodeTree *ntree)
void ntreeCompositUpdateRLayers(bNodeTree *ntree)
void ntreeCompositClearTags(bNodeTree *ntree)
static bool composite_node_tree_socket_type_valid(blender::bke::bNodeTreeType *, blender::bke::bNodeSocketType *socket_type)
static void composite_get_from_context(const bContext *C, blender::bke::bNodeTreeType *, bNodeTree **r_ntree, ID **r_id, ID **r_from)
blender::bke::bNodeTreeType * ntreeType_Composite
void register_node_tree_type_cmp()
static void foreach_nodeclass(void *calldata, blender::bke::bNodeClassCallback func)
StructRNA * srna
Definition RNA_types.hh:780
Definition DNA_ID.h:413
void * next
Definition DNA_ID.h:416
void * first
ListBase nodes
bNodeTypeHandle * typeinfo
struct ID * id
struct bNode * next
bNodeRuntimeHandle * runtime
Defines a socket type.
Definition BKE_node.hh:151
void(* update)(bNodeTree *ntree)
Definition BKE_node.hh:473
void(* foreach_nodeclass)(void *calldata, bNodeClassCallback func)
Definition BKE_node.hh:461
void(* node_add_init)(bNodeTree *ntree, bNode *bnode)
Definition BKE_node.hh:477
void(* get_from_context)(const bContext *C, bNodeTreeType *ntreetype, bNodeTree **r_ntree, ID **r_id, ID **r_from)
Definition BKE_node.hh:465
void(* localize)(bNodeTree *localtree, bNodeTree *ntree)
Definition BKE_node.hh:469
void(* local_merge)(Main *bmain, bNodeTree *localtree, bNodeTree *ntree)
Definition BKE_node.hh:470
bool(* valid_socket_type)(bNodeTreeType *ntreetype, bNodeSocketType *socket_type)
Definition BKE_node.hh:480
#define N_(msgid)