[Bf-blender-cvs] [585bc61a7a0] temp_cryptomatte: Compositor: Added Cryptomatte node

Stefan Werner noreply at git.blender.org
Fri Nov 3 21:09:38 CET 2017


Commit: 585bc61a7a0c564e19c82856968ad5d50f428bba
Author: Stefan Werner
Date:   Thu Apr 6 13:47:38 2017 +0200
Branches: temp_cryptomatte
https://developer.blender.org/rB585bc61a7a0c564e19c82856968ad5d50f428bba

Compositor: Added Cryptomatte node

===================================================================

M	release/scripts/startup/nodeitems_builtins.py
M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/intern/node.c
M	source/blender/compositor/CMakeLists.txt
M	source/blender/compositor/intern/COM_Converter.cpp
A	source/blender/compositor/nodes/COM_CryptomatteNode.cpp
A	source/blender/compositor/nodes/COM_CryptomatteNode.h
A	source/blender/compositor/operations/COM_CryptomatteOperation.cpp
A	source/blender/compositor/operations/COM_CryptomatteOperation.h
M	source/blender/editors/space_node/drawnode.c
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/CMakeLists.txt
M	source/blender/nodes/NOD_composite.h
M	source/blender/nodes/NOD_static_types.h
A	source/blender/nodes/composite/nodes/node_composite_cryptomatte.c

===================================================================

diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 0a59cc6f551..e00a743542a 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -389,6 +389,7 @@ compositor_node_categories = [
         NodeItem("CompositorNodeChromaMatte"),
         NodeItem("CompositorNodeColorMatte"),
         NodeItem("CompositorNodeDoubleEdgeMask"),
+        NodeItem("CompositorNodeCryptomatte"),
         ]),
     CompositorNodeCategory("CMP_DISTORT", "Distort", items=[
         NodeItem("CompositorNodeScale"),
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 516f9e74570..75356cd13e7 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -938,6 +938,7 @@ void            ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMateria
 #define CMP_NODE_PLANETRACKDEFORM	320
 #define CMP_NODE_CORNERPIN          321
 #define CMP_NODE_SWITCH_VIEW    322
+#define CMP_NODE_CRYPTOMATTE	323
 
 /* channel toggles */
 #define CMP_CHAN_RGB		1
@@ -990,6 +991,9 @@ void ntreeCompositOutputFileUniqueLayer(struct ListBase *list, struct bNodeSocke
 void ntreeCompositColorBalanceSyncFromLGG(bNodeTree *ntree, bNode *node);
 void ntreeCompositColorBalanceSyncFromCDL(bNodeTree *ntree, bNode *node);
 
+void ntreeCompositCryptomatteSyncFromAdd(bNodeTree *ntree, bNode *node);
+void ntreeCompositCryptomatteSyncFromRemove(bNodeTree *ntree, bNode *node);
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index b5cfd0e34ed..c61f799d8fc 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -3486,6 +3486,7 @@ static void registerCompositNodes(void)
 	register_node_type_cmp_doubleedgemask();
 	register_node_type_cmp_keyingscreen();
 	register_node_type_cmp_keying();
+	register_node_type_cmp_cryptomatte();
 
 	register_node_type_cmp_translate();
 	register_node_type_cmp_rotate();
diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt
index 3e1dd83112a..0ad53d3ab80 100644
--- a/source/blender/compositor/CMakeLists.txt
+++ b/source/blender/compositor/CMakeLists.txt
@@ -182,6 +182,11 @@ set(SRC
 	operations/COM_SunBeamsOperation.cpp
 	operations/COM_SunBeamsOperation.h
 
+	nodes/COM_CryptomatteNode.cpp
+	nodes/COM_CryptomatteNode.h
+	operations/COM_CryptomatteOperation.cpp
+	operations/COM_CryptomatteOperation.h
+
 	nodes/COM_CornerPinNode.cpp
 	nodes/COM_CornerPinNode.h
 	nodes/COM_PlaneTrackDeformNode.cpp
diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp
index 9fa59be4a1c..3c040f62701 100644
--- a/source/blender/compositor/intern/COM_Converter.cpp
+++ b/source/blender/compositor/intern/COM_Converter.cpp
@@ -55,6 +55,7 @@ extern "C" {
 #include "COM_Converter.h"
 #include "COM_CornerPinNode.h"
 #include "COM_CropNode.h"
+#include "COM_CryptomatteNode.h"
 #include "COM_DefocusNode.h"
 #include "COM_DespeckleNode.h"
 #include "COM_DifferenceMatteNode.h"
@@ -406,6 +407,9 @@ Node *Converter::convert(bNode *b_node)
 		case CMP_NODE_SUNBEAMS:
 			node = new SunBeamsNode(b_node);
 			break;
+		case CMP_NODE_CRYPTOMATTE:
+			node = new CryptomatteNode(b_node);
+			break;
 	}
 	return node;
 }
diff --git a/source/blender/compositor/nodes/COM_CryptomatteNode.cpp b/source/blender/compositor/nodes/COM_CryptomatteNode.cpp
new file mode 100644
index 00000000000..ab3cfbc7562
--- /dev/null
+++ b/source/blender/compositor/nodes/COM_CryptomatteNode.cpp
@@ -0,0 +1,291 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ *              Lukas Stockner
+ *              Stefan Werner
+ */
+
+#include "COM_CryptomatteNode.h"
+#include "COM_CryptomatteOperation.h"
+#include <iterator>
+
+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
+ * 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 = std::max(exponent, (uint32_t) 1);
+	exponent = std::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);
+	return f;
+}
+
+extern "C" void cryptomatte_add(NodeCryptomatte* n, float f)
+{
+	static char number[64];
+	std::snprintf(number, sizeof(number), "<%.9g>", f);
+	if(::strnlen(n->matte_id, sizeof(n->matte_id)) == 0)
+	{
+		std::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(f == atof(token.substr(1, token.length()-2).c_str()))
+				return;
+		} else {
+			uint32_t hash = 0;
+			MurmurHash3_x86_32(token.c_str(), token.length(), 0, &hash);
+			if (f == hash_to_float(hash))
+				return;
+		}
+	}
+	strlcat(n->matte_id, ", ", sizeof(n->matte_id));
+	strlcat(n->matte_id, number, 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;
+	}
+	strlcpy(n->matte_id, os.str().c_str(), sizeof(n->matte_id));
+}
+
+void CryptomatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const
+{
+	CryptomatteOperation *operation = new CryptomatteOperation();
+	
+	bNode *no

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list