[Bf-blender-cvs] [fd553c5] master: Fix T37334: Better "internal links" function for muting and node disconnect.

Lukas Tönne noreply at git.blender.org
Sun Mar 2 16:09:25 CET 2014


Commit: fd553c5b7bdfd5bec1cc005bc67785c54916a64a
Author: Lukas Tönne
Date:   Sun Mar 2 16:04:25 2014 +0100
https://developer.blender.org/rBfd553c5b7bdfd5bec1cc005bc67785c54916a64a

Fix T37334: Better "internal links" function for muting and node disconnect.

Implements a more flexible internal connect function for standard nodes
(compositor, shader, texture). Allow feasible datatype connections by
priority.

The priorities for common datatypes in compositor, shader and texture
nodes are encoded in a simple function. Certain impossible connections
(e.g. color -> cycles shader) are excluded by giving them -1 priority.

Priority overrides link status: If a higher priority input can be found,
this will be used regardless of link status. Link status only comes into
play for inputs with same priority.

Reviewers: brecht

CC: sebastian_k

Differential Revision: https://developer.blender.org/D356

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

M	source/blender/blenkernel/BKE_node.h
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/nodes/intern/node_socket.c
M	source/blender/nodes/intern/node_util.c
M	source/blender/nodes/shader/nodes/node_shader_tex_brick.c
M	source/blender/nodes/shader/nodes/node_shader_tex_checker.c
M	source/blender/nodes/shader/nodes/node_shader_tex_environment.c
M	source/blender/nodes/shader/nodes/node_shader_tex_gradient.c
M	source/blender/nodes/shader/nodes/node_shader_tex_image.c
M	source/blender/nodes/shader/nodes/node_shader_tex_magic.c
M	source/blender/nodes/shader/nodes/node_shader_tex_musgrave.c
M	source/blender/nodes/shader/nodes/node_shader_tex_noise.c
M	source/blender/nodes/shader/nodes/node_shader_tex_sky.c
M	source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c
M	source/blender/nodes/shader/nodes/node_shader_tex_wave.c
M	source/blender/nodes/shader/nodes/node_shader_texture.c

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

diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 59ea921..d37e16e 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -101,6 +101,8 @@ typedef struct bNodeSocketTemplate {
 	float min, max;
 	int subtype;  /* would use PropertySubType but this is a bad level include to use RNA */
 	int flag;
+	/* optional: allowed inputs for internal links */
+	const bool *internal_links;
 	
 	/* after this line is used internal only */
 	struct bNodeSocket *sock;		/* used to hold verified socket */
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 4f7c49a..c21cdfa 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -128,19 +128,23 @@ typedef struct bNodeSocket {
 
 	/* XXX deprecated, socket input values are stored in default_value now. kept for forward compatibility */
 	bNodeStack ns  DNA_DEPRECATED;	/* custom data for inputs, only UI writes in this */
+
+	/* optional: allowed inputs for internal links */
+	const bool *internal_links;
 } bNodeSocket;
 
 /* sock->type */
-#define SOCK_CUSTOM			-1	/* socket has no integer type */
-#define SOCK_FLOAT			0
-#define SOCK_VECTOR			1
-#define SOCK_RGBA			2
-#define SOCK_SHADER			3
-#define SOCK_BOOLEAN		4
-#define __SOCK_MESH			5	/* deprecated */
-#define SOCK_INT			6
-#define SOCK_STRING			7
-#define NUM_SOCKET_TYPES	8	/* must be last! */
+typedef enum eNodeSocketDatatype {
+	SOCK_CUSTOM			= -1,	/* socket has no integer type */
+	SOCK_FLOAT			= 0,
+	SOCK_VECTOR			= 1,
+	SOCK_RGBA			= 2,
+	SOCK_SHADER			= 3,
+	SOCK_BOOLEAN		= 4,
+	__SOCK_MESH			= 5,	/* deprecated */
+	SOCK_INT			= 6,
+	SOCK_STRING			= 7
+} eNodeSocketDatatype;
 
 /* socket side (input/output) */
 typedef enum eNodeSocketInOut {
diff --git a/source/blender/nodes/intern/node_socket.c b/source/blender/nodes/intern/node_socket.c
index b30658f..b791f6f 100644
--- a/source/blender/nodes/intern/node_socket.c
+++ b/source/blender/nodes/intern/node_socket.c
@@ -56,6 +56,7 @@ struct bNodeSocket *node_add_socket_from_template(struct bNodeTree *ntree, struc
 	bNodeSocket *sock = nodeAddStaticSocket(ntree, node, in_out, stemp->type, stemp->subtype, stemp->identifier, stemp->name);
 	
 	sock->flag |= stemp->flag;
+	sock->internal_links = stemp->internal_links;
 	
 	/* initialize default_value */
 	switch (stemp->type) {
@@ -117,6 +118,7 @@ static bNodeSocket *verify_socket_template(bNodeTree *ntree, bNode *node, int in
 		sock->type = stemp->type;
 		sock->limit = (stemp->limit == 0 ? 0xFFF : stemp->limit);
 		sock->flag |= stemp->flag;
+		sock->internal_links = stemp->internal_links;
 		
 		BLI_remlink(socklist, sock);
 		
diff --git a/source/blender/nodes/intern/node_util.c b/source/blender/nodes/intern/node_util.c
index 3997d9c..8fb455c 100644
--- a/source/blender/nodes/intern/node_util.c
+++ b/source/blender/nodes/intern/node_util.c
@@ -81,6 +81,7 @@ void *node_initexec_curves(bNodeExecContext *UNUSED(context), bNode *node, bNode
 	return NULL;  /* unused return */
 }
 
+
 /**** Labels ****/
 
 void node_blend_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen)
@@ -111,45 +112,139 @@ void node_filter_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int m
 	BLI_strncpy(label, IFACE_(name), maxlen);
 }
 
+
+/**** Internal Links (mute and disconnect) ****/
+
+/* common datatype priorities, works for compositor, shader and texture nodes alike
+ * defines priority of datatype connection based on output type (to):
+ *   < 0  : never connect these types
+ *   >= 0 : priority of connection (higher values chosen first)
+ */
+static int node_datatype_priority(eNodeSocketDatatype from, eNodeSocketDatatype to)
+{
+	switch (to) {
+		case SOCK_RGBA:
+			switch (from) {
+				case SOCK_RGBA:     return 4;
+				case SOCK_FLOAT:    return 3;
+				case SOCK_INT:      return 2;
+				case SOCK_BOOLEAN:  return 1;
+				default: return -1;
+			}
+		case SOCK_VECTOR:
+			switch (from) {
+				case SOCK_VECTOR:   return 4;
+				case SOCK_FLOAT:    return 3;
+				case SOCK_INT:      return 2;
+				case SOCK_BOOLEAN:  return 1;
+				default:            return -1;
+			}
+		case SOCK_FLOAT:
+			switch (from) {
+				case SOCK_FLOAT:    return 5;
+				case SOCK_INT:      return 4;
+				case SOCK_BOOLEAN:  return 3;
+				case SOCK_RGBA:     return 2;
+				case SOCK_VECTOR:   return 1;
+				default:            return -1;
+			}
+		case SOCK_INT:
+			switch (from) {
+				case SOCK_INT:      return 5;
+				case SOCK_FLOAT:    return 4;
+				case SOCK_BOOLEAN:  return 3;
+				case SOCK_RGBA:     return 2;
+				case SOCK_VECTOR:   return 1;
+				default:            return -1;
+			}
+		case SOCK_BOOLEAN:
+			switch (from) {
+				case SOCK_BOOLEAN:  return 5;
+				case SOCK_INT:      return 4;
+				case SOCK_FLOAT:    return 3;
+				case SOCK_RGBA:     return 2;
+				case SOCK_VECTOR:   return 1;
+				default:            return -1;
+			}
+		case SOCK_SHADER:
+			switch (from) {
+				case SOCK_SHADER:   return 1;
+				default:            return -1;
+			}
+		case SOCK_STRING:
+			switch (from) {
+				case SOCK_STRING:   return 1;
+				default:            return -1;
+			}
+		default: return -1;
+	}
+}
+
+/* select a suitable input socket for an output */
+static bNodeSocket *select_internal_link_input(bNode *node, bNodeSocket *output)
+{
+	const bool *allowed_inputs = output->internal_links;
+	bNodeSocket *selected = NULL, *input;
+	int i;
+	int sel_priority = -1;
+	bool sel_is_linked = false;
+	
+	for (input = node->inputs.first, i = 0; input; input = input->next, ++i) {
+		int priority = node_datatype_priority(input->type, output->type);
+		bool is_linked = (input->link != NULL);
+		bool preferred;
+		
+		if (nodeSocketIsHidden(input) ||                /* ignore hidden sockets */
+		    (allowed_inputs && !allowed_inputs[i]) ||   /* ignore if input is not allowed */
+		    priority < 0 ||                             /* ignore incompatible types */
+		    (priority < sel_priority))                  /* ignore if we already found a higher priority input */
+			continue;
+		
+		/* determine if this input is preferred over the currently selected */
+		preferred = (priority > sel_priority) ||    /* prefer higher datatype priority */
+		            (is_linked && !sel_is_linked);  /* prefer linked over unlinked */
+		
+		if (preferred) {
+			selected = input;
+			sel_is_linked = is_linked;
+			sel_priority = priority;
+		}
+	}
+	
+	return selected;
+}
+
 void node_update_internal_links_default(bNodeTree *ntree, bNode *node)
 {
 	bNodeLink *link;
-	bNodeSocket *output, *input, *selected;
-
+	bNodeSocket *output, *input;
+	
 	/* sanity check */
 	if (!ntree)
 		return;
-
+	
 	/* use link pointer as a tag for handled sockets (for outputs is unused anyway) */
 	for (output = node->outputs.first; output; output = output->next)
 		output->link = NULL;
 	
 	for (link = ntree->links.first; link; link = link->next) {
+		if (nodeLinkIsHidden(link))
+			continue;
+		
 		output = link->fromsock;
 		if (link->fromnode != node || output->link)
 			continue;
+		if (nodeSocketIsHidden(output))
+			continue;
 		output->link = link; /* not really used, just for tagging handled sockets */
 		
 		/* look for suitable input */
-		selected = NULL;
-		for (input = node->inputs.first; input; input = input->next) {
-			/* only use if same type */
-			if (input->type == output->type) {
-				if (!selected) {
-					selected = input;
-				}
-				else {
-					/* linked inputs preferred */
-					if (input->link && !selected->link)
-						selected = input;
-				}
-			}
-		}
+		input = select_internal_link_input(node, output);
 		
-		if (selected) {
+		if (input) {
 			bNodeLink *ilink = MEM_callocN(sizeof(bNodeLink), "internal node link");
 			ilink->fromnode = node;
-			ilink->fromsock = selected;
+			ilink->fromsock = input;
 			ilink->tonode = node;
 			ilink->tosock = output;
 			/* internal link is always valid */
@@ -163,6 +258,9 @@ void node_update_internal_links_default(bNodeTree *ntree, bNode *node)
 		output->link = NULL;
 }
 
+
+/**** Default value RNA access ****/
+
 float node_socket_get_float(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock)
 {
 	PointerRNA ptr;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_brick.c b/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
index 8162b5b..f75f6a6 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
@@ -30,21 +30,21 @@
 /* **************** OUTPUT ******************** */
 
 static bNodeSocketTemplate sh_node_tex_brick_in[] = {
-	{	SOCK_VECTOR, 1, N_("Vector"),		0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+	{	SOCK_VECTOR, 1, N_("Vector"),		0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE | SOCK_NO_INTERNAL_LINK},
 	{ 	SOCK_RGBA, 1, 	N_("Color1"), 		0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
 	{ 	SOCK_RGBA, 1, 	N_("Color2"), 		0.2f, 0.2f, 0.2f, 1.0f, 0.0f, 1.0f},
-	{ 	SOCK_RGBA, 1, 	N_("Mortar"), 		0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
-	{	SOCK_FLOAT, 1,  N_("Scale"),		5.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f},
-	{	SOCK_FLOAT, 1,  N_("Mortar Size"),	0.02f, 0.0f, 0.0f, 0.0f, 0.0f, 0.125f},
-	{	SOCK_FLOAT, 1,  N_("Bias"),		    0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f},
-	{	SOCK_FLOAT, 1,  N_("Brick Width"),	0.5f, 0.0f, 0.0f, 0.0f, 0.01f, 100.0f},
-	{	SOCK_FLOAT, 1,  N_("Row Height"),   0.25f, 0.0f, 0.0f, 0.0f, 0.01f, 100.0f},
+	{ 	SOCK_RGBA, 1, 	N_("Mortar"), 		0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+	{	SOCK_FLOAT, 1,  N_("Scale"),		5.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+	{	SOCK_FLOAT, 1,  N_("Mortar Size"),	0.02f, 0.0f, 0.0f, 0.0f, 0.0f, 0.125f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+	{	SOCK_FLOAT, 1,  N_("Bias"),		    0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+	{	SOCK_FLOAT, 1,  N_("Brick Width"),	0.5f, 0.0f, 0.0f, 0.0f, 0.01f, 100.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+	{	SOCK_FLOAT, 1,  N_("Row Height"),   0.25f, 0.0f, 0.0f, 0.0f, 0.01f, 100.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
 	{	-1, 0, ""	}
 };
 
 static bNodeSocketTemplate sh_n

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list