[Bf-blender-cvs] [29b4f84b273] temp-cryptomatte-manifest-parser: Cryptomatte Manifest parser.
Jeroen Bakker
noreply at git.blender.org
Thu Feb 25 10:12:33 CET 2021
Commit: 29b4f84b27374bbf7526ecd7e38bb5e9908b40dd
Author: Jeroen Bakker
Date: Wed Feb 24 17:04:37 2021 +0100
Branches: temp-cryptomatte-manifest-parser
https://developer.blender.org/rB29b4f84b27374bbf7526ecd7e38bb5e9908b40dd
Cryptomatte Manifest parser.
THis commits adds a basic parser to construct a CryptomatteLayer from a
manifest string. The goal is to be able to parse OpenExr Cryptomatte
Layers from external render engines and use it in the new cryptomatte
workflow.
===================================================================
M source/blender/blenkernel/BKE_cryptomatte.hh
M source/blender/blenkernel/intern/cryptomatte.cc
M source/blender/blenkernel/intern/cryptomatte_test.cc
===================================================================
diff --git a/source/blender/blenkernel/BKE_cryptomatte.hh b/source/blender/blenkernel/BKE_cryptomatte.hh
index b7d3508e725..00969c0b52c 100644
--- a/source/blender/blenkernel/BKE_cryptomatte.hh
+++ b/source/blender/blenkernel/BKE_cryptomatte.hh
@@ -63,8 +63,12 @@ struct CryptomatteLayer {
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("cryptomatte:CryptomatteLayer")
#endif
- std::string encode_hash(uint32_t cryptomatte_hash);
+ CryptomatteLayer();
+ /** Create a cryptomatte layer from the given manifest. */
+ CryptomatteLayer(blender::StringRefNull manifest);
+
+ static std::string encode_hash(uint32_t cryptomatte_hash);
void add_hash(blender::StringRef name, uint32_t cryptomatte_hash);
void add_encoded_hash(blender::StringRef name, blender::StringRefNull cryptomatte_encoded_hash);
std::string manifest();
diff --git a/source/blender/blenkernel/intern/cryptomatte.cc b/source/blender/blenkernel/intern/cryptomatte.cc
index a4924bb86f1..492138b8783 100644
--- a/source/blender/blenkernel/intern/cryptomatte.cc
+++ b/source/blender/blenkernel/intern/cryptomatte.cc
@@ -315,6 +315,94 @@ StringRef BKE_cryptomatte_extract_layer_name(const StringRef render_pass_name)
return render_pass_name.substr(0, last_token);
}
+struct CryptomatteManifestParser {
+ int skip_whitespaces_len_(blender::StringRef manifest)
+ {
+ int skip_len = 0;
+ while (!manifest.is_empty()) {
+ char front = manifest[skip_len];
+ if (!std::isspace<char>(front, std::locale::classic())) {
+ break;
+ }
+ skip_len++;
+ }
+ return skip_len;
+ }
+
+ int quoted_string_len_(blender::StringRef ref)
+ {
+ int len = 1;
+ while (len < ref.size()) {
+ char current_char = ref[len];
+ if (current_char == '\"') {
+ len += 1;
+ break;
+ }
+ len += 1;
+ }
+ return len;
+ }
+
+ bool parse(CryptomatteLayer &layer, blender::StringRefNull manifest)
+ {
+ StringRef ref = manifest;
+ ref = ref.drop_prefix(skip_whitespaces_len_(ref));
+ if (ref.is_empty() || ref.front() != '{') {
+ return false;
+ }
+ ref = ref.drop_prefix(1);
+ while (!ref.is_empty()) {
+ char front = ref.front();
+
+ if (front == '\"') {
+ const int quoted_name_len = quoted_string_len_(ref);
+ const int name_len = quoted_name_len - 2;
+ blender::StringRef name = ref.substr(1, name_len);
+ ref = ref.drop_prefix(quoted_name_len);
+ ref = ref.drop_prefix(skip_whitespaces_len_(ref));
+
+ char colon = ref.front();
+ if (colon != ':') {
+ return false;
+ }
+ ref = ref.drop_prefix(skip_whitespaces_len_(ref));
+
+ const int quoted_hash_len = quoted_string_len_(ref);
+ const int hash_len = quoted_hash_len - 2;
+ blender::StringRef hash = ref.substr(1, hash_len);
+ ref = ref.drop_prefix(quoted_hash_len);
+ layer.add_encoded_hash(name, blender::StringRefNull(hash));
+ }
+ if (front == ',') {
+ ref = ref.drop_prefix(1);
+ }
+ if (front == '}') {
+ ref = ref.drop_prefix(1);
+ ref = ref.drop_prefix(skip_whitespaces_len_(ref));
+
+ break;
+ }
+ ref = ref.drop_prefix(skip_whitespaces_len_(ref));
+ }
+
+ if (!ref.is_empty()) {
+ return false;
+ }
+
+ return true;
+ }
+};
+
+CryptomatteLayer::CryptomatteLayer()
+{
+}
+
+CryptomatteLayer::CryptomatteLayer(blender::StringRefNull manifest)
+{
+ CryptomatteManifestParser parser;
+ parser.parse(*this, manifest);
+}
+
std::string CryptomatteLayer::encode_hash(uint32_t cryptomatte_hash)
{
std::stringstream encoded;
diff --git a/source/blender/blenkernel/intern/cryptomatte_test.cc b/source/blender/blenkernel/intern/cryptomatte_test.cc
index 5c9412c0c4d..fe80d919d23 100644
--- a/source/blender/blenkernel/intern/cryptomatte_test.cc
+++ b/source/blender/blenkernel/intern/cryptomatte_test.cc
@@ -60,4 +60,9 @@ TEST(cryptomatte, cryptomatte_layer_quoted)
ASSERT_EQ("{\"\\\"Object\\\"\":\"0000007b\"}", layer.manifest());
}
+TEST(cryptomatte, cryptomatte_layer_from_manifest)
+{
+ ASSERT_EQ("{}", blender::CryptomatteLayer("{}").manifest());
+}
+
} // namespace blender::bke::tests
More information about the Bf-blender-cvs
mailing list