[Bf-blender-cvs] [6d111a2] master: Fix T48613: Bump mapping in cycles is not shown on the viewport when the material use node groups

Sergey Sharybin noreply at git.blender.org
Tue Jun 14 11:36:39 CEST 2016


Commit: 6d111a233cd65433564ffb106bb9e0c6f34939e8
Author: Sergey Sharybin
Date:   Tue Jun 14 11:31:00 2016 +0200
Branches: master
https://developer.blender.org/rB6d111a233cd65433564ffb106bb9e0c6f34939e8

Fix T48613: Bump mapping in cycles is not shown on the viewport when the material use node groups

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

M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/intern/node.c
M	source/blender/nodes/shader/node_shader_tree.c

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

diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 76e4956..4b92c1f 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -348,6 +348,7 @@ void              ntreeUserDecrefID(struct bNodeTree *ntree);
 struct bNodeTree *ntreeFromID(struct ID *id);
 
 void              ntreeMakeLocal(struct bNodeTree *ntree, bool id_in_mainlist);
+struct bNode     *ntreeFindType(const struct bNodeTree *ntree, int type);
 bool              ntreeHasType(const struct bNodeTree *ntree, int type);
 bool              ntreeHasTree(const struct bNodeTree *ntree, const struct bNodeTree *lookup);
 void              ntreeUpdateTree(struct Main *main, struct bNodeTree *ntree);
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 75f899d..fa0367d 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -2418,15 +2418,20 @@ void ntreeInterfaceTypeUpdate(bNodeTree *ntree)
 
 /* ************ find stuff *************** */
 
+bNode *ntreeFindType(const bNodeTree *ntree, int type) {
+	if (ntree) {
+		for (bNode * node = ntree->nodes.first; node; node = node->next) {
+			if (node->type == type) {
+				return node;
+			}
+		}
+	}
+	return NULL;
+}
+
 bool ntreeHasType(const bNodeTree *ntree, int type)
 {
-	bNode *node;
-	
-	if (ntree)
-		for (node = ntree->nodes.first; node; node = node->next)
-			if (node->type == type)
-				return true;
-	return false;
+	return ntreeFindType(ntree, type) != NULL;
 }
 
 bool ntreeHasTree(const bNodeTree *ntree, const bNodeTree *lookup)
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c
index 29b1e5b..afccef4 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.c
@@ -199,6 +199,12 @@ void register_node_tree_type_sh(void)
 
 /* GPU material from shader nodes */
 
+static void ntree_shader_link_builtin_normal(bNodeTree *ntree,
+                                             bNode *node_from,
+                                             bNodeSocket *socket_from,
+                                             bNode *displacement_node,
+                                             bNodeSocket *displacement_socket);
+
 /* Find an output node of the shader tree.
  *
  * NOTE: it will only return output which is NOT in the group, which isn't how
@@ -277,32 +283,138 @@ static bool ntree_shader_has_displacement(bNodeTree *ntree,
 	return displacement->link != NULL;
 }
 
+static bool ntree_shader_relink_node_normal(bNodeTree *ntree,
+                                            bNode *node,
+                                            bNode *node_from,
+                                            bNodeSocket *socket_from)
+{
+	bNodeSocket *sock = ntree_shader_node_find_input(node, "Normal");
+	/* TODO(sergey): Can we do something smarter here than just a name-based
+	 * matching?
+	 */
+	if (sock == NULL) {
+		/* There's no Normal input, nothing to link. */
+		return false;
+	}
+	if (sock->link != NULL) {
+		/* Something is linked to the normal input already. can't
+		 * use other input for that.
+		 */
+		return false;
+	}
+	/* Create connection between specified node and the normal input. */
+	nodeAddLink(ntree, node_from, socket_from, node, sock);
+	return true;
+}
+
+static void ntree_shader_link_builtin_group_normal(
+        bNodeTree *ntree,
+        bNode *group_node,
+        bNode *node_from,
+        bNodeSocket *socket_from,
+        bNode *displacement_node,
+        bNodeSocket *displacement_socket)
+{
+	bNodeTree *group_ntree = (bNodeTree *)group_node->id;
+	/* Create input socket to plug displacement connection to. */
+	bNodeSocket *group_normal_socket =
+	        ntreeAddSocketInterface(group_ntree,
+	                                SOCK_IN,
+	                                "NodeSocketVector",
+	                                "Normal");
+	/* Need to update tree so all node instances nodes gets proper sockets. */
+	ntreeUpdateTree(G.main, group_ntree);
+	/* Assumes sockets are always added at the end. */
+	bNodeSocket *group_node_normal_socket = (bNodeSocket*)group_node->inputs.last;
+	if (displacement_node == group_node) {
+		/* If displacement is coming from this node group we need to perform
+		 * some internal re-linking in order to avoid cycles.
+		 */
+		bNode *group_output_node = ntreeFindType(group_ntree, NODE_GROUP_OUTPUT);
+		BLI_assert(group_output_node != NULL);
+		bNodeSocket *group_output_node_displacement_socket =
+		        nodeFindSocket(group_output_node,
+		                       SOCK_IN,
+		                       displacement_socket->identifier);
+		bNodeLink *group_displacement_link = group_output_node_displacement_socket->link;
+		if (group_displacement_link == NULL) {
+			/* Displacement output is not connected to anything, can just stop
+			 * right away.
+			 */
+			return;
+		}
+		/* This code is similar to ntree_shader_relink_displacement() */
+		bNode *group_displacement_node = group_displacement_link->fromnode;
+		bNodeSocket *group_displacement_socket = group_displacement_link->fromsock;
+		nodeRemLink(group_ntree, group_displacement_link);
+		/* Create and link bump node.
+		 * Can't re-use bump node from parent tree because it'll cause cycle.
+		 */
+		bNode *bump_node = nodeAddStaticNode(NULL, group_ntree, SH_NODE_BUMP);
+		bNodeSocket *bump_input_socket = ntree_shader_node_find_input(bump_node, "Height");
+		bNodeSocket *bump_output_socket = ntree_shader_node_find_output(bump_node, "Normal");
+		BLI_assert(bump_input_socket != NULL);
+		BLI_assert(bump_output_socket != NULL);
+		nodeAddLink(group_ntree,
+		            group_displacement_node, group_displacement_socket,
+		            bump_node, bump_input_socket);
+		/* Relink normals inside of the instanced tree. */
+		ntree_shader_link_builtin_normal(group_ntree,
+		                                 bump_node,
+		                                 bump_output_socket,
+		                                 group_displacement_node,
+		                                 group_displacement_socket);
+		ntreeUpdateTree(G.main, group_ntree);
+	}
+	else {
+		/* Connect group node normal input. */
+		nodeAddLink(ntree,
+		            node_from, socket_from,
+		            group_node, group_node_normal_socket);
+		bNode *group_input_node = ntreeFindType(group_ntree, NODE_GROUP_INPUT);
+		BLI_assert(group_input_node != NULL);
+		bNodeSocket *group_input_node_normal_socket =
+		        nodeFindSocket(group_input_node,
+		                       SOCK_OUT,
+		                       group_normal_socket->identifier);
+		BLI_assert(group_input_node_normal_socket != NULL);
+		/* Relink normals inside of the instanced tree. */
+		ntree_shader_link_builtin_normal(group_ntree,
+		                                 group_input_node,
+		                                 group_input_node_normal_socket,
+		                                 displacement_node,
+		                                 displacement_socket);
+		ntreeUpdateTree(G.main, group_ntree);
+	}
+}
+
 /* Use specified node and socket as an input for unconnected normal sockets. */
 static void ntree_shader_link_builtin_normal(bNodeTree *ntree,
                                              bNode *node_from,
-                                             bNodeSocket *socket_from)
+                                             bNodeSocket *socket_from,
+                                             bNode *displacement_node,
+                                             bNodeSocket *displacement_socket)
 {
 	for (bNode *node = ntree->nodes.first; node != NULL; node = node->next) {
 		if (node == node_from) {
 			/* Don't connect node itself! */
 			continue;
 		}
-		bNodeSocket *sock = ntree_shader_node_find_input(node, "Normal");
-		/* TODO(sergey): Can we do something smarter here than just a name-based
-		 * matching?
-		 */
-		if (sock == NULL) {
-			/* There's no Normal input, nothing to link. */
+		if (node->type == NODE_GROUP && node->id) {
+			/* Special re-linking for group nodes. */
+			ntree_shader_link_builtin_group_normal(ntree,
+			                                       node,
+			                                       node_from,
+			                                       socket_from,
+			                                       displacement_node,
+			                                       displacement_socket);
 			continue;
 		}
-		if (sock->link != NULL) {
-			/* Something is linked to the normal input already. can't
-			 * use other input for that.
-			 */
+		if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) {
+			/* Group inputs and outputs needs nothing special. */
 			continue;
 		}
-		/* Create connection between specified node and the normal input. */
-		nodeAddLink(ntree, node_from, socket_from, node, sock);
+		ntree_shader_relink_node_normal(ntree, node, node_from, socket_from);
 	}
 }
 
@@ -346,7 +458,11 @@ static void ntree_shader_relink_displacement(bNodeTree *ntree,
 	            displacement_node, displacement_socket,
 	            bump_node, bump_input_socket);
 	/* Connect all free-standing Normal inputs. */
-	ntree_shader_link_builtin_normal(ntree, bump_node, bump_output_socket);
+	ntree_shader_link_builtin_normal(ntree,
+	                                 bump_node,
+	                                 bump_output_socket,
+	                                 displacement_node,
+	                                 displacement_socket);
 	/* TODO(sergey): Reconnect Geometry Info->Normal sockets to the new
 	 * bump node.
 	 */




More information about the Bf-blender-cvs mailing list