diff options
Diffstat (limited to 'source/blender/blenkernel/intern/cryptomatte.cc')
-rw-r--r-- | source/blender/blenkernel/intern/cryptomatte.cc | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/cryptomatte.cc b/source/blender/blenkernel/intern/cryptomatte.cc index 3ecbbe56a22..a20c53ed270 100644 --- a/source/blender/blenkernel/intern/cryptomatte.cc +++ b/source/blender/blenkernel/intern/cryptomatte.cc @@ -37,6 +37,8 @@ #include "BLI_listbase.h" #include "BLI_string.h" +#include "RE_pipeline.h" + #include "MEM_guardedalloc.h" #include <cctype> @@ -51,6 +53,7 @@ struct CryptomatteSession { CryptomatteSession(); CryptomatteSession(const Main *bmain); + CryptomatteSession(StampData *metadata); blender::bke::cryptomatte::CryptomatteLayer &add_layer(std::string layer_name); std::optional<std::string> operator[](float encoded_hash) const; @@ -80,6 +83,22 @@ CryptomatteSession::CryptomatteSession(const Main *bmain) } } +CryptomatteSession::CryptomatteSession(StampData *stamp_data) +{ + blender::bke::cryptomatte::CryptomatteStampDataCallbackData callback_data; + callback_data.session = this; + BKE_stamp_info_callback( + &callback_data, + stamp_data, + blender::bke::cryptomatte::CryptomatteStampDataCallbackData::extract_layer_names, + false); + BKE_stamp_info_callback( + &callback_data, + stamp_data, + blender::bke::cryptomatte::CryptomatteStampDataCallbackData::extract_layer_manifest, + false); +} + blender::bke::cryptomatte::CryptomatteLayer &CryptomatteSession::add_layer(std::string layer_name) { return layers.lookup_or_add_default(layer_name); @@ -102,6 +121,13 @@ CryptomatteSession *BKE_cryptomatte_init(void) return session; } +struct CryptomatteSession *BKE_cryptomatte_init_from_render_result( + const struct RenderResult *render_result) +{ + CryptomatteSession *session = new CryptomatteSession(render_result->stamp_data); + return session; +} + void BKE_cryptomatte_add_layer(struct CryptomatteSession *session, const char *layer_name) { session->add_layer(layer_name); @@ -502,4 +528,65 @@ std::string CryptomatteLayer::manifest() const return blender::bke::cryptomatte::manifest::to_manifest(this); } +blender::StringRef CryptomatteStampDataCallbackData::extract_layer_hash(blender::StringRefNull key) +{ + BLI_assert(key.startswith("cryptomatte/")); + + size_t start_index = key.find_first_of('/'); + size_t end_index = key.find_last_of('/'); + if (start_index == blender::StringRef::not_found) { + return ""; + } + if (end_index == blender::StringRef::not_found) { + return ""; + } + if (end_index <= start_index) { + return ""; + } + return key.substr(start_index + 1, end_index - start_index - 1); +} + +void CryptomatteStampDataCallbackData::extract_layer_names(void *_data, + const char *propname, + char *propvalue, + int UNUSED(len)) +{ + CryptomatteStampDataCallbackData *data = static_cast<CryptomatteStampDataCallbackData *>(_data); + + blender::StringRefNull key(propname); + if (!key.startswith("cryptomatte/")) { + return; + } + if (!key.endswith("/name")) { + return; + } + blender::StringRef layer_hash = extract_layer_hash(key); + data->hash_to_layer_name.add(layer_hash, propvalue); +} + +/* C type callback function (StampCallback). */ +void CryptomatteStampDataCallbackData::extract_layer_manifest(void *_data, + const char *propname, + char *propvalue, + int UNUSED(len)) +{ + CryptomatteStampDataCallbackData *data = static_cast<CryptomatteStampDataCallbackData *>(_data); + + blender::StringRefNull key(propname); + if (!key.startswith("cryptomatte/")) { + return; + } + if (!key.endswith("/manifest")) { + return; + } + blender::StringRef layer_hash = extract_layer_hash(key); + if (!data->hash_to_layer_name.contains(layer_hash)) { + return; + } + + blender::StringRef layer_name = data->hash_to_layer_name.lookup(layer_hash); + blender::bke::cryptomatte::CryptomatteLayer &layer = data->session->add_layer(layer_name); + blender::bke::cryptomatte::manifest::from_manifest(layer, propvalue); +} + } // namespace blender::bke::cryptomatte |