Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Bakker <jeroen@blender.org>2020-12-14 18:14:21 +0300
committerJeroen Bakker <jeroen@blender.org>2020-12-14 18:14:38 +0300
commitf4df036bc497b134789b624efd9008c6f4b9c6c8 (patch)
treefd9537758878f679087ff6854b1913b129b3ded8 /source/blender/nodes
parent07ce9910f7ccaa48ae28c35049dec598b6214b36 (diff)
Cryptomatte: Data structure in compositor node
This changes the way how the mattes are stored in the compositor node. This used to be a single string what was decoded/encoded when needed. The new data structure stores all entries in `CryptomatteEntry` and is converted to the old `matte_id` property on the fly. This is done for some future changes in the workflow where a more structured approach leads to less confusing and easier to read code.
Diffstat (limited to 'source/blender/nodes')
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_cryptomatte.c178
1 files changed, 18 insertions, 160 deletions
diff --git a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c
index c8d2d993e75..f5308fe2671 100644
--- a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c
+++ b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c
@@ -27,172 +27,36 @@
#include "BLI_utildefines.h"
#include "node_composite_util.h"
-/* this is taken from the cryptomatte specification 1.0 */
-
-BLI_INLINE float hash_to_float(uint32_t hash)
+static CryptomatteEntry *cryptomatte_find(NodeCryptomatte *n, float encoded_hash)
{
- uint32_t mantissa = hash & ((1 << 23) - 1);
- uint32_t exponent = (hash >> 23) & ((1 << 8) - 1);
- exponent = MAX2(exponent, (uint32_t)1);
- exponent = MIN2(exponent, (uint32_t)254);
- exponent = exponent << 23;
- uint32_t sign = (hash >> 31);
- sign = sign << 31;
- uint32_t float_bits = sign | exponent | mantissa;
- float f;
- /* Bit casting relies on equal size for both types. */
- BLI_STATIC_ASSERT(sizeof(float) == sizeof(uint32_t), "float and uint32_t are not the same size")
- memcpy(&f, &float_bits, sizeof(float));
- return f;
+ LISTBASE_FOREACH (CryptomatteEntry *, entry, &n->entries) {
+ if (entry->encoded_hash == encoded_hash) {
+ return entry;
+ }
+ }
+ return NULL;
}
static void cryptomatte_add(NodeCryptomatte *n, float f)
{
- /* Turn the number into a string. */
- char number[32];
- BLI_snprintf(number, sizeof(number), "<%.9g>", f);
-
- /* Search if we already have the number. */
- if (n->matte_id && strlen(n->matte_id) != 0) {
- size_t start = 0;
- const size_t end = strlen(n->matte_id);
- size_t token_len = 0;
- while (start < end) {
- /* Ignore leading whitespace. */
- while (start < end && n->matte_id[start] == ' ') {
- start++;
- }
-
- /* Find the next separator. */
- char *token_end = strchr(n->matte_id + start, ',');
- if (ELEM(token_end, NULL, n->matte_id + start)) {
- token_end = n->matte_id + end;
- }
- /* Be aware that token_len still contains any trailing white space. */
- token_len = token_end - (n->matte_id + start);
-
- /* If this has a leading bracket,
- * assume a raw floating point number and look for the closing bracket. */
- if (n->matte_id[start] == '<') {
- if (strncmp(n->matte_id + start, number, strlen(number)) == 0) {
- /* This number is already there, so continue. */
- return;
- }
- }
- else {
- /* Remove trailing white space */
- size_t name_len = token_len;
- while (n->matte_id[start + name_len] == ' ' && name_len > 0) {
- name_len--;
- }
- /* Calculate the hash of the token and compare. */
- uint32_t hash = BLI_hash_mm3((const unsigned char *)(n->matte_id + start), name_len, 0);
- if (f == hash_to_float(hash)) {
- return;
- }
- }
- start += token_len + 1;
- }
- }
-
- DynStr *new_matte = BLI_dynstr_new();
- if (!new_matte) {
+ /* Check if entry already exist. */
+ if (cryptomatte_find(n, f) != NULL) {
return;
}
-
- if (n->matte_id) {
- BLI_dynstr_append(new_matte, n->matte_id);
- MEM_freeN(n->matte_id);
- }
-
- if (BLI_dynstr_get_len(new_matte) > 0) {
- BLI_dynstr_append(new_matte, ",");
- }
- BLI_dynstr_append(new_matte, number);
- n->matte_id = BLI_dynstr_get_cstring(new_matte);
- BLI_dynstr_free(new_matte);
+ CryptomatteEntry *entry = MEM_callocN(sizeof(CryptomatteEntry), __func__);
+ entry->encoded_hash = f;
+ BLI_addtail(&n->entries, entry);
}
static void cryptomatte_remove(NodeCryptomatte *n, float f)
{
- if (n->matte_id == NULL || strlen(n->matte_id) == 0) {
- /* Empty string, nothing to remove. */
+ CryptomatteEntry *entry = cryptomatte_find(n, f);
+ if (entry == NULL) {
return;
}
- /* This will be the new string without the removed key. */
- DynStr *new_matte = BLI_dynstr_new();
- if (!new_matte) {
- return;
- }
-
- /* Turn the number into a string. */
- static char number[32];
- BLI_snprintf(number, sizeof(number), "<%.9g>", f);
-
- /* Search if we already have the number. */
- size_t start = 0;
- const size_t end = strlen(n->matte_id);
- size_t token_len = 0;
- bool is_first = true;
- while (start < end) {
- bool skip = false;
- /* Ignore leading whitespace or commas. */
- while (start < end && ((n->matte_id[start] == ' ') || (n->matte_id[start] == ','))) {
- start++;
- }
-
- /* Find the next separator. */
- char *token_end = strchr(n->matte_id + start + 1, ',');
- if (ELEM(token_end, NULL, n->matte_id + start)) {
- token_end = n->matte_id + end;
- }
- /* Be aware that token_len still contains any trailing white space. */
- token_len = token_end - (n->matte_id + start);
-
- if (token_len == 1) {
- skip = true;
- }
- /* If this has a leading bracket,
- * assume a raw floating point number and look for the closing bracket. */
- else if (n->matte_id[start] == '<') {
- if (strncmp(n->matte_id + start, number, strlen(number)) == 0) {
- /* This number is already there, so skip it. */
- skip = true;
- }
- }
- else {
- /* Remove trailing white space */
- size_t name_len = token_len;
- while (n->matte_id[start + name_len] == ' ' && name_len > 0) {
- name_len--;
- }
- /* Calculate the hash of the token and compare. */
- uint32_t hash = BLI_hash_mm3((const unsigned char *)(n->matte_id + start), name_len, 0);
- if (f == hash_to_float(hash)) {
- skip = true;
- }
- }
- if (!skip) {
- if (is_first) {
- is_first = false;
- }
- else {
- BLI_dynstr_append(new_matte, ", ");
- }
- BLI_dynstr_nappend(new_matte, n->matte_id + start, token_len);
- }
- start += token_len + 1;
- }
-
- if (n->matte_id) {
- MEM_freeN(n->matte_id);
- n->matte_id = NULL;
- }
- if (BLI_dynstr_get_len(new_matte) > 0) {
- n->matte_id = BLI_dynstr_get_cstring(new_matte);
- }
- BLI_dynstr_free(new_matte);
+ BLI_remlink(&n->entries, entry);
+ MEM_freeN(entry);
}
static bNodeSocketTemplate outputs[] = {
@@ -265,10 +129,7 @@ static void node_free_cryptomatte(bNode *node)
NodeCryptomatte *nc = node->storage;
if (nc) {
- if (nc->matte_id) {
- MEM_freeN(nc->matte_id);
- }
-
+ BLI_freelistN(&nc->entries);
MEM_freeN(nc);
}
}
@@ -280,10 +141,7 @@ static void node_copy_cryptomatte(bNodeTree *UNUSED(dest_ntree),
NodeCryptomatte *src_nc = src_node->storage;
NodeCryptomatte *dest_nc = MEM_dupallocN(src_nc);
- if (src_nc->matte_id) {
- dest_nc->matte_id = MEM_dupallocN(src_nc->matte_id);
- }
-
+ BLI_duplicatelist(&dest_nc->entries, &src_nc->entries);
dest_node->storage = dest_nc;
}