Blender V4.5
blenkernel/intern/compositor.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include <string>
6
7#include <fmt/format.h>
8
9#include "BLI_index_range.hh"
10#include "BLI_math_base.hh"
11#include "BLI_set.hh"
12#include "BLI_string_ref.hh"
13
14#include "BKE_compositor.hh"
15#include "BKE_cryptomatte.hh"
16#include "BKE_node.hh"
18#include "BKE_node_runtime.hh"
19
20#include "DNA_layer_types.h"
21#include "DNA_node_types.h"
22#include "DNA_scene_types.h"
23
25
26/* Adds the pass names of the passes used by the given Render Layer node to the given used passes.
27 * This essentially adds the identifiers of the outputs that are logically linked, their the
28 * identifiers are the names of the passes. Note however that the Image output is actually the
29 * Combined pass, but named as Image for compatibility reasons. */
30static void add_passes_used_by_render_layer_node(const bNode *node, Set<std::string> &used_passes)
31{
32 for (const bNodeSocket *output : node->output_sockets()) {
33 if (output->is_logically_linked()) {
34 if (StringRef(output->identifier) == "Image") {
35 used_passes.add(RE_PASSNAME_COMBINED);
36 }
37 else {
38 used_passes.add(output->identifier);
39 }
40 }
41 }
42}
43
44/* Adds the pass names of all Cryptomatte layers needed by the given node to the given used passes.
45 * Only passes in the given viewer layers are added. */
47 const ViewLayer *view_layer,
48 Set<std::string> &used_passes)
49{
51 return;
52 }
53
54 Scene *scene = reinterpret_cast<Scene *>(node->id);
55 if (!scene) {
56 return;
57 }
58
61
63 if (layer_names.is_empty()) {
64 return;
65 }
66
67 /* If the stored layer name doesn't corresponds to an existing Cryptomatte layer, fall back to
68 * the name of the first layer. */
69 const NodeCryptomatte *data = static_cast<NodeCryptomatte *>(node->storage);
70 const std::string layer_name = layer_names.contains(data->layer_name) ? data->layer_name :
71 layer_names[0];
72
73 /* Does not use passes from the given view layer, so no need to add anything. */
74 if (!StringRef(layer_name).startswith(view_layer->name)) {
75 return;
76 }
77
78 /* Find out which type of Cryptomatte layers the node needs. Also ensure the type is enabled in
79 * the view layer, because the node can use one of the types as a placeholder. */
80 const char *cryptomatte_type_name = nullptr;
81 if (StringRef(layer_name).endswith(RE_PASSNAME_CRYPTOMATTE_OBJECT)) {
83 cryptomatte_type_name = RE_PASSNAME_CRYPTOMATTE_OBJECT;
84 }
85 }
86 else if (StringRef(layer_name).endswith(RE_PASSNAME_CRYPTOMATTE_ASSET)) {
88 cryptomatte_type_name = RE_PASSNAME_CRYPTOMATTE_ASSET;
89 }
90 }
91 else if (StringRef(layer_name).endswith(RE_PASSNAME_CRYPTOMATTE_MATERIAL)) {
93 cryptomatte_type_name = RE_PASSNAME_CRYPTOMATTE_MATERIAL;
94 }
95 }
96
97 if (!cryptomatte_type_name) {
98 return;
99 }
100
101 /* Each layer stores two ranks/levels, so do ceiling division by two. */
102 const int cryptomatte_layers_count = int(math::ceil(view_layer->cryptomatte_levels / 2.0f));
103 for (const int i : IndexRange(cryptomatte_layers_count)) {
104 used_passes.add(fmt::format("{}{:02}", cryptomatte_type_name, i));
105 }
106}
107
108/* Adds the pass names of the passes used by the given compositor node tree to the given used
109 * passes. This is called recursively for node groups. */
110static void add_used_passes_recursive(const bNodeTree *node_tree,
111 const ViewLayer *view_layer,
112 Set<const bNodeTree *> &node_trees_already_searched,
113 Set<std::string> &used_passes)
114{
115 if (node_tree == nullptr) {
116 return;
117 }
118
119 node_tree->ensure_topology_cache();
120 for (const bNode *node : node_tree->all_nodes()) {
121 if (node->is_muted()) {
122 continue;
123 }
124
125 switch (node->type_legacy) {
126 case NODE_GROUP:
127 case NODE_CUSTOM_GROUP: {
128 const bNodeTree *node_group_tree = reinterpret_cast<const bNodeTree *>(node->id);
129 if (node_trees_already_searched.add(node_group_tree)) {
131 node_group_tree, view_layer, node_trees_already_searched, used_passes);
132 }
133 break;
134 }
136 add_passes_used_by_render_layer_node(node, used_passes);
137 break;
139 add_passes_used_by_cryptomatte_node(node, view_layer, used_passes);
140 break;
141 default:
142 break;
143 }
144 }
145}
146
147Set<std::string> get_used_passes(const Scene &scene, const ViewLayer *view_layer)
148{
149 Set<std::string> used_passes;
150 Set<const bNodeTree *> node_trees_already_searched;
151 add_used_passes_recursive(scene.nodetree, view_layer, node_trees_already_searched, used_passes);
152 return used_passes;
153}
154
155} // namespace blender::bke::compositor
struct CryptomatteSession * BKE_cryptomatte_init_from_scene(const struct Scene *scene, bool build_meta_data)
#define NODE_CUSTOM_GROUP
Definition BKE_node.hh:801
#define NODE_GROUP
Definition BKE_node.hh:796
#define CMP_NODE_CRYPTOMATTE
#define CMP_NODE_R_LAYERS
@ VIEW_LAYER_CRYPTOMATTE_MATERIAL
@ VIEW_LAYER_CRYPTOMATTE_ASSET
@ VIEW_LAYER_CRYPTOMATTE_OBJECT
@ CMP_NODE_CRYPTOMATTE_SOURCE_RENDER
#define RE_PASSNAME_COMBINED
#define RE_PASSNAME_CRYPTOMATTE_MATERIAL
#define RE_PASSNAME_CRYPTOMATTE_ASSET
#define RE_PASSNAME_CRYPTOMATTE_OBJECT
BMesh const char void * data
bool add(const Key &key)
Definition BLI_set.hh:248
bool contains(const T &value) const
bool is_empty() const
#define output
static void add_passes_used_by_cryptomatte_node(const bNode *node, const ViewLayer *view_layer, Set< std::string > &used_passes)
static void add_used_passes_recursive(const bNodeTree *node_tree, const ViewLayer *view_layer, Set< const bNodeTree * > &node_trees_already_searched, Set< std::string > &used_passes)
Set< std::string > get_used_passes(const Scene &scene, const ViewLayer *view_layer)
static void add_passes_used_by_render_layer_node(const bNode *node, Set< std::string > &used_passes)
std::unique_ptr< CryptomatteSession, CryptomatteSessionDeleter > CryptomatteSessionPtr
const blender::Vector< std::string > & BKE_cryptomatte_layer_names_get(const CryptomatteSession &session)
T ceil(const T &a)
struct bNodeTree * nodetree
short cryptomatte_flag
short cryptomatte_levels
char name[64]
int16_t custom1
struct ID * id
void * storage
i
Definition text_draw.cc:230