[Bf-blender-cvs] [5a87a07c0f4] temp_cryptomatte: Compositor: rewrote Cryptomatte string operations in C to allow for game engine builds
Stefan Werner
noreply at git.blender.org
Fri Nov 3 21:10:12 CET 2017
Commit: 5a87a07c0f4b57b70081abb3988a4821142a41e8
Author: Stefan Werner
Date: Tue Sep 5 13:20:41 2017 +0200
Branches: temp_cryptomatte
https://developer.blender.org/rB5a87a07c0f4b57b70081abb3988a4821142a41e8
Compositor: rewrote Cryptomatte string operations in C to allow for game engine builds
===================================================================
M source/blender/compositor/nodes/COM_CryptomatteNode.cpp
M source/blender/nodes/composite/nodes/node_composite_cryptomatte.c
M source/blenderplayer/bad_level_call_stubs/stubs.c
===================================================================
diff --git a/source/blender/compositor/nodes/COM_CryptomatteNode.cpp b/source/blender/compositor/nodes/COM_CryptomatteNode.cpp
index d0d3529c3bb..8ac31e20d54 100644
--- a/source/blender/compositor/nodes/COM_CryptomatteNode.cpp
+++ b/source/blender/compositor/nodes/COM_CryptomatteNode.cpp
@@ -31,7 +31,6 @@ CryptomatteNode::CryptomatteNode(bNode *editorNode) : Node(editorNode)
{
/* pass */
}
-
/* this is taken from alShaders/Cryptomatte/MurmurHash3.h:
*
* MurmurHash3 was written by Austin Appleby, and is placed in the public
@@ -49,9 +48,9 @@ CryptomatteNode::CryptomatteNode(bNode *editorNode) : Node(editorNode)
#define BIG_CONSTANT(x) (x)
-// Other compilers
+/* Other compilers */
-#else // defined(_MSC_VER)
+#else /* defined(_MSC_VER) */
#define FORCE_INLINE inline __attribute__((always_inline))
@@ -70,11 +69,11 @@ inline uint64_t rotl64 ( uint64_t x, int8_t r )
#define BIG_CONSTANT(x) (x##LLU)
-#endif // !defined(_MSC_VER)
+#endif /* !defined(_MSC_VER) */
-//-----------------------------------------------------------------------------
-// Block read - if your platform needs to do endian-swapping or can only
-// handle aligned reads, do the conversion here
+/* Block read - if your platform needs to do endian-swapping or can only
+ * handle aligned reads, do the conversion here
+ */
FORCE_INLINE uint32_t getblock32 ( const uint32_t * p, int i )
{
@@ -86,8 +85,7 @@ FORCE_INLINE uint64_t getblock64 ( const uint64_t * p, int i )
return p[i];
}
-//-----------------------------------------------------------------------------
-// Finalization mix - force all bits of a hash block to avalanche
+/* Finalization mix - force all bits of a hash block to avalanche */
FORCE_INLINE uint32_t fmix32 ( uint32_t h )
{
@@ -100,8 +98,6 @@ FORCE_INLINE uint32_t fmix32 ( uint32_t h )
return h;
}
-//----------
-
FORCE_INLINE uint64_t fmix64 ( uint64_t k )
{
k ^= k >> 33;
@@ -113,8 +109,6 @@ FORCE_INLINE uint64_t fmix64 ( uint64_t k )
return k;
}
-//-----------------------------------------------------------------------------
-
static void MurmurHash3_x86_32 ( const void * key, int len,
uint32_t seed, void * out )
{
@@ -126,8 +120,7 @@ static void MurmurHash3_x86_32 ( const void * key, int len,
const uint32_t c1 = 0xcc9e2d51;
const uint32_t c2 = 0x1b873593;
- //----------
- // body
+ /* body */
const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
@@ -144,8 +137,7 @@ static void MurmurHash3_x86_32 ( const void * key, int len,
h1 = h1*5+0xe6546b64;
}
- //----------
- // tail
+ /* tail */
const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
@@ -159,8 +151,7 @@ static void MurmurHash3_x86_32 ( const void * key, int len,
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
};
- //----------
- // finalization
+ /* finalization */
h1 ^= len;
@@ -174,91 +165,17 @@ static void MurmurHash3_x86_32 ( const void * key, int len,
static inline float hash_to_float(uint32_t hash) {
uint32_t mantissa = hash & (( 1 << 23) - 1);
uint32_t exponent = (hash >> 23) & ((1 << 8) - 1);
- exponent = std::max(exponent, (uint32_t) 1);
- exponent = std::min(exponent, (uint32_t) 254);
+ exponent = max(exponent, (uint32_t) 1);
+ exponent = min(exponent, (uint32_t) 254);
exponent = exponent << 23;
uint32_t sign = (hash >> 31);
sign = sign << 31;
uint32_t float_bits = sign | exponent | mantissa;
float f;
- std::memcpy(&f, &float_bits, 4);
+ memcpy(&f, &float_bits, 4);
return f;
}
-extern "C" void cryptomatte_add(NodeCryptomatte* n, float f)
-{
- static char number[64];
- BLI_snprintf(number, sizeof(number), "<%.9g>", f);
- if(BLI_strnlen(n->matte_id, sizeof(n->matte_id)) == 0)
- {
- BLI_strncpy(n->matte_id, number, sizeof(n->matte_id));
- return;
- }
-
- // search if we already have the number
- std::istringstream ss(n->matte_id);
- while( ss.good() )
- {
- std::string token;
- getline(ss, token, ',');
- size_t first = token.find_first_not_of(' ');
- size_t last = token.find_last_not_of(' ');
- token = token.substr(first, (last-first+1));
- if (*token.begin() == '<' && *(--token.end()) == '>') {
- if(std::string(number) == token)
- return;
- } else {
- uint32_t hash = 0;
- MurmurHash3_x86_32(token.c_str(), token.length(), 0, &hash);
- if (f == hash_to_float(hash))
- return;
- }
- }
-
- std::string matte_id = n->matte_id;
- matte_id += ", ";
- matte_id += number;
- BLI_strncpy(n->matte_id, matte_id.c_str(), sizeof(n->matte_id));
-}
-
-extern "C" void cryptomatte_remove(NodeCryptomatte*n, float f)
-{
- if(::strnlen(n->matte_id, sizeof(n->matte_id)) == 0)
- {
- // empty string, nothing to remove
- return;
- }
-
- std::istringstream ss(n->matte_id);
- std::ostringstream os;
- bool first_string = true;
- while( ss.good() )
- {
- std::string token;
- getline(ss, token, ',');
- size_t first = token.find_first_not_of(' ');
- size_t last = token.find_last_not_of(' ');
- token = token.substr(first, (last-first+1));
- if (*token.begin() == '<' && *(--token.end()) == '>') {
- float fx = atof(token.substr(1, token.length()-2).c_str());
- if(f == fx)
- continue;
- } else {
- uint32_t hash = 0;
- MurmurHash3_x86_32(token.c_str(), token.length(), 0, &hash);
- if (f == hash_to_float(hash))
- continue;
- }
- if(!first_string) {
- os << ", ";
- } else {
- first_string = false;
- }
- os << token;
- }
- BLI_strncpy(n->matte_id, os.str().c_str(), sizeof(n->matte_id));
-}
-
void CryptomatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const
{
NodeInput *inputSocketImage = this->getInputSocket(0);
diff --git a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c
index c514ac59bb0..7c1dd4e61ab 100644
--- a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c
+++ b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c
@@ -30,10 +30,279 @@
*/
#include "node_composite_util.h"
+#include "BLI_dynstr.h"
-// I can't be bothered to do string operations without std::string
-extern void cryptomatte_add(NodeCryptomatte* n, float f);
-extern void cryptomatte_remove(NodeCryptomatte*n, float f);
+/* this is taken from alShaders/Cryptomatte/MurmurHash3.h:
+ *
+ * MurmurHash3 was written by Austin Appleby, and is placed in the public
+ * domain. The author hereby disclaims copyright to this source code.
+ *
+ */
+#if defined(_MSC_VER)
+
+#define FORCE_INLINE __forceinline
+
+#include <stdlib.h>
+
+#define ROTL32(x,y) _rotl(x,y)
+#define ROTL64(x,y) _rotl64(x,y)
+
+#define BIG_CONSTANT(x) (x)
+
+/* Other compilers */
+
+#else /* defined(_MSC_VER) */
+
+#define FORCE_INLINE inline __attribute__((always_inline))
+
+inline uint32_t rotl32 ( uint32_t x, int8_t r )
+{
+ return (x << r) | (x >> (32 - r));
+}
+
+inline uint64_t rotl64 ( uint64_t x, int8_t r )
+{
+ return (x << r) | (x >> (64 - r));
+}
+
+#define ROTL32(x,y) rotl32(x,y)
+#define ROTL64(x,y) rotl64(x,y)
+
+#define BIG_CONSTANT(x) (x##LLU)
+
+#endif /* !defined(_MSC_VER) */
+
+/* Block read - if your platform needs to do endian-swapping or can only
+ * handle aligned reads, do the conversion here
+ */
+
+FORCE_INLINE uint32_t getblock32 ( const uint32_t * p, int i )
+{
+ return p[i];
+}
+
+FORCE_INLINE uint64_t getblock64 ( const uint64_t * p, int i )
+{
+ return p[i];
+}
+
+/* Finalization mix - force all bits of a hash block to avalanche */
+
+FORCE_INLINE uint32_t fmix32 ( uint32_t h )
+{
+ h ^= h >> 16;
+ h *= 0x85ebca6b;
+ h ^= h >> 13;
+ h *= 0xc2b2ae35;
+ h ^= h >> 16;
+
+ return h;
+}
+
+FORCE_INLINE uint64_t fmix64 ( uint64_t k )
+{
+ k ^= k >> 33;
+ k *= BIG_CONSTANT(0xff51afd7ed558ccd);
+ k ^= k >> 33;
+ k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
+ k ^= k >> 33;
+
+ return k;
+}
+
+static void MurmurHash3_x86_32 ( const void * key, int len,
+ uint32_t seed, void * out )
+{
+ const uint8_t * data = (const uint8_t*)key;
+ const int nblocks = len / 4;
+
+ uint32_t h1 = seed;
+
+ const uint32_t c1 = 0xcc9e2d51;
+ const uint32_t c2 = 0x1b873593;
+
+ /* body */
+
+ const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
+
+ for(int i = -nblocks; i; i++)
+ {
+ uint32_t k1 = getblock32(blocks,i);
+
+ k1 *= c1;
+ k1 = ROTL32(k1,15);
+ k1 *= c2;
+
+ h1 ^= k1;
+ h1 = ROTL32(h1,13);
+ h1 = h1*5+0xe6546b64;
+ }
+
+ /* tail */
+
+ const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
+
+ uint32_t k1 = 0;
+
+ switch(len & 3)
+ {
+ case 3: k1 ^= tail[2] << 16;
+ case 2: k1 ^= tail[1] << 8;
+ case 1: k1 ^= tail[0];
+ k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
+ };
+
+ /* finalization */
+
+ h1 ^= len;
+
+ h1 = fmix32(h1);
+
+ *(uint32_t*)out = h1;
+}
+
+/* this is taken from the cryptomatte specification 1.0 */
+
+static inline float hash_to_float(uint32_t hash) {
+ uint32_t mantissa = hash & (( 1 << 23) - 1);
+ uint32_t exponent = (hash >> 23) & ((1 << 8) - 1);
+ exponent = max(exponent, (uint32_t) 1);
+ exponent = min(exponent, (uint32_t) 254);
+ exponent = exponent << 23;
+ uint32_t sign = (hash >> 31);
+ sign = sign << 31;
+ uint32_t float_bits = sign | exponent | mantissa;
+ float f;
+ memcpy(&f, &float_bits, 4);
+ return f;
+}
+
+extern void cryptomatte_add(NodeCryptomatte* n, float f)
+{
+ /* Turn the number into a string. */
+ static char number[32];
+ BLI_snprintf(number, sizeof(number), "<%.9g>", f);
+
+ if(BLI_strnlen(n->matte_id, sizeof(n->matte_id)) == 0)
+ {
+ BLI_snprintf(n->matte_id, sizeof(n->matte_id), "%s", number);
+ return;
+ }
+
+ /* Search if we already have the number. */
+ size_t start = 0;
+ const size_t end = strlen(n->matte_id);
+ const size_t number_len = strlen(number);
+ size_t token_len = 0;
+ while(start < end) {
+ /* Ignore leading whitespace. */
+ while (start < end && n->matte_id[start] == ' ') {
+ ++start;
+ }
+
+ /* Find the next seprator. */
+ char* token_end = strchr(n->matte_id+start, ',');
+ if (token_end == NULL || token_end == 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 l
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list