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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to