Long on the wishlist, quite simple even, and there it finally is:
authorTon Roosendaal <ton@blender.org>
Sat, 8 Mar 2008 19:02:08 +0000 (19:02 +0000)
committerTon Roosendaal <ton@blender.org>
Sat, 8 Mar 2008 19:02:08 +0000 (19:02 +0000)
  Compositor:
  Muting option to temporary disable/enable nodes.
  Hotkey: press M on selection. It toggles.

Note: no menu entry yet, and drawing style could be tweakered...

source/blender/blenkernel/intern/node.c
source/blender/makesdna/DNA_node_types.h
source/blender/nodes/intern/CMP_util.c
source/blender/nodes/intern/CMP_util.h
source/blender/src/drawnode.c
source/blender/src/editnode.c

index 179e5b0ba944b2b1f401849e7915a20eb482315a..ec73d35ed9cc28bcfd7d210810d4095437412a06 100644 (file)
@@ -64,6 +64,8 @@
 #include "RE_render_ext.h"             /* <- ibuf_sample() */
 
 #include "CMP_node.h"
+#include "intern/CMP_util.h"   /* stupid include path... */
+
 #include "SHD_node.h"
 
 /* not very important, but the stack solver likes to know a maximum */
@@ -1990,6 +1992,27 @@ void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread)
 
 
 /* ***************************** threaded version for execute composite nodes ************* */
+/* these are nodes without input, only giving values */
+/* or nodes with only value inputs */
+static int node_only_value(bNode *node)
+{
+       bNodeSocket *sock;
+       
+       if(ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_VALUE, CMP_NODE_RGB))
+               return 1;
+       
+       /* doing this for all node types goes wrong. memory free errors */
+       if(node->inputs.first && node->type==CMP_NODE_MAP_VALUE) {
+               int retval= 1;
+               for(sock= node->inputs.first; sock; sock= sock->next) {
+                       if(sock->link)
+                               retval &= node_only_value(sock->link->fromnode);
+               }
+               return retval;
+       }
+       return 0;
+}
+
 
 /* not changing info, for thread callback */
 typedef struct ThreadData {
@@ -2006,7 +2029,14 @@ static void *exec_composite_node(void *node_v)
        
        node_get_stack(node, thd->stack, nsin, nsout);
        
-       if(node->typeinfo->execfunc) {
+       if((node->flag & NODE_MUTED) && (!node_only_value(node))) {
+               /* viewers we execute, for feedback to user */
+               if(ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) 
+                       node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
+               else
+                       node_compo_pass_on(node, nsin, nsout);
+       }
+       else if(node->typeinfo->execfunc) {
                node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
        }
        else if(node->type==NODE_GROUP && node->id) {
@@ -2017,27 +2047,6 @@ static void *exec_composite_node(void *node_v)
        return 0;
 }
 
-/* these are nodes without input, only giving values */
-/* or nodes with only value inputs */
-static int node_only_value(bNode *node)
-{
-       bNodeSocket *sock;
-       
-       if(ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_VALUE, CMP_NODE_RGB))
-               return 1;
-       
-       /* doing this for all node types goes wrong. memory free errors */
-       if(node->inputs.first && node->type==CMP_NODE_MAP_VALUE) {
-               int retval= 1;
-               for(sock= node->inputs.first; sock; sock= sock->next) {
-                       if(sock->link)
-                               retval &= node_only_value(sock->link->fromnode);
-               }
-               return retval;
-       }
-       return 0;
-}
-
 /* return total of executable nodes, for timecursor */
 /* only compositor uses it */
 static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
index ecf86175999b94fa21aa7420c3c68a91bfba5715..f74e858c0e496e34b15708d33c55397ca2cc9579 100644 (file)
@@ -144,6 +144,8 @@ typedef struct bNode {
 #define NODE_GROUP_EDIT                128
                /* free test flag, undefined */
 #define NODE_TEST                      256
+               /* composite: don't do node but pass on buffer(s) */
+#define NODE_MUTED                     512
 
 typedef struct bNodeLink {
        struct bNodeLink *next, *prev;
index 21e0f034a159dedcfe434d815b33f73ae6dc06b2..a2629aa396ec43c1d995bc6389de23e598e65936 100644 (file)
@@ -122,6 +122,48 @@ void print_compbuf(char *str, CompBuf *cbuf)
        
 }
 
+/* used for disabling node  (similar code in drawnode.c for disable line) */
+void node_compo_pass_on(bNode *node, bNodeStack **nsin, bNodeStack **nsout)
+{
+       CompBuf *valbuf= NULL, *colbuf= NULL, *vecbuf= NULL;
+       bNodeSocket *sock;
+       int a;
+       
+       /* connect the first value buffer in with first value out */
+       /* connect the first RGBA buffer in with first RGBA out */
+       
+       /* test the inputs */
+       for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) {
+               if(nsin[a]->data) {
+                       CompBuf *cbuf= nsin[a]->data;
+                       if(cbuf->type==1 && valbuf==NULL) valbuf= cbuf;
+                       if(cbuf->type==3 && vecbuf==NULL) vecbuf= cbuf;
+                       if(cbuf->type==4 && colbuf==NULL) colbuf= cbuf;
+               }
+       }
+       
+       /* outputs */
+       if(valbuf || colbuf || vecbuf) {
+               for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
+                       if(nsout[a]->hasoutput) {
+                               if(sock->type==SOCK_VALUE && valbuf) {
+                                       nsout[a]->data= pass_on_compbuf(valbuf);
+                                       valbuf= NULL;
+                               }
+                               if(sock->type==SOCK_VECTOR && vecbuf) {
+                                       nsout[a]->data= pass_on_compbuf(vecbuf);
+                                       vecbuf= NULL;
+                               }
+                               if(sock->type==SOCK_RGBA && colbuf) {
+                                       nsout[a]->data= pass_on_compbuf(colbuf);
+                                       colbuf= NULL;
+                               }
+                       }
+               }
+       }
+}
+
+
 CompBuf *get_cropped_compbuf(rcti *drect, float *rectf, int rectx, int recty, int type)
 {
        CompBuf *cbuf;
index 6fa5251710a61ef1ec978f414c08fa8a9ae9759b..a0e2f90f0dabe2fb7580a89aaa0ba04795256698 100644 (file)
@@ -132,6 +132,7 @@ CompBuf *dupalloc_compbuf(CompBuf *cbuf);
 CompBuf *pass_on_compbuf(CompBuf *cbuf);
 void free_compbuf(CompBuf *cbuf);
 void print_compbuf(char *str, CompBuf *cbuf);
+void node_compo_pass_on(struct bNode *node, struct bNodeStack **nsin, struct bNodeStack **nsout);
 
 CompBuf *get_cropped_compbuf(rcti *drect, float *rectf, int rectx, int recty, int type);
 CompBuf *scalefast_compbuf(CompBuf *inbuf, int newx, int newy);
index 504c5dbe55fc9991ed9ebef47192f9e545c3734a..8638cb9d83782380ff14e474f0888c6957f23c37 100644 (file)
@@ -2694,6 +2694,168 @@ static int node_get_colorid(bNode *node)
        return TH_NODE;
 }
 
+static void node_draw_link_bezier(float vec[][3], int th_col1, int th_col2, int do_shaded)
+{
+       float dist;
+       
+       dist= 0.5f*ABS(vec[0][0] - vec[3][0]);
+       
+       /* check direction later, for top sockets */
+       vec[1][0]= vec[0][0]+dist;
+       vec[1][1]= vec[0][1];
+       
+       vec[2][0]= vec[3][0]-dist;
+       vec[2][1]= vec[3][1];
+       
+       if( MIN4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > G.v2d->cur.xmax); /* clipped */  
+       else if ( MAX4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < G.v2d->cur.xmin); /* clipped */
+       else {
+               float curve_res = 24, spline_step = 0.0f;
+               
+               /* we can reuse the dist variable here to increment the GL curve eval amount*/
+               dist = 1.0f/curve_res;
+               
+               glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, vec[0]);
+               glBegin(GL_LINE_STRIP);
+               while (spline_step < 1.000001f) {
+                       if(do_shaded)
+                               BIF_ThemeColorBlend(th_col1, th_col2, spline_step);
+                       glEvalCoord1f(spline_step);
+                       spline_step += dist;
+               }
+               glEnd();
+       }
+       
+}
+
+/* note; this is used for fake links in groups too */
+void node_draw_link(SpaceNode *snode, bNodeLink *link)
+{
+       float vec[4][3];
+       float mx=0.0f, my=0.0f;
+       int do_shaded= 1, th_col1= TH_WIRE, th_col2= TH_WIRE;
+       
+       if(link->fromnode==NULL && link->tonode==NULL)
+               return;
+       
+       /* this is dragging link */
+       if(link->fromnode==NULL || link->tonode==NULL) {
+               short mval[2];
+               getmouseco_areawin(mval);
+               areamouseco_to_ipoco(G.v2d, mval, &mx, &my);
+               BIF_ThemeColor(TH_WIRE);
+               do_shaded= 0;
+       }
+       else {
+               /* going to give issues once... */
+               if(link->tosock->flag & SOCK_UNAVAIL)
+                       return;
+               if(link->fromsock->flag & SOCK_UNAVAIL)
+                       return;
+               
+               /* a bit ugly... but thats how we detect the internal group links */
+               if(link->fromnode==link->tonode) {
+                       BIF_ThemeColorBlend(TH_BACK, TH_WIRE, 0.25f);
+                       do_shaded= 0;
+               }
+               else {
+                       /* check cyclic */
+                       if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
+                               if(link->fromnode->flag & SELECT)
+                                       th_col1= TH_EDGE_SELECT;
+                               if(link->tonode->flag & SELECT)
+                                       th_col2= TH_EDGE_SELECT;
+                       }                               
+                       else {
+                               BIF_ThemeColor(TH_REDALERT);
+                               do_shaded= 0;
+                       }
+               }
+       }
+       
+       vec[0][2]= vec[1][2]= vec[2][2]= vec[3][2]= 0.0; /* only 2d spline, set the Z to 0*/
+       
+       /* in v0 and v3 we put begin/end points */
+       if(link->fromnode) {
+               vec[0][0]= link->fromsock->locx;
+               vec[0][1]= link->fromsock->locy;
+       }
+       else {
+               vec[0][0]= mx;
+               vec[0][1]= my;
+       }
+       if(link->tonode) {
+               vec[3][0]= link->tosock->locx;
+               vec[3][1]= link->tosock->locy;
+       }
+       else {
+               vec[3][0]= mx;
+               vec[3][1]= my;
+       }
+       
+       node_draw_link_bezier(vec, th_col1, th_col2, do_shaded);
+}
+
+
+/* note: in cmp_util.c is similar code, for node_compo_pass_on() */
+static void node_draw_mute_line(SpaceNode *snode, bNode *node)
+{
+       bNodeSocket *valsock= NULL, *colsock= NULL, *vecsock= NULL;
+       bNodeSocket *sock;
+       float vec[4][3];
+       int a;
+       
+       vec[0][2]= vec[1][2]= vec[2][2]= vec[3][2]= 0.0; /* only 2d spline, set the Z to 0*/
+       
+       /* connect the first value buffer in with first value out */
+       /* connect the first RGBA buffer in with first RGBA out */
+       
+       /* test the inputs */
+       for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) {
+               if(nodeCountSocketLinks(snode->edittree, sock)) {
+                       if(sock->type==SOCK_VALUE && valsock==NULL) valsock= sock;
+                       if(sock->type==SOCK_VECTOR && vecsock==NULL) vecsock= sock;
+                       if(sock->type==SOCK_RGBA && colsock==NULL) colsock= sock;
+               }
+       }
+       
+       /* outputs, draw lines */
+       BIF_ThemeColor(TH_REDALERT);
+       glEnable(GL_BLEND);
+       glEnable( GL_LINE_SMOOTH );
+       
+       if(valsock || colsock || vecsock) {
+               for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
+                       if(nodeCountSocketLinks(snode->edittree, sock)) {
+                               vec[3][0]= sock->locx;
+                               vec[3][1]= sock->locy;
+                               
+                               if(sock->type==SOCK_VALUE && valsock) {
+                                       vec[0][0]= valsock->locx;
+                                       vec[0][1]= valsock->locy;
+                                       node_draw_link_bezier(vec, TH_WIRE, TH_WIRE, 0);
+                                       valsock= NULL;
+                               }
+                               if(sock->type==SOCK_VECTOR && vecsock) {
+                                       vec[0][0]= vecsock->locx;
+                                       vec[0][1]= vecsock->locy;
+                                       node_draw_link_bezier(vec, TH_WIRE, TH_WIRE, 0);
+                                       vecsock= NULL;
+                               }
+                               if(sock->type==SOCK_RGBA && colsock) {
+                                       vec[0][0]= colsock->locx;
+                                       vec[0][1]= colsock->locy;
+                                       node_draw_link_bezier(vec, TH_WIRE, TH_WIRE, 0);
+                                       colsock= NULL;
+                               }
+                       }
+               }
+       }
+       glDisable(GL_BLEND);
+       glDisable( GL_LINE_SMOOTH );
+}
+
+
 static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
 {
        bNodeSocket *sock;
@@ -2702,7 +2864,7 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
        rctf *rct= &node->totr;
        float slen, iconofs;
        int ofs, color_id= node_get_colorid(node);
-       char showname[128];
+       char showname[128]; /* 128 used below */
        
        uiSetRoundBox(15-4);
        ui_dropshadow(rct, BASIS_RAD, snode->aspect, node->flag & SELECT);
@@ -2782,14 +2944,12 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
        
        ui_rasterpos_safe(rct->xmin+19.0f, rct->ymax-NODE_DY+5.0f, snode->aspect);
        
-       if(node->username[0]) {
-               strcpy(showname,"(");
-               strcat(showname, node->username);
-               strcat(showname,") ");
-               strcat(showname, node->name);
-       }
+       if(node->flag & NODE_MUTED)
+               sprintf(showname, "[%s]", node->name);
+       else if(node->username[0])
+               sprintf(showname, "(%s)%s", node->username, node->name);
        else
-               strcpy(showname, node->name);
+               BLI_strncpy(showname, node->name, 128);
 
        snode_drawstring(snode, showname, (int)(iconofs - rct->xmin-18.0f));
 
@@ -2812,6 +2972,10 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
                glDisable(GL_BLEND);
        }
        
+       /* disable lines */
+       if(node->flag & NODE_MUTED)
+               node_draw_mute_line(snode, node);
+
        /* we make buttons for input sockets, if... */
        if(node->flag & NODE_OPTIONS) {
                if(node->inputs.first || node->typeinfo->butfunc) {
@@ -2904,7 +3068,7 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
                        uiDrawBlock(block);
                }
        }
-
+       
 }
 
 static void node_draw_hidden(SpaceNode *snode, bNode *node)
@@ -2914,7 +3078,7 @@ static void node_draw_hidden(SpaceNode *snode, bNode *node)
        float dx, centy= 0.5f*(rct->ymax+rct->ymin);
        float hiddenrad= 0.5f*(rct->ymax-rct->ymin);
        int color_id= node_get_colorid(node);
-       char showname[128];
+       char showname[128];     /* 128 is used below */
        
        /* shadow */
        uiSetRoundBox(15);
@@ -2941,6 +3105,10 @@ static void node_draw_hidden(SpaceNode *snode, bNode *node)
        /* open entirely icon */
        ui_draw_tria_icon(rct->xmin+9.0f, centy-6.0f, snode->aspect, 'h');      
        
+       /* disable lines */
+       if(node->flag & NODE_MUTED)
+               node_draw_mute_line(snode, node);       
+       
        if(node->flag & SELECT) 
                BIF_ThemeColor(TH_TEXT_HI);
        else
@@ -2949,14 +3117,12 @@ static void node_draw_hidden(SpaceNode *snode, bNode *node)
        if(node->miniwidth>0.0f) {
                ui_rasterpos_safe(rct->xmin+21.0f, centy-4.0f, snode->aspect);
 
-               if(node->username[0]) {
-                       strcpy(showname,"(");
-                       strcat(showname, node->username);
-                       strcat(showname,") ");
-                       strcat(showname, node->name);
-               }
+               if(node->flag & NODE_MUTED)
+                       sprintf(showname, "[%s]", node->name);
+               else if(node->username[0])
+                       sprintf(showname, "(%s)%s", node->username, node->name);
                else
-                       strcpy(showname, node->name);
+                       BLI_strncpy(showname, node->name, 128);
 
                snode_drawstring(snode, showname, (int)(rct->xmax - rct->xmin-18.0f -12.0f));
        }       
@@ -2984,101 +3150,6 @@ static void node_draw_hidden(SpaceNode *snode, bNode *node)
        }
 }
 
-/* note; this is used for fake links in groups too */
-void node_draw_link(SpaceNode *snode, bNodeLink *link)
-{
-       float vec[4][3];
-       float dist, spline_step, mx=0.0f, my=0.0f;
-       int curve_res, do_shaded= 1, th_col1= TH_WIRE, th_col2= TH_WIRE;
-       
-       if(link->fromnode==NULL && link->tonode==NULL)
-               return;
-       
-       /* this is dragging link */
-       if(link->fromnode==NULL || link->tonode==NULL) {
-               short mval[2];
-               getmouseco_areawin(mval);
-               areamouseco_to_ipoco(G.v2d, mval, &mx, &my);
-               BIF_ThemeColor(TH_WIRE);
-               do_shaded= 0;
-       }
-       else {
-               /* going to give issues once... */
-               if(link->tosock->flag & SOCK_UNAVAIL)
-                       return;
-               if(link->fromsock->flag & SOCK_UNAVAIL)
-                       return;
-               
-               /* a bit ugly... but thats how we detect the internal group links */
-               if(link->fromnode==link->tonode) {
-                       BIF_ThemeColorBlend(TH_BACK, TH_WIRE, 0.25f);
-                       do_shaded= 0;
-               }
-               else {
-                       /* check cyclic */
-                       if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
-                               if(link->fromnode->flag & SELECT)
-                                       th_col1= TH_EDGE_SELECT;
-                               if(link->tonode->flag & SELECT)
-                                       th_col2= TH_EDGE_SELECT;
-                       }                               
-                       else {
-                               BIF_ThemeColor(TH_REDALERT);
-                               do_shaded= 0;
-                       }
-               }
-       }
-       
-       vec[0][2]= vec[1][2]= vec[2][2]= vec[3][2]= 0.0; /* only 2d spline, set the Z to 0*/
-       
-       /* in v0 and v3 we put begin/end points */
-       if(link->fromnode) {
-               vec[0][0]= link->fromsock->locx;
-               vec[0][1]= link->fromsock->locy;
-       }
-       else {
-               vec[0][0]= mx;
-               vec[0][1]= my;
-       }
-       if(link->tonode) {
-               vec[3][0]= link->tosock->locx;
-               vec[3][1]= link->tosock->locy;
-       }
-       else {
-               vec[3][0]= mx;
-               vec[3][1]= my;
-       }
-       
-       dist= 0.5f*ABS(vec[0][0] - vec[3][0]);
-       
-       /* check direction later, for top sockets */
-       vec[1][0]= vec[0][0]+dist;
-       vec[1][1]= vec[0][1];
-       
-       vec[2][0]= vec[3][0]-dist;
-       vec[2][1]= vec[3][1];
-       
-       if( MIN4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > G.v2d->cur.xmax); /* clipped */  
-       else if ( MAX4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < G.v2d->cur.xmin); /* clipped */
-       else {
-               curve_res = 24;
-               
-               /* we can reuse the dist variable here to increment the GL curve eval amount*/
-               dist = 1.0f/curve_res;
-               spline_step = 0.0f;
-               
-               glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, vec[0]);
-               glBegin(GL_LINE_STRIP);
-               while (spline_step < 1.000001f) {
-                       if(do_shaded)
-                               BIF_ThemeColorBlend(th_col1, th_col2, spline_step);
-                       glEvalCoord1f(spline_step);
-                       spline_step += dist;
-               }
-               glEnd();
-       }
-}
-
 static void node_draw_nodetree(ScrArea *sa, SpaceNode *snode, bNodeTree *ntree)
 {
        bNode *node;
index 8a5385cd9614110624cabe09aed60e2c3777049d..a308b42889450e777488d7a99bba928b72683ff0 100644 (file)
@@ -1633,6 +1633,30 @@ bNode *node_add_node(SpaceNode *snode, int type, float locx, float locy)
        return node;
 }
 
+void node_mute(SpaceNode *snode)
+{
+       bNode *node;
+
+       /* no disabling inside of groups */
+       if(snode_get_editgroup(snode))
+               return;
+       
+       for(node= snode->edittree->nodes.first; node; node= node->next) {
+               if(node->flag & SELECT) {
+                       if(node->inputs.first && node->outputs.first) {
+                               if(node->flag & NODE_MUTED)
+                                       node->flag &= ~NODE_MUTED;
+                               else
+                                       node->flag |= NODE_MUTED;
+                       }
+               }
+       }
+       
+       allqueue(REDRAWNODE, 0);
+       BIF_undo_push("Enable/Disable nodes");
+
+}
+
 void node_adduplicate(SpaceNode *snode)
 {
        
@@ -2421,6 +2445,9 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                case LKEY:
                        node_select_linked(snode, G.qual==LR_SHIFTKEY);
                        break;
+               case MKEY:
+                       node_mute(snode);
+                       break;
                case RKEY:
                        if(G.qual==LR_CTRLKEY) {
                                node_rename(snode);