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;
|
2025-06-10 17:46:55 +02:00
|
|
|
*r_ntree = scene->compositing_node_group;
|
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
|
|
|
|
2019-06-03 17:08:25 +02:00
|
|
|
node = node->next;
|
|
|
|
|
local_node = local_node->next;
|
2011-09-05 21:01:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-18 16:18:53 +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-07-18 16:18:53 +02:00
|
|
|
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-07-18 11:08:30 +02:00
|
|
|
return blender::bke::node_is_static_socket_type(*socket_type) && ELEM(socket_type->type,
|
|
|
|
|
SOCK_FLOAT,
|
|
|
|
|
SOCK_INT,
|
|
|
|
|
SOCK_BOOLEAN,
|
|
|
|
|
SOCK_VECTOR,
|
|
|
|
|
SOCK_RGBA,
|
2025-08-12 08:54:13 +02:00
|
|
|
SOCK_MENU,
|
|
|
|
|
SOCK_STRING);
|
2021-04-29 23:36:46 -05:00
|
|
|
}
|
|
|
|
|
|
2025-08-08 07:37:33 +10:00
|
|
|
/**
|
|
|
|
|
* Keep consistent with the #is_conversion_supported function in #compositor::ConversionOperation
|
|
|
|
|
* on the compositor side.
|
|
|
|
|
*/
|
2025-07-18 11:08:30 +02:00
|
|
|
static bool composite_validate_link(eNodeSocketDatatype from_type, eNodeSocketDatatype to_type)
|
2025-02-28 16:34:38 +02:00
|
|
|
{
|
2025-07-18 11:08:30 +02:00
|
|
|
/* Basic math types can be implicitly converted to each other. */
|
|
|
|
|
if (ELEM(from_type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA, SOCK_BOOLEAN, SOCK_INT) &&
|
|
|
|
|
ELEM(to_type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA, SOCK_BOOLEAN, SOCK_INT))
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return from_type == to_type;
|
2025-02-28 16:34:38 +02:00
|
|
|
}
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
2025-06-10 17:46:55 +02:00
|
|
|
if (sce_iter->compositing_node_group) {
|
|
|
|
|
for (bNode *node : sce_iter->compositing_node_group->all_nodes()) {
|
Compositor: Replace Composite node with Group Output node
This patch replaces the Composite node with the Group Output node as the
primary compositor output. The old node was removed and versioned. This
was done for consistency with Geometry Nodes and in preparation for more
generic use of the compositor in VSE modifiers, layered compositing, NPR
multi-stage compositing, and more.
The Group Output node relies on the node tree interface, so we now have
a default interface of a single input and a single output. For now, only
the first input is considered while the rest are ignored, just like the
Geometry Nodes design. Furthermore, the input is required to be of type
color. Warnings and errors are issues if any of those are not met, also
similar to Geometry Nodes.
This introduces a new limitation: Composite outputs can no longer exist
in node groups, since they obviously then act as their respective group
outputs.
A refactor for the compositor scheduler is needed to simplify the logic
after this change, but this will be done in a separate patch.
Pull Request: https://projects.blender.org/blender/blender/pulls/142232
2025-07-24 13:41:56 +02:00
|
|
|
if (node->id == (ID *)scene) {
|
2025-06-10 17:46:55 +02:00
|
|
|
BKE_ntree_update_tag_node_property(sce_iter->compositing_node_group, 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;
|
|
|
|
|
}
|