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.
         */

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

Reply via email to