diff options
Diffstat (limited to 'source/blender/compositor/operations/COM_RenderLayersProg.cpp')
-rw-r--r-- | source/blender/compositor/operations/COM_RenderLayersProg.cpp | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.cpp b/source/blender/compositor/operations/COM_RenderLayersProg.cpp index 11f64aa4d6a..2a0a6e33b6a 100644 --- a/source/blender/compositor/operations/COM_RenderLayersProg.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersProg.cpp @@ -18,8 +18,16 @@ #include "COM_RenderLayersProg.h" +#include "COM_MetaData.h" + +#include "BKE_cryptomatte.hh" +#include "BKE_image.h" #include "BKE_scene.h" + #include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_string_ref.hh" + #include "DNA_scene_types.h" #include "RE_pipeline.h" @@ -209,6 +217,82 @@ void RenderLayersProg::determineResolution(unsigned int resolution[2], } } +struct CallbackData { + std::unique_ptr<MetaData> meta_data; + std::string hash_key; + std::string conversion_key; + std::string manifest_key; + + void addMetaData(blender::StringRef key, blender::StringRefNull value) + { + if (!meta_data) { + meta_data = std::make_unique<MetaData>(); + } + meta_data->add(key, value); + } + + void setCryptomatteKeys(blender::StringRef cryptomatte_layer_name) + { + manifest_key = blender::BKE_cryptomatte_meta_data_key(cryptomatte_layer_name, "manifest"); + hash_key = blender::BKE_cryptomatte_meta_data_key(cryptomatte_layer_name, "hash"); + conversion_key = blender::BKE_cryptomatte_meta_data_key(cryptomatte_layer_name, "conversion"); + } +}; + +/* C type callback function (StampCallback). */ +static void extract_cryptomatte_meta_data(void *_data, + const char *propname, + char *propvalue, + int UNUSED(len)) +{ + CallbackData *data = static_cast<CallbackData *>(_data); + blender::StringRefNull key(propname); + if (key == data->hash_key) { + data->addMetaData(META_DATA_KEY_CRYPTOMATTE_HASH, propvalue); + } + else if (key == data->conversion_key) { + data->addMetaData(META_DATA_KEY_CRYPTOMATTE_CONVERSION, propvalue); + } + else if (key == data->manifest_key) { + data->addMetaData(META_DATA_KEY_CRYPTOMATTE_MANIFEST, propvalue); + } +} + +std::unique_ptr<MetaData> RenderLayersProg::getMetaData() const +{ + Scene *scene = this->getScene(); + Render *re = (scene) ? RE_GetSceneRender(scene) : nullptr; + RenderResult *rr = nullptr; + CallbackData callback_data = {nullptr}; + + if (re) { + rr = RE_AcquireResultRead(re); + } + + if (rr && rr->stamp_data) { + ViewLayer *view_layer = (ViewLayer *)BLI_findlink(&scene->view_layers, getLayerId()); + if (view_layer) { + std::string full_layer_name = std::string( + view_layer->name, + BLI_strnlen(view_layer->name, sizeof(view_layer->name))) + + "." + m_passName; + blender::StringRef cryptomatte_layer_name = blender::BKE_cryptomatte_extract_layer_name( + full_layer_name); + callback_data.setCryptomatteKeys(cryptomatte_layer_name); + + BKE_stamp_info_callback( + &callback_data, rr->stamp_data, extract_cryptomatte_meta_data, false); + } + } + + if (re) { + RE_ReleaseResult(re); + re = nullptr; + } + + return std::move(callback_data.meta_data); +} + /* ******** Render Layers AO Operation ******** */ void RenderLayersAOOperation::executePixelSampled(float output[4], float x, |