2023-08-16 00:20:26 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2007 Blender Authors
|
2023-05-31 16:19:06 +02:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2011-09-05 21:01:50 +00:00
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup nodes
|
2011-09-05 21:01:50 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "DNA_node_types.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "DNA_scene_types.h"
|
2011-09-05 21:01:50 +00:00
|
|
|
|
2025-02-11 16:59:42 +01:00
|
|
|
#include "BLI_listbase.h"
|
|
|
|
|
|
2023-11-16 11:41:55 +01:00
|
|
|
#include "BKE_context.hh"
|
2024-02-10 18:25:14 +01:00
|
|
|
#include "BKE_global.hh"
|
2024-11-12 15:21:59 +01:00
|
|
|
#include "BKE_image.hh"
|
2023-12-01 19:43:16 +01:00
|
|
|
#include "BKE_main.hh"
|
2023-05-15 15:14:22 +02:00
|
|
|
#include "BKE_node.hh"
|
2022-11-18 14:03:00 +01:00
|
|
|
#include "BKE_node_runtime.hh"
|
2023-11-16 11:41:55 +01:00
|
|
|
#include "BKE_node_tree_update.hh"
|
2011-11-07 12:56:05 +00:00
|
|
|
#include "BKE_tracking.h"
|
2011-09-05 21:01:50 +00:00
|
|
|
|
2023-08-05 02:57:52 +02:00
|
|
|
#include "UI_resources.hh"
|
2021-12-24 22:47:58 -05:00
|
|
|
|
2012-08-06 18:49:28 +00:00
|
|
|
#include "node_common.h"
|
2011-09-05 21:01:50 +00:00
|
|
|
|
2024-07-10 18:30:02 +02:00
|
|
|
#include "RNA_prototypes.hh"
|
2011-09-05 21:01:50 +00:00
|
|
|
|
2023-10-16 10:45:54 +02:00
|
|
|
#include "NOD_composite.hh"
|
2021-09-28 15:29:16 -04:00
|
|
|
#include "node_composite_util.hh"
|
2012-06-30 14:14:22 +00:00
|
|
|
|
2024-05-13 16:07:12 +02:00
|
|
|
static void composite_get_from_context(const bContext *C,
|
|
|
|
|
blender::bke::bNodeTreeType * /*treetype*/,
|
|
|
|
|
bNodeTree **r_ntree,
|
|
|
|
|
ID **r_id,
|
|
|
|
|
ID **r_from)
|
2011-09-05 21:01:50 +00:00
|
|
|
{
|
2013-03-18 16:34:57 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2018-06-08 08:07:48 +02:00
|
|
|
|
2021-09-28 15:29:16 -04:00
|
|
|
*r_from = nullptr;
|
2013-03-18 16:34:57 +00:00
|
|
|
*r_id = &scene->id;
|
|
|
|
|
*r_ntree = scene->nodetree;
|
2011-09-05 21:01:50 +00:00
|
|
|
}
|
|
|
|
|
|
2024-05-13 16:07:12 +02:00
|
|
|
static void foreach_nodeclass(void *calldata, blender::bke::bNodeClassCallback func)
|
2011-11-07 22:14:48 +00:00
|
|
|
{
|
2012-05-16 15:01:46 +00:00
|
|
|
func(calldata, NODE_CLASS_INPUT, N_("Input"));
|
|
|
|
|
func(calldata, NODE_CLASS_OUTPUT, N_("Output"));
|
|
|
|
|
func(calldata, NODE_CLASS_OP_COLOR, N_("Color"));
|
|
|
|
|
func(calldata, NODE_CLASS_OP_VECTOR, N_("Vector"));
|
|
|
|
|
func(calldata, NODE_CLASS_OP_FILTER, N_("Filter"));
|
2021-08-23 16:23:58 +02:00
|
|
|
func(calldata, NODE_CLASS_CONVERTER, N_("Converter"));
|
2012-05-16 15:01:46 +00:00
|
|
|
func(calldata, NODE_CLASS_MATTE, N_("Matte"));
|
|
|
|
|
func(calldata, NODE_CLASS_DISTORT, N_("Distort"));
|
|
|
|
|
func(calldata, NODE_CLASS_GROUP, N_("Group"));
|
2013-03-18 16:34:57 +00:00
|
|
|
func(calldata, NODE_CLASS_INTERFACE, N_("Interface"));
|
2012-05-16 15:01:46 +00:00
|
|
|
func(calldata, NODE_CLASS_LAYOUT, N_("Layout"));
|
2011-11-07 22:14:48 +00:00
|
|
|
}
|
|
|
|
|
|
2011-09-05 21:01:50 +00:00
|
|
|
/* local tree then owns all compbufs */
|
2019-06-03 17:08:25 +02:00
|
|
|
static void localize(bNodeTree *localtree, bNodeTree *ntree)
|
2011-09-05 21:01:50 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-09-28 15:29:16 -04:00
|
|
|
bNode *node = (bNode *)ntree->nodes.first;
|
|
|
|
|
bNode *local_node = (bNode *)localtree->nodes.first;
|
|
|
|
|
while (node != nullptr) {
|
2019-06-03 17:08:25 +02:00
|
|
|
|
2020-03-15 21:46:18 +11:00
|
|
|
/* Ensure new user input gets handled ok. */
|
2022-11-18 12:46:20 +01:00
|
|
|
node->runtime->need_exec = 0;
|
|
|
|
|
local_node->runtime->original = node;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-09-05 21:01:50 +00:00
|
|
|
/* move over the compbufs */
|
2024-08-19 20:27:37 +02:00
|
|
|
/* right after #blender::bke::node_tree_copy_tree() `oldsock` pointers are valid */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-01-09 15:28:57 +01:00
|
|
|
if (node->type_legacy == CMP_NODE_VIEWER) {
|
2012-03-24 06:38:07 +00:00
|
|
|
if (node->id) {
|
2019-04-22 13:31:31 +10:00
|
|
|
if (node->flag & NODE_DO_OUTPUT) {
|
2019-06-03 17:08:25 +02:00
|
|
|
local_node->id = (ID *)node->id;
|
2019-04-22 13:31:31 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2021-09-28 15:29:16 -04:00
|
|
|
local_node->id = nullptr;
|
2019-04-22 13:31:31 +10:00
|
|
|
}
|
2011-09-05 21:01:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-06-03 17:08:25 +02:00
|
|
|
node = node->next;
|
|
|
|
|
local_node = local_node->next;
|
2011-09-05 21:01:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-11 15:40:37 +02:00
|
|
|
static void local_merge(Main *bmain, bNodeTree *localtree, bNodeTree *ntree)
|
2011-09-05 21:01:50 +00:00
|
|
|
{
|
|
|
|
|
/* move over the compbufs and previews */
|
2023-05-15 15:14:22 +02:00
|
|
|
blender::bke::node_preview_merge_tree(ntree, localtree, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-08-04 08:51:13 +10:00
|
|
|
LISTBASE_FOREACH (bNode *, lnode, &localtree->nodes) {
|
2025-02-19 13:44:11 +01:00
|
|
|
if (bNode *orig_node = blender::bke::node_find_node_by_name(*ntree, lnode->name)) {
|
2025-01-09 15:28:57 +01:00
|
|
|
if (lnode->type_legacy == CMP_NODE_VIEWER) {
|
2012-03-24 06:38:07 +00:00
|
|
|
if (lnode->id && (lnode->flag & NODE_DO_OUTPUT)) {
|
2011-09-05 21:01:50 +00:00
|
|
|
/* image_merge does sanity check for pointers */
|
2021-12-22 08:47:46 -06:00
|
|
|
BKE_image_merge(bmain, (Image *)orig_node->id, (Image *)lnode->id);
|
2011-09-05 21:01:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
2025-01-09 15:28:57 +01:00
|
|
|
else if (lnode->type_legacy == CMP_NODE_MOVIEDISTORTION) {
|
2011-11-07 12:56:05 +00:00
|
|
|
/* special case for distortion node: distortion context is allocating in exec function
|
2012-09-26 20:05:38 +00:00
|
|
|
* and to achieve much better performance on further calls this context should be
|
2012-06-30 22:49:33 +00:00
|
|
|
* copied back to original node */
|
2012-03-24 06:38:07 +00:00
|
|
|
if (lnode->storage) {
|
2021-12-22 08:47:46 -06:00
|
|
|
if (orig_node->storage) {
|
|
|
|
|
BKE_tracking_distortion_free((MovieDistortion *)orig_node->storage);
|
2019-04-22 13:31:31 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-12-22 08:47:46 -06:00
|
|
|
orig_node->storage = BKE_tracking_distortion_copy((MovieDistortion *)lnode->storage);
|
2011-11-07 12:56:05 +00:00
|
|
|
}
|
|
|
|
|
}
|
2011-09-05 21:01:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-19 17:08:35 +00:00
|
|
|
static void update(bNodeTree *ntree)
|
|
|
|
|
{
|
2025-02-19 13:44:11 +01:00
|
|
|
blender::bke::node_tree_set_output(*ntree);
|
2018-06-08 08:07:48 +02:00
|
|
|
|
2012-08-06 18:49:28 +00:00
|
|
|
ntree_update_reroute_nodes(ntree);
|
2011-10-19 17:08:35 +00:00
|
|
|
}
|
|
|
|
|
|
2022-10-03 17:37:25 -05:00
|
|
|
static void composite_node_add_init(bNodeTree * /*bnodetree*/, bNode *bnode)
|
2013-12-10 13:44:46 +11:00
|
|
|
{
|
2018-06-08 08:07:48 +02:00
|
|
|
/* Composite node will only show previews for input classes
|
|
|
|
|
* by default, other will be hidden
|
2013-12-08 21:53:35 +01:00
|
|
|
* but can be made visible with the show_preview option */
|
|
|
|
|
if (bnode->typeinfo->nclass != NODE_CLASS_INPUT) {
|
|
|
|
|
bnode->flag &= ~NODE_PREVIEW;
|
2018-06-08 08:07:48 +02:00
|
|
|
}
|
2013-12-08 21:53:35 +01:00
|
|
|
}
|
|
|
|
|
|
2024-05-13 16:07:12 +02:00
|
|
|
static bool composite_node_tree_socket_type_valid(blender::bke::bNodeTreeType * /*ntreetype*/,
|
|
|
|
|
blender::bke::bNodeSocketType *socket_type)
|
2021-04-29 23:36:46 -05:00
|
|
|
{
|
2025-02-19 13:44:11 +01:00
|
|
|
return blender::bke::node_is_static_socket_type(*socket_type) &&
|
Compositor: Support node integer sockets
This patch adds support for using integer sockets in compositor nodes.
This involves updating the Result class, node tree compiler, implicit
conversion operation, multi-function procedure operation, shader
operation, and some operations that supports multiple types.
Shader operation internally treats integers as floats, doing conversion
to and from int when reading and writing. That's because the GPUMaterial
compiler doesn't support integers. This is also the same workaround used
by the shader system. Though the GPU module are eyeing adding support
for integers, so we will update the code once they do that.
Domain realization is not yet supported for integer types, but this is
an internal limitation so far, as we do not plan to add nodes that
outputs integers soon. We are not yet sure how realization should happen
with regards to interpolation and we do not have base functions to
sample integer images, that's why I decided to delay its implementation
when it is actually needed.
Pull Request: https://projects.blender.org/blender/blender/pulls/132599
2025-01-06 10:09:26 +01:00
|
|
|
ELEM(socket_type->type, SOCK_FLOAT, SOCK_INT, SOCK_VECTOR, SOCK_RGBA);
|
2021-04-29 23:36:46 -05:00
|
|
|
}
|
|
|
|
|
|
2025-02-28 16:34:38 +02:00
|
|
|
static bool composite_validate_link(eNodeSocketDatatype /*from*/, eNodeSocketDatatype /*to*/)
|
|
|
|
|
{
|
|
|
|
|
/* All supported types can be implicitly converted to other types. */
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-13 16:07:12 +02:00
|
|
|
blender::bke::bNodeTreeType *ntreeType_Composite;
|
2013-03-18 16:34:57 +00:00
|
|
|
|
2021-12-07 12:36:33 -05:00
|
|
|
void register_node_tree_type_cmp()
|
2013-03-18 16:34:57 +00:00
|
|
|
{
|
2025-01-08 16:34:41 +01:00
|
|
|
blender::bke::bNodeTreeType *tt = ntreeType_Composite = MEM_new<blender::bke::bNodeTreeType>(
|
2024-05-13 16:07:12 +02:00
|
|
|
__func__);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-18 16:34:57 +00:00
|
|
|
tt->type = NTREE_COMPOSIT;
|
2025-01-08 16:34:41 +01:00
|
|
|
tt->idname = "CompositorNodeTree";
|
|
|
|
|
tt->group_idname = "CompositorNodeGroup";
|
|
|
|
|
tt->ui_name = N_("Compositor");
|
2021-12-24 22:47:58 -05:00
|
|
|
tt->ui_icon = ICON_NODE_COMPOSITING;
|
2025-01-08 16:34:41 +01:00
|
|
|
tt->ui_description = N_("Compositing nodes");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-18 16:34:57 +00:00
|
|
|
tt->foreach_nodeclass = foreach_nodeclass;
|
|
|
|
|
tt->localize = localize;
|
|
|
|
|
tt->local_merge = local_merge;
|
|
|
|
|
tt->update = update;
|
|
|
|
|
tt->get_from_context = composite_get_from_context;
|
2013-12-08 21:53:35 +01:00
|
|
|
tt->node_add_init = composite_node_add_init;
|
2025-02-28 16:34:38 +02:00
|
|
|
tt->validate_link = composite_validate_link;
|
2021-04-29 23:36:46 -05:00
|
|
|
tt->valid_socket_type = composite_node_tree_socket_type_valid;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-03 18:24:08 +02:00
|
|
|
tt->rna_ext.srna = &RNA_CompositorNodeTree;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-02-19 13:44:11 +01:00
|
|
|
blender::bke::node_tree_type_add(*tt);
|
2013-03-18 16:34:57 +00:00
|
|
|
}
|
2011-09-05 21:01:50 +00:00
|
|
|
|
|
|
|
|
/* *********************************************** */
|
|
|
|
|
|
Render API/Cycles: Identify Render Passes by their name instead of a type flag
Previously, every RenderPass would have a bitfield that specified its type. That limits the number of passes to 32, which was reached a while ago.
However, most of the code already supported arbitrary RenderPasses since they were also used to store Multilayer EXR images.
Therefore, this commit completely removes the passflag from RenderPass and changes all code to use the unique pass name for identification.
Since Blender Internal relies on hardcoded passes and to preserve compatibility, 32 pass names are reserved for the old hardcoded passes.
To support these arbitrary passes, the Render Result compositor node now adds dynamic sockets. For compatibility, the old hardcoded sockets are always stored and just hidden when the corresponding pass isn't available.
To use these changes, the Render Engine API now includes a function that allows render engines to add arbitrary passes to the render result. To be able to add options for these passes, addons can now add their own properties to SceneRenderLayers.
To keep the compositor input node updated, render engine plugins have to implement a callback that registers all the passes that will be generated.
From a user perspective, nothing should change with this commit.
Differential Revision: https://developer.blender.org/D2443
Differential Revision: https://developer.blender.org/D2444
2017-05-03 00:21:18 +02:00
|
|
|
void ntreeCompositUpdateRLayers(bNodeTree *ntree)
|
2011-09-05 21:01:50 +00:00
|
|
|
{
|
2021-09-28 15:29:16 -04:00
|
|
|
if (ntree == nullptr) {
|
Render API/Cycles: Identify Render Passes by their name instead of a type flag
Previously, every RenderPass would have a bitfield that specified its type. That limits the number of passes to 32, which was reached a while ago.
However, most of the code already supported arbitrary RenderPasses since they were also used to store Multilayer EXR images.
Therefore, this commit completely removes the passflag from RenderPass and changes all code to use the unique pass name for identification.
Since Blender Internal relies on hardcoded passes and to preserve compatibility, 32 pass names are reserved for the old hardcoded passes.
To support these arbitrary passes, the Render Result compositor node now adds dynamic sockets. For compatibility, the old hardcoded sockets are always stored and just hidden when the corresponding pass isn't available.
To use these changes, the Render Engine API now includes a function that allows render engines to add arbitrary passes to the render result. To be able to add options for these passes, addons can now add their own properties to SceneRenderLayers.
To keep the compositor input node updated, render engine plugins have to implement a callback that registers all the passes that will be generated.
From a user perspective, nothing should change with this commit.
Differential Revision: https://developer.blender.org/D2443
Differential Revision: https://developer.blender.org/D2444
2017-05-03 00:21:18 +02:00
|
|
|
return;
|
2019-04-22 13:31:31 +10:00
|
|
|
}
|
Render API/Cycles: Identify Render Passes by their name instead of a type flag
Previously, every RenderPass would have a bitfield that specified its type. That limits the number of passes to 32, which was reached a while ago.
However, most of the code already supported arbitrary RenderPasses since they were also used to store Multilayer EXR images.
Therefore, this commit completely removes the passflag from RenderPass and changes all code to use the unique pass name for identification.
Since Blender Internal relies on hardcoded passes and to preserve compatibility, 32 pass names are reserved for the old hardcoded passes.
To support these arbitrary passes, the Render Result compositor node now adds dynamic sockets. For compatibility, the old hardcoded sockets are always stored and just hidden when the corresponding pass isn't available.
To use these changes, the Render Engine API now includes a function that allows render engines to add arbitrary passes to the render result. To be able to add options for these passes, addons can now add their own properties to SceneRenderLayers.
To keep the compositor input node updated, render engine plugins have to implement a callback that registers all the passes that will be generated.
From a user perspective, nothing should change with this commit.
Differential Revision: https://developer.blender.org/D2443
Differential Revision: https://developer.blender.org/D2444
2017-05-03 00:21:18 +02:00
|
|
|
|
2022-12-02 11:12:51 -06:00
|
|
|
for (bNode *node : ntree->all_nodes()) {
|
2025-01-09 15:28:57 +01:00
|
|
|
if (node->type_legacy == CMP_NODE_R_LAYERS) {
|
Render API/Cycles: Identify Render Passes by their name instead of a type flag
Previously, every RenderPass would have a bitfield that specified its type. That limits the number of passes to 32, which was reached a while ago.
However, most of the code already supported arbitrary RenderPasses since they were also used to store Multilayer EXR images.
Therefore, this commit completely removes the passflag from RenderPass and changes all code to use the unique pass name for identification.
Since Blender Internal relies on hardcoded passes and to preserve compatibility, 32 pass names are reserved for the old hardcoded passes.
To support these arbitrary passes, the Render Result compositor node now adds dynamic sockets. For compatibility, the old hardcoded sockets are always stored and just hidden when the corresponding pass isn't available.
To use these changes, the Render Engine API now includes a function that allows render engines to add arbitrary passes to the render result. To be able to add options for these passes, addons can now add their own properties to SceneRenderLayers.
To keep the compositor input node updated, render engine plugins have to implement a callback that registers all the passes that will be generated.
From a user perspective, nothing should change with this commit.
Differential Revision: https://developer.blender.org/D2443
Differential Revision: https://developer.blender.org/D2444
2017-05-03 00:21:18 +02:00
|
|
|
node_cmp_rlayers_outputs(ntree, node);
|
2019-04-22 13:31:31 +10:00
|
|
|
}
|
2025-01-09 15:28:57 +01:00
|
|
|
else if (node->type_legacy == CMP_NODE_CRYPTOMATTE &&
|
2024-07-17 09:40:28 +02:00
|
|
|
node->custom1 == CMP_NODE_CRYPTOMATTE_SOURCE_RENDER)
|
|
|
|
|
{
|
|
|
|
|
node->typeinfo->updatefunc(ntree, node);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
Render API/Cycles: Identify Render Passes by their name instead of a type flag
Previously, every RenderPass would have a bitfield that specified its type. That limits the number of passes to 32, which was reached a while ago.
However, most of the code already supported arbitrary RenderPasses since they were also used to store Multilayer EXR images.
Therefore, this commit completely removes the passflag from RenderPass and changes all code to use the unique pass name for identification.
Since Blender Internal relies on hardcoded passes and to preserve compatibility, 32 pass names are reserved for the old hardcoded passes.
To support these arbitrary passes, the Render Result compositor node now adds dynamic sockets. For compatibility, the old hardcoded sockets are always stored and just hidden when the corresponding pass isn't available.
To use these changes, the Render Engine API now includes a function that allows render engines to add arbitrary passes to the render result. To be able to add options for these passes, addons can now add their own properties to SceneRenderLayers.
To keep the compositor input node updated, render engine plugins have to implement a callback that registers all the passes that will be generated.
From a user perspective, nothing should change with this commit.
Differential Revision: https://developer.blender.org/D2443
Differential Revision: https://developer.blender.org/D2444
2017-05-03 00:21:18 +02:00
|
|
|
}
|
|
|
|
|
|
2020-09-04 20:59:13 +02:00
|
|
|
void ntreeCompositTagRender(Scene *scene)
|
2011-09-05 21:01:50 +00:00
|
|
|
{
|
2018-06-25 12:02:20 +02:00
|
|
|
/* XXX Think using G_MAIN here is valid, since you want to update current file's scene nodes,
|
|
|
|
|
* not the ones in temp main generated for rendering?
|
2019-04-29 20:12:09 +10:00
|
|
|
* This is still rather weak though,
|
2024-03-07 16:20:36 -05:00
|
|
|
* ideally render struct would store its own main AND original G_MAIN. */
|
2019-04-29 20:12:09 +10:00
|
|
|
|
2021-09-28 15:29:16 -04:00
|
|
|
for (Scene *sce_iter = (Scene *)G_MAIN->scenes.first; sce_iter;
|
|
|
|
|
sce_iter = (Scene *)sce_iter->id.next)
|
|
|
|
|
{
|
2020-09-04 20:59:13 +02:00
|
|
|
if (sce_iter->nodetree) {
|
2022-12-02 11:12:51 -06:00
|
|
|
for (bNode *node : sce_iter->nodetree->all_nodes()) {
|
2025-01-09 15:28:57 +01:00
|
|
|
if (node->id == (ID *)scene || node->type_legacy == CMP_NODE_COMPOSITE) {
|
2021-12-21 15:18:56 +01:00
|
|
|
BKE_ntree_update_tag_node_property(sce_iter->nodetree, node);
|
2019-04-22 13:31:31 +10:00
|
|
|
}
|
2025-01-09 15:28:57 +01:00
|
|
|
else if (node->type_legacy == CMP_NODE_TEXTURE) /* uses scene size_x/size_y */ {
|
2021-12-21 15:18:56 +01:00
|
|
|
BKE_ntree_update_tag_node_property(sce_iter->nodetree, node);
|
2019-04-22 13:31:31 +10:00
|
|
|
}
|
2011-09-05 21:01:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-09 17:00:05 +01:00
|
|
|
BKE_ntree_update(*G_MAIN);
|
2011-09-05 21:01:50 +00:00
|
|
|
}
|
|
|
|
|
|
2011-10-19 17:08:35 +00:00
|
|
|
void ntreeCompositClearTags(bNodeTree *ntree)
|
2011-09-05 21:01:50 +00:00
|
|
|
{
|
2023-03-29 14:16:31 +11:00
|
|
|
/* XXX: after render animation system gets a refresh, this call allows composite to end clean. */
|
|
|
|
|
|
2021-09-28 15:29:16 -04:00
|
|
|
if (ntree == nullptr) {
|
2012-08-23 07:10:48 +00:00
|
|
|
return;
|
2019-04-22 13:31:31 +10:00
|
|
|
}
|
2012-08-23 07:10:48 +00:00
|
|
|
|
2022-12-02 11:12:51 -06:00
|
|
|
for (bNode *node : ntree->all_nodes()) {
|
2022-11-18 12:46:20 +01:00
|
|
|
node->runtime->need_exec = 0;
|
2025-01-17 12:17:49 +01:00
|
|
|
if (node->is_group()) {
|
2011-10-19 17:08:35 +00:00
|
|
|
ntreeCompositClearTags((bNodeTree *)node->id);
|
2019-04-22 13:31:31 +10:00
|
|
|
}
|
2011-09-05 21:01:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
2022-11-18 12:46:20 +01:00
|
|
|
|
|
|
|
|
void ntreeCompositTagNeedExec(bNode *node)
|
|
|
|
|
{
|
|
|
|
|
node->runtime->need_exec = true;
|
|
|
|
|
}
|