Blender  V2.93
node_composite_cryptomatte.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2018 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "node_composite_util.h"
25 
26 #include "BLI_assert.h"
27 #include "BLI_dynstr.h"
28 #include "BLI_hash_mm3.h"
29 #include "BLI_string_ref.hh"
30 #include "BLI_utildefines.h"
31 
32 #include "BKE_context.h"
33 #include "BKE_cryptomatte.hh"
34 #include "BKE_global.h"
35 #include "BKE_lib_id.h"
36 #include "BKE_library.h"
37 #include "BKE_main.h"
38 
39 #include <optional>
40 
44  const bNode &node, const bool use_meta_data)
45 {
47 
48  Scene *scene = (Scene *)node.id;
49  if (!scene) {
50  return session;
51  }
53 
54  if (use_meta_data) {
55  Render *render = (scene) ? RE_GetSceneRender(scene) : nullptr;
56  RenderResult *render_result = render ? RE_AcquireResultRead(render) : nullptr;
57  if (render_result) {
60  }
61  if (render) {
62  RE_ReleaseResult(render);
63  }
64  }
65 
66  if (session == nullptr) {
69  }
70  return session;
71 }
72 
74  const Scene &scene, const bNode &node)
75 {
77  Image *image = (Image *)node.id;
78  if (!image) {
79  return session;
80  }
81  BLI_assert(GS(image->id.name) == ID_IM);
82 
83  NodeCryptomatte *node_cryptomatte = static_cast<NodeCryptomatte *>(node.storage);
84  ImageUser *iuser = &node_cryptomatte->iuser;
85  BKE_image_user_frame_calc(image, iuser, scene.r.cfra);
86  ImBuf *ibuf = BKE_image_acquire_ibuf(image, iuser, nullptr);
87  RenderResult *render_result = image->rr;
88  if (render_result) {
91  }
92  BKE_image_release_ibuf(image, ibuf, nullptr);
93  return session;
94 }
95 
97  const Scene &scene, const bNode &node, const bool use_meta_data)
98 {
100  if (node.type != CMP_NODE_CRYPTOMATTE) {
101  return session;
102  }
103 
104  switch (node.custom1) {
106  return cryptomatte_init_from_node_render(node, use_meta_data);
107  }
108 
111  }
112  }
113  return session;
114 }
115 
116 extern "C" {
117 static CryptomatteEntry *cryptomatte_find(const NodeCryptomatte &n, float encoded_hash)
118 {
119  LISTBASE_FOREACH (CryptomatteEntry *, entry, &n.entries) {
120  if (entry->encoded_hash == encoded_hash) {
121  return entry;
122  }
123  }
124  return nullptr;
125 }
126 
127 static void cryptomatte_add(const Scene &scene,
128  bNode &node,
129  NodeCryptomatte &node_cryptomatte,
130  float encoded_hash)
131 {
132  /* Check if entry already exist. */
133  if (cryptomatte_find(node_cryptomatte, encoded_hash)) {
134  return;
135  }
136 
137  CryptomatteEntry *entry = static_cast<CryptomatteEntry *>(
138  MEM_callocN(sizeof(CryptomatteEntry), __func__));
139  entry->encoded_hash = encoded_hash;
141  scene, node, true);
142  if (session) {
143  BKE_cryptomatte_find_name(session.get(), encoded_hash, entry->name, sizeof(entry->name));
144  }
145 
146  BLI_addtail(&node_cryptomatte.entries, entry);
147 }
148 
149 static void cryptomatte_remove(NodeCryptomatte &n, float encoded_hash)
150 {
151  CryptomatteEntry *entry = cryptomatte_find(n, encoded_hash);
152  if (!entry) {
153  return;
154  }
155  BLI_remlink(&n.entries, entry);
156  MEM_freeN(entry);
157 }
158 
160  {SOCK_RGBA, N_("Image"), 0.0f, 0.0f, 0.0f, 1.0f}, {-1, ""}};
161 
163  {SOCK_RGBA, N_("Image")},
164  {SOCK_FLOAT, N_("Matte")},
165  {SOCK_RGBA, N_("Pick")},
166  {-1, ""},
167 };
168 
170 {
172  NodeCryptomatte *n = static_cast<NodeCryptomatte *>(node->storage);
173  if (n->runtime.add[0] != 0.0f) {
174  cryptomatte_add(*scene, *node, *n, n->runtime.add[0]);
175  zero_v3(n->runtime.add);
176  }
177 }
178 
180 {
182  NodeCryptomatte *n = static_cast<NodeCryptomatte *>(node->storage);
183  if (n->runtime.remove[0] != 0.0f) {
184  cryptomatte_remove(*n, n->runtime.remove[0]);
185  zero_v3(n->runtime.remove);
186  }
187 }
189 {
191  NodeCryptomatte *n = static_cast<NodeCryptomatte *>(node->storage);
193 
195  *scene, *node, false);
196 
197  if (session) {
198  for (blender::StringRef layer_name :
200  CryptomatteLayer *layer = static_cast<CryptomatteLayer *>(
201  MEM_callocN(sizeof(CryptomatteLayer), __func__));
202  layer_name.copy(layer->name);
203  BLI_addtail(&n->runtime.layers, layer);
204  }
205  }
206 }
207 
209  const bNode *node,
210  char *r_prefix,
211  size_t prefix_len)
212 {
214  NodeCryptomatte *node_cryptomatte = (NodeCryptomatte *)node->storage;
216  *scene, *node, false);
217  std::string first_layer_name;
218 
219  if (session) {
220  for (blender::StringRef layer_name :
222  if (first_layer_name.empty()) {
223  first_layer_name = layer_name;
224  }
225 
226  if (layer_name == node_cryptomatte->layer_name) {
227  BLI_strncpy(r_prefix, node_cryptomatte->layer_name, prefix_len);
228  return;
229  }
230  }
231  }
232 
233  const char *cstr = first_layer_name.c_str();
234  BLI_strncpy(r_prefix, cstr, prefix_len);
235 }
236 
238 {
240  *scene, *node, true);
241  return session_ptr.release();
242 }
243 
245 {
246  NodeCryptomatte *user = static_cast<NodeCryptomatte *>(
247  MEM_callocN(sizeof(NodeCryptomatte), __func__));
248  node->storage = user;
249 }
250 
252 {
254  bNode *node = static_cast<bNode *>(ptr->data);
256  node->id = &scene->id;
257  id_us_plus(node->id);
258 }
259 
261 {
263  NodeCryptomatte *nc = static_cast<NodeCryptomatte *>(node->storage);
264 
265  if (nc) {
267  BLI_freelistN(&nc->entries);
268  MEM_freeN(nc);
269  }
270 }
271 
272 static void node_copy_cryptomatte(bNodeTree *UNUSED(dest_ntree),
273  bNode *dest_node,
274  const bNode *src_node)
275 {
276  NodeCryptomatte *src_nc = static_cast<NodeCryptomatte *>(src_node->storage);
277  NodeCryptomatte *dest_nc = static_cast<NodeCryptomatte *>(MEM_dupallocN(src_nc));
278 
279  BLI_duplicatelist(&dest_nc->entries, &src_nc->entries);
280  BLI_listbase_clear(&dest_nc->runtime.layers);
281  dest_node->storage = dest_nc;
282 }
283 
285  bNodeTree *ntree,
286  const char **r_disabled_hint)
287 {
288  if (STREQ(ntree->idname, "CompositorNodeTree")) {
289  Scene *scene;
290 
291  /* See node_composit_poll_rlayers. */
292  for (scene = static_cast<Scene *>(G.main->scenes.first); scene;
293  scene = static_cast<Scene *>(scene->id.next)) {
294  if (scene->nodetree == ntree) {
295  break;
296  }
297  }
298 
299  if (scene == nullptr) {
300  *r_disabled_hint =
301  "The node tree must be the compositing node tree of any scene in the file";
302  }
303  return scene != nullptr;
304  }
305  *r_disabled_hint = "Not a compositor node tree";
306  return false;
307 }
308 
310 {
311  static bNodeType ntype;
312 
313  cmp_node_type_base(&ntype, CMP_NODE_CRYPTOMATTE, "Cryptomatte", NODE_CLASS_MATTE, 0);
315  node_type_size(&ntype, 240, 100, 700);
318  ntype.poll = node_poll_cryptomatte;
320  nodeRegisterType(&ntype);
321 }
322 
328 {
330 
331  nodeAddStaticSocket(ntree, node, SOCK_IN, SOCK_RGBA, PROP_NONE, "image", "Image");
332 
333  /* Add three inputs by default, as recommended by the Cryptomatte specification. */
337 }
338 
340 {
342  NodeCryptomatte *n = static_cast<NodeCryptomatte *>(node->storage);
343  char sockname[32];
344  n->num_inputs++;
345  BLI_snprintf(sockname, sizeof(sockname), "Crypto %.2d", n->num_inputs - 1);
347  ntree, node, SOCK_IN, SOCK_RGBA, PROP_NONE, nullptr, sockname);
348  return sock;
349 }
350 
352 {
354  NodeCryptomatte *n = static_cast<NodeCryptomatte *>(node->storage);
355  if (n->num_inputs < 2) {
356  return 0;
357  }
358  bNodeSocket *sock = static_cast<bNodeSocket *>(node->inputs.last);
359  nodeRemoveSocket(ntree, node, sock);
360  n->num_inputs--;
361  return 1;
362 }
363 
365 {
366  static bNodeType ntype;
367 
372  nodeRegisterType(&ntype);
373 }
374 
376 }
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
bool BKE_cryptomatte_find_name(const struct CryptomatteSession *session, const float encoded_hash, char *r_name, int name_len)
struct CryptomatteSession * BKE_cryptomatte_init_from_render_result(const struct RenderResult *render_result)
Definition: cryptomatte.cc:148
struct CryptomatteSession * BKE_cryptomatte_init_from_scene(const struct Scene *scene)
Definition: cryptomatte.cc:155
void BKE_image_release_ibuf(struct Image *ima, struct ImBuf *ibuf, void *lock)
Definition: image.c:5113
struct ImBuf * BKE_image_acquire_ibuf(struct Image *ima, struct ImageUser *iuser, void **r_lock)
Definition: image.c:5100
void BKE_image_user_frame_calc(struct Image *ima, struct ImageUser *iuser, int cfra)
Definition: image.c:5335
void id_us_plus(struct ID *id)
Definition: lib_id.c:288
void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwidth)
Definition: node.cc:4565
void node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs)
Definition: node.cc:4527
#define NODE_CLASS_MATTE
Definition: BKE_node.h:342
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4559
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:1716
#define CMP_NODE_CRYPTOMATTE_LEGACY
Definition: BKE_node.h:1225
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:4599
void nodeRemoveSocket(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock)
Definition: node.cc:1775
#define CMP_CRYPTOMATTE_SRC_RENDER
Definition: BKE_node.h:1259
#define CMP_CRYPTOMATTE_SRC_IMAGE
Definition: BKE_node.h:1260
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1298
#define BLI_assert(a)
Definition: BLI_assert.h:58
A dynamically sized string ADT.
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
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:128
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:133
MINLINE void zero_v3(float r[3])
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
#define N_(msgid)
@ ID_IM
Definition: DNA_ID_enums.h:65
@ ID_SCE
Definition: DNA_ID_enums.h:57
@ SOCK_IN
@ SOCK_FLOAT
@ SOCK_RGBA
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel Split ID Combine Luminance Directional Alpha Distance Hue Movie Ellipse Bokeh View Corner CMP_NODE_CRYPTOMATTE
@ PROP_NONE
Definition: RNA_types.h:113
#define C
Definition: RandGen.cpp:39
struct RenderResult * rr
OperationNode * node
Scene scene
bNodeTree * ntree
#define GS(x)
Definition: iris.c:241
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
std::unique_ptr< CryptomatteSession, CryptomatteSessionDeleter > CryptomatteSessionPtr
const blender::Vector< std::string > & BKE_cryptomatte_layer_names_get(const CryptomatteSession &session)
Definition: cryptomatte.cc:654
static void node_copy_cryptomatte(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
CryptomatteSession * ntreeCompositCryptomatteSession(const Scene *scene, bNode *node)
static void node_init_api_cryptomatte(const bContext *C, PointerRNA *ptr)
static bool node_poll_cryptomatte(bNodeType *UNUSED(ntype), bNodeTree *ntree, const char **r_disabled_hint)
static blender::bke::cryptomatte::CryptomatteSessionPtr cryptomatte_init_from_node_image(const Scene &scene, const bNode &node)
static bNodeSocketTemplate cmp_node_cryptomatte_in[]
void register_node_type_cmp_cryptomatte_legacy(void)
static blender::bke::cryptomatte::CryptomatteSessionPtr cryptomatte_init_from_node_render(const bNode &node, const bool use_meta_data)
static bNodeSocketTemplate cmp_node_cryptomatte_out[]
static void node_init_cryptomatte_legacy(bNodeTree *ntree, bNode *node)
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)
void register_node_type_cmp_cryptomatte(void)
static void cryptomatte_remove(NodeCryptomatte &n, float encoded_hash)
static void node_free_cryptomatte(bNode *node)
bNodeSocket * ntreeCompositCryptomatteAddSocket(bNodeTree *ntree, bNode *node)
static void cryptomatte_add(const Scene &scene, bNode &node, NodeCryptomatte &node_cryptomatte, float encoded_hash)
static void node_init_cryptomatte(bNodeTree *UNUSED(ntree), bNode *node)
void ntreeCompositCryptomatteUpdateLayerNames(const Scene *scene, bNode *node)
void cmp_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
RenderResult * RE_AcquireResultRead(Render *re)
Definition: pipeline.c:343
Render * RE_GetSceneRender(const Scene *scene)
Definition: pipeline.c:591
void RE_ReleaseResult(Render *re)
Definition: pipeline.c:379
void * next
Definition: DNA_ID.h:274
char name[66]
Definition: DNA_ID.h:283
NodeCryptomatte_Runtime runtime
void * data
Definition: RNA_types.h:52
struct bNodeTree * nodetree
struct RenderData r
Compact definition of a node socket.
Definition: BKE_node.h:95
char idname[64]
Defines a node type.
Definition: BKE_node.h:221
bool(* poll)(struct bNodeType *ntype, struct bNodeTree *nodetree, const char **r_disabled_hint)
Definition: BKE_node.h:301
void(* initfunc_api)(const struct bContext *C, struct PointerRNA *ptr)
Definition: BKE_node.h:288
void * storage
#define G(x, y, z)
PointerRNA * ptr
Definition: wm_files.c:3157