Blender V4.3
node_composite_cryptomatte.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2018 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <string>
10
11#include <fmt/format.h>
12
14
15#include "BLI_assert.h"
16#include "BLI_dynstr.h"
17#include "BLI_hash_mm3.hh"
18#include "BLI_listbase.h"
19#include "BLI_math_vector.h"
21#include "BLI_string.h"
22#include "BLI_string_ref.hh"
23#include "BLI_utildefines.h"
24#include "BLI_vector.hh"
25
26#include "IMB_imbuf_types.hh"
27
28#include "GPU_shader.hh"
29#include "GPU_texture.hh"
30
31#include "DNA_image_types.h"
32#include "DNA_scene_types.h"
33
34#include "BKE_context.hh"
35#include "BKE_cryptomatte.hh"
36#include "BKE_global.hh"
37#include "BKE_image.hh"
38#include "BKE_lib_id.hh"
39#include "BKE_library.hh"
40#include "BKE_main.hh"
41
42#include "MEM_guardedalloc.h"
43
44#include "RE_pipeline.h"
45
46#include "COM_node_operation.hh"
47#include "COM_result.hh"
48#include "COM_utilities.hh"
49
50#include <optional>
51
52/* -------------------------------------------------------------------- */
57 const bNode &node, const bool build_meta_data)
58{
60
61 Scene *scene = (Scene *)node.id;
62 if (!scene) {
63 return session;
64 }
65 BLI_assert(GS(scene->id.name) == ID_SCE);
66
68 BKE_cryptomatte_init_from_scene(scene, build_meta_data));
69 return session;
70}
71
73 const bNode &node)
74{
76 Image *image = (Image *)node.id;
77 if (!image) {
78 return session;
79 }
80 BLI_assert(GS(image->id.name) == ID_IM);
81
82 NodeCryptomatte *node_cryptomatte = static_cast<NodeCryptomatte *>(node.storage);
83 ImageUser *iuser = &node_cryptomatte->iuser;
84 ImBuf *ibuf = BKE_image_acquire_ibuf(image, iuser, nullptr);
85 RenderResult *render_result = image->rr;
86 if (render_result) {
89 }
90 BKE_image_release_ibuf(image, ibuf, nullptr);
91 return session;
92}
93
95 const bNode &node, const bool build_meta_data)
96{
98 if (node.type != CMP_NODE_CRYPTOMATTE) {
99 return session;
100 }
101
102 switch (node.custom1) {
104 return cryptomatte_init_from_node_render(node, build_meta_data);
105 }
106
109 }
110 }
111 return session;
112}
113
114static CryptomatteEntry *cryptomatte_find(const NodeCryptomatte &n, float encoded_hash)
115{
117 if (entry->encoded_hash == encoded_hash) {
118 return entry;
119 }
120 }
121 return nullptr;
122}
123
124static void cryptomatte_add(bNode &node, NodeCryptomatte &node_cryptomatte, float encoded_hash)
125{
126 /* Check if entry already exist. */
127 if (cryptomatte_find(node_cryptomatte, encoded_hash)) {
128 return;
129 }
130
131 CryptomatteEntry *entry = MEM_cnew<CryptomatteEntry>(__func__);
132 entry->encoded_hash = encoded_hash;
134 true);
135 if (session) {
136 BKE_cryptomatte_find_name(session.get(), encoded_hash, entry->name, sizeof(entry->name));
137 }
138
139 BLI_addtail(&node_cryptomatte.entries, entry);
140}
141
142static void cryptomatte_remove(NodeCryptomatte &n, float encoded_hash)
143{
144 CryptomatteEntry *entry = cryptomatte_find(n, encoded_hash);
145 if (!entry) {
146 return;
147 }
148 BLI_remlink(&n.entries, entry);
149 MEM_freeN(entry);
150}
151
153{
154 BLI_assert(ELEM(node->type, CMP_NODE_CRYPTOMATTE, CMP_NODE_CRYPTOMATTE_LEGACY));
155 NodeCryptomatte *n = static_cast<NodeCryptomatte *>(node->storage);
156 if (n->runtime.add[0] != 0.0f) {
157 cryptomatte_add(*node, *n, n->runtime.add[0]);
158 zero_v3(n->runtime.add);
159 }
160}
161
163{
164 BLI_assert(ELEM(node->type, CMP_NODE_CRYPTOMATTE, CMP_NODE_CRYPTOMATTE_LEGACY));
165 NodeCryptomatte *n = static_cast<NodeCryptomatte *>(node->storage);
166 if (n->runtime.remove[0] != 0.0f) {
169 }
170}
172{
173 BLI_assert(node->type == CMP_NODE_CRYPTOMATTE);
174 NodeCryptomatte *n = static_cast<NodeCryptomatte *>(node->storage);
176
178 false);
179
180 if (session) {
181 for (blender::StringRef layer_name :
183 {
184 CryptomatteLayer *layer = MEM_cnew<CryptomatteLayer>(__func__);
185 layer_name.copy(layer->name);
186 BLI_addtail(&n->runtime.layers, layer);
187 }
188 }
189}
190
191void ntreeCompositCryptomatteLayerPrefix(const bNode *node, char *r_prefix, size_t prefix_maxncpy)
192{
193 BLI_assert(node->type == CMP_NODE_CRYPTOMATTE);
194 NodeCryptomatte *node_cryptomatte = (NodeCryptomatte *)node->storage;
196 false);
197 std::string first_layer_name;
198
199 if (session) {
200 for (blender::StringRef layer_name :
202 {
203 if (first_layer_name.empty()) {
204 first_layer_name = layer_name;
205 }
206
207 if (layer_name == node_cryptomatte->layer_name) {
208 BLI_strncpy(r_prefix, node_cryptomatte->layer_name, prefix_maxncpy);
209 return;
210 }
211 }
212 }
213
214 const char *cstr = first_layer_name.c_str();
215 BLI_strncpy(r_prefix, cstr, prefix_maxncpy);
216}
217
219{
221 true);
222 return session_ptr.release();
223}
224
226
228
229using namespace blender::realtime_compositor;
230
232 public:
234
235 /* Should return the input image result. */
236 virtual Result &get_input_image() = 0;
237
238 /* Should returns all the Cryptomatte layers in order. */
240
241 /* If only a subset area of the Cryptomatte layers is to be considered, this method should return
242 * the lower bound of that area. The upper bound will be derived from the operation domain. */
244 {
245 return int2(0);
246 }
247
248 void execute() override
249 {
251 if (layers.is_empty()) {
253 return;
254 }
255
256 Result &output_pick = get_result("Pick");
257 if (output_pick.should_compute()) {
258 compute_pick(layers);
259 }
260
261 Result &matte_output = get_result("Matte");
262 Result &image_output = get_result("Image");
263 if (!matte_output.should_compute() && !image_output.should_compute()) {
264 return;
265 }
266
267 Result matte = compute_matte(layers);
268
269 if (image_output.should_compute()) {
270 compute_image(matte);
271 }
272
273 if (matte_output.should_compute()) {
274 matte_output.steal_data(matte);
275 }
276 else {
277 matte.release();
278 }
279 }
280
282 {
283 Result &pick = get_result("Pick");
284 if (pick.should_compute()) {
285 pick.allocate_invalid();
286 }
287
288 Result &matte = get_result("Matte");
289 if (matte.should_compute()) {
290 matte.allocate_invalid();
291 }
292
293 Result &image = get_result("Image");
294 if (image.should_compute()) {
295 image.allocate_invalid();
296 }
297 }
298
299 /* Computes the pick result, which is a special human-viewable image that the user can pick
300 * entities from using the Cryptomatte picker operator. See the shader for more information. */
302 {
303 /* See the comment below for why full precision is necessary. */
304 GPUShader *shader = context().get_shader("compositor_cryptomatte_pick", ResultPrecision::Full);
305 GPU_shader_bind(shader);
306
307 const int2 lower_bound = this->get_layers_lower_bound();
308 GPU_shader_uniform_2iv(shader, "lower_bound", lower_bound);
309
310 GPUTexture *first_layer = layers[0];
311 const int input_unit = GPU_shader_get_sampler_binding(shader, "first_layer_tx");
312 GPU_texture_bind(first_layer, input_unit);
313
314 Result &output_pick = get_result("Pick");
315
316 /* Promote to full precision since it stores the identifiers of the first Cryptomatte rank,
317 * which is a 32-bit float. See the shader for more information. */
318 output_pick.set_precision(ResultPrecision::Full);
319
320 output_pick.meta_data.is_non_color_data = true;
321
322 const Domain domain = compute_domain();
323 output_pick.allocate_texture(domain);
324 output_pick.bind_as_image(shader, "output_img");
325
326 compute_dispatch_threads_at_least(shader, domain.size);
327
329 GPU_texture_unbind(first_layer);
330 output_pick.unbind_as_image();
331 }
332
333 /* Computes and returns the matte by accumulating the coverage of all entities whose identifiers
334 * are selected by the user, across all layers. See the shader for more information. */
336 {
337 const Domain domain = compute_domain();
338 Result output_matte = context().create_result(ResultType::Float);
339 output_matte.allocate_texture(domain);
340
341 /* Clear the matte to zero to ready it to accumulate the coverage. */
342 const float4 zero_color = float4(0.0f);
343 GPU_texture_clear(output_matte, GPU_DATA_FLOAT, zero_color);
344
345 Vector<float> identifiers = get_identifiers();
346 /* The user haven't selected any entities, return the currently zero matte. */
347 if (identifiers.is_empty()) {
348 return output_matte;
349 }
350
351 GPUShader *shader = context().get_shader("compositor_cryptomatte_matte");
352 GPU_shader_bind(shader);
353
354 const int2 lower_bound = this->get_layers_lower_bound();
355 GPU_shader_uniform_2iv(shader, "lower_bound", lower_bound);
356 GPU_shader_uniform_1i(shader, "identifiers_count", identifiers.size());
357 GPU_shader_uniform_1f_array(shader, "identifiers", identifiers.size(), identifiers.data());
358
359 for (GPUTexture *layer : layers) {
360 const int input_unit = GPU_shader_get_sampler_binding(shader, "layer_tx");
361 GPU_texture_bind(layer, input_unit);
362
363 /* Bind the matte with read access, since we will be accumulating in it. */
364 output_matte.bind_as_image(shader, "matte_img", true);
365
366 compute_dispatch_threads_at_least(shader, domain.size);
367
368 GPU_texture_unbind(layer);
369 output_matte.unbind_as_image();
370 }
371
373
374 return output_matte;
375 }
376
377 /* Computes the output image result by pre-multiplying the matte to the image. */
379 {
380 GPUShader *shader = context().get_shader("compositor_cryptomatte_image");
381 GPU_shader_bind(shader);
382
383 Result &input_image = get_input_image();
384 input_image.bind_as_texture(shader, "input_tx");
385
386 matte.bind_as_texture(shader, "matte_tx");
387
388 const Domain domain = compute_domain();
389 Result &image_output = get_result("Image");
390 image_output.allocate_texture(domain);
391 image_output.bind_as_image(shader, "output_img");
392
393 compute_dispatch_threads_at_least(shader, domain.size);
394
396 input_image.unbind_as_texture();
397 matte.unbind_as_texture();
398 image_output.unbind_as_image();
399 }
400
401 /* Get the identifiers of the entities selected by the user to generate a matte from. The
402 * identifiers are hashes of the names of the entities encoded in floats. See the "ID Generation"
403 * section of the Cryptomatte specification for more information. */
405 {
406 Vector<float> identifiers;
407 LISTBASE_FOREACH (CryptomatteEntry *, cryptomatte_entry, &node_storage(bnode()).entries) {
408 identifiers.append(cryptomatte_entry->encoded_hash);
409 }
410 return identifiers;
411 }
412};
413
414} // namespace blender::nodes::node_composite_base_cryptomatte_cc
415
417
419
420static bke::bNodeSocketTemplate cmp_node_cryptomatte_out[] = {
421 {SOCK_RGBA, N_("Image")},
422 {SOCK_FLOAT, N_("Matte")},
423 {SOCK_RGBA, N_("Pick")},
424 {-1, ""},
425};
426
428{
429 b.add_input<decl::Color>("Image")
430 .default_value({0.0f, 0.0f, 0.0f, 1.0f})
431 .compositor_domain_priority(0);
432 b.add_output<decl::Color>("Image");
433 b.add_output<decl::Float>("Matte");
434 b.add_output<decl::Color>("Pick");
435}
436
437static void node_init_cryptomatte(bNodeTree * /*ntree*/, bNode *node)
438{
439 NodeCryptomatte *user = MEM_cnew<NodeCryptomatte>(__func__);
440 node->storage = user;
441}
442
444{
445 Scene *scene = CTX_data_scene(C);
446 bNode *node = static_cast<bNode *>(ptr->data);
447 BLI_assert(node->type == CMP_NODE_CRYPTOMATTE);
448 node->id = &scene->id;
449 id_us_plus(node->id);
450}
451
452static void node_free_cryptomatte(bNode *node)
453{
454 BLI_assert(ELEM(node->type, CMP_NODE_CRYPTOMATTE, CMP_NODE_CRYPTOMATTE_LEGACY));
455 NodeCryptomatte *nc = static_cast<NodeCryptomatte *>(node->storage);
456
457 if (nc) {
461 MEM_freeN(nc);
462 }
463}
464
465static void node_copy_cryptomatte(bNodeTree * /*dst_ntree*/,
466 bNode *dest_node,
467 const bNode *src_node)
468{
469 NodeCryptomatte *src_nc = static_cast<NodeCryptomatte *>(src_node->storage);
470 NodeCryptomatte *dest_nc = static_cast<NodeCryptomatte *>(MEM_dupallocN(src_nc));
471
472 BLI_duplicatelist(&dest_nc->entries, &src_nc->entries);
474 dest_nc->matte_id = static_cast<char *>(MEM_dupallocN(src_nc->matte_id));
475 dest_node->storage = dest_nc;
476}
477
478static bool node_poll_cryptomatte(const blender::bke::bNodeType * /*ntype*/,
479 const bNodeTree *ntree,
480 const char **r_disabled_hint)
481{
482 if (STREQ(ntree->idname, "CompositorNodeTree")) {
483 Scene *scene;
484
485 /* See node_composit_poll_rlayers. */
486 for (scene = static_cast<Scene *>(G.main->scenes.first); scene;
487 scene = static_cast<Scene *>(scene->id.next))
488 {
489 if (scene->nodetree == ntree) {
490 break;
491 }
492 }
493
494 if (scene == nullptr) {
495 *r_disabled_hint = RPT_(
496 "The node tree must be the compositing node tree of any scene in the file");
497 }
498 return scene != nullptr;
499 }
500 *r_disabled_hint = RPT_("Not a compositor node tree");
501 return false;
502}
503
504static void node_update_cryptomatte(bNodeTree *ntree, bNode *node)
505{
506 cmp_node_update_default(ntree, node);
508}
509
510using namespace blender::realtime_compositor;
512
514 public:
515 using BaseCryptoMatteOperation::BaseCryptoMatteOperation;
516
518 {
519 return get_input("Image");
520 }
521
522 /* Returns all the relevant Cryptomatte layers from the selected source. */
535
536 /* Returns all the relevant Cryptomatte layers from the selected layer. */
538 {
540
541 Scene *scene = get_scene();
542 if (!scene) {
543 return layers;
544 }
545
546 const std::string type_name = get_type_name();
547
548 int view_layer_index = 0;
549 LISTBASE_FOREACH_INDEX (ViewLayer *, view_layer, &scene->view_layers, view_layer_index) {
550 /* Not the viewer layer used by the node. */
551 if (!StringRef(type_name).startswith(view_layer->name)) {
552 continue;
553 }
554
555 /* Find out which type of Cryptomatte layer the node uses. */
556 const char *cryptomatte_type = nullptr;
557 const std::string layer_prefix = std::string(view_layer->name) + ".";
558 if (type_name == layer_prefix + RE_PASSNAME_CRYPTOMATTE_OBJECT) {
559 cryptomatte_type = RE_PASSNAME_CRYPTOMATTE_OBJECT;
560 }
561 else if (type_name == layer_prefix + RE_PASSNAME_CRYPTOMATTE_ASSET) {
562 cryptomatte_type = RE_PASSNAME_CRYPTOMATTE_ASSET;
563 }
564 else if (type_name == layer_prefix + RE_PASSNAME_CRYPTOMATTE_MATERIAL) {
565 cryptomatte_type = RE_PASSNAME_CRYPTOMATTE_MATERIAL;
566 }
567
568 if (!cryptomatte_type) {
569 return layers;
570 }
571
572 /* Each layer stores two ranks/levels, so do ceiling division by two. */
573 const int cryptomatte_layers_count = int(math::ceil(view_layer->cryptomatte_levels / 2.0f));
574 for (int i = 0; i < cryptomatte_layers_count; i++) {
575 const std::string pass_name = fmt::format("{}{:02}", cryptomatte_type, i);
576 GPUTexture *pass_texture = context().get_input_texture(
577 scene, view_layer_index, pass_name.c_str());
578
579 /* If this Cryptomatte layer wasn't found, then all later Cryptomatte layers can't be used
580 * even if they were found. */
581 if (!pass_texture) {
582 return layers;
583 }
584 layers.append(pass_texture);
585 }
586
587 /* The target view later was processed already, no need to check other view layers. */
588 return layers;
589 }
590
591 return layers;
592 }
593
594 /* Returns all the relevant Cryptomatte layers from the selected EXR image. */
596 {
598
599 Image *image = get_image();
600 if (!image || image->type != IMA_TYPE_MULTILAYER) {
601 return layers;
602 }
603
604 /* The render result structure of the image is populated as a side effect of the acquisition of
605 * an image buffer, so acquire an image buffer and immediately release it since it is not
606 * actually needed. */
607 ImageUser image_user_for_layer = *get_image_user();
608 ImBuf *image_buffer = BKE_image_acquire_ibuf(image, &image_user_for_layer, nullptr);
609 BKE_image_release_ibuf(image, image_buffer, nullptr);
610 if (!image_buffer || !image->rr) {
611 return layers;
612 }
613
614 int layer_index;
615 const std::string type_name = get_type_name();
616 LISTBASE_FOREACH_INDEX (RenderLayer *, render_layer, &image->rr->layers, layer_index) {
617 /* If the Cryptomatte type name doesn't start with the layer name, then it is not a
618 * Cryptomatte layer. Unless it is an unnamed layer, in which case, we need to check its
619 * passes. */
620 const bool is_unnamed_layer = render_layer->name[0] == '\0';
621 if (!is_unnamed_layer && !StringRefNull(type_name).startswith(render_layer->name)) {
622 continue;
623 }
624
625 image_user_for_layer.layer = layer_index;
626 LISTBASE_FOREACH (RenderPass *, render_pass, &render_layer->passes) {
627 /* If the combined pass name doesn't start with the Cryptomatte type name, then it is not a
628 * Cryptomatte layer. */
629 const std::string combined_name = get_combined_layer_pass_name(render_layer, render_pass);
630 if (combined_name == type_name || !StringRef(combined_name).startswith(type_name)) {
631 continue;
632 }
633
634 Result *pass_result = context().cache_manager().cached_images.get(
635 context(), image, &image_user_for_layer, render_pass->name);
636 layers.append(*pass_result);
637 }
638
639 /* If we already found Cryptomatte layers, no need to check other render layers. */
640 if (!layers.is_empty()) {
641 return layers;
642 }
643 }
644
645 return layers;
646 }
647
648 /* Returns the combined name of the render layer and pass using the EXR convention of a period
649 * separator. */
650 std::string get_combined_layer_pass_name(RenderLayer *render_layer, RenderPass *render_pass)
651 {
652 if (render_layer->name[0] == '\0') {
653 return std::string(render_pass->name);
654 }
655 return std::string(render_layer->name) + "." + std::string(render_pass->name);
656 }
657
658 /* Get the selected type name of the Cryptomatte from the metadata of the image/render. This type
659 * name will be used to identify the corresponding layers in the source image/render. See the
660 * "EXR File: Layer Naming" section of the Cryptomatte specification for more information on what
661 * this represents. */
662 std::string get_type_name()
663 {
664 char type_name[MAX_NAME];
665 ntreeCompositCryptomatteLayerPrefix(&bnode(), type_name, sizeof(type_name));
666 return std::string(type_name);
667 }
668
670 {
671 switch (get_source()) {
673 const rcti compositing_region = this->context().get_compositing_region();
674 return int2(compositing_region.xmin, compositing_region.ymin);
675 }
677 return int2(0);
678 }
679
681 return int2(0);
682 }
683
684 /* The domain should be centered with the same size as the source. In case of invalid source,
685 * fallback to the domain inferred from the input. */
687 {
688 switch (get_source()) {
690 return Domain(context().get_compositing_region_size());
692 return compute_image_domain();
693 }
694
696 return Domain::identity();
697 }
698
699 /* In case of a render source, the domain should be centered with the same size as the render. In
700 * case of an invalid render, fallback to the domain inferred from the input. */
702 {
704
705 Scene *scene = get_scene();
706 if (!scene) {
707 return NodeOperation::compute_domain();
708 }
709
710 Render *render = RE_GetSceneRender(scene);
711 if (!render) {
712 return NodeOperation::compute_domain();
713 }
714
715 RenderResult *render_result = RE_AcquireResultRead(render);
716 if (!render_result) {
717 RE_ReleaseResult(render);
718 return NodeOperation::compute_domain();
719 }
720
721 const int2 render_size = int2(render_result->rectx, render_result->rectx);
722 RE_ReleaseResult(render);
723 return Domain(render_size);
724 }
725
726 /* In case of an image source, the domain should be centered with the same size as the source
727 * image. In case of an invalid image, fallback to the domain inferred from the input. */
729 {
731
732 Image *image = get_image();
733 if (!image) {
734 return NodeOperation::compute_domain();
735 }
736
737 ImageUser image_user = *get_image_user();
738 ImBuf *image_buffer = BKE_image_acquire_ibuf(image, &image_user, nullptr);
739 if (!image_buffer) {
740 return NodeOperation::compute_domain();
741 }
742
743 const int2 image_size = int2(image_buffer->x, image_buffer->y);
744 BKE_image_release_ibuf(image, image_buffer, nullptr);
745 return Domain(image_size);
746 }
747
749 {
751 return &node_storage(bnode()).iuser;
752 }
753
755 {
757 return reinterpret_cast<Scene *>(bnode().id);
758 }
759
761 {
763 return reinterpret_cast<Image *>(bnode().id);
764 }
765
770};
771
773{
774 return new CryptoMatteOperation(context, node);
775}
776
777} // namespace blender::nodes::node_composite_cryptomatte_cc
778
780{
782
783 static blender::bke::bNodeType ntype;
784
785 cmp_node_type_base(&ntype, CMP_NODE_CRYPTOMATTE, "Cryptomatte", NODE_CLASS_MATTE);
786 ntype.declare = file_ns::cmp_node_cryptomatte_declare;
787 blender::bke::node_type_size(&ntype, 240, 100, 700);
788 ntype.initfunc = file_ns::node_init_cryptomatte;
789 ntype.initfunc_api = file_ns::node_init_api_cryptomatte;
790 ntype.poll = file_ns::node_poll_cryptomatte;
791 ntype.updatefunc = file_ns::node_update_cryptomatte;
793 &ntype, "NodeCryptomatte", file_ns::node_free_cryptomatte, file_ns::node_copy_cryptomatte);
794 ntype.get_compositor_operation = file_ns::get_compositor_operation;
795
797}
798
801/* -------------------------------------------------------------------- */
806{
807 BLI_assert(node->type == CMP_NODE_CRYPTOMATTE_LEGACY);
808 NodeCryptomatte *n = static_cast<NodeCryptomatte *>(node->storage);
809 char sockname[32];
810 n->inputs_num++;
811 SNPRINTF(sockname, "Crypto %.2d", n->inputs_num - 1);
813 ntree, node, SOCK_IN, SOCK_RGBA, PROP_NONE, nullptr, sockname);
814 return sock;
815}
816
818{
819 BLI_assert(node->type == CMP_NODE_CRYPTOMATTE_LEGACY);
820 NodeCryptomatte *n = static_cast<NodeCryptomatte *>(node->storage);
821 if (n->inputs_num < 2) {
822 return 0;
823 }
824 bNodeSocket *sock = static_cast<bNodeSocket *>(node->inputs.last);
825 blender::bke::node_remove_socket(ntree, node, sock);
826 n->inputs_num--;
827 return 1;
828}
829
831
833{
835 file_ns::node_init_cryptomatte(ntree, node);
836
837 bke::node_add_static_socket(ntree, node, SOCK_IN, SOCK_RGBA, PROP_NONE, "image", "Image");
838
839 /* Add three inputs by default, as recommended by the Cryptomatte specification. */
843}
844
845using namespace blender::realtime_compositor;
847
849 public:
850 using BaseCryptoMatteOperation::BaseCryptoMatteOperation;
851
853 {
854 return get_input("image");
855 }
856
858 {
860 /* Add all textures of all inputs except the first input, which is the input image. */
861 for (const bNodeSocket *socket : bnode().input_sockets().drop_front(1)) {
862 layers.append(get_input(socket->identifier));
863 }
864 return layers;
865 }
866};
867
869{
870 return new LegacyCryptoMatteOperation(context, node);
871}
872
873} // namespace blender::nodes::node_composite_legacy_cryptomatte_cc
874
876{
879
880 static blender::bke::bNodeType ntype;
881
883 &ntype, CMP_NODE_CRYPTOMATTE_LEGACY, "Cryptomatte (Legacy)", NODE_CLASS_MATTE);
884 blender::bke::node_type_socket_templates(&ntype, nullptr, file_ns::cmp_node_cryptomatte_out);
885 ntype.initfunc = legacy_file_ns::node_init_cryptomatte_legacy;
887 &ntype, "NodeCryptomatte", file_ns::node_free_cryptomatte, file_ns::node_copy_cryptomatte);
888 ntype.gather_link_search_ops = nullptr;
889 ntype.get_compositor_operation = legacy_file_ns::get_compositor_operation;
890
892}
893
Scene * CTX_data_scene(const bContext *C)
bool BKE_cryptomatte_find_name(const struct CryptomatteSession *session, float encoded_hash, char *r_name, int name_maxncpy)
struct CryptomatteSession * BKE_cryptomatte_init_from_render_result(const struct RenderResult *render_result)
struct CryptomatteSession * BKE_cryptomatte_init_from_scene(const struct Scene *scene, bool build_meta_data)
ImBuf * BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
void id_us_plus(ID *id)
Definition lib_id.cc:351
#define NODE_CLASS_MATTE
Definition BKE_node.hh:411
#define NODE_STORAGE_FUNCS(StorageT)
Definition BKE_node.hh:1799
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
A dynamically sized string ADT.
#define LISTBASE_FOREACH(type, var, list)
void 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)
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:496
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:130
MINLINE void zero_v3(float r[3])
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:597
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define ELEM(...)
#define STREQ(a, b)
#define RPT_(msgid)
@ ID_IM
@ ID_SCE
#define MAX_NAME
Definition DNA_defs.h:50
@ IMA_TYPE_MULTILAYER
CMPNodeCryptomatteSource
@ CMP_NODE_CRYPTOMATTE_SOURCE_IMAGE
@ CMP_NODE_CRYPTOMATTE_SOURCE_RENDER
@ SOCK_IN
@ SOCK_FLOAT
@ SOCK_RGBA
#define RE_PASSNAME_CRYPTOMATTE_MATERIAL
#define RE_PASSNAME_CRYPTOMATTE_ASSET
#define RE_PASSNAME_CRYPTOMATTE_OBJECT
int GPU_shader_get_sampler_binding(GPUShader *shader, const char *name)
void GPU_shader_uniform_1i(GPUShader *sh, const char *name, int value)
void GPU_shader_uniform_1f_array(GPUShader *sh, const char *name, int len, const float *val)
void GPU_shader_uniform_2iv(GPUShader *sh, const char *name, const int data[2])
void GPU_shader_bind(GPUShader *shader)
void GPU_shader_unbind()
void GPU_texture_bind(GPUTexture *texture, int unit)
void GPU_texture_clear(GPUTexture *texture, eGPUDataFormat data_format, const void *data)
void GPU_texture_unbind(GPUTexture *texture)
@ GPU_DATA_FLOAT
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
@ PROP_NONE
Definition RNA_types.hh:136
struct GPUShader GPUShader
int64_t size() const
void append(const T &value)
bool is_empty() const
std::string get_combined_layer_pass_name(RenderLayer *render_layer, RenderPass *render_pass)
Result * get(Context &context, Image *image, const ImageUser *image_user, const char *pass_name)
virtual rcti get_compositing_region() const =0
GPUShader * get_shader(const char *info_name, ResultPrecision precision)
Result create_result(ResultType type, ResultPrecision precision)
virtual GPUTexture * get_input_texture(const Scene *scene, int view_layer, const char *pass_name)=0
NodeOperation(Context &context, DNode node)
Result & get_input(StringRef identifier) const
Definition operation.cc:144
Result & get_result(StringRef identifier)
Definition operation.cc:46
void bind_as_image(GPUShader *shader, const char *image_name, bool read=false) const
Definition result.cc:264
void set_precision(ResultPrecision precision)
Definition result.cc:677
void allocate_texture(Domain domain, bool from_pool=true)
Definition result.cc:204
void steal_data(Result &source)
Definition result.cc:304
void bind_as_texture(GPUShader *shader, const char *texture_name) const
Definition result.cc:253
local_group_size(16, 16) .push_constant(Type b
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
#define GS(x)
Definition iris.cc:202
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_dupallocN)(const void *vmemh)
Definition mallocn.cc:39
#define G(x, y, z)
std::unique_ptr< CryptomatteSession, CryptomatteSessionDeleter > CryptomatteSessionPtr
const blender::Vector< std::string > & BKE_cryptomatte_layer_names_get(const CryptomatteSession &session)
bNodeSocket * node_add_static_socket(bNodeTree *ntree, bNode *node, eNodeSocketInOut in_out, int type, int subtype, const char *identifier, const char *name)
Definition node.cc:2359
void node_type_socket_templates(bNodeType *ntype, bNodeSocketTemplate *inputs, bNodeSocketTemplate *outputs)
Definition node.cc:4570
void node_remove_socket(bNodeTree *ntree, bNode *node, bNodeSocket *sock)
Definition node.cc:2405
void node_type_size(bNodeType *ntype, int width, int minwidth, int maxwidth)
Definition node.cc:4602
void node_type_storage(bNodeType *ntype, const char *storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
Definition node.cc:4632
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
T ceil(const T &a)
static void node_update_cryptomatte(bNodeTree *ntree, bNode *node)
static void node_copy_cryptomatte(bNodeTree *, bNode *dest_node, const bNode *src_node)
static void node_init_api_cryptomatte(const bContext *C, PointerRNA *ptr)
static NodeOperation * get_compositor_operation(Context &context, DNode node)
static void cmp_node_cryptomatte_declare(NodeDeclarationBuilder &b)
static bool node_poll_cryptomatte(const blender::bke::bNodeType *, const bNodeTree *ntree, const char **r_disabled_hint)
static void node_init_cryptomatte(bNodeTree *, bNode *node)
static void node_init_cryptomatte_legacy(bNodeTree *ntree, bNode *node)
static NodeOperation * get_compositor_operation(Context &context, DNode node)
void compute_dispatch_threads_at_least(GPUShader *shader, int2 threads_range, int2 local_size=int2(16))
Definition utilities.cc:131
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
void ntreeCompositCryptomatteLayerPrefix(const bNode *node, char *r_prefix, size_t prefix_maxncpy)
void register_node_type_cmp_cryptomatte_legacy()
static blender::bke::cryptomatte::CryptomatteSessionPtr cryptomatte_init_from_node_render(const bNode &node, const bool build_meta_data)
static CryptomatteEntry * cryptomatte_find(const NodeCryptomatte &n, float encoded_hash)
int ntreeCompositCryptomatteRemoveSocket(bNodeTree *ntree, bNode *node)
void ntreeCompositCryptomatteSyncFromRemove(bNode *node)
CryptomatteSession * ntreeCompositCryptomatteSession(bNode *node)
bNodeSocket * ntreeCompositCryptomatteAddSocket(bNodeTree *ntree, bNode *node)
void ntreeCompositCryptomatteUpdateLayerNames(bNode *node)
static void cryptomatte_remove(NodeCryptomatte &n, float encoded_hash)
static blender::bke::cryptomatte::CryptomatteSessionPtr cryptomatte_init_from_node(const bNode &node, const bool build_meta_data)
static void cryptomatte_add(bNode &node, NodeCryptomatte &node_cryptomatte, float encoded_hash)
void register_node_type_cmp_cryptomatte()
void ntreeCompositCryptomatteSyncFromAdd(bNode *node)
static blender::bke::cryptomatte::CryptomatteSessionPtr cryptomatte_init_from_node_image(const bNode &node)
void cmp_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
void cmp_node_update_default(bNodeTree *, bNode *node)
RenderResult * RE_AcquireResultRead(Render *re)
void RE_ReleaseResult(Render *re)
Render * RE_GetSceneRender(const Scene *scene)
NodeCryptomatte_Runtime runtime
void * data
Definition RNA_types.hh:42
char name[RE_MAXNAME]
Definition RE_pipeline.h:89
char name[64]
Definition RE_pipeline.h:58
char idname[64]
int16_t custom1
struct ID * id
void * storage
Defines a node type.
Definition BKE_node.hh:218
NodeGetCompositorOperationFunction get_compositor_operation
Definition BKE_node.hh:324
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:267
bool(* poll)(const bNodeType *ntype, const bNodeTree *nodetree, const char **r_disabled_hint)
Definition BKE_node.hh:299
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
Definition BKE_node.hh:363
NodeDeclareFunction declare
Definition BKE_node.hh:347
void(* updatefunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:257
void(* initfunc_api)(const bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:280
int ymin
int xmin
#define N_(msgid)
PointerRNA * ptr
Definition wm_files.cc:4126