[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