Long on the wishlist, quite simple even, and there it finally is:

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...
This commit is contained in:
Ton Roosendaal 2008-03-08 19:02:08 +00:00
parent 19ec73c908
commit d7ef04a519
6 changed files with 291 additions and 139 deletions

@ -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,33 +1992,6 @@ void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread)
/* ***************************** threaded version for execute composite nodes ************* */
/* not changing info, for thread callback */
typedef struct ThreadData {
bNodeStack *stack;
RenderData *rd;
} ThreadData;
static void *exec_composite_node(void *node_v)
{
bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
bNode *node= node_v;
ThreadData *thd= (ThreadData *)node->new_node; /* abuse */
node_get_stack(node, thd->stack, nsin, nsout);
if(node->typeinfo->execfunc) {
node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
}
else if(node->type==NODE_GROUP && node->id) {
node_group_execute(thd->stack, thd->rd, node, nsin, nsout);
}
node->exec |= NODE_READY;
return 0;
}
/* these are nodes without input, only giving values */
/* or nodes with only value inputs */
static int node_only_value(bNode *node)
@ -2038,6 +2013,40 @@ static int node_only_value(bNode *node)
return 0;
}
/* not changing info, for thread callback */
typedef struct ThreadData {
bNodeStack *stack;
RenderData *rd;
} ThreadData;
static void *exec_composite_node(void *node_v)
{
bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
bNode *node= node_v;
ThreadData *thd= (ThreadData *)node->new_node; /* abuse */
node_get_stack(node, thd->stack, nsin, nsout);
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) {
node_group_execute(thd->stack, thd->rd, node, nsin, nsout);
}
node->exec |= NODE_READY;
return 0;
}
/* return total of executable nodes, for timecursor */
/* only compositor uses it */
static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)

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

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

@ -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);

@ -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) {
@ -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;

@ -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);