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. @@

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

Reply via email to