Orange: made Compositing more interactive. It now has an event based

system tracking changes in nodes, making sure only these nodes and
the ones that depend, are executed.

Further the 'time cursor' now counts down to indicate which node is being
done.

Also: you now can disable the "use nodes" button in the header, edit all
changes, and when you press that button again it nicely executes the
changes.

Still on the todo:
- make compositing threaded
- find a way to nicely exit compositing on input events... so the UI
  keeps being responsive
- idea; a 'percentage' menu in header to enforce calculations on smaller
  images temporally
This commit is contained in:
Ton Roosendaal 2006-01-28 15:21:04 +00:00
parent 80bd3a1e98
commit 45c7b2c5c2
13 changed files with 358 additions and 125 deletions

@ -41,6 +41,7 @@ struct bNodeStack;
struct uiBlock; struct uiBlock;
struct rctf; struct rctf;
struct ListBase; struct ListBase;
struct RenderData;
#define SOCK_IN 1 #define SOCK_IN 1
#define SOCK_OUT 2 #define SOCK_OUT 2
@ -101,6 +102,7 @@ void ntreeSolveOrder(struct bNodeTree *ntree);
void ntreeBeginExecTree(struct bNodeTree *ntree); void ntreeBeginExecTree(struct bNodeTree *ntree);
void ntreeExecTree(struct bNodeTree *ntree, void *callerdata, int thread); void ntreeExecTree(struct bNodeTree *ntree, void *callerdata, int thread);
void ntreeCompositExecTree(struct bNodeTree *ntree, struct RenderData *rd, int do_previews);
void ntreeEndExecTree(struct bNodeTree *ntree); void ntreeEndExecTree(struct bNodeTree *ntree);
void ntreeInitPreview(struct bNodeTree *, int xsize, int ysize); void ntreeInitPreview(struct bNodeTree *, int xsize, int ysize);
@ -126,6 +128,8 @@ struct bNode *nodeGetActive(struct bNodeTree *ntree);
struct bNode *nodeGetActiveID(struct bNodeTree *ntree, short idtype); struct bNode *nodeGetActiveID(struct bNodeTree *ntree, short idtype);
void nodeClearActiveID(struct bNodeTree *ntree, short idtype); void nodeClearActiveID(struct bNodeTree *ntree, short idtype);
void NodeTagChanged(struct bNodeTree *ntree, struct bNode *node);
/* ************** Groups ****************** */ /* ************** Groups ****************** */
struct bNode *nodeMakeGroupFromSelected(struct bNodeTree *ntree); struct bNode *nodeMakeGroupFromSelected(struct bNodeTree *ntree);
@ -218,9 +222,9 @@ extern bNodeType *node_all_composit[];
/* API */ /* API */
struct CompBuf; struct CompBuf;
struct RenderData;
void ntreeCompositExecTree(struct bNodeTree *ntree, struct RenderData *rd, int do_previews);
int ntreeCompositNeedsRender(struct bNodeTree *ntree); int ntreeCompositNeedsRender(struct bNodeTree *ntree);
void ntreeCompositTagRender(struct bNodeTree *ntree);
void free_compbuf(struct CompBuf *cbuf); /* internal...*/ void free_compbuf(struct CompBuf *cbuf); /* internal...*/
#endif #endif

@ -38,6 +38,7 @@
#include "BKE_blender.h" #include "BKE_blender.h"
#include "BKE_colortools.h" #include "BKE_colortools.h"
#include "BKE_global.h" #include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_library.h" #include "BKE_library.h"
#include "BKE_main.h" #include "BKE_main.h"
#include "BKE_node.h" #include "BKE_node.h"
@ -282,7 +283,7 @@ static void group_verify_own_indices(bNodeTree *ngroup)
if(sock->own_index==0 && sock->intern==0) if(sock->own_index==0 && sock->intern==0)
sock->own_index= ++(ngroup->cur_index); sock->own_index= ++(ngroup->cur_index);
} }
printf("internal index %d\n", ngroup->cur_index); // printf("internal index %d\n", ngroup->cur_index);
} }
@ -776,8 +777,10 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
sock->own_index= 0; sock->own_index= 0;
duplicatelist(&nnode->outputs, &node->outputs); duplicatelist(&nnode->outputs, &node->outputs);
for(sock= nnode->outputs.first; sock; sock= sock->next) for(sock= nnode->outputs.first; sock; sock= sock->next) {
sock->own_index= 0; sock->own_index= 0;
sock->ns.data= NULL;
}
if(nnode->id) if(nnode->id)
nnode->id->us++; nnode->id->us++;
@ -850,8 +853,10 @@ static void node_unlink_node(bNodeTree *ntree, bNode *node)
for(link= ntree->links.first; link; link= next) { for(link= ntree->links.first; link; link= next) {
next= link->next; next= link->next;
if(link->fromnode==node) if(link->fromnode==node) {
lb= &node->outputs; lb= &node->outputs;
NodeTagChanged(ntree, link->tonode);
}
else if(link->tonode==node) else if(link->tonode==node)
lb= &node->inputs; lb= &node->inputs;
else else
@ -869,6 +874,16 @@ static void node_unlink_node(bNodeTree *ntree, bNode *node)
} }
} }
static void composit_free_sockets(bNode *node)
{
bNodeSocket *sock;
for(sock= node->outputs.first; sock; sock= sock->next) {
if(sock->ns.data)
free_compbuf(sock->ns.data);
}
}
void nodeFreeNode(bNodeTree *ntree, bNode *node) void nodeFreeNode(bNodeTree *ntree, bNode *node)
{ {
node_unlink_node(ntree, node); node_unlink_node(ntree, node);
@ -877,6 +892,8 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node)
if(node->id) if(node->id)
node->id->us--; node->id->us--;
if(ntree->type==NTREE_COMPOSIT)
composit_free_sockets(node);
BLI_freelistN(&node->inputs); BLI_freelistN(&node->inputs);
BLI_freelistN(&node->outputs); BLI_freelistN(&node->outputs);
@ -1207,6 +1224,22 @@ void ntreeSolveOrder(bNodeTree *ntree)
might be different for editor or for "real" use... */ might be different for editor or for "real" use... */
} }
/* should be callback! */
void NodeTagChanged(bNodeTree *ntree, bNode *node)
{
if(ntree->type==NTREE_COMPOSIT) {
bNodeSocket *sock;
for(sock= node->outputs.first; sock; sock= sock->next) {
if(sock->ns.data) {
free_compbuf(sock->ns.data);
sock->ns.data= NULL;
}
}
node->need_exec= 1;
}
}
#pragma mark /* *************** preview *********** */ #pragma mark /* *************** preview *********** */
/* if node->preview, then we assume the rect to exist */ /* if node->preview, then we assume the rect to exist */
@ -1362,6 +1395,54 @@ static int ntree_begin_exec_tree(bNodeTree *ntree)
return index; return index;
} }
/* copy socket compbufs to stack */
static void composit_begin_exec(bNodeTree *ntree)
{
bNode *node;
for(node= ntree->nodes.first; node; node= node->next) {
bNodeSocket *sock;
for(sock= node->outputs.first; sock; sock= sock->next) {
if(sock->ns.data) {
bNodeStack *ns= ntree->stack + sock->stack_index;
ns->data= sock->ns.data;
sock->ns.data= NULL;
}
}
}
}
/* copy stack compbufs to sockets */
static void composit_end_exec(bNodeTree *ntree)
{
extern void print_compbuf(char *str, struct CompBuf *cbuf);
bNode *node;
bNodeStack *ns;
int a;
for(node= ntree->nodes.first; node; node= node->next) {
bNodeSocket *sock;
for(sock= node->outputs.first; sock; sock= sock->next) {
ns= ntree->stack + sock->stack_index;
if(ns->data) {
sock->ns.data= ns->data;
ns->data= NULL;
}
}
node->need_exec= 0;
}
for(ns= ntree->stack, a=0; a<ntree->stacksize; a++, ns++) {
if(ns->data) {
print_compbuf("error: buf hanging in stack", ns->data);
free_compbuf(ns->data);
}
}
}
/* stack indices make sure all nodes only write in allocated data, for making it thread safe */ /* stack indices make sure all nodes only write in allocated data, for making it thread safe */
/* only root tree gets the stack, to enable instances to have own stack entries */ /* only root tree gets the stack, to enable instances to have own stack entries */
/* only two threads now! */ /* only two threads now! */
@ -1385,7 +1466,8 @@ void ntreeBeginExecTree(bNodeTree *ntree)
/* tag inputs, the get_stack() gives own socket stackdata if not in use */ /* tag inputs, the get_stack() gives own socket stackdata if not in use */
for(a=0; a<ntree->stacksize; a++, ns++) ns->hasinput= 1; for(a=0; a<ntree->stacksize; a++, ns++) ns->hasinput= 1;
/* tag outputs, so we know when we can skip operations */ /* tag used outputs, so we know when we can skip operations */
/* hrms... groups... */
for(node= ntree->nodes.first; node; node= node->next) { for(node= ntree->nodes.first; node; node= node->next) {
bNodeSocket *sock; bNodeSocket *sock;
for(sock= node->inputs.first; sock; sock= sock->next) { for(sock= node->inputs.first; sock; sock= sock->next) {
@ -1395,8 +1477,10 @@ void ntreeBeginExecTree(bNodeTree *ntree)
} }
} }
} }
if(ntree->type==NTREE_COMPOSIT)
ntree->stack1= MEM_dupallocN(ntree->stack); composit_begin_exec(ntree);
else
ntree->stack1= MEM_dupallocN(ntree->stack);
} }
ntree->init |= NTREE_EXEC_INIT; ntree->init |= NTREE_EXEC_INIT;
@ -1407,25 +1491,17 @@ void ntreeEndExecTree(bNodeTree *ntree)
if(ntree->init & NTREE_EXEC_INIT) { if(ntree->init & NTREE_EXEC_INIT) {
if(ntree->stack) { /* another callback candidate! */
if(ntree->type==NTREE_COMPOSIT)
/* another callback candidate! */ composit_end_exec(ntree);
if(ntree->type==NTREE_COMPOSIT) {
bNodeStack *ns; if(ntree->stack)
int a;
for(ns= ntree->stack, a=0; a<ntree->stacksize; a++, ns++)
if(ns->data)
free_compbuf(ns->data);
for(ns= ntree->stack1, a=0; a<ntree->stacksize; a++, ns++)
if(ns->data)
free_compbuf(ns->data);
}
MEM_freeN(ntree->stack); MEM_freeN(ntree->stack);
ntree->stack= NULL; ntree->stack= NULL;
if(ntree->stack1)
MEM_freeN(ntree->stack1); MEM_freeN(ntree->stack1);
ntree->stack1= NULL; ntree->stack1= NULL;
}
ntree->init &= ~NTREE_EXEC_INIT; ntree->init &= ~NTREE_EXEC_INIT;
} }
@ -1477,3 +1553,78 @@ void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread)
} }
} }
/* optimized tree execute test for compositing */
void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
{
bNode *node;
bNodeSocket *sock;
bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
bNodeStack *stack;
int totnode;
if(ntree==NULL) return;
totnode= BLI_countlist(&ntree->nodes);
if(do_preview)
ntreeInitPreview(ntree, 0, 0);
ntreeBeginExecTree(ntree);
stack= ntree->stack;
for(node= ntree->nodes.first; node; node= node->next) {
if(node->typeinfo->execfunc) {
int a;
node_get_stack(node, stack, nsin, nsout);
/* test the inputs */
for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) {
/* is sock in use? */
if(sock->link) {
if(nsin[a]->data==NULL || sock->link->fromnode->need_exec) {
node->need_exec= 1;
break;
}
}
}
/* test the outputs */
for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
if(nsout[a]->data==NULL && nsout[a]->hasoutput) {
node->need_exec= 1;
break;
}
}
if(node->need_exec) {
/* free output buffers */
for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
if(nsout[a]->data) {
free_compbuf(nsout[a]->data);
nsout[a]->data= NULL;
}
}
if(ntree->timecursor)
ntree->timecursor(totnode);
printf("exec node %s\n", node->name);
node->typeinfo->execfunc(rd, node, nsin, nsout);
}
}
else if(node->type==NODE_GROUP && node->id) {
node_get_stack(node, stack, nsin, nsout);
node_group_execute(stack, rd, node, nsin, nsout);
}
totnode--;
}
ntreeEndExecTree(ntree);
free_unused_animimages();
}

@ -81,9 +81,9 @@ static CompBuf *alloc_compbuf(int sizex, int sizey, int type, int alloc)
cbuf->type= type; cbuf->type= type;
if(alloc) { if(alloc) {
if(cbuf->type==CB_RGBA) if(cbuf->type==CB_RGBA)
cbuf->rect= MEM_mallocN(4*sizeof(float)*sizex*sizey, "new rect"); cbuf->rect= MEM_mallocN(4*sizeof(float)*sizex*sizey, "compbuf RGBA rect");
else else
cbuf->rect= MEM_mallocN(sizeof(float)*sizex*sizey, "new rect"); cbuf->rect= MEM_mallocN(sizeof(float)*sizex*sizey, "compbuf Fac rect");
cbuf->malloc= 1; cbuf->malloc= 1;
} }
cbuf->disprect.xmin= 0; cbuf->disprect.xmin= 0;
@ -101,6 +101,14 @@ void free_compbuf(CompBuf *cbuf)
MEM_freeN(cbuf); MEM_freeN(cbuf);
} }
void print_compbuf(char *str, CompBuf *cbuf)
{
printf("Compbuf %s %d %d %p\n", str, cbuf->x, cbuf->y, cbuf->rect);
}
#if 0 #if 0
/* on first call, disprect should be initialized to 'out', then you can call this on all 'src' images */ /* on first call, disprect should be initialized to 'out', then you can call this on all 'src' images */
static void get_overlap_rct(CompBuf *out, CompBuf *src, rcti *disprect) static void get_overlap_rct(CompBuf *out, CompBuf *src, rcti *disprect)
@ -449,7 +457,7 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in,
cbuf= alloc_compbuf(rectx, recty, CB_RGBA, 0); // no alloc cbuf= alloc_compbuf(rectx, recty, CB_RGBA, 0); // no alloc
cbuf->rect= ima->ibuf->rect_float; cbuf->rect= ima->ibuf->rect_float;
/* when no alpha, we can simply copy */ /* when no alpha, we can simply copy */
if(in[1]->data==NULL) if(in[1]->data==NULL)
composit1_pixel_processor(node, cbuf, in[0]->data, in[0]->vec, do_copy_rgba); composit1_pixel_processor(node, cbuf, in[0]->data, in[0]->vec, do_copy_rgba);
@ -733,6 +741,7 @@ static bNodeSocketType cmp_node_rresult_out[]= {
static void node_composit_exec_rresult(void *data, bNode *node, bNodeStack **in, bNodeStack **out) static void node_composit_exec_rresult(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{ {
RenderResult *rr= RE_GetResult(RE_GetRender("Render")); RenderResult *rr= RE_GetResult(RE_GetRender("Render"));
if(rr) { if(rr) {
RenderLayer *rl= BLI_findlink(&rr->layers, node->custom1); RenderLayer *rl= BLI_findlink(&rr->layers, node->custom1);
if(rl) { if(rl) {
@ -1815,7 +1824,7 @@ bNodeType *node_all_composit[]= {
NULL NULL
}; };
/* ******************* execute and parse ************ */ /* ******************* parse ************ */
/* helper call to detect if theres a render-result node */ /* helper call to detect if theres a render-result node */
int ntreeCompositNeedsRender(bNodeTree *ntree) int ntreeCompositNeedsRender(bNodeTree *ntree)
@ -1831,23 +1840,15 @@ int ntreeCompositNeedsRender(bNodeTree *ntree)
return 0; return 0;
} }
/* note; if called without preview, and previews exist, they get updated */ void ntreeCompositTagRender(bNodeTree *ntree)
/* render calls it without previews, works nicer for bg render */
void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
{ {
bNode *node;
if(ntree==NULL) return; if(ntree==NULL) return;
if(do_preview) for(node= ntree->nodes.first; node; node= node->next) {
ntreeInitPreview(ntree, 0, 0); if(node->type==CMP_NODE_R_RESULT)
NodeTagChanged(ntree, node);
ntreeBeginExecTree(ntree); }
/* allocate composit data? */
ntreeExecTree(ntree, rd, 0); /* threads */
ntreeEndExecTree(ntree);
free_unused_animimages();
} }

@ -494,7 +494,8 @@ void scene_add_render_layer(Scene *sce)
srl= MEM_callocN(sizeof(SceneRenderLayer), "new render layer"); srl= MEM_callocN(sizeof(SceneRenderLayer), "new render layer");
sprintf(srl->name, "%d RenderLayer", tot); sprintf(srl->name, "%d RenderLayer", tot);
BLI_addtail(&sce->r.layers, srl); BLI_addtail(&sce->r.layers, srl);
/* note, this is also in render, pipeline.c, to make layer when scenedata doesnt have it */
srl->lay= (1<<20) -1; srl->lay= (1<<20) -1;
srl->layflag= 0x7FFF; /* solid ztra halo strand */ srl->layflag= 0x7FFF; /* solid ztra halo strand */
srl->passflag= SCE_PASS_COMBINED|SCE_PASS_Z; srl->passflag= SCE_PASS_COMBINED|SCE_PASS_Z;

@ -1260,6 +1260,7 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
ntree->init= 0; /* to set callbacks */ ntree->init= 0; /* to set callbacks */
ntree->owntype= NULL; ntree->owntype= NULL;
ntree->timecursor= NULL;
link_list(fd, &ntree->nodes); link_list(fd, &ntree->nodes);
for(node= ntree->nodes.first; node; node= node->next) { for(node= ntree->nodes.first; node; node= node->next) {
@ -1285,6 +1286,8 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
node->lasty= 0; node->lasty= 0;
for(sock= node->inputs.first; sock; sock= sock->next) for(sock= node->inputs.first; sock; sock= sock->next)
sock->link= newdataadr(fd, sock->link); sock->link= newdataadr(fd, sock->link);
for(sock= node->outputs.first; sock; sock= sock->next)
sock->ns.data= NULL;
} }
for(link= ntree->links.first; link; link= link->next) { for(link= ntree->links.first; link; link= link->next) {
link->fromnode= newdataadr(fd, link->fromnode); link->fromnode= newdataadr(fd, link->fromnode);

@ -194,9 +194,6 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_MAT_LAYERBROWSE 1220 #define B_MAT_LAYERBROWSE 1220
#define B_MAT_USENODES 1221 #define B_MAT_USENODES 1221
/* also handled in editnode.c */
#define B_NODE_EXEC 1222
#define B_NODE_LOADIMAGE 1223
/* *********************** */ /* *********************** */
#define B_TEXBUTS 1400 #define B_TEXBUTS 1400
@ -655,8 +652,21 @@ enum {
#define B_MODIFIER_REDRAW 3502 #define B_MODIFIER_REDRAW 3502
/* *********************** */ /* *********************** */
/* BUTTON BUT: > 4000 */ #define B_NODE_BUTS 4000
/* BUTTON 4001-4032: layers */ /* 400 slots reserved, we want an exec event for each node */
#define B_NODE_LOADIMAGE 3601
#define B_NODE_TREE_EXEC 3602
/* exec should be last in this list */
#define B_NODE_EXEC 3610
/* *********************** */
/* BUTTON 4001-4032: layers? (sort this out!) */
/* *********************** */
/* event code 0x4000 (16384) and larger: general events (redraws, etc) */
#endif #endif

@ -51,7 +51,7 @@ typedef struct bNodeStack {
short hasinput; /* when input has link, tagged before executing */ short hasinput; /* when input has link, tagged before executing */
short hasoutput; /* when output is linked, tagged before executing */ short hasoutput; /* when output is linked, tagged before executing */
short datatype; /* type of data pointer */ short datatype; /* type of data pointer */
short pad1; short pad;
} bNodeStack; } bNodeStack;
/* ns->datatype, shadetree only */ /* ns->datatype, shadetree only */
@ -109,7 +109,7 @@ typedef struct bNode {
short done, level; /* both for dependency and sorting */ short done, level; /* both for dependency and sorting */
short lasty, menunr; /* lasty: check preview render status, menunr: browse ID blocks */ short lasty, menunr; /* lasty: check preview render status, menunr: browse ID blocks */
short stack_index; /* for groupnode, offset in global caller stack */ short stack_index; /* for groupnode, offset in global caller stack */
short pad; short nr; /* number of this node in list, used for exec events */
ListBase inputs, outputs; ListBase inputs, outputs;
struct ID *id; /* optional link to libdata */ struct ID *id; /* optional link to libdata */
@ -119,7 +119,8 @@ typedef struct bNode {
float locx, locy; /* root offset for drawing */ float locx, locy; /* root offset for drawing */
float width, miniwidth; float width, miniwidth;
short custom1, custom2; /* to be abused for buttons */ short custom1, custom2; /* to be abused for buttons */
int pad1;
short need_exec, pad1; /* need_exec is set to optimize execution */
rctf totr; /* entire boundbox */ rctf totr; /* entire boundbox */
rctf butr; /* optional buttons area */ rctf butr; /* optional buttons area */
@ -164,6 +165,9 @@ typedef struct bNodeTree {
struct bNodeType **alltypes; /* type definitions, set on fileread, no read/write */ struct bNodeType **alltypes; /* type definitions, set on fileread, no read/write */
struct bNodeType *owntype; /* for groups or dynamic trees, no read/write */ struct bNodeType *owntype; /* for groups or dynamic trees, no read/write */
/* callbacks */
void (*timecursor)(int nr);
} bNodeTree; } bNodeTree;
/* ntree->type, index */ /* ntree->type, index */

@ -832,7 +832,7 @@ static void do_render_final(Render *re, Scene *scene)
/* first check if theres nodetree with render result */ /* first check if theres nodetree with render result */
int do_render= ntreeCompositNeedsRender(scene->nodetree); int do_render= ntreeCompositNeedsRender(scene->nodetree);
/* but.. do we use nodes? */ /* but.. do we use nodes? */
if(scene->use_nodes==NULL) do_render= 1; if(scene->use_nodes==0) do_render= 1;
re->scene= scene; re->scene= scene;
@ -847,6 +847,9 @@ static void do_render_final(Render *re, Scene *scene)
else else
render_one_frame(re); render_one_frame(re);
} }
ntreeCompositTagRender(scene->nodetree);
if(re->r.scemode & R_DOCOMP) if(re->r.scemode & R_DOCOMP)
ntreeCompositExecTree(scene->nodetree, &re->r, 0); ntreeCompositExecTree(scene->nodetree, &re->r, 0);
} }

@ -42,6 +42,7 @@
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
#include "DNA_color_types.h" #include "DNA_color_types.h"
#include "DNA_material_types.h"
#include "DNA_object_types.h" #include "DNA_object_types.h"
#include "DNA_scene_types.h" #include "DNA_scene_types.h"
#include "DNA_screen_types.h" #include "DNA_screen_types.h"
@ -52,12 +53,14 @@
#include "BKE_colortools.h" #include "BKE_colortools.h"
#include "BKE_global.h" #include "BKE_global.h"
#include "BKE_main.h" #include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_library.h" #include "BKE_library.h"
#include "BKE_utildefines.h" #include "BKE_utildefines.h"
#include "BLI_blenlib.h" #include "BLI_blenlib.h"
#include "BSE_drawview.h" // for do_viewbuttons.c .... hurms #include "BSE_drawview.h" // for do_viewbuttons.c .... hurms
#include "BSE_node.h"
#include "BIF_gl.h" #include "BIF_gl.h"
#include "BIF_graphics.h" #include "BIF_graphics.h"
@ -470,6 +473,26 @@ void curvemap_buttons(uiBlock *block, CurveMapping *cumap, char labeltype, short
/* --------------------------------- */ /* --------------------------------- */
/* nodes have button callbacks, that can draw in butspace too. need separate handling */
static void do_node_buts(unsigned short event)
{
Material *ma;
/* all operations default on active material layer here */
/* but this also gets called for lamp and world... */
ma= G.buts->lockpoin;
if(ma && GS(ma->id.name)==ID_MA)
ma = editnode_get_active_material(ma);
else
ma= NULL;
if(event>=B_NODE_EXEC) {
if(ma) end_render_material(ma); /// temporal... 3d preview
BIF_preview_changed(ID_MA);
allqueue(REDRAWNODE, 0);
allqueue(REDRAWBUTSSHADING, 0);
}
}
void do_butspace(unsigned short event) void do_butspace(unsigned short event)
{ {
@ -566,6 +589,9 @@ void do_butspace(unsigned short event)
extern void do_modifier_panels(unsigned short event); extern void do_modifier_panels(unsigned short event);
do_modifier_panels(event); do_modifier_panels(event);
} }
else if(event<=B_NODE_BUTS) {
do_node_buts(event);
}
else if(event==REDRAWVIEW3D) allqueue(event, 1); // 1=do header too else if(event==REDRAWVIEW3D) allqueue(event, 1); // 1=do header too
else if(event>REDRAWVIEW3D) allqueue(event, 0); else if(event>REDRAWVIEW3D) allqueue(event, 0);
} }

@ -2548,13 +2548,6 @@ void do_matbuts(unsigned short event)
allqueue(REDRAWBUTSSHADING, 0); allqueue(REDRAWBUTSSHADING, 0);
} }
break; break;
case B_NODE_EXEC:
if(ma) end_render_material(ma); /// temporal... 3d preview
BIF_preview_changed(ID_MA);
allqueue(REDRAWNODE, 0);
allqueue(REDRAWBUTSSHADING, 0);
break;
} }
} }

@ -208,7 +208,7 @@ static int node_buts_value(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *
if(block) { if(block) {
bNodeSocket *sock= node->outputs.first; /* first socket stores value */ bNodeSocket *sock= node->outputs.first; /* first socket stores value */
uiDefButF(block, NUM, B_NODE_EXEC, "", uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "",
butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
sock->ns.vec, 0.0f, 1.0f, 10, 2, ""); sock->ns.vec, 0.0f, 1.0f, 10, 2, "");
@ -224,10 +224,10 @@ static int node_buts_rgb(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *bu
/* enforce square box drawing */ /* enforce square box drawing */
uiBlockSetEmboss(block, UI_EMBOSSP); uiBlockSetEmboss(block, UI_EMBOSSP);
uiDefButF(block, HSVCUBE, B_NODE_EXEC, "", uiDefButF(block, HSVCUBE, B_NODE_EXEC+node->nr, "",
butr->xmin, butr->ymin, butr->xmax-butr->xmin, 12, butr->xmin, butr->ymin, butr->xmax-butr->xmin, 12,
sock->ns.vec, 0.0f, 1.0f, 3, 0, ""); sock->ns.vec, 0.0f, 1.0f, 3, 0, "");
uiDefButF(block, HSVCUBE, B_NODE_EXEC, "", uiDefButF(block, HSVCUBE, B_NODE_EXEC+node->nr, "",
butr->xmin, butr->ymin+15, butr->xmax-butr->xmin, butr->ymax-butr->ymin -15 -15, butr->xmin, butr->ymin+15, butr->xmax-butr->xmin, butr->ymax-butr->ymin -15 -15,
sock->ns.vec, 0.0f, 1.0f, 2, 0, ""); sock->ns.vec, 0.0f, 1.0f, 2, 0, "");
uiDefButF(block, COL, B_NOP, "", uiDefButF(block, COL, B_NOP, "",
@ -247,7 +247,7 @@ static int node_buts_mix_rgb(uiBlock *block, bNodeTree *ntree, bNode *node, rctf
uiBut *bt; uiBut *bt;
/* blend type */ /* blend type */
bt=uiDefButS(block, MENU, B_NODE_EXEC, "Mix %x0|Add %x1|Subtract %x3|Multiply %x2|Screen %x4|Divide %x5|Difference %x6|Darken %x7|Lighten %x8", bt=uiDefButS(block, MENU, B_NODE_EXEC+node->nr, "Mix %x0|Add %x1|Subtract %x3|Multiply %x2|Screen %x4|Divide %x5|Difference %x6|Darken %x7|Lighten %x8",
butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
&node->custom1, 0, 0, 0, 0, ""); &node->custom1, 0, 0, 0, 0, "");
uiButSetFunc(bt, node_but_title_cb, node, bt); uiButSetFunc(bt, node_but_title_cb, node, bt);
@ -259,7 +259,7 @@ static int node_buts_valtorgb(uiBlock *block, bNodeTree *ntree, bNode *node, rct
{ {
if(block) { if(block) {
if(node->storage) { if(node->storage) {
draw_colorband_buts_small(block, node->storage, butr, B_NODE_EXEC); draw_colorband_buts_small(block, node->storage, butr, B_NODE_EXEC+node->nr);
} }
} }
return 40; return 40;
@ -268,7 +268,7 @@ static int node_buts_valtorgb(uiBlock *block, bNodeTree *ntree, bNode *node, rct
static int node_buts_curvevec(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) static int node_buts_curvevec(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{ {
if(block) { if(block) {
curvemap_buttons(block, node->storage, 'v', B_NODE_EXEC, B_REDR, butr); curvemap_buttons(block, node->storage, 'v', B_NODE_EXEC+node->nr, B_REDR, butr);
} }
return (int)(node->width-NODE_DY); return (int)(node->width-NODE_DY);
} }
@ -276,7 +276,7 @@ static int node_buts_curvevec(uiBlock *block, bNodeTree *ntree, bNode *node, rct
static int node_buts_curvecol(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) static int node_buts_curvecol(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{ {
if(block) { if(block) {
curvemap_buttons(block, node->storage, 'c', B_NODE_EXEC, B_REDR, butr); curvemap_buttons(block, node->storage, 'c', B_NODE_EXEC+node->nr, B_REDR, butr);
} }
return (int)(node->width-NODE_DY); return (int)(node->width-NODE_DY);
} }
@ -286,7 +286,7 @@ static int node_buts_normal(uiBlock *block, bNodeTree *ntree, bNode *node, rctf
if(block) { if(block) {
bNodeSocket *sock= node->outputs.first; /* first socket stores normal */ bNodeSocket *sock= node->outputs.first; /* first socket stores normal */
uiDefButF(block, BUT_NORMAL, B_NODE_EXEC, "", uiDefButF(block, BUT_NORMAL, B_NODE_EXEC+node->nr, "",
butr->xmin, butr->ymin, butr->xmax-butr->xmin, butr->ymax-butr->ymin, butr->xmin, butr->ymin, butr->xmax-butr->xmin, butr->ymax-butr->ymin,
sock->ns.vec, 0.0f, 1.0f, 0, 0, ""); sock->ns.vec, 0.0f, 1.0f, 0, 0, "");
@ -426,13 +426,13 @@ static int node_shader_buts_material(uiBlock *block, bNodeTree *ntree, bNode *no
if(butr->ymax-butr->ymin > 21.0f) { if(butr->ymax-butr->ymin > 21.0f) {
/* node options */ /* node options */
uiBlockSetCol(block, TH_AUTO); uiBlockSetCol(block, TH_AUTO);
uiDefButBitS(block, TOG, SH_NODE_MAT_DIFF, B_NODE_EXEC, "Diff", uiDefButBitS(block, TOG, SH_NODE_MAT_DIFF, B_NODE_EXEC+node->nr, "Diff",
butr->xmin, butr->ymin, dx, 19, butr->xmin, butr->ymin, dx, 19,
&node->custom1, 0, 0, 0, 0, "Material Node outputs Diffuse"); &node->custom1, 0, 0, 0, 0, "Material Node outputs Diffuse");
uiDefButBitS(block, TOG, SH_NODE_MAT_SPEC, B_NODE_EXEC, "Spec", uiDefButBitS(block, TOG, SH_NODE_MAT_SPEC, B_NODE_EXEC+node->nr, "Spec",
butr->xmin+dx, butr->ymin, dx, 19, butr->xmin+dx, butr->ymin, dx, 19,
&node->custom1, 0, 0, 0, 0, "Material Node outputs Specular"); &node->custom1, 0, 0, 0, 0, "Material Node outputs Specular");
uiDefButBitS(block, TOG, SH_NODE_MAT_NEG, B_NODE_EXEC, "Neg Normal", uiDefButBitS(block, TOG, SH_NODE_MAT_NEG, B_NODE_EXEC+node->nr, "Neg Normal",
butr->xmax-dx, butr->ymin, dx, 19, butr->xmax-dx, butr->ymin, dx, 19,
&node->custom1, 0, 0, 0, 0, "Material Node uses inverted Normal"); &node->custom1, 0, 0, 0, 0, "Material Node uses inverted Normal");
} }
@ -447,7 +447,7 @@ static int node_shader_buts_texture(uiBlock *block, bNodeTree *ntree, bNode *nod
if(block) { if(block) {
uiBut *bt; uiBut *bt;
bt= uiDefIDPoinBut(block, test_texpoin_but, ID_TE, B_NODE_EXEC, "", bt= uiDefIDPoinBut(block, test_texpoin_but, ID_TE, B_NODE_EXEC+node->nr, "",
butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19, butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19,
&node->id, ""); &node->id, "");
uiButSetFunc(bt, node_ID_title_cb, node, NULL); uiButSetFunc(bt, node_ID_title_cb, node, NULL);
@ -467,26 +467,26 @@ static int node_shader_buts_mapping(uiBlock *block, bNodeTree *ntree, bNode *nod
uiBlockSetFunc(block, node_texmap_cb, texmap, NULL); /* all buttons get this */ uiBlockSetFunc(block, node_texmap_cb, texmap, NULL); /* all buttons get this */
uiBlockBeginAlign(block); uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->loc, -1000.0f, 1000.0f, 10, 2, ""); uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+dx, dy, 2*dx, 19, texmap->loc, -1000.0f, 1000.0f, 10, 2, "");
uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->loc+1, -1000.0f, 1000.0f, 10, 2, ""); uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->loc+1, -1000.0f, 1000.0f, 10, 2, "");
uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->loc+2, -1000.0f, 1000.0f, 10, 2, ""); uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->loc+2, -1000.0f, 1000.0f, 10, 2, "");
dy-= 19; dy-= 19;
uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->rot, -1000.0f, 1000.0f, 1000, 1, ""); uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+dx, dy, 2*dx, 19, texmap->rot, -1000.0f, 1000.0f, 1000, 1, "");
uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->rot+1, -1000.0f, 1000.0f, 1000, 1, ""); uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->rot+1, -1000.0f, 1000.0f, 1000, 1, "");
uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->rot+2, -1000.0f, 1000.0f, 1000, 1, ""); uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->rot+2, -1000.0f, 1000.0f, 1000, 1, "");
dy-= 19; dy-= 19;
uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->size, -1000.0f, 1000.0f, 10, 2, ""); uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+dx, dy, 2*dx, 19, texmap->size, -1000.0f, 1000.0f, 10, 2, "");
uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->size+1, -1000.0f, 1000.0f, 10, 2, ""); uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->size+1, -1000.0f, 1000.0f, 10, 2, "");
uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->size+2, -1000.0f, 1000.0f, 10, 2, ""); uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->size+2, -1000.0f, 1000.0f, 10, 2, "");
dy-= 25; dy-= 25;
uiBlockBeginAlign(block); uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->min, -10.0f, 10.0f, 100, 2, ""); uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+dx, dy, 2*dx, 19, texmap->min, -10.0f, 10.0f, 100, 2, "");
uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->min+1, -10.0f, 10.0f, 100, 2, ""); uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->min+1, -10.0f, 10.0f, 100, 2, "");
uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->min+2, -10.0f, 10.0f, 100, 2, ""); uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->min+2, -10.0f, 10.0f, 100, 2, "");
dy-= 19; dy-= 19;
uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->max, -10.0f, 10.0f, 10, 2, ""); uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+dx, dy, 2*dx, 19, texmap->max, -10.0f, 10.0f, 10, 2, "");
uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->max+1, -10.0f, 10.0f, 10, 2, ""); uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->max+1, -10.0f, 10.0f, 10, 2, "");
uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->max+2, -10.0f, 10.0f, 10, 2, ""); uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->max+2, -10.0f, 10.0f, 10, 2, "");
uiBlockEndAlign(block); uiBlockEndAlign(block);
/* labels/options */ /* labels/options */
@ -498,9 +498,9 @@ static int node_shader_buts_mapping(uiBlock *block, bNodeTree *ntree, bNode *nod
dy-= 19; dy-= 19;
uiDefBut(block, LABEL, B_NOP, "Size", butr->xmin, dy, dx, 19, NULL, 0.0f, 0.0f, 0, 0, ""); uiDefBut(block, LABEL, B_NOP, "Size", butr->xmin, dy, dx, 19, NULL, 0.0f, 0.0f, 0, 0, "");
dy-= 25; dy-= 25;
uiDefButBitI(block, TOG, TEXMAP_CLIP_MIN, B_NODE_EXEC, "Min", butr->xmin, dy, dx-4, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, ""); uiDefButBitI(block, TOG, TEXMAP_CLIP_MIN, B_NODE_EXEC+node->nr, "Min", butr->xmin, dy, dx-4, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, "");
dy-= 19; dy-= 19;
uiDefButBitI(block, TOG, TEXMAP_CLIP_MAX, B_NODE_EXEC, "Max", butr->xmin, dy, dx-4, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, ""); uiDefButBitI(block, TOG, TEXMAP_CLIP_MAX, B_NODE_EXEC+node->nr, "Max", butr->xmin, dy, dx-4, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, "");
} }
return 5*19 + 6; return 5*19 + 6;
@ -640,17 +640,17 @@ static int node_composit_buts_image(uiBlock *block, bNodeTree *ntree, bNode *nod
short width= (short)(butr->xmax-butr->xmin)/2; short width= (short)(butr->xmax-butr->xmin)/2;
dy-= 19; dy-= 19;
uiDefButS(block, NUM, B_NODE_EXEC, "Frs:", uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Frs:",
butr->xmin, dy, width, 19, butr->xmin, dy, width, 19,
&nia->frames, 0.0, 10000.0, 0, 0, "Amount of images used in animation"); &nia->frames, 0.0, 10000.0, 0, 0, "Amount of images used in animation");
uiDefButS(block, NUM, B_NODE_EXEC, "SFra:", uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "SFra:",
butr->xmin+width, dy, width, 19, butr->xmin+width, dy, width, 19,
&nia->sfra, 1.0, 1000.0, 0, 0, "Start frame of animation"); &nia->sfra, 1.0, 1000.0, 0, 0, "Start frame of animation");
dy-= 19; dy-= 19;
uiDefButS(block, NUM, B_NODE_EXEC, "First:", uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "First:",
butr->xmin, dy, width, 19, butr->xmin, dy, width, 19,
&nia->nr, 0.0, 10000.0, 0, 0, "Number in image name, used as first in animation"); &nia->nr, 0.0, 10000.0, 0, 0, "Number in image name, used as first in animation");
uiDefButC(block, TOG, B_NODE_EXEC, "Cycl", uiDefButC(block, TOG, B_NODE_EXEC+node->nr, "Cycl",
butr->xmin+width, dy, width, 19, butr->xmin+width, dy, width, 19,
&nia->cyclic, 0.0, 0.0, 0, 0, "Make animation go cyclic"); &nia->cyclic, 0.0, 0.0, 0, 0, "Make animation go cyclic");
@ -687,7 +687,7 @@ static int node_composit_buts_renderresult(uiBlock *block, bNodeTree *ntree, bNo
char *strp; char *strp;
strp= scene_layer_menu(); strp= scene_layer_menu();
bt= uiDefButS(block, MENU, B_NODE_EXEC, strp, bt= uiDefButS(block, MENU, B_NODE_EXEC+node->nr, strp,
butr->xmin, butr->ymin, (butr->xmax-butr->xmin), 19, butr->xmin, butr->ymin, (butr->xmax-butr->xmin), 19,
&node->custom1, 0, 0, 0, 0, "Choose Render Layer"); &node->custom1, 0, 0, 0, 0, "Choose Render Layer");
uiButSetFunc(bt, node_but_title_cb, node, bt); uiButSetFunc(bt, node_but_title_cb, node, bt);
@ -702,10 +702,10 @@ static int node_composit_buts_blur(uiBlock *block, bNodeTree *ntree, bNode *node
uiBut *bt; uiBut *bt;
uiBlockBeginAlign(block); uiBlockBeginAlign(block);
bt=uiDefButS(block, NUM, B_NODE_EXEC, "X:", bt=uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "X:",
butr->xmin, butr->ymin, (butr->xmax-butr->xmin)/2, 19, butr->xmin, butr->ymin, (butr->xmax-butr->xmin)/2, 19,
&node->custom1, 0, 256, 0, 0, ""); &node->custom1, 0, 256, 0, 0, "");
bt=uiDefButS(block, NUM, B_NODE_EXEC, "Y:", bt=uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Y:",
butr->xmin+(butr->xmax-butr->xmin)/2, butr->ymin, (butr->xmax-butr->xmin)/2, 19, butr->xmin+(butr->xmax-butr->xmin)/2, butr->ymin, (butr->xmax-butr->xmin)/2, 19,
&node->custom2, 0, 256, 0, 0, ""); &node->custom2, 0, 256, 0, 0, "");
} }
@ -718,7 +718,7 @@ static int node_composit_buts_filter(uiBlock *block, bNodeTree *ntree, bNode *no
uiBut *bt; uiBut *bt;
/* blend type */ /* blend type */
bt=uiDefButS(block, MENU, B_NODE_EXEC, "Soften %x0|Sharpen %x1|Laplace %x2|Sobel %x3|Prewitt %x4|Kirsch %x5|Shadow %x6", bt=uiDefButS(block, MENU, B_NODE_EXEC+node->nr, "Soften %x0|Sharpen %x1|Laplace %x2|Sobel %x3|Prewitt %x4|Kirsch %x5|Shadow %x6",
butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
&node->custom1, 0, 0, 0, 0, ""); &node->custom1, 0, 0, 0, 0, "");
uiButSetFunc(bt, node_but_title_cb, node, bt); uiButSetFunc(bt, node_but_title_cb, node, bt);
@ -735,16 +735,16 @@ static int node_composit_buts_map_value(uiBlock *block, bNodeTree *ntree, bNode
short dx= (short)(butr->xmax-butr->xmin)/2; short dx= (short)(butr->xmax-butr->xmin)/2;
uiBlockBeginAlign(block); uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_NODE_EXEC, "Offs:", xstart, dy, 2*dx, 19, texmap->loc, -1000.0f, 1000.0f, 10, 2, ""); uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Offs:", xstart, dy, 2*dx, 19, texmap->loc, -1000.0f, 1000.0f, 10, 2, "");
dy-= 19; dy-= 19;
uiDefButF(block, NUM, B_NODE_EXEC, "Size:", xstart, dy, 2*dx, 19, texmap->size, -1000.0f, 1000.0f, 10, 3, ""); uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Size:", xstart, dy, 2*dx, 19, texmap->size, -1000.0f, 1000.0f, 10, 3, "");
dy-= 23; dy-= 23;
uiBlockBeginAlign(block); uiBlockBeginAlign(block);
uiDefButBitI(block, TOG, TEXMAP_CLIP_MIN, B_NODE_EXEC, "Min", xstart, dy, dx, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, ""); uiDefButBitI(block, TOG, TEXMAP_CLIP_MIN, B_NODE_EXEC+node->nr, "Min", xstart, dy, dx, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, "");
uiDefButF(block, NUM, B_NODE_EXEC, "", xstart+dx, dy, dx, 19, texmap->min, -1000.0f, 1000.0f, 10, 2, ""); uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", xstart+dx, dy, dx, 19, texmap->min, -1000.0f, 1000.0f, 10, 2, "");
dy-= 19; dy-= 19;
uiDefButBitI(block, TOG, TEXMAP_CLIP_MIN, B_NODE_EXEC, "Max", xstart, dy, dx, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, ""); uiDefButBitI(block, TOG, TEXMAP_CLIP_MIN, B_NODE_EXEC+node->nr, "Max", xstart, dy, dx, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, "");
uiDefButF(block, NUM, B_NODE_EXEC, "", xstart+dx, dy, dx, 19, texmap->min, -1000.0f, 1000.0f, 10, 2, ""); uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", xstart+dx, dy, dx, 19, texmap->min, -1000.0f, 1000.0f, 10, 2, "");
} }
return 80; return 80;
} }
@ -1315,7 +1315,7 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
butpoin= sock->tosock->ns.vec; butpoin= sock->tosock->ns.vec;
if(sock->type==SOCK_VALUE) { if(sock->type==SOCK_VALUE) {
bt= uiDefButF(node->block, NUM, B_NODE_EXEC, sock->name, bt= uiDefButF(node->block, NUM, B_NODE_EXEC+node->nr, sock->name,
(short)sock->locx+NODE_DYS, (short)(sock->locy)-9, (short)node->width-NODE_DY, 17, (short)sock->locx+NODE_DYS, (short)(sock->locy)-9, (short)node->width-NODE_DY, 17,
butpoin, 0.0f, 1.0f, 10, 2, ""); butpoin, 0.0f, 1.0f, 10, 2, "");
uiButSetFunc(bt, node_sync_cb, snode, node); uiButSetFunc(bt, node_sync_cb, snode, node);
@ -1330,7 +1330,7 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
if(labelw>0) width= 40; else width= node->width-NODE_DY; if(labelw>0) width= 40; else width= node->width-NODE_DY;
bt= uiDefButF(node->block, COL, B_NODE_EXEC, "", bt= uiDefButF(node->block, COL, B_NODE_EXEC+node->nr, "",
(short)(sock->locx+NODE_DYS), (short)sock->locy-8, width, 15, (short)(sock->locx+NODE_DYS), (short)sock->locy-8, width, 15,
butpoin, 0, 0, 0, 0, ""); butpoin, 0, 0, 0, 0, "");
uiButSetFunc(bt, node_sync_cb, snode, node); uiButSetFunc(bt, node_sync_cb, snode, node);
@ -1539,6 +1539,7 @@ static void node_draw_nodetree(ScrArea *sa, SpaceNode *snode, bNodeTree *ntree)
{ {
bNode *node; bNode *node;
bNodeLink *link; bNodeLink *link;
int a;
if(ntree==NULL) return; /* groups... */ if(ntree==NULL) return; /* groups... */
@ -1551,8 +1552,9 @@ static void node_draw_nodetree(ScrArea *sa, SpaceNode *snode, bNodeTree *ntree)
glDisable( GL_LINE_SMOOTH ); glDisable( GL_LINE_SMOOTH );
/* not selected first */ /* not selected first */
for(node= ntree->nodes.first; node; node= node->next) { for(a=0, node= ntree->nodes.first; node; node= node->next, a++) {
node->block= NULL; /* were freed */ node->block= NULL; /* were freed */
node->nr= a; /* index of node in list, used for exec event code */
if(!(node->flag & SELECT)) { if(!(node->flag & SELECT)) {
if(node->flag & NODE_GROUP_EDIT); if(node->flag & NODE_GROUP_EDIT);
else if(node->flag & NODE_HIDDEN) else if(node->flag & NODE_HIDDEN)

@ -140,12 +140,20 @@ static void snode_handle_recalc(SpaceNode *snode)
BIF_preview_changed(ID_MA); /* signals buttons windows and node editors */ BIF_preview_changed(ID_MA); /* signals buttons windows and node editors */
} }
else if(snode->treetype==NTREE_COMPOSIT) { else if(snode->treetype==NTREE_COMPOSIT) {
ntreeCompositExecTree(snode->nodetree, &G.scene->r, 1); /* 1 is do_previews */ if(G.scene->use_nodes) {
allqueue(REDRAWNODE, 1); snode->nodetree->timecursor= set_timecursor;
allqueue(REDRAWIMAGE, 1);
if(G.scene->r.scemode & R_DOCOMP) { ntreeCompositExecTree(snode->nodetree, &G.scene->r, 1); /* 1 is do_previews */
BIF_redraw_render_rect(); /* seems to screwup display? */
mywinset(curarea->win); waitcursor(0);
allqueue(REDRAWNODE, 1);
allqueue(REDRAWIMAGE, 1);
if(G.scene->r.scemode & R_DOCOMP) {
BIF_redraw_render_rect(); /* seems to screwup display? */
mywinset(curarea->win);
}
snode->nodetree->timecursor= NULL;
} }
} }
} }
@ -153,19 +161,21 @@ static void snode_handle_recalc(SpaceNode *snode)
static void shader_node_event(SpaceNode *snode, short event) static void shader_node_event(SpaceNode *snode, short event)
{ {
switch(event) { switch(event) {
case B_NODE_EXEC:
snode_handle_recalc(snode);
break;
case B_REDR: case B_REDR:
allqueue(REDRAWNODE, 1); allqueue(REDRAWNODE, 1);
break; break;
default:
/* B_NODE_EXEC */
snode_handle_recalc(snode);
break;
} }
} }
static void load_node_image(char *str) /* called from fileselect */ static void load_node_image(char *str) /* called from fileselect */
{ {
SpaceNode *snode= curarea->spacedata.first; SpaceNode *snode= curarea->spacedata.first;
bNode *node= nodeGetActive(snode->nodetree); bNode *node= nodeGetActive(snode->edittree);
Image *ima= NULL; Image *ima= NULL;
ima= add_image(str); ima= add_image(str);
@ -188,15 +198,12 @@ static void composit_node_event(SpaceNode *snode, short event)
{ {
switch(event) { switch(event) {
case B_NODE_EXEC:
snode_handle_recalc(snode);
break;
case B_REDR: case B_REDR:
allqueue(REDRAWNODE, 1); allqueue(REDRAWNODE, 1);
break; break;
case B_NODE_LOADIMAGE: case B_NODE_LOADIMAGE:
{ {
bNode *node= nodeGetActive(snode->nodetree); bNode *node= nodeGetActive(snode->edittree);
char name[FILE_MAXDIR+FILE_MAXFILE]; char name[FILE_MAXDIR+FILE_MAXFILE];
if(node->id) if(node->id)
@ -205,6 +212,16 @@ static void composit_node_event(SpaceNode *snode, short event)
activate_fileselect(FILE_SPECIAL, "SELECT IMAGE", name, load_node_image); activate_fileselect(FILE_SPECIAL, "SELECT IMAGE", name, load_node_image);
} }
case B_NODE_TREE_EXEC:
snode_handle_recalc(snode);
break;
default:
/* B_NODE_EXEC */
{
bNode *node= BLI_findlink(&snode->edittree->nodes, event-B_NODE_EXEC);
if(node) NodeTagChanged(snode->edittree, node);
snode_handle_recalc(snode);
}
} }
} }
@ -345,7 +362,10 @@ static void node_set_active(SpaceNode *snode, bNode *node)
tnode->flag &= ~NODE_DO_OUTPUT; tnode->flag &= ~NODE_DO_OUTPUT;
node->flag |= NODE_DO_OUTPUT; node->flag |= NODE_DO_OUTPUT;
if(was_output==0) snode_handle_recalc(snode); if(was_output==0) {
NodeTagChanged(snode->edittree, node);
snode_handle_recalc(snode);
}
/* add node doesnt link this yet... */ /* add node doesnt link this yet... */
if(node->id==NULL) { if(node->id==NULL) {
@ -1283,11 +1303,17 @@ static int node_add_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock,
else BIF_wait_for_statechange(); else BIF_wait_for_statechange();
} }
/* remove link? */
if(link->tonode==NULL || link->fromnode==NULL) { if(link->tonode==NULL || link->fromnode==NULL) {
nodeRemLink(snode->edittree, link); nodeRemLink(snode->edittree, link);
} }
else { else {
bNodeLink *tlink; bNodeLink *tlink;
/* send changed events for original tonode and new */
if(link->tonode)
NodeTagChanged(snode->edittree, link->tonode);
/* we might need to remove a link */ /* we might need to remove a link */
if(in_out==SOCK_OUT) { if(in_out==SOCK_OUT) {
if(nodeCountSocketLinks(snode->edittree, link->tosock) > tsock->limit) { if(nodeCountSocketLinks(snode->edittree, link->tosock) > tsock->limit) {
@ -1365,6 +1391,10 @@ static int node_add_link(SpaceNode *snode)
break; break;
} }
if(link) { if(link) {
/* send changed event to original tonode */
if(link->tonode)
NodeTagChanged(snode->edittree, link->tonode);
node= link->fromnode; node= link->fromnode;
sock= link->fromsock; sock= link->fromsock;
nodeRemLink(snode->edittree, link); nodeRemLink(snode->edittree, link);
@ -1472,11 +1502,12 @@ static void node_border_link_delete(SpaceNode *snode)
for(a=0; a<hits; a++) { for(a=0; a<hits; a++) {
bNodeLink *link= BLI_findlink(&snode->edittree->links, buffer[ (4 * a) + 3]); bNodeLink *link= BLI_findlink(&snode->edittree->links, buffer[ (4 * a) + 3]);
if(link) if(link)
link->tonode= NULL; /* first tag for delete, otherwise indices are wrong */ link->fromnode= NULL; /* first tag for delete, otherwise indices are wrong */
} }
for(link= snode->edittree->links.first; link; link= next) { for(link= snode->edittree->links.first; link; link= next) {
next= link->next; next= link->next;
if(link->tonode==NULL) { if(link->fromnode==NULL) {
NodeTagChanged(snode->edittree, link->tonode);
nodeRemLink(snode->edittree, link); nodeRemLink(snode->edittree, link);
} }
} }

@ -82,7 +82,11 @@ void do_node_buttons(ScrArea *sa, unsigned short event)
break; break;
case B_NODE_USESCENE: case B_NODE_USESCENE:
node_composit_default(G.scene); if(G.scene->use_nodes) {
if(G.scene->nodetree==NULL)
node_composit_default(G.scene);
addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC);
}
snode_set_context(snode); snode_set_context(snode);
allqueue(REDRAWNODE, 0); allqueue(REDRAWNODE, 0);
break; break;