Blender V4.3
cryptomatte_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "testing/testing.h"
6
7#include "BLI_string.h"
8
9#include "BKE_cryptomatte.h"
10#include "BKE_cryptomatte.hh"
11#include "BKE_image.hh"
12
13#include "RE_pipeline.h"
14
15#include "MEM_guardedalloc.h"
16
17namespace blender::bke::cryptomatte::tests {
18
19TEST(cryptomatte, meta_data_key)
20{
21 ASSERT_EQ("cryptomatte/c7dbf5e/key",
22 BKE_cryptomatte_meta_data_key("ViewLayer.CryptoMaterial", "key"));
23 ASSERT_EQ("cryptomatte/b990b65/𝓴𝓮𝔂",
24 BKE_cryptomatte_meta_data_key("𝖚𝖓𝖎𝖈𝖔𝖉𝖊.CryptoMaterial", "𝓴𝓮𝔂"));
25}
26
27TEST(cryptomatte, extract_layer_name)
28{
29 ASSERT_EQ("ViewLayer.CryptoMaterial",
30 BKE_cryptomatte_extract_layer_name("ViewLayer.CryptoMaterial00"));
31 ASSERT_EQ("𝖚𝖓𝖎𝖈𝖔𝖉𝖊", BKE_cryptomatte_extract_layer_name("𝖚𝖓𝖎𝖈𝖔𝖉𝖊13"));
32 ASSERT_EQ("NoTrailingSampleNumber",
33 BKE_cryptomatte_extract_layer_name("NoTrailingSampleNumber"));
34 ASSERT_EQ("W1thM1dd13Numb3rs", BKE_cryptomatte_extract_layer_name("W1thM1dd13Numb3rs09"));
35 ASSERT_EQ("", BKE_cryptomatte_extract_layer_name("0123"));
36 ASSERT_EQ("", BKE_cryptomatte_extract_layer_name(""));
37}
38
39TEST(cryptomatte, layer)
40{
42 ASSERT_EQ("{}", layer.manifest());
43
44 layer.add_hash("Object", 123);
45 ASSERT_EQ("{\"Object\":\"0000007b\"}", layer.manifest());
46
47 layer.add_hash("Object2", 123245678);
48 ASSERT_EQ("{\"Object\":\"0000007b\",\"Object2\":\"0758946e\"}", layer.manifest());
49}
50
51TEST(cryptomatte, layer_quoted)
52{
54 layer.add_hash("\"Object\"", 123);
55 ASSERT_EQ("{\"\\\"Object\\\"\":\"0000007b\"}", layer.manifest());
56}
57
58static void test_cryptomatte_manifest(std::string expected, std::string manifest)
59{
60 EXPECT_EQ(expected,
61 blender::bke::cryptomatte::CryptomatteLayer::read_from_manifest(manifest)->manifest());
62}
63
64TEST(cryptomatte, layer_from_manifest)
65{
66 test_cryptomatte_manifest("{}", "{}");
67 test_cryptomatte_manifest(R"({"Object":"12345678"})", R"({"Object": "12345678"})");
68 test_cryptomatte_manifest(R"({"Object":"12345678","Object2":"87654321"})",
69 R"({"Object":"12345678","Object2":"87654321"})");
70 test_cryptomatte_manifest(R"({"Object":"12345678","Object2":"87654321"})",
71 R"( { "Object" : "12345678" , "Object2" : "87654321" } )");
72 test_cryptomatte_manifest(R"({"Object\"01\"":"12345678"})", R"({"Object\"01\"": "12345678"})");
73 test_cryptomatte_manifest(
74 R"({"Object\"01\"":"12345678","Object":"12345678","Object2":"87654321"})",
75 R"({"Object\"01\"":"12345678","Object":"12345678", "Object2":"87654321"})");
76}
77
78TEST(cryptomatte, extract_layer_hash_from_metadata_key)
79{
80 EXPECT_EQ("eb4c67b",
82 "cryptomatte/eb4c67b/conversion"));
83 EXPECT_EQ("qwerty",
85 "cryptomatte/qwerty/name"));
86 /* Check if undefined behaviors are handled. */
87 EXPECT_EQ("",
89 "cryptomatte/name"));
90 EXPECT_EQ("",
92 "cryptomatte/"));
93}
94
95static void validate_cryptomatte_session_from_stamp_data(void * /*data*/,
96 const char *propname,
97 char *propvalue,
98 int /*propvalue_maxncpy*/)
99{
100 blender::StringRefNull prop_name(propname);
101 if (!prop_name.startswith("cryptomatte/")) {
102 return;
103 }
104
105 if (prop_name == "cryptomatte/67da54b/name") {
106 EXPECT_STREQ("layer1", propvalue);
107 }
108 else if (prop_name == "cryptomatte/67da54b/hash") {
109 EXPECT_STREQ("MurmurHash3_32", propvalue);
110 }
111 else if (prop_name == "cryptomatte/67da54b/conversion") {
112 EXPECT_STREQ("uint32_to_float32", propvalue);
113 }
114 else if (prop_name == "cryptomatte/67da54b/manifest") {
115 EXPECT_STREQ(R"({"Object":"12345678"})", propvalue);
116 }
117
118 else if (prop_name == "cryptomatte/79b2306/name") {
119 EXPECT_STREQ("layer2", propvalue);
120 }
121 else if (prop_name == "cryptomatte/79b2306/hash") {
122 EXPECT_STREQ("MurmurHash3_32", propvalue);
123 }
124 else if (prop_name == "cryptomatte/79b2306/conversion") {
125 EXPECT_STREQ("uint32_to_float32", propvalue);
126 }
127 else if (prop_name == "cryptomatte/79b2306/manifest") {
128 EXPECT_STREQ(R"({"Object2":"87654321"})", propvalue);
129 }
130
131 else {
132 EXPECT_EQ("Unhandled", std::string(propname) + ": " + propvalue);
133 }
134}
135
136TEST(cryptomatte, session_from_stamp_data)
137{
138 /* Create CryptomatteSession from stamp data. */
139 RenderResult *render_result = static_cast<RenderResult *>(
140 MEM_callocN(sizeof(RenderResult), __func__));
141 BKE_render_result_stamp_data(render_result, "cryptomatte/qwerty/name", "layer1");
143 render_result, "cryptomatte/qwerty/manifest", R"({"Object":"12345678"})");
144 BKE_render_result_stamp_data(render_result, "cryptomatte/uiop/name", "layer2");
146 render_result, "cryptomatte/uiop/manifest", R"({"Object2":"87654321"})");
148 EXPECT_NE(session.get(), nullptr);
149 RE_FreeRenderResult(render_result);
150
151 /* Create StampData from CryptomatteSession. */
152 RenderResult *render_result2 = static_cast<RenderResult *>(
153 MEM_callocN(sizeof(RenderResult), __func__));
154 BKE_cryptomatte_store_metadata(session.get(), render_result2);
155
156 /* Validate StampData. */
158 nullptr, render_result2->stamp_data, validate_cryptomatte_session_from_stamp_data, false);
159
160 RE_FreeRenderResult(render_result2);
161}
162
166TEST(cryptomatte, parsing_malformed_manifests)
167{
168 /* Manifest from `multilayer.exr` in the cryptomatte git-repository. */
169 test_cryptomatte_manifest(
170 R"({"/obj/instance1:instances:0":"0d54c6cc","/obj/instance1:instances:1":"293d9340","/obj/instance1:instances:110":"ccb9e1f2","/obj/instance1:instances:111":"f8dd3a48","/obj/instance1:instances:112":"a99e07a8","/obj/instance1:instances:113":"e75599a4","/obj/instance1:instances:114":"794200f3","/obj/instance1:instances:115":"2a3a1728","/obj/instance1:instances:116":"478544a1","/obj/instance1:instances:117":"b2bd969a","/obj/instance1:instances:10":"3a0c8681","/obj/instance1:instances:11":"01e5970d","/obj/box:polygons:1":"9d416418","/obj/instance1:instances:100":"2dcd2966","/obj/instance1:instances:101":"9331cd82","/obj/instance1:instances:102":"df50fccb","/obj/instance1:instances:103":"97f8590d","/obj/instance1:instances:104":"bbcd220d","/obj/instance1:instances:105":"4ae06139","/obj/instance1:instances:106":"8873d5ea","/obj/instance1:instances:107":"39d8af8d","/obj/instance1:instances:108":"bb11bd4e","/obj/instance1:instances:109":"a32bba35"})",
171 R"({"\/obj\/box:polygons:1":"9d416418","\/obj\/instance1:instances:0":"0d54c6cc","\/obj\/instance1:instances:1":"293d9340","\/obj\/instance1:instances:10":"3a0c8681","\/obj\/instance1:instances:100":"2dcd2966","\/obj\/instance1:instances:101":"9331cd82","\/obj\/instance1:instances:102":"df50fccb","\/obj\/instance1:instances:103":"97f8590d","\/obj\/instance1:instances:104":"bbcd220d","\/obj\/instance1:instances:105":"4ae06139","\/obj\/instance1:instances:106":"8873d5ea","\/obj\/instance1:instances:107":"39d8af8d","\/obj\/instance1:instances:108":"bb11bd4e","\/obj\/instance1:instances:109":"a32bba35","\/obj\/instance1:instances:11":"01e5970d","\/obj\/instance1:instances:110":"ccb9e1f2","\/obj\/instance1:instances:111":"f8dd3a48","\/obj\/instance1:instances:112":"a99e07a8","\/obj\/instance1:instances:113":"e75599a4","\/obj\/instance1:instances:114":"794200f3","\/obj\/instance1:instances:115":"2a3a1728","\/obj\/instance1:instances:116":"478544a1","\/obj\/instance1:instances:117":"b2bd969a","\/obj\/instance1:instance)");
172}
173} // namespace blender::bke::cryptomatte::tests
void BKE_cryptomatte_store_metadata(const struct CryptomatteSession *session, struct RenderResult *render_result)
struct CryptomatteSession * BKE_cryptomatte_init_from_render_result(const struct RenderResult *render_result)
void BKE_stamp_info_callback(void *data, StampData *stamp_data, StampCallback callback, bool noskip)
void BKE_render_result_stamp_data(RenderResult *rr, const char *key, const char *value)
TEST(array_store, Nop)
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
Read Guarded memory(de)allocation.
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
std::unique_ptr< CryptomatteSession, CryptomatteSessionDeleter > CryptomatteSessionPtr
StringRef BKE_cryptomatte_extract_layer_name(const StringRef render_pass_name)
std::string BKE_cryptomatte_meta_data_key(const StringRef layer_name, const StringRefNull key_name)
void RE_FreeRenderResult(RenderResult *rr)
struct StampData * stamp_data
void add_hash(blender::StringRef name, CryptomatteHash cryptomatte_hash)
static blender::StringRef extract_layer_hash(blender::StringRefNull key)