1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2020 Blender Foundation. All rights reserved. */
/** \file
* \ingroup bke
*/
#pragma once
#include <optional>
#include <string>
#include "BKE_cryptomatte.h"
#include "BLI_map.hh"
#include "BLI_string_ref.hh"
#include "BKE_cryptomatte.h"
struct ID;
namespace blender::bke::cryptomatte {
/**
* Format to a cryptomatte meta data key.
*
* Cryptomatte stores meta data. The keys are formatted containing a hash that
* is generated from its layer name.
*
* The output of this function is:
* 'cryptomatte/{hash of layer_name}/{key_name}'.
*/
std::string BKE_cryptomatte_meta_data_key(const StringRef layer_name,
const StringRefNull key_name);
/**
* Extract the cryptomatte layer name from the given `render_pass_name`.
*
* Cryptomatte passes are formatted with a trailing number for storing multiple samples that belong
* to the same cryptomatte layer. This function would remove the trailing numbers to determine the
* cryptomatte layer name.
*
* # Example
*
* A render_pass_name could be 'View Layer.CryptoMaterial02'. The cryptomatte layer would be 'View
* Layer.CryptoMaterial'.
*
* \note The return type is a sub-string of `render_pass_name` and therefore cannot outlive the
* `render_pass_name` internal data.
*/
StringRef BKE_cryptomatte_extract_layer_name(const StringRef render_pass_name);
struct CryptomatteHash {
uint32_t hash;
CryptomatteHash(uint32_t hash);
CryptomatteHash(const char *name, int name_len);
static CryptomatteHash from_hex_encoded(blender::StringRef hex_encoded);
std::string hex_encoded() const;
/**
* Convert a cryptomatte hash to a float.
*
* Cryptomatte hashes are stored in float textures and images. The conversion is taken from the
* cryptomatte specification. See Floating point conversion section in
* https://github.com/Psyop/Cryptomatte/blob/master/specification/cryptomatte_specification.pdf.
*
* The conversion uses as many 32 bit floating point values as possible to minimize hash
* collisions. Unfortunately not all 32 bits can be used as NaN and Inf can be problematic.
*
* Note that this conversion assumes to be running on a L-endian system.
*/
float float_encoded() const;
};
struct CryptomatteLayer {
blender::Map<std::string, CryptomatteHash> hashes;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("cryptomatte:CryptomatteLayer")
#endif
static std::unique_ptr<CryptomatteLayer> read_from_manifest(blender::StringRefNull manifest);
uint32_t add_ID(const struct ID &id);
void add_hash(blender::StringRef name, CryptomatteHash cryptomatte_hash);
std::string manifest() const;
std::optional<std::string> operator[](float encoded_hash) const;
};
struct CryptomatteStampDataCallbackData {
struct CryptomatteSession *session;
blender::Map<std::string, std::string> hash_to_layer_name;
/**
* Extract the hash from a stamp data key.
*
* Cryptomatte keys are formatted as "cryptomatte/{layer_hash}/{attribute}".
*/
static blender::StringRef extract_layer_hash(blender::StringRefNull key);
/* C type callback function (StampCallback). */
static void extract_layer_names(void *_data, const char *propname, char *propvalue, int len);
/* C type callback function (StampCallback). */
static void extract_layer_manifest(void *_data, const char *propname, char *propvalue, int len);
};
const blender::Vector<std::string> &BKE_cryptomatte_layer_names_get(
const CryptomatteSession &session);
struct CryptomatteSessionDeleter {
void operator()(CryptomatteSession *session)
{
BKE_cryptomatte_free(session);
}
};
using CryptomatteSessionPtr = std::unique_ptr<CryptomatteSession, CryptomatteSessionDeleter>;
} // namespace blender::bke::cryptomatte
|