[Bf-blender-cvs] [f1a8e5dcec1] temp-cryptomatte-manifest-parser: Cryptomatte: Lookup name by encoded hash.
Jeroen Bakker
noreply at git.blender.org
Fri Feb 26 12:42:03 CET 2021
Commit: f1a8e5dcec14ce23916a3d85f7246553ea2f7c8a
Author: Jeroen Bakker
Date: Fri Feb 26 11:49:04 2021 +0100
Branches: temp-cryptomatte-manifest-parser
https://developer.blender.org/rBf1a8e5dcec14ce23916a3d85f7246553ea2f7c8a
Cryptomatte: Lookup name by encoded hash.
===================================================================
M source/blender/blenkernel/BKE_cryptomatte.hh
M source/blender/blenkernel/intern/cryptomatte.cc
===================================================================
diff --git a/source/blender/blenkernel/BKE_cryptomatte.hh b/source/blender/blenkernel/BKE_cryptomatte.hh
index 608fa777124..8c1a881fb25 100644
--- a/source/blender/blenkernel/BKE_cryptomatte.hh
+++ b/source/blender/blenkernel/BKE_cryptomatte.hh
@@ -23,11 +23,14 @@
#pragma once
+#include <optional>
#include <string>
#include "BLI_map.hh"
#include "BLI_string_ref.hh"
+struct ID;
+
namespace blender::bke::cryptomatte {
/* Format to a cryptomatte meta data key.
@@ -65,7 +68,9 @@ struct 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, uint32_t cryptomatte_hash);
+ std::optional<std::string> find_name_by_float_hash(float encoded_hash) const;
std::string manifest();
};
diff --git a/source/blender/blenkernel/intern/cryptomatte.cc b/source/blender/blenkernel/intern/cryptomatte.cc
index dd14486a8c5..859ab968718 100644
--- a/source/blender/blenkernel/intern/cryptomatte.cc
+++ b/source/blender/blenkernel/intern/cryptomatte.cc
@@ -51,11 +51,39 @@ struct CryptomatteSession {
blender::bke::cryptomatte::CryptomatteLayer assets;
blender::bke::cryptomatte::CryptomatteLayer materials;
+ CryptomatteSession();
+ CryptomatteSession(const Main *bmain);
+
+ std::optional<std::string> find_name_by_float_hash(float encoded_hash) const;
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("cryptomatte:CryptomatteSession")
#endif
};
+CryptomatteSession::CryptomatteSession()
+{
+}
+
+CryptomatteSession::CryptomatteSession(const Main *bmain)
+{
+ LISTBASE_FOREACH (ID *, id, &bmain->objects) {
+ objects.add_ID(*id);
+ }
+ LISTBASE_FOREACH (ID *, id, &bmain->materials) {
+ materials.add_ID(*id);
+ }
+}
+
+std::optional<std::string> CryptomatteSession::find_name_by_float_hash(float encoded_hash) const
+{
+ std::optional<std::string> result = objects.find_name_by_float_hash(encoded_hash);
+ if (result) {
+ return result;
+ }
+ return materials.find_name_by_float_hash(encoded_hash);
+}
+
CryptomatteSession *BKE_cryptomatte_init(void)
{
CryptomatteSession *session = new CryptomatteSession();
@@ -74,22 +102,9 @@ uint32_t BKE_cryptomatte_hash(const char *name, const int name_len)
return cryptohash_int;
}
-static uint32_t cryptomatte_hash(blender::bke::cryptomatte::CryptomatteLayer *layer, const ID *id)
-{
- const char *name = &id->name[2];
- const int name_len = BLI_strnlen(name, MAX_NAME - 2);
- uint32_t cryptohash_int = BKE_cryptomatte_hash(name, name_len);
-
- if (layer != nullptr) {
- layer->add_hash(blender::StringRef(name, name_len), cryptohash_int);
- }
-
- return cryptohash_int;
-}
-
uint32_t BKE_cryptomatte_object_hash(CryptomatteSession *session, const Object *object)
{
- return cryptomatte_hash(&session->objects, &object->id);
+ return session->objects.add_ID(object->id);
}
uint32_t BKE_cryptomatte_material_hash(CryptomatteSession *session, const Material *material)
@@ -97,7 +112,7 @@ uint32_t BKE_cryptomatte_material_hash(CryptomatteSession *session, const Materi
if (material == nullptr) {
return 0.0f;
}
- return cryptomatte_hash(&session->materials, &material->id);
+ return session->materials.add_ID(material->id);
}
uint32_t BKE_cryptomatte_asset_hash(CryptomatteSession *session, const Object *object)
@@ -106,7 +121,7 @@ uint32_t BKE_cryptomatte_asset_hash(CryptomatteSession *session, const Object *o
while (asset_object->parent != nullptr) {
asset_object = asset_object->parent;
}
- return cryptomatte_hash(&session->assets, &asset_object->id);
+ return session->assets.add_ID(asset_object->id);
}
/* Convert a cryptomatte hash to a float.
@@ -134,28 +149,6 @@ float BKE_cryptomatte_hash_to_float(uint32_t cryptomatte_hash)
return f;
}
-static ID *cryptomatte_find_id(const ListBase *ids, const float encoded_hash)
-{
- LISTBASE_FOREACH (ID *, id, ids) {
- uint32_t hash = BKE_cryptomatte_hash((id->name + 2), BLI_strnlen(id->name + 2, MAX_NAME));
- if (BKE_cryptomatte_hash_to_float(hash) == encoded_hash) {
- return id;
- }
- }
- return nullptr;
-}
-
-/* Find an ID in the given main that matches the given encoded float. */
-static struct ID *BKE_cryptomatte_find_id(const Main *bmain, const float encoded_hash)
-{
- ID *result;
- result = cryptomatte_find_id(&bmain->objects, encoded_hash);
- if (result == nullptr) {
- result = cryptomatte_find_id(&bmain->materials, encoded_hash);
- }
- return result;
-}
-
char *BKE_cryptomatte_entries_to_matte_id(NodeCryptomatte *node_storage)
{
DynStr *matte_id = BLI_dynstr_new();
@@ -182,6 +175,7 @@ void BKE_cryptomatte_matte_id_to_entries(const Main *bmain,
const char *matte_id)
{
BLI_freelistN(&node_storage->entries);
+ CryptomatteSession session(bmain);
std::istringstream ss(matte_id);
while (ss.good()) {
@@ -201,9 +195,9 @@ void BKE_cryptomatte_matte_id_to_entries(const Main *bmain,
entry = (CryptomatteEntry *)MEM_callocN(sizeof(CryptomatteEntry), __func__);
entry->encoded_hash = encoded_hash;
if (bmain) {
- ID *id = BKE_cryptomatte_find_id(bmain, encoded_hash);
- if (id != nullptr) {
- BLI_strncpy(entry->name, id->name + 2, sizeof(entry->name));
+ std::optional<std::string> name = session.find_name_by_float_hash(encoded_hash);
+ if (name) {
+ STRNCPY(entry->name, name->c_str());
}
}
}
@@ -211,7 +205,7 @@ void BKE_cryptomatte_matte_id_to_entries(const Main *bmain,
const char *name = token.c_str();
int name_len = token.length();
entry = (CryptomatteEntry *)MEM_callocN(sizeof(CryptomatteEntry), __func__);
- BLI_strncpy(entry->name, name, sizeof(entry->name));
+ STRNCPY(entry->name, name);
uint32_t hash = BKE_cryptomatte_hash(name, name_len);
entry->encoded_hash = BKE_cryptomatte_hash_to_float(hash);
}
@@ -463,11 +457,33 @@ std::unique_ptr<CryptomatteLayer> CryptomatteLayer::read_from_manifest(
return layer;
}
+uint32_t CryptomatteLayer::add_ID(const ID &id)
+{
+ const char *name = &id.name[2];
+ const int name_len = BLI_strnlen(name, MAX_NAME - 2);
+ uint32_t cryptohash_int = BKE_cryptomatte_hash(name, name_len);
+
+ add_hash(blender::StringRef(name, name_len), cryptohash_int);
+
+ return cryptohash_int;
+}
+
void CryptomatteLayer::add_hash(blender::StringRef name, uint32_t cryptomatte_hash)
{
hashes.add_overwrite(name, cryptomatte_hash);
}
+std::optional<std::string> CryptomatteLayer::find_name_by_float_hash(float encoded_hash) const
+{
+ const blender::Map<std::string, uint32_t> &const_map = hashes;
+ for (blender::Map<std::string, uint32_t>::Item item : const_map.items()) {
+ if (BKE_cryptomatte_hash_to_float(item.value) == encoded_hash) {
+ return std::make_optional(item.key);
+ }
+ }
+ return std::nullopt;
+}
+
std::string CryptomatteLayer::manifest()
{
return blender::bke::cryptomatte::manifest::to_manifest(this);
More information about the Bf-blender-cvs
mailing list