Blender V5.0
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
8
9#include "DNA_node_types.h"
10#include "DNA_scene_types.h"
11#include "DNA_space_types.h"
12
13#include "BLI_listbase.h"
14
15#include "BKE_context.hh"
16#include "BKE_global.hh"
17#include "BKE_image.hh"
18#include "BKE_main.hh"
19#include "BKE_node.hh"
20#include "BKE_node_runtime.hh"
22#include "BKE_tracking.h"
23
24#include "UI_resources.hh"
25
26#include "SEQ_modifier.hh"
27#include "SEQ_select.hh"
28#include "SEQ_sequencer.hh"
29
30#include "node_common.h"
31
32#include "RNA_prototypes.hh"
33
34#include "NOD_composite.hh"
36
38 blender::bke::bNodeTreeType * /*treetype*/,
39 bNodeTree **r_ntree,
40 ID **r_id,
41 ID **r_from)
42{
43 using namespace blender;
44 const SpaceNode *snode = CTX_wm_space_node(C);
46 Scene *sequencer_scene = CTX_data_sequencer_scene(C);
47 if (!sequencer_scene) {
48 *r_ntree = nullptr;
49 return;
50 }
51 Editing *ed = seq::editing_get(sequencer_scene);
52 if (!ed) {
53 *r_ntree = nullptr;
54 return;
55 }
56 Strip *strip = seq::select_active_get(sequencer_scene);
57 if (!strip) {
58 *r_ntree = nullptr;
59 return;
60 }
62 if (!smd) {
63 *r_ntree = nullptr;
64 return;
65 }
67 *r_ntree = nullptr;
68 return;
69 }
71 smd);
72 *r_from = nullptr;
73 *r_id = &sequencer_scene->id;
74 *r_ntree = scmd->node_group;
75 return;
76 }
77
78 Scene *scene = CTX_data_scene(C);
79
80 *r_from = nullptr;
81 *r_id = &scene->id;
82 *r_ntree = scene->compositing_node_group;
83}
84
85static void foreach_nodeclass(void *calldata, blender::bke::bNodeClassCallback func)
86{
87 func(calldata, NODE_CLASS_INPUT, N_("Input"));
88 func(calldata, NODE_CLASS_OUTPUT, N_("Output"));
89 func(calldata, NODE_CLASS_OP_COLOR, N_("Color"));
90 func(calldata, NODE_CLASS_OP_VECTOR, N_("Vector"));
91 func(calldata, NODE_CLASS_OP_FILTER, N_("Filter"));
92 func(calldata, NODE_CLASS_CONVERTER, N_("Converter"));
93 func(calldata, NODE_CLASS_MATTE, N_("Matte"));
94 func(calldata, NODE_CLASS_DISTORT, N_("Distort"));
95 func(calldata, NODE_CLASS_GROUP, N_("Group"));
96 func(calldata, NODE_CLASS_INTERFACE, N_("Interface"));
97 func(calldata, NODE_CLASS_LAYOUT, N_("Layout"));
98}
99
100/* local tree then owns all compbufs */
101static void localize(bNodeTree *localtree, bNodeTree *ntree)
102{
103
104 bNode *node = (bNode *)ntree->nodes.first;
105 bNode *local_node = (bNode *)localtree->nodes.first;
106 while (node != nullptr) {
107
108 /* Ensure new user input gets handled ok. */
109 node->runtime->need_exec = 0;
110 local_node->runtime->original = node;
111
112 /* move over the compbufs */
113 /* right after #blender::bke::node_tree_copy_tree() `oldsock` pointers are valid */
114
115 node = node->next;
116 local_node = local_node->next;
117 }
118}
119
120static void local_merge(Main * /*bmain*/, bNodeTree *localtree, bNodeTree *ntree)
121{
122 /* move over the compbufs and previews */
123 blender::bke::node_preview_merge_tree(ntree, localtree, true);
124
125 LISTBASE_FOREACH (bNode *, lnode, &localtree->nodes) {
126 if (bNode *orig_node = blender::bke::node_find_node_by_name(*ntree, lnode->name)) {
127 if (lnode->type_legacy == CMP_NODE_MOVIEDISTORTION) {
128 /* special case for distortion node: distortion context is allocating in exec function
129 * and to achieve much better performance on further calls this context should be
130 * copied back to original node */
131 if (lnode->storage) {
132 if (orig_node->storage) {
133 BKE_tracking_distortion_free((MovieDistortion *)orig_node->storage);
134 }
135
136 orig_node->storage = BKE_tracking_distortion_copy((MovieDistortion *)lnode->storage);
137 }
138 }
139 }
140 }
141}
142
143static void update(bNodeTree *ntree)
144{
146
148}
149
150static void composite_node_add_init(bNodeTree * /*bnodetree*/, bNode *bnode)
151{
152 /* Composite node will only show previews for input classes
153 * by default, other will be hidden
154 * but can be made visible with the show_preview option */
155 if (bnode->typeinfo->nclass != NODE_CLASS_INPUT) {
156 bnode->flag &= ~NODE_PREVIEW;
157 }
158}
159
162{
163 return blender::bke::node_is_static_socket_type(*socket_type) && ELEM(socket_type->type,
165 SOCK_INT,
168 SOCK_RGBA,
169 SOCK_MENU,
171}
172
178{
179 /* Basic math types can be implicitly converted to each other. */
182 {
183 return true;
184 }
185
186 return from_type == to_type;
187}
188
190
192{
193 blender::bke::bNodeTreeType *tt = ntreeType_Composite = MEM_new<blender::bke::bNodeTreeType>(
194 __func__);
195
196 tt->type = NTREE_COMPOSIT;
197 tt->idname = "CompositorNodeTree";
198 tt->group_idname = "CompositorNodeGroup";
199 tt->ui_name = N_("Compositor");
200 tt->ui_icon = ICON_NODE_COMPOSITING;
201 tt->ui_description = N_("Create effects and post-process renders, images, and the 3D Viewport");
202
204 tt->localize = localize;
206 tt->update = update;
211
212 tt->rna_ext.srna = &RNA_CompositorNodeTree;
213
215}
216
217/* *********************************************** */
218
220{
221 if (ntree == nullptr) {
222 return;
223 }
224
225 for (bNode *node : ntree->all_nodes()) {
226 if (node->type_legacy == CMP_NODE_R_LAYERS) {
227 node_cmp_rlayers_outputs(ntree, node);
228 }
229 else if (node->type_legacy == CMP_NODE_CRYPTOMATTE &&
230 node->custom1 == CMP_NODE_CRYPTOMATTE_SOURCE_RENDER)
231 {
232 node->typeinfo->updatefunc(ntree, node);
233 }
234 }
235}
236
238{
239 /* XXX Think using G_MAIN here is valid, since you want to update current file's scene nodes,
240 * not the ones in temp main generated for rendering?
241 * This is still rather weak though,
242 * ideally render struct would store its own main AND original G_MAIN. */
243
244 for (Scene *sce_iter = (Scene *)G_MAIN->scenes.first; sce_iter;
245 sce_iter = (Scene *)sce_iter->id.next)
246 {
247 if (sce_iter->compositing_node_group) {
248 for (bNode *node : sce_iter->compositing_node_group->all_nodes()) {
249 if (node->id == (ID *)scene) {
250 BKE_ntree_update_tag_node_property(sce_iter->compositing_node_group, node);
251 }
252 }
253 }
254 }
256}
257
259{
260 /* XXX: after render animation system gets a refresh, this call allows composite to end clean. */
261
262 if (ntree == nullptr) {
263 return;
264 }
265
266 for (bNode *node : ntree->all_nodes()) {
267 node->runtime->need_exec = 0;
268 if (node->is_group()) {
270 }
271 }
272}
273
275{
276 node->runtime->need_exec = true;
277}
SpaceNode * CTX_wm_space_node(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Scene * CTX_data_sequencer_scene(const bContext *C)
#define G_MAIN
#define NODE_CLASS_OUTPUT
Definition BKE_node.hh:448
#define NODE_CLASS_INTERFACE
Definition BKE_node.hh:459
#define NODE_CLASS_MATTE
Definition BKE_node.hh:454
#define NODE_CLASS_CONVERTER
Definition BKE_node.hh:453
#define NODE_CLASS_DISTORT
Definition BKE_node.hh:455
#define NODE_CLASS_OP_VECTOR
Definition BKE_node.hh:450
#define NODE_CLASS_LAYOUT
Definition BKE_node.hh:463
#define NODE_CLASS_OP_COLOR
Definition BKE_node.hh:449
#define NODE_CLASS_INPUT
Definition BKE_node.hh:447
#define NODE_CLASS_OP_FILTER
Definition BKE_node.hh:451
#define NODE_CLASS_GROUP
Definition BKE_node.hh:452
#define CMP_NODE_CRYPTOMATTE
#define CMP_NODE_MOVIEDISTORTION
#define CMP_NODE_R_LAYERS
void BKE_ntree_update(Main &bmain, std::optional< blender::Span< bNodeTree * > > modified_trees=std::nullopt, const 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:2307
void BKE_tracking_distortion_free(struct MovieDistortion *distortion)
Definition tracking.cc:2408
#define LISTBASE_FOREACH(type, var, list)
#define ELEM(...)
@ CMP_NODE_CRYPTOMATTE_SOURCE_RENDER
@ NODE_PREVIEW
@ NTREE_COMPOSIT
eNodeSocketDatatype
@ SOCK_INT
@ SOCK_VECTOR
@ SOCK_BOOLEAN
@ SOCK_FLOAT
@ SOCK_STRING
@ SOCK_RGBA
@ SOCK_MENU
@ eSeqModifierType_Compositor
@ SNODE_COMPOSITOR_SEQUENCER
#define C
Definition RandGen.cpp:29
bNode * node_find_node_by_name(bNodeTree &ntree, StringRefNull name)
Definition node.cc:3275
void node_tree_set_output(bNodeTree &ntree)
Definition node.cc:4469
void node_tree_type_add(bNodeTreeType &nt)
Definition node.cc:2340
void(*)(void *calldata, int nclass, StringRefNull name) bNodeClassCallback
Definition BKE_node.hh:492
void node_preview_merge_tree(bNodeTree *to_ntree, bNodeTree *from_ntree, bool remove_old)
Definition node.cc:4240
bool node_is_static_socket_type(const bNodeSocketType &stype)
Definition node.cc:2826
Editing * editing_get(const Scene *scene)
Definition sequencer.cc:286
Strip * select_active_get(const Scene *scene)
StripModifierData * modifier_get_active(const Strip *strip)
void ntree_update_reroute_nodes(bNodeTree *ntree)
void node_cmp_rlayers_outputs(bNodeTree *ntree, bNode *node)
static void composite_node_add_init(bNodeTree *, bNode *bnode)
void ntreeCompositTagRender(Scene *scene)
static void localize(bNodeTree *localtree, bNodeTree *ntree)
void ntreeCompositTagNeedExec(bNode *node)
static void update(bNodeTree *ntree)
static void local_merge(Main *, bNodeTree *localtree, 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
static bool composite_validate_link(eNodeSocketDatatype from_type, eNodeSocketDatatype to_type)
void register_node_tree_type_cmp()
static void foreach_nodeclass(void *calldata, blender::bke::bNodeClassCallback func)
StructRNA * srna
Definition DNA_ID.h:414
void * first
struct bNodeTree * compositing_node_group
char node_tree_sub_type
ListBase nodes
bNodeTypeHandle * typeinfo
struct bNode * next
bNodeRuntimeHandle * runtime
Defines a socket type.
Definition BKE_node.hh:158
eNodeSocketDatatype type
Definition BKE_node.hh:193
void(* update)(bNodeTree *ntree)
Definition BKE_node.hh:522
void(* foreach_nodeclass)(void *calldata, bNodeClassCallback func)
Definition BKE_node.hh:507
void(* node_add_init)(bNodeTree *ntree, bNode *bnode)
Definition BKE_node.hh:526
void(* get_from_context)(const bContext *C, bNodeTreeType *ntreetype, bNodeTree **r_ntree, ID **r_id, ID **r_from)
Definition BKE_node.hh:511
void(* localize)(bNodeTree *localtree, bNodeTree *ntree)
Definition BKE_node.hh:518
void(* local_merge)(Main *bmain, bNodeTree *localtree, bNodeTree *ntree)
Definition BKE_node.hh:519
bool(* validate_link)(eNodeSocketDatatype from, eNodeSocketDatatype to)
Definition BKE_node.hh:524
bool(* valid_socket_type)(bNodeTreeType *ntreetype, bNodeSocketType *socket_type)
Definition BKE_node.hh:529
#define N_(msgid)