Blender  V3.3
node_composite_cryptomatte.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2018 Blender Foundation. All rights reserved. */
3 
8 #include "node_composite_util.hh"
9 
10 #include "BLI_assert.h"
11 #include "BLI_dynstr.h"
12 #include "BLI_hash_mm3.h"
13 #include "BLI_math_vector.h"
14 #include "BLI_string_ref.hh"
15 #include "BLI_utildefines.h"
16 
17 #include "BKE_context.h"
18 #include "BKE_cryptomatte.hh"
19 #include "BKE_global.h"
20 #include "BKE_image.h"
21 #include "BKE_lib_id.h"
22 #include "BKE_library.h"
23 #include "BKE_main.h"
24 
25 #include "MEM_guardedalloc.h"
26 
27 #include "RE_pipeline.h"
28 
29 #include <optional>
30 
31 /* -------------------------------------------------------------------- */
36  const bNode &node, const bool use_meta_data)
37 {
39 
40  Scene *scene = (Scene *)node.id;
41  if (!scene) {
42  return session;
43  }
45 
46  if (use_meta_data) {
47  Render *render = RE_GetSceneRender(scene);
48  RenderResult *render_result = render ? RE_AcquireResultRead(render) : nullptr;
49  if (render_result) {
52  }
53  if (render) {
54  RE_ReleaseResult(render);
55  }
56  }
57 
58  if (session == nullptr) {
61  }
62  return session;
63 }
64 
66  const Scene &scene, const bNode &node)
67 {
69  Image *image = (Image *)node.id;
70  if (!image) {
71  return session;
72  }
73  BLI_assert(GS(image->id.name) == ID_IM);
74 
75  NodeCryptomatte *node_cryptomatte = static_cast<NodeCryptomatte *>(node.storage);
76  ImageUser *iuser = &node_cryptomatte->iuser;
78  ImBuf *ibuf = BKE_image_acquire_ibuf(image, iuser, nullptr);
79  RenderResult *render_result = image->rr;
80  if (render_result) {
83  }
84  BKE_image_release_ibuf(image, ibuf, nullptr);
85  return session;
86 }
87 
89  const Scene &scene, const bNode &node, const bool use_meta_data)
90 {
92  if (node.type != CMP_NODE_CRYPTOMATTE) {
93  return session;
94  }
95 
96  switch (node.custom1) {
98  return cryptomatte_init_from_node_render(node, use_meta_data);
99  }
100 
103  }
104  }
105  return session;
106 }
107 
108 extern "C" {
109 static CryptomatteEntry *cryptomatte_find(const NodeCryptomatte &n, float encoded_hash)
110 {
111  LISTBASE_FOREACH (CryptomatteEntry *, entry, &n.entries) {
112  if (entry->encoded_hash == encoded_hash) {
113  return entry;
114  }
115  }
116  return nullptr;
117 }
118 
119 static void cryptomatte_add(const Scene &scene,
120  bNode &node,
121  NodeCryptomatte &node_cryptomatte,
122  float encoded_hash)
123 {
124  /* Check if entry already exist. */
125  if (cryptomatte_find(node_cryptomatte, encoded_hash)) {
126  return;
127  }
128 
129  CryptomatteEntry *entry = MEM_cnew<CryptomatteEntry>(__func__);
130  entry->encoded_hash = encoded_hash;
132  scene, node, true);
133  if (session) {
134  BKE_cryptomatte_find_name(session.get(), encoded_hash, entry->name, sizeof(entry->name));
135  }
136 
137  BLI_addtail(&node_cryptomatte.entries, entry);
138 }
139 
140 static void cryptomatte_remove(NodeCryptomatte &n, float encoded_hash)
141 {
142  CryptomatteEntry *entry = cryptomatte_find(n, encoded_hash);
143  if (!entry) {
144  return;
145  }
146  BLI_remlink(&n.entries, entry);
147  MEM_freeN(entry);
148 }
149 
151 {
153  NodeCryptomatte *n = static_cast<NodeCryptomatte *>(node->storage);
154  if (n->runtime.add[0] != 0.0f) {
155  cryptomatte_add(*scene, *node, *n, n->runtime.add[0]);
156  zero_v3(n->runtime.add);
157  }
158 }
159 
161 {
163  NodeCryptomatte *n = static_cast<NodeCryptomatte *>(node->storage);
164  if (n->runtime.remove[0] != 0.0f) {
165  cryptomatte_remove(*n, n->runtime.remove[0]);
166  zero_v3(n->runtime.remove);
167  }
168 }
170 {
172  NodeCryptomatte *n = static_cast<NodeCryptomatte *>(node->storage);
174 
176  *scene, *node, false);
177 
178  if (session) {
179  for (blender::StringRef layer_name :
181  CryptomatteLayer *layer = MEM_cnew<CryptomatteLayer>(__func__);
182  layer_name.copy(layer->name);
183  BLI_addtail(&n->runtime.layers, layer);
184  }
185  }
186 }
187 
189  const bNode *node,
190  char *r_prefix,
191  size_t prefix_len)
192 {
194  NodeCryptomatte *node_cryptomatte = (NodeCryptomatte *)node->storage;
196  *scene, *node, false);
197  std::string first_layer_name;
198 
199  if (session) {
200  for (blender::StringRef layer_name :
202  if (first_layer_name.empty()) {
203  first_layer_name = layer_name;
204  }
205 
206  if (layer_name == node_cryptomatte->layer_name) {
207  BLI_strncpy(r_prefix, node_cryptomatte->layer_name, prefix_len);
208  return;
209  }
210  }
211  }
212 
213  const char *cstr = first_layer_name.c_str();
214  BLI_strncpy(r_prefix, cstr, prefix_len);
215 }
216 
218 {
220  *scene, *node, true);
221  return session_ptr.release();
222 }
223 
225 
227  {SOCK_RGBA, N_("Image"), 0.0f, 0.0f, 0.0f, 1.0f}, {-1, ""}};
228 
230  {SOCK_RGBA, N_("Image")},
231  {SOCK_FLOAT, N_("Matte")},
232  {SOCK_RGBA, N_("Pick")},
233  {-1, ""},
234 };
235 
237 {
238  NodeCryptomatte *user = MEM_cnew<NodeCryptomatte>(__func__);
239  node->storage = user;
240 }
241 
243 {
245  bNode *node = static_cast<bNode *>(ptr->data);
247  node->id = &scene->id;
248  id_us_plus(node->id);
249 }
250 
252 {
254  NodeCryptomatte *nc = static_cast<NodeCryptomatte *>(node->storage);
255 
256  if (nc) {
257  MEM_SAFE_FREE(nc->matte_id);
259  BLI_freelistN(&nc->entries);
260  MEM_freeN(nc);
261  }
262 }
263 
264 static void node_copy_cryptomatte(bNodeTree *UNUSED(dest_ntree),
265  bNode *dest_node,
266  const bNode *src_node)
267 {
268  NodeCryptomatte *src_nc = static_cast<NodeCryptomatte *>(src_node->storage);
269  NodeCryptomatte *dest_nc = static_cast<NodeCryptomatte *>(MEM_dupallocN(src_nc));
270 
271  BLI_duplicatelist(&dest_nc->entries, &src_nc->entries);
272  BLI_listbase_clear(&dest_nc->runtime.layers);
273  dest_nc->matte_id = static_cast<char *>(MEM_dupallocN(src_nc->matte_id));
274  dest_node->storage = dest_nc;
275 }
276 
278  bNodeTree *ntree,
279  const char **r_disabled_hint)
280 {
281  if (STREQ(ntree->idname, "CompositorNodeTree")) {
282  Scene *scene;
283 
284  /* See node_composit_poll_rlayers. */
285  for (scene = static_cast<Scene *>(G.main->scenes.first); scene;
286  scene = static_cast<Scene *>(scene->id.next)) {
287  if (scene->nodetree == ntree) {
288  break;
289  }
290  }
291 
292  if (scene == nullptr) {
293  *r_disabled_hint = TIP_(
294  "The node tree must be the compositing node tree of any scene in the file");
295  }
296  return scene != nullptr;
297  }
298  *r_disabled_hint = TIP_("Not a compositor node tree");
299  return false;
300 }
301 
302 } // namespace blender::nodes::node_composite_cryptomatte_cc
303 
305 {
307 
308  static bNodeType ntype;
309 
313  node_type_size(&ntype, 240, 100, 700);
319  nodeRegisterType(&ntype);
320 }
321 
324 /* -------------------------------------------------------------------- */
329 {
331  NodeCryptomatte *n = static_cast<NodeCryptomatte *>(node->storage);
332  char sockname[32];
333  n->inputs_num++;
334  BLI_snprintf(sockname, sizeof(sockname), "Crypto %.2d", n->inputs_num - 1);
336  ntree, node, SOCK_IN, SOCK_RGBA, PROP_NONE, nullptr, sockname);
337  return sock;
338 }
339 
341 {
343  NodeCryptomatte *n = static_cast<NodeCryptomatte *>(node->storage);
344  if (n->inputs_num < 2) {
345  return 0;
346  }
347  bNodeSocket *sock = static_cast<bNodeSocket *>(node->inputs.last);
348  nodeRemoveSocket(ntree, node, sock);
349  n->inputs_num--;
350  return 1;
351 }
352 
354 
356 {
359 
360  nodeAddStaticSocket(ntree, node, SOCK_IN, SOCK_RGBA, PROP_NONE, "image", "Image");
361 
362  /* Add three inputs by default, as recommended by the Cryptomatte specification. */
366 }
367 
368 } // namespace blender::nodes::node_composite_cryptomatte_cc
369 
371 {
372  namespace legacy_file_ns = blender::nodes::node_composite_cryptomatte_cc;
374 
375  static bNodeType ntype;
376 
382  ntype.gather_link_search_ops = nullptr;
383 
384  nodeRegisterType(&ntype);
385 }
386 
388 }
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct CryptomatteSession * BKE_cryptomatte_init_from_render_result(const struct RenderResult *render_result)
Definition: cryptomatte.cc:132
struct CryptomatteSession * BKE_cryptomatte_init_from_scene(const struct Scene *scene)
Definition: cryptomatte.cc:139
bool BKE_cryptomatte_find_name(const struct CryptomatteSession *session, float encoded_hash, char *r_name, int name_len)
void BKE_image_release_ibuf(struct Image *ima, struct ImBuf *ibuf, void *lock)
struct ImBuf * BKE_image_acquire_ibuf(struct Image *ima, struct ImageUser *iuser, void **r_lock)
void BKE_image_user_frame_calc(struct Image *ima, struct ImageUser *iuser, int cfra)
void id_us_plus(struct ID *id)
Definition: lib_id.c:305
void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwidth)
Definition: node.cc:4396
void node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs)
Definition: node.cc:4358
#define NODE_CLASS_MATTE
Definition: BKE_node.h:352
#define CMP_NODE_CRYPTOMATTE
Definition: BKE_node.h:1292
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4390
struct bNodeSocket * nodeAddStaticSocket(struct bNodeTree *ntree, struct bNode *node, eNodeSocketInOut in_out, int type, int subtype, const char *identifier, const char *name)
Definition: node.cc:1897
#define CMP_NODE_CRYPTOMATTE_LEGACY
Definition: BKE_node.h:1289
void node_type_storage(struct bNodeType *ntype, const char *storagename, void(*freefunc)(struct bNode *node), void(*copyfunc)(struct bNodeTree *dest_ntree, struct bNode *dest_node, const struct bNode *src_node))
Definition: node.cc:4426
void nodeRemoveSocket(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock)
Definition: node.cc:1933
#define CMP_CRYPTOMATTE_SRC_RENDER
Definition: BKE_node.h:1331
#define CMP_CRYPTOMATTE_SRC_IMAGE
Definition: BKE_node.h:1332
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
#define BLI_assert(a)
Definition: BLI_assert.h:46
A dynamically sized string ADT.
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void void void void void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
MINLINE void zero_v3(float r[3])
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
#define TIP_(msgid)
@ ID_IM
Definition: DNA_ID_enums.h:53
@ ID_SCE
Definition: DNA_ID_enums.h:45
@ SOCK_IN
@ SOCK_FLOAT
@ SOCK_RGBA
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
@ PROP_NONE
Definition: RNA_types.h:126
#define C
Definition: RandGen.cpp:25
OperationNode * node
Scene scene
depth_tx normal_tx diffuse_light_tx specular_light_tx volume_light_tx environment_tx ambient_occlusion_tx aov_value_tx in_weight_img image(1, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D_ARRAY, "out_weight_img") .image(3
bNodeTree * ntree
#define GS(x)
Definition: iris.c:225
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
#define G(x, y, z)
std::unique_ptr< CryptomatteSession, CryptomatteSessionDeleter > CryptomatteSessionPtr
const blender::Vector< std::string > & BKE_cryptomatte_layer_names_get(const CryptomatteSession &session)
Definition: cryptomatte.cc:622
static void node_init_api_cryptomatte(const bContext *C, PointerRNA *ptr)
static void node_init_cryptomatte(bNodeTree *UNUSED(ntree), bNode *node)
static void node_copy_cryptomatte(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
static void node_init_cryptomatte_legacy(bNodeTree *ntree, bNode *node)
static bool node_poll_cryptomatte(bNodeType *UNUSED(ntype), bNodeTree *ntree, const char **r_disabled_hint)
CryptomatteSession * ntreeCompositCryptomatteSession(const Scene *scene, bNode *node)
static blender::bke::cryptomatte::CryptomatteSessionPtr cryptomatte_init_from_node_image(const Scene &scene, const bNode &node)
void register_node_type_cmp_cryptomatte_legacy()
static blender::bke::cryptomatte::CryptomatteSessionPtr cryptomatte_init_from_node_render(const bNode &node, const bool use_meta_data)
static blender::bke::cryptomatte::CryptomatteSessionPtr cryptomatte_init_from_node(const Scene &scene, const bNode &node, const bool use_meta_data)
void ntreeCompositCryptomatteLayerPrefix(const Scene *scene, const bNode *node, char *r_prefix, size_t prefix_len)
int ntreeCompositCryptomatteRemoveSocket(bNodeTree *ntree, bNode *node)
void ntreeCompositCryptomatteSyncFromRemove(bNode *node)
static CryptomatteEntry * cryptomatte_find(const NodeCryptomatte &n, float encoded_hash)
void ntreeCompositCryptomatteSyncFromAdd(const Scene *scene, bNode *node)
static void cryptomatte_remove(NodeCryptomatte &n, float encoded_hash)
void register_node_type_cmp_cryptomatte()
bNodeSocket * ntreeCompositCryptomatteAddSocket(bNodeTree *ntree, bNode *node)
static void cryptomatte_add(const Scene &scene, bNode &node, NodeCryptomatte &node_cryptomatte, float encoded_hash)
void ntreeCompositCryptomatteUpdateLayerNames(const Scene *scene, bNode *node)
void cmp_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
RenderResult * RE_AcquireResultRead(Render *re)
Definition: pipeline.c:314
Render * RE_GetSceneRender(const Scene *scene)
Definition: pipeline.c:551
void RE_ReleaseResult(Render *re)
Definition: pipeline.c:351
void * next
Definition: DNA_ID.h:369
char name[66]
Definition: DNA_ID.h:378
NodeCryptomatte_Runtime runtime
void * data
Definition: RNA_types.h:38
struct bNodeTree * nodetree
struct RenderData r
Compact definition of a node socket.
Definition: BKE_node.h:84
char idname[64]
Defines a node type.
Definition: BKE_node.h:226
bool(* poll)(struct bNodeType *ntype, struct bNodeTree *nodetree, const char **r_disabled_hint)
Definition: BKE_node.h:292
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
Definition: BKE_node.h:335
void(* initfunc_api)(const struct bContext *C, struct PointerRNA *ptr)
Definition: BKE_node.h:279
void * storage
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480