[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